Files
HidSliders/HidSliders.Hid/HidInterface.cs

88 lines
2.7 KiB
C#

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);
}
}
}