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:
2024-05-16 23:42:27 -05:00
parent efdbb11f92
commit 700e87f807
39 changed files with 4246 additions and 3514 deletions

View File

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