App sync code, handles button presses from mixer and syncs changes from VM. Included python code from the mixer. Some other PCB changes, but still needs improvements
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
namespace HidSliders.Hid
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
87
HidSliders.Hid/HidInterface.cs
Normal file
87
HidSliders.Hid/HidInterface.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System.Reactive.Subjects;
|
||||
using HidLibrary;
|
||||
|
||||
namespace HidSliders.Hid
|
||||
{
|
||||
public class HidInterface
|
||||
{
|
||||
private IHidDevice? _device;
|
||||
private Subject<int[]> _sliderUpdate = new();
|
||||
private Subject<List<MixerButton>> _buttonsUpdate = new();
|
||||
|
||||
public IObservable<int[]> SliderObservable => _sliderUpdate;
|
||||
public IObservable<List<MixerButton>> ButtonsObservable => _buttonsUpdate;
|
||||
|
||||
public bool ConnectDevice(int vendorId, int devId)
|
||||
{
|
||||
var enumerator = new HidEnumerator();
|
||||
IEnumerable<IHidDevice> hidDevices = enumerator.Enumerate(vendorId, [devId]);
|
||||
|
||||
_device = hidDevices.FirstOrDefault();
|
||||
|
||||
if (_device is { IsConnected: true })
|
||||
{
|
||||
_device.OpenDevice();
|
||||
_device.MonitorDeviceEvents = true;
|
||||
|
||||
_device.ReadReport(OnReport);
|
||||
_device.Removed += DeviceOnRemoved;
|
||||
_device.Inserted += DeviceOnInserted;
|
||||
}
|
||||
|
||||
return _device?.IsConnected ?? false;
|
||||
}
|
||||
|
||||
private void DeviceOnInserted()
|
||||
{
|
||||
_sliderUpdate = new Subject<int[]>();
|
||||
_buttonsUpdate = new Subject<List<MixerButton>>();
|
||||
}
|
||||
|
||||
private void DeviceOnRemoved()
|
||||
{
|
||||
_sliderUpdate.OnCompleted();
|
||||
_buttonsUpdate.OnCompleted();
|
||||
}
|
||||
|
||||
private void ReadSliders(byte[] reportSliderBytes)
|
||||
{
|
||||
var reportChunk = new byte[4];
|
||||
var sliderValues = new int[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Array.Copy(reportSliderBytes, i * 2, reportChunk, 0, 2);
|
||||
sliderValues[i] = BitConverter.ToInt32(reportChunk);
|
||||
}
|
||||
_sliderUpdate.OnNext(sliderValues);
|
||||
}
|
||||
|
||||
private void ReadButtons(byte[] reportButtonBytes)
|
||||
{
|
||||
if (reportButtonBytes.Length != 8)
|
||||
{
|
||||
throw new ArgumentException("incoming report data was not padded to 8 bytes");
|
||||
}
|
||||
var buttonLong = BitConverter.ToInt64(reportButtonBytes);
|
||||
_buttonsUpdate.OnNext(MixerButtonHelper.GetSetFlags(buttonLong));
|
||||
}
|
||||
|
||||
private void ReadReport(byte[] reportBytes)
|
||||
{
|
||||
var buttons = new byte[8];
|
||||
var sliders = new byte[10];
|
||||
Array.Copy(reportBytes, 0, buttons, 0, 6);
|
||||
Array.Copy(reportBytes, 6, sliders, 0, 10);
|
||||
ReadSliders(sliders);
|
||||
ReadButtons(buttons);
|
||||
}
|
||||
|
||||
private void OnReport(HidReport report)
|
||||
{
|
||||
if (!_device!.IsConnected) return;
|
||||
|
||||
ReadReport(report.Data);
|
||||
_device!.ReadReport(OnReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="hidlibrary" Version="3.3.40" />
|
||||
<PackageReference Include="hidlibrary" Version="3.2.49" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
75
HidSliders.Hid/MixerButton.cs
Normal file
75
HidSliders.Hid/MixerButton.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
namespace HidSliders.Hid;
|
||||
|
||||
[Flags]
|
||||
public enum MixerButton : long
|
||||
{
|
||||
Button1 = 1L << 0, // 1
|
||||
Button2 = 1L << 1, // 2
|
||||
Button3 = 1L << 2, // 4
|
||||
Button4 = 1L << 3, // 8
|
||||
Button5 = 1L << 4, // 16
|
||||
Button6 = 1L << 5, // 32
|
||||
Button7 = 1L << 6, // 64
|
||||
Button8 = 1L << 7, // 128
|
||||
Button9 = 1L << 8, // 256
|
||||
Button10 = 1L << 9, // 512
|
||||
Button11 = 1L << 10, // 1024
|
||||
Button12 = 1L << 11, // 2048
|
||||
Button13 = 1L << 12, // 4096
|
||||
Button14 = 1L << 13, // 8192
|
||||
Button15 = 1L << 14, // 16384
|
||||
Button16 = 1L << 15, // 32768
|
||||
Button17 = 1L << 16, // 65536
|
||||
Button18 = 1L << 17, // 131072
|
||||
Button19 = 1L << 18, // 262144
|
||||
Button20 = 1L << 19, // 524288
|
||||
Button21 = 1L << 20, // 1048576
|
||||
Button22 = 1L << 21, // 2097152
|
||||
Button23 = 1L << 22, // 4194304
|
||||
Button24 = 1L << 23, // 8388608
|
||||
Button25 = 1L << 24, // 16777216
|
||||
Button26 = 1L << 25, // 33554432
|
||||
Button27 = 1L << 26, // 67108864
|
||||
Button28 = 1L << 27, // 134217728
|
||||
Button29 = 1L << 28, // 268435456
|
||||
Button30 = 1L << 29, // 536870912
|
||||
Button31 = 1L << 30, // 1073741824
|
||||
Button32 = 1L << 31, // 2147483648
|
||||
Button33 = 1L << 32, // 4294967296
|
||||
Button34 = 1L << 33, // 8589934592
|
||||
Button35 = 1L << 34, // 17179869184
|
||||
Button36 = 1L << 35, // 34359738368
|
||||
Button37 = 1L << 36, // 68719476736
|
||||
Button38 = 1L << 37, // 137438953472
|
||||
Button39 = 1L << 38, // 274877906944
|
||||
Button40 = 1L << 39, // 549755813888
|
||||
Button41 = 1L << 40, // 1099511627776
|
||||
Button42 = 1L << 41, // 2199023255552
|
||||
Button43 = 1L << 42, // 4398046511104
|
||||
Button44 = 1L << 43, // 8796093022208
|
||||
Button45 = 1L << 44 // 17592186044416
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ButtonGroups : long
|
||||
{
|
||||
Channel1 = 0b00001_00000000_00000000_00000000_00000000_11111111,
|
||||
Channel2 = 0b00010_00000000_00000000_00000000_11111111_00000000,
|
||||
Channel3 = 0b00100_00000000_00000000_11111111_00000000_00000000,
|
||||
Channel4 = 0b01000_00000000_11111111_00000000_00000000_00000000,
|
||||
Channel5 = 0b10000_11111111_00000000_00000000_00000000_00000000,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ChannelButton
|
||||
{
|
||||
ChannelA1 = 1 << 0,
|
||||
ChannelA2 = 1 << 1,
|
||||
ChannelA3 = 1 << 2,
|
||||
ChannelA4 = 1 << 3,
|
||||
ChannelA5 = 1 << 4,
|
||||
ChannelB1 = 1 << 5,
|
||||
ChannelB2 = 1 << 6,
|
||||
ChannelB3 = 1 << 7,
|
||||
ChannelMute = 1 << 8,
|
||||
}
|
||||
75
HidSliders.Hid/MixerButtonHelper.cs
Normal file
75
HidSliders.Hid/MixerButtonHelper.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
namespace HidSliders.Hid;
|
||||
|
||||
public class MixerButtonHelper
|
||||
{
|
||||
public static List<MixerButton> GetSetFlags(long value)
|
||||
{
|
||||
var setFlags = new List<MixerButton>();
|
||||
foreach (MixerButton flag in Enum.GetValues(typeof(MixerButton)))
|
||||
{
|
||||
if ((value & (long)flag) == (long)flag)
|
||||
{
|
||||
setFlags.Add(flag);
|
||||
}
|
||||
}
|
||||
return setFlags;
|
||||
}
|
||||
|
||||
public static ButtonGroups GetButtonGroup(MixerButton button)
|
||||
{
|
||||
var buttonValue = (long)button;
|
||||
|
||||
if (((long)ButtonGroups.Channel1 & buttonValue) != 0) return ButtonGroups.Channel1;
|
||||
if (((long)ButtonGroups.Channel2 & buttonValue) != 0) return ButtonGroups.Channel2;
|
||||
if (((long)ButtonGroups.Channel3 & buttonValue) != 0) return ButtonGroups.Channel3;
|
||||
if (((long)ButtonGroups.Channel4 & buttonValue) != 0) return ButtonGroups.Channel4;
|
||||
if (((long)ButtonGroups.Channel5 & buttonValue) != 0) return ButtonGroups.Channel5;
|
||||
|
||||
throw new ArgumentException("The provided button does not match any button group.", nameof(button));
|
||||
}
|
||||
|
||||
public static ChannelButton GetChannelButton(MixerButton button)
|
||||
{
|
||||
return GetChannelButton(button, GetButtonGroup(button));
|
||||
}
|
||||
|
||||
public static ChannelButton GetChannelButton(MixerButton button, ButtonGroups buttonGroup)
|
||||
{
|
||||
var longButton = (long)button;
|
||||
if (longButton >= 0x10000000000)
|
||||
{
|
||||
return ChannelButton.ChannelMute;
|
||||
}
|
||||
|
||||
int intButton = 0;
|
||||
switch (buttonGroup)
|
||||
{
|
||||
case ButtonGroups.Channel1:
|
||||
intButton = (int)(longButton >> 0);
|
||||
break;
|
||||
case ButtonGroups.Channel2:
|
||||
intButton = (int)(longButton >> 8);
|
||||
break;
|
||||
case ButtonGroups.Channel3:
|
||||
intButton = (int)(longButton >> 16);
|
||||
break;
|
||||
case ButtonGroups.Channel4:
|
||||
intButton = (int)(longButton >> 24);
|
||||
break;
|
||||
case ButtonGroups.Channel5:
|
||||
intButton = (int)(longButton >> 32);
|
||||
break;
|
||||
}
|
||||
|
||||
if (((int)ChannelButton.ChannelA1 & intButton) != 0) return ChannelButton.ChannelA1;
|
||||
if (((int)ChannelButton.ChannelA2 & intButton) != 0) return ChannelButton.ChannelA2;
|
||||
if (((int)ChannelButton.ChannelA3 & intButton) != 0) return ChannelButton.ChannelA3;
|
||||
if (((int)ChannelButton.ChannelA4 & intButton) != 0) return ChannelButton.ChannelA4;
|
||||
if (((int)ChannelButton.ChannelA5 & intButton) != 0) return ChannelButton.ChannelA5;
|
||||
if (((int)ChannelButton.ChannelB1 & intButton) != 0) return ChannelButton.ChannelB1;
|
||||
if (((int)ChannelButton.ChannelB2 & intButton) != 0) return ChannelButton.ChannelB2;
|
||||
if (((int)ChannelButton.ChannelB3 & intButton) != 0) return ChannelButton.ChannelB3;
|
||||
|
||||
throw new ArgumentException("The provided button does not match any channel button in the specified button group.", nameof(button));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user