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,17 +1,21 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using HidLibrary;
|
||||
using HidSliders.Hid;
|
||||
using Voicemeeter;
|
||||
using VoiceMeeter;
|
||||
using Timer = System.Windows.Forms.Timer;
|
||||
|
||||
namespace HidSliders.Gui
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
private IDisposable? _vmClient;
|
||||
private IHidDevice? _hidDevice;
|
||||
private const float Resolution = 72.0f;
|
||||
private bool _mixerConnected;
|
||||
private List<MixerButton> _previousButtons = [];
|
||||
private readonly HidInterface _hidInterface;
|
||||
private const int ZeroPercent = 90;
|
||||
private readonly List<ChannelControlCollection> _channels;
|
||||
private bool _suppressCheckboxUpdate = false;
|
||||
private Timer _syncTimer = new();
|
||||
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -44,24 +48,134 @@ namespace HidSliders.Gui
|
||||
_channels[3].ChannelSelector.Value = Properties.Settings.Default.Channel4Strip;
|
||||
_channels[4].ChannelSelector.Value = Properties.Settings.Default.Channel5Strip;
|
||||
|
||||
_syncTimer.Tick += SyncVM;
|
||||
_syncTimer.Interval = 100;
|
||||
_syncTimer.Enabled = true;
|
||||
if (Properties.Settings.Default.AutoConnect)
|
||||
{
|
||||
autoConnectCheckBox.Checked = true;
|
||||
Task.Run(ConnectVoicemeeter).Wait();
|
||||
}
|
||||
|
||||
var enumerator = new HidEnumerator();
|
||||
var hidDevices = enumerator.Enumerate(0x0359, [0x6497]);
|
||||
_hidDevice = hidDevices.FirstOrDefault();
|
||||
voicemeeterStatusLabel.Text = $"Mixer {(_hidDevice?.IsConnected == true ? "" : "not ")}connected";
|
||||
_hidInterface = new HidInterface();
|
||||
mixerLabel.Text = "Mixer not connected";
|
||||
|
||||
if (_hidDevice?.IsConnected == true && Properties.Settings.Default.MixerAutoConnect)
|
||||
if (Properties.Settings.Default.MixerAutoConnect)
|
||||
{
|
||||
UsbListenerLoop();
|
||||
ConnectHidMixer();
|
||||
mixerAutoConnectCheckbox.Checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSliderValues(int[] values)
|
||||
{
|
||||
this.BeginInvoke(() =>
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
var gain = HidToGain(values[i]);
|
||||
SetStripGain(_channels[i].CurrentStrip, gain);
|
||||
_channels[i].TrackBar.Value = (int)gain;
|
||||
_channels[i].IndicatorLabel.Text = $"{gain} dB";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleButtonPress(MixerButton button)
|
||||
{
|
||||
var buttonGroup = MixerButtonHelper.GetButtonGroup(button);
|
||||
var channelButton = MixerButtonHelper.GetChannelButton(button, buttonGroup);
|
||||
|
||||
ChannelControlCollection channel;
|
||||
switch (buttonGroup)
|
||||
{
|
||||
case ButtonGroups.Channel1:
|
||||
channel = _channels[0];
|
||||
break;
|
||||
case ButtonGroups.Channel2:
|
||||
channel = _channels[1];
|
||||
break;
|
||||
case ButtonGroups.Channel3:
|
||||
channel = _channels[2];
|
||||
break;
|
||||
case ButtonGroups.Channel4:
|
||||
channel = _channels[3];
|
||||
break;
|
||||
case ButtonGroups.Channel5:
|
||||
channel = _channels[4];
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
switch (channelButton)
|
||||
{
|
||||
case ChannelButton.ChannelA1:
|
||||
channel.BusA1Checkbox.Checked = !channel.BusA1Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelA2:
|
||||
channel.BusA2Checkbox.Checked = !channel.BusA2Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelA3:
|
||||
channel.BusA3Checkbox.Checked = !channel.BusA3Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelA4:
|
||||
channel.BusA4Checkbox.Checked = !channel.BusA4Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelA5:
|
||||
channel.BusA5Checkbox.Checked = !channel.BusA5Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelB1:
|
||||
channel.BusB1Checkbox.Checked = !channel.BusB1Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelB2:
|
||||
channel.BusB2Checkbox.Checked = !channel.BusB2Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelB3:
|
||||
channel.BusB3Checkbox.Checked = !channel.BusB3Checkbox.Checked;
|
||||
break;
|
||||
case ChannelButton.ChannelMute:
|
||||
channel.MuteCheckBox.Checked = !channel.MuteCheckBox.Checked;
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
listBox1.Items.Add($"{buttonGroup} {channelButton} pressed");
|
||||
}
|
||||
|
||||
private void OnButtons(List<MixerButton> buttons)
|
||||
{
|
||||
BeginInvoke(() =>
|
||||
{
|
||||
var newButtons = buttons.Except(_previousButtons).ToList();
|
||||
_previousButtons = buttons;
|
||||
|
||||
newButtons.ForEach(HandleButtonPress);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnSliderComplete()
|
||||
{
|
||||
BeginInvoke(() =>
|
||||
{
|
||||
_mixerConnected = false;
|
||||
button1.Enabled = true;
|
||||
mixerLabel.Text = "Mixer disconnected";
|
||||
});
|
||||
}
|
||||
|
||||
private void ConnectHidMixer()
|
||||
{
|
||||
_mixerConnected = _hidInterface.ConnectDevice(0x0359, 0x6497);
|
||||
if (_mixerConnected)
|
||||
{
|
||||
mixerLabel.Text = "Mixer connected";
|
||||
button1.Enabled = false;
|
||||
_hidInterface.SliderObservable.Subscribe(OnSliderValues, OnSliderComplete);
|
||||
_hidInterface.ButtonsObservable.Subscribe(OnButtons);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ConnectVoicemeeter()
|
||||
{
|
||||
RunVoicemeeterParam version = RunVoicemeeterParam.None;
|
||||
@@ -84,6 +198,7 @@ namespace HidSliders.Gui
|
||||
{
|
||||
EnableVMControls(version);
|
||||
voicemeeterStatusLabel.Text = "Connected";
|
||||
_syncTimer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +207,16 @@ namespace HidSliders.Gui
|
||||
await ConnectVoicemeeter();
|
||||
}
|
||||
|
||||
private void SyncVM(object? sender, EventArgs eventArgs)
|
||||
{
|
||||
if (_vmClient == null || Remote.IsParametersDirty() != 1) return;
|
||||
|
||||
foreach (var channelControlCollection in _channels)
|
||||
{
|
||||
SyncChannelControls(channelControlCollection);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnableVMControls(RunVoicemeeterParam version)
|
||||
{
|
||||
foreach (var channel in _channels)
|
||||
@@ -106,6 +231,7 @@ namespace HidSliders.Gui
|
||||
|
||||
private void SyncChannelControls(ChannelControlCollection channel)
|
||||
{
|
||||
_suppressCheckboxUpdate = true;
|
||||
channel.BusA1Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.A1);
|
||||
channel.BusB1Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.B1);
|
||||
if (vmBananaRadio.Checked || vmPotatoRadio.Checked)
|
||||
@@ -125,6 +251,7 @@ namespace HidSliders.Gui
|
||||
channel.TrackBar.Value = (int)GetStripGain(channel.CurrentStrip);
|
||||
channel.SoloCheckBox.Checked = GetChannelSolo(channel.CurrentStrip);
|
||||
channel.MuteCheckBox.Checked = GetChannelMute(channel.CurrentStrip);
|
||||
_suppressCheckboxUpdate = false;
|
||||
}
|
||||
|
||||
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||||
@@ -133,44 +260,9 @@ namespace HidSliders.Gui
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private async void UsbListenerLoop()
|
||||
{
|
||||
if (_hidDevice == null) return;
|
||||
mixerLabel.Text = "Mixer online";
|
||||
while (true)
|
||||
{
|
||||
if (_hidDevice.IsConnected)
|
||||
{
|
||||
button1.Enabled = false;
|
||||
//label1.Text = "waiting for report";
|
||||
var progress = new Progress<string>();
|
||||
progress.ProgressChanged += (o, s) => voicemeeterStatusLabel.Text = s;
|
||||
var report = await Task.Run(() => _hidDevice.ReadReport());
|
||||
if (report.ReadStatus == HidDeviceData.ReadStatus.Success)
|
||||
{
|
||||
var reportChunk = new byte[2];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Array.Copy(report.Data, i * 2, reportChunk, 0, 2);
|
||||
var sliderVal = BitConverter.ToInt16(reportChunk);
|
||||
var gain = HidToGain(sliderVal);
|
||||
SetStripGain(_channels[i].CurrentStrip, gain);
|
||||
_channels[i].TrackBar.Value = (int)gain;
|
||||
_channels[i].IndicatorLabel.Text = $"{gain} dB";
|
||||
}
|
||||
}
|
||||
//button1.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
button1.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
UsbListenerLoop();
|
||||
ConnectHidMixer();
|
||||
}
|
||||
|
||||
private float HidToGain(int hidValue)
|
||||
@@ -179,11 +271,43 @@ namespace HidSliders.Gui
|
||||
// Truncate to first decimal (move decimal, int truncate, move decimal)
|
||||
//var realResult = 5.8456f + 17.0486f * (float)Math.Log(Math.Max(hidValue / Resolution, 0.02));
|
||||
//return ((int)(realResult * 10)) / 10.0f;
|
||||
return hidValue - 60;
|
||||
return (int)(CalculateGain(hidValue, ZeroPercent) * 10) / 10.0f;
|
||||
}
|
||||
|
||||
public static float CalculateGain(float slider, int zeroPct)
|
||||
{
|
||||
float minSlider;
|
||||
float maxSlider;
|
||||
float minGain;
|
||||
float maxGain;
|
||||
|
||||
if (slider >= zeroPct)
|
||||
{
|
||||
minSlider = zeroPct;
|
||||
maxSlider = 100;
|
||||
minGain = 0;
|
||||
maxGain = 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
minSlider = 0;
|
||||
maxSlider = zeroPct;
|
||||
minGain = -60;
|
||||
maxGain = 0;
|
||||
}
|
||||
|
||||
// Calculate the percentage of slider position within the range
|
||||
var percentage = (slider - minSlider) / (maxSlider - minSlider);
|
||||
|
||||
// Interpolate gain within the range based on the percentage
|
||||
var calculatedGain = minGain + (percentage * (maxGain - minGain));
|
||||
|
||||
return calculatedGain;
|
||||
}
|
||||
|
||||
private void trackBar_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
if (_suppressCheckboxUpdate) return;
|
||||
if (sender is TrackBar trackBar && _vmClient != null)
|
||||
{
|
||||
var channel = _channels.First(c => c.OwnsControl(trackBar));
|
||||
@@ -193,6 +317,7 @@ namespace HidSliders.Gui
|
||||
|
||||
private void busCheckbox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_suppressCheckboxUpdate) return;
|
||||
if (sender is CheckBox { Tag: VMBus bus } checkBox && _vmClient != null)
|
||||
{
|
||||
var channel = _channels.First(c => c.OwnsControl(checkBox));
|
||||
@@ -243,8 +368,6 @@ namespace HidSliders.Gui
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void SetBusEnabled(int strip, VMBus bus, bool enabled)
|
||||
{
|
||||
Remote.SetParameter($"Strip[{strip}].{bus}", enabled ? 1 : 0);
|
||||
@@ -292,6 +415,7 @@ namespace HidSliders.Gui
|
||||
|
||||
private void soloCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_suppressCheckboxUpdate) return;
|
||||
if (sender is CheckBox checkBox && _vmClient != null)
|
||||
{
|
||||
var channel = _channels.First(c => c.OwnsControl(checkBox));
|
||||
@@ -301,6 +425,7 @@ namespace HidSliders.Gui
|
||||
|
||||
private void muteCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_suppressCheckboxUpdate) return;
|
||||
if (sender is CheckBox checkBox && _vmClient != null)
|
||||
{
|
||||
var channel = _channels.First(c => c.OwnsControl(checkBox));
|
||||
|
||||
Reference in New Issue
Block a user