Skip to content

Commit

Permalink
a little bit of refactoring in the CLI project
Browse files Browse the repository at this point in the history
  • Loading branch information
brentmaxwell committed Feb 1, 2024
1 parent 420df70 commit 7fc4265
Show file tree
Hide file tree
Showing 23 changed files with 32,419 additions and 32,278 deletions.
63 changes: 63 additions & 0 deletions LtAmpDotNet/LtAmpDotNet.Cli/Commands/BaseCommandDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using LtAmpDotNet.Lib;
using LtAmpDotNet.Tests.Mock;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LtAmpDotNet.Cli.Commands
{
internal abstract class BaseCommandDefinition
{
internal virtual Command CommandDefinition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

internal LtAmplifier? Amp;

internal virtual void Open()
{
if (!Console.IsOutputRedirected)
{
Console.Write($"Connecting to device {0}...");
}
Amp = new LtAmplifier(new MockHidDevice(), false);
WaitForEvent(() => { Amp.Open(); }, handler => Amp.AmplifierConnected += handler, 5);
}

/// <summary>Executes the command, and waits for the event to respond before continuing.</summary>
/// <param name="action">the action to run</param>
/// <param name="eventHandler">the event to wait for</param>
/// <param name="waitTime">timeout (in seconds)</param>
internal static EventArgs? WaitForEvent(Action action, Action<EventHandler> eventHandler, int waitTime = 5)
{
EventArgs? returnVal = null;
var wait = new AutoResetEvent(false);
eventHandler((sender, eventArgs) => {
returnVal = eventArgs;
wait.Set();
});
action.Invoke();
wait.WaitOne(TimeSpan.FromSeconds(waitTime));
return returnVal;
}

/// <summary>Executes the command, and waits for the event to respond before continuing.</summary>
/// <param name="action">the action to run</param>
/// <param name="eventHandler">the event to wait for</param>
/// <param name="waitTime">timeout (in seconds)</param>
internal static T? WaitForEvent<T>(Action action, Action<EventHandler<T>> eventHandler, int waitTime = 5)
{
T? returnVal = default;
var wait = new AutoResetEvent(false);
eventHandler((sender, eventArgs) => {
returnVal = eventArgs;
wait.Set();
});
action.Invoke();
wait.WaitOne(TimeSpan.FromSeconds(waitTime));
return returnVal;
}
}
}

33 changes: 15 additions & 18 deletions LtAmpDotNet/LtAmpDotNet.Cli/Commands/FootswitchCommandDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.CommandLine;
using LtAmpDotNet.Lib.Events;
using System.CommandLine;

namespace LtAmpDotNet.Cli.Commands
{
internal class FootswitchCommandDefinition
internal class FootswitchCommandDefinition : BaseCommandDefinition
{
internal Command CommandDefinition { get; set; }
internal override Command CommandDefinition { get; set; }

internal FootswitchCommandDefinition()
{
Expand All @@ -26,27 +27,23 @@ internal FootswitchCommandDefinition()

internal void FootswitchGet()
{
var wait = new AutoResetEvent(false);
Program.amp.QASlotsStatusMessageReceived += (sender, eventArgs) =>
Open();
if(Amp != null)
{
Console.WriteLine($"[{eventArgs.Message.QASlotsStatus.Slots[0]}],[{eventArgs.Message.QASlotsStatus.Slots[1]}]");
wait.Set();
};
Program.amp.GetQASlots();
wait.WaitOne(TimeSpan.FromSeconds(5));
FenderMessageEventArgs? eventArgs = WaitForEvent<FenderMessageEventArgs>(Amp.GetQASlots, handler => Amp.QASlotsStatusMessageReceived += handler, 5);
Console.WriteLine($"[{eventArgs?.Message?.QASlotsStatus.Slots[0]}],[{eventArgs?.Message?.QASlotsStatus.Slots[1]}]");
}
}

internal void FootswitchSet(uint presetBankIndexA, uint presetBankIndexB)
{
var wait = new AutoResetEvent(false);
Program.amp.QASlotsStatusMessageReceived += (sender, eventArgs) =>
Open();
if (Amp != null)
{
Console.WriteLine($"[{eventArgs.Message.QASlotsStatus.Slots[0]}],[{eventArgs.Message.QASlotsStatus.Slots[1]}]");
wait.Set();
};
uint[] slots = new uint[] { presetBankIndexA, presetBankIndexB };
Program.amp.SetQASlots(slots);
wait.WaitOne(TimeSpan.FromSeconds(5));
uint[] slots = [presetBankIndexA, presetBankIndexB];
FenderMessageEventArgs? eventArgs = WaitForEvent<FenderMessageEventArgs>(() => Amp.SetQASlots(slots), handler => Amp.QASlotsStatusMessageReceived += handler, 5);
Console.WriteLine($"[{eventArgs?.Message?.QASlotsStatus.Slots[0]}],[{eventArgs?.Message?.QASlotsStatus.Slots[1]}]");
}
}
}
}
14 changes: 14 additions & 0 deletions LtAmpDotNet/LtAmpDotNet.Cli/Commands/ICommandDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LtAmpDotNet.Cli.Commands
{
internal interface ICommandDefinition
{
Command CommandDefinition { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,40 @@
using NAudio.Midi;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LtAmpDotNet.Cli
namespace LtAmpDotNet.Cli.Commands
{
internal class MidiListener
internal class MidiCommandDefinition : BaseCommandDefinition
{
private LtAmplifier amp = new LtAmplifier();
internal override Command CommandDefinition { get; set; }

private Preset currentPreset;
internal Preset? currentPreset;

//private Dictionary<MidiEvent, Action> events;
internal readonly Dictionary<MidiCommandCode, Dictionary<MidiController, Action<int>>> eventCommands;

private Dictionary<MidiCommandCode, Dictionary<MidiController, Action<int>>> eventCommands;
internal MidiCommandDefinition()
{
var midiDeviceArgument = new Argument<int>(
name: "deviceId",
description: "MIDI deviceId",
getDefaultValue: () => 0
);

var midiCommand = new Command("midi", "Listen to MIDI mesages");
midiCommand.AddArgument(midiDeviceArgument);
midiCommand.SetHandler(StartListening, midiDeviceArgument);

var midiListCommand = new Command("list", "List midi devices");
midiListCommand.SetHandler(ListDevices);
midiCommand.AddCommand(midiListCommand);

CommandDefinition = midiCommand;

public MidiListener()
{
eventCommands = new Dictionary<MidiCommandCode, Dictionary<MidiController, Action<int>>>()
{
{
Expand All @@ -41,46 +55,54 @@ public MidiListener()
};
}

public void Open(int device = 0)
internal void StartListening(int deviceId)
{
Console.Write($"Connecting to device {0}...");
amp.AmplifierConnected += Amp_AmplifierConnected;
amp.MessageReceived += Amp_MessageReceived;
amp.Open();
var midiIn = new MidiIn(device);
Open();
Amp!.AmplifierConnected += Amp_AmplifierConnected;
Amp!.MessageReceived += Amp_MessageReceived;

var midiIn = new MidiIn(deviceId);
midiIn.MessageReceived += MidiIn_MessageReceived; ;
midiIn.ErrorReceived += MidiIn_ErrorReceived;
midiIn.Start();
Console.WriteLine("Connected");
while (true) { Thread.Sleep(100); }
}

private void Amp_MessageReceived(object? sender, Lib.Events.FenderMessageEventArgs e)
internal void ListDevices()
{
for (int device = 0; device < MidiIn.NumberOfDevices; device++)
{
Console.WriteLine($"{device} {MidiIn.DeviceInfo(device).ProductName} {MidiIn.DeviceInfo(device).ProductName}");
}
}

internal void Amp_MessageReceived(object? sender, Lib.Events.FenderMessageEventArgs e)
{
Console.WriteLine($"[AMP] {e.Message}");
}

private void Amp_AmplifierConnected(object? sender, EventArgs e)
internal void Amp_AmplifierConnected(object? sender, EventArgs e)
{
amp.CurrentPresetStatusMessageReceived += Amp_CurrentPresetStatusMessageReceived;
Amp!.CurrentPresetStatusMessageReceived += Amp_CurrentPresetStatusMessageReceived;
}

private void Amp_CurrentPresetStatusMessageReceived(object? sender, Lib.Events.FenderMessageEventArgs e)
internal void Amp_CurrentPresetStatusMessageReceived(object? sender, Lib.Events.FenderMessageEventArgs e)
{
currentPreset = Preset.FromString(e.Message.CurrentPresetStatus.CurrentPresetData);
currentPreset = Preset.FromString(e.Message!.CurrentPresetStatus.CurrentPresetData)!;
}

private void MidiIn_ErrorReceived(object? sender, MidiInMessageEventArgs e)
internal void MidiIn_ErrorReceived(object? sender, MidiInMessageEventArgs e)
{
Console.WriteLine($"[MIDI] Error: {e.RawMessage}");
}

private void MidiIn_MessageReceived(object? sender, MidiInMessageEventArgs e)
internal void MidiIn_MessageReceived(object? sender, MidiInMessageEventArgs e)
{
switch (e.MidiEvent.CommandCode)
{
case MidiCommandCode.ControlChange:
var ccEvent = ((ControlChangeEvent)e.MidiEvent);
var ccEvent = (ControlChangeEvent)e.MidiEvent;
eventCommands[ccEvent.CommandCode][ccEvent.Controller].Invoke(ccEvent.ControllerValue);
Console.WriteLine($"[MIDI] {ccEvent.CommandCode}: {ccEvent.Channel}: {ccEvent.Controller}: {ccEvent.ControllerValue}");
break;
Expand All @@ -90,41 +112,28 @@ private void MidiIn_MessageReceived(object? sender, MidiInMessageEventArgs e)
}
}

public void Bypass(string nodeId, int value)
internal void Bypass(string nodeId, int value)
{
if (amp.IsOpen)
if (Amp != null && Amp.IsOpen)
{
amp.SetDspUnitParameter(nodeId, new Lib.Model.Preset.DspUnitParameter() { Name = "bypass", Value = value > 64 });
Amp.SetDspUnitParameter(nodeId, new DspUnitParameter() { Name = "bypass", Value = value > 64 });
}
}

public void EnableTuner(int value)
internal void EnableTuner(int value)
{
if (amp.IsOpen)
if (Amp != null && Amp.IsOpen)
{
amp.SetTuner(value > 64);
Amp.SetTuner(value > 64);
}
}

public void BypassAll(int value)
internal void BypassAll(int value)
{
Bypass("stomp", value);
Bypass("mod", value);
Bypass("delay", value);
Bypass("reverb", value);
}

public static void ListDevices()
{
for (int device = 0; device < MidiIn.NumberOfDevices; device++)
{
Console.WriteLine($"{device} {MidiIn.DeviceInfo(device).ProductName} {MidiIn.DeviceInfo(device).ProductName}");
}
}
public static void StartListening(int deviceId)
{
var midiListener = new MidiListener();
midiListener.Open(deviceId);
}
}
}
44 changes: 44 additions & 0 deletions LtAmpDotNet/LtAmpDotNet.Cli/Commands/OtherCommandDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Google.Protobuf;
using LtAmpDotNet.Lib.Models.Protobuf;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LtAmpDotNet.Cli.Commands
{
internal class OtherCommandDefinition : BaseCommandDefinition
{
internal override Command CommandDefinition { get; set; }
internal OtherCommandDefinition()
{
var terminalCommand = new Command("term", "Terminal");
terminalCommand.SetHandler(Terminal);
CommandDefinition = terminalCommand;
}

internal void Terminal()
{
Open();
if(Amp != null)
{
IMessage definition = (IMessage)Activator.CreateInstance(typeof(FenderMessageLT))!;
string? input;
Amp.MessageReceived += Amp_MessageReceived;
while ((input = Console.ReadLine()) != null)
{
var message = (FenderMessageLT)JsonParser.Default.Parse(input, definition?.Descriptor);
Amp.SendMessage(message);
}
}
}

internal void Amp_MessageReceived(object? sender, Lib.Events.FenderMessageEventArgs e)
{
Console.WriteLine(e.Message);
}
}
}
Loading

0 comments on commit 7fc4265

Please sign in to comment.