341 lines
13 KiB
C#
341 lines
13 KiB
C#
using System.Diagnostics;
|
|
using System.Reflection;
|
|
using HidLibrary;
|
|
using Voicemeeter;
|
|
using VoiceMeeter;
|
|
|
|
namespace HidSliders.Gui
|
|
{
|
|
public partial class Form1 : Form
|
|
{
|
|
private IDisposable? _vmClient;
|
|
private IHidDevice? _hidDevice;
|
|
private const float Resolution = 72.0f;
|
|
private readonly List<ChannelControlCollection> _channels;
|
|
public Form1()
|
|
{
|
|
InitializeComponent();
|
|
_channels = new List<ChannelControlCollection>
|
|
{
|
|
new (numericUpDown1, trackBar1, ch1A1Checkbox, ch1A2Checkbox, ch1A3Checkbox, ch1A4Checkbox, ch1A5Checkbox, ch1B1Checkbox, ch1B2Checkbox, ch1B3Checkbox, checkBox1, checkBox2, slider1Label),
|
|
new (numericUpDown2, trackBar2, checkBox12, checkBox11, checkBox10, checkBox9, checkBox8, checkBox7, checkBox6, checkBox5, checkBox4, checkBox3, slider2Label),
|
|
new (numericUpDown3, trackBar3, checkBox22, checkBox21, checkBox20, checkBox19, checkBox18, checkBox17, checkBox16, checkBox15, checkBox14, checkBox13, slider3Label),
|
|
new (numericUpDown4, trackBar4, checkBox32, checkBox31, checkBox30, checkBox29, checkBox28, checkBox27, checkBox26, checkBox25, checkBox24, checkBox23, slider4Label),
|
|
new (numericUpDown5, trackBar5, checkBox42, checkBox41, checkBox40, checkBox39, checkBox38, checkBox37, checkBox36, checkBox35, checkBox34, checkBox33, slider5Label),
|
|
|
|
};
|
|
|
|
switch (Properties.Settings.Default.VMVersion)
|
|
{
|
|
case 1:
|
|
vmRadio.Checked = true;
|
|
break;
|
|
case 2:
|
|
vmBananaRadio.Checked = true;
|
|
break;
|
|
case 3:
|
|
vmPotatoRadio.Checked = true;
|
|
break;
|
|
}
|
|
|
|
_channels[0].ChannelSelector.Value = Properties.Settings.Default.Channel1Strip;
|
|
_channels[1].ChannelSelector.Value = Properties.Settings.Default.Channel2Strip;
|
|
_channels[2].ChannelSelector.Value = Properties.Settings.Default.Channel3Strip;
|
|
_channels[3].ChannelSelector.Value = Properties.Settings.Default.Channel4Strip;
|
|
_channels[4].ChannelSelector.Value = Properties.Settings.Default.Channel5Strip;
|
|
|
|
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";
|
|
|
|
if (_hidDevice?.IsConnected == true && Properties.Settings.Default.MixerAutoConnect)
|
|
{
|
|
UsbListenerLoop();
|
|
mixerAutoConnectCheckbox.Checked = true;
|
|
}
|
|
}
|
|
|
|
private async Task ConnectVoicemeeter()
|
|
{
|
|
RunVoicemeeterParam version = RunVoicemeeterParam.None;
|
|
if (vmRadio.Checked)
|
|
{
|
|
version = RunVoicemeeterParam.Voicemeeter;
|
|
}
|
|
else if (vmBananaRadio.Checked)
|
|
{
|
|
version = RunVoicemeeterParam.VoicemeeterBanana;
|
|
}
|
|
else if (vmPotatoRadio.Checked)
|
|
{
|
|
version = RunVoicemeeterParam.VoicemeeterPotato;
|
|
}
|
|
|
|
Properties.Settings.Default.VMVersion = (int)version;
|
|
_vmClient = await Remote.Initialize(version);
|
|
if (_vmClient != null)
|
|
{
|
|
EnableVMControls(version);
|
|
voicemeeterStatusLabel.Text = "Connected";
|
|
}
|
|
}
|
|
|
|
private async void connectButton_Click(object sender, EventArgs e)
|
|
{
|
|
await ConnectVoicemeeter();
|
|
}
|
|
|
|
private void EnableVMControls(RunVoicemeeterParam version)
|
|
{
|
|
foreach (var channel in _channels)
|
|
{
|
|
channel.TrackBar.Enabled = true;
|
|
channel.SoloCheckBox.Enabled = true;
|
|
channel.MuteCheckBox.Enabled = true;
|
|
channel.EnableBusses(version);
|
|
SyncChannelControls(channel);
|
|
}
|
|
}
|
|
|
|
private void SyncChannelControls(ChannelControlCollection channel)
|
|
{
|
|
channel.BusA1Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.A1);
|
|
channel.BusB1Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.B1);
|
|
if (vmBananaRadio.Checked || vmPotatoRadio.Checked)
|
|
{
|
|
channel.BusA2Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.A2);
|
|
channel.BusA3Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.A3);
|
|
channel.BusB2Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.B2);
|
|
}
|
|
|
|
if (vmPotatoRadio.Checked)
|
|
{
|
|
channel.BusA4Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.A4);
|
|
channel.BusA5Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.A5);
|
|
channel.BusB3Checkbox.Checked = GetBusEnabled(channel.CurrentStrip, VMBus.B3);
|
|
}
|
|
|
|
channel.TrackBar.Value = (int)GetStripGain(channel.CurrentStrip);
|
|
channel.SoloCheckBox.Checked = GetChannelSolo(channel.CurrentStrip);
|
|
channel.MuteCheckBox.Checked = GetChannelMute(channel.CurrentStrip);
|
|
}
|
|
|
|
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
_vmClient?.Dispose();
|
|
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();
|
|
}
|
|
|
|
private float HidToGain(int hidValue)
|
|
{
|
|
// adjusted regression of yamaha board is approx y = 5.8456 + 17.0486 * ln(x)
|
|
// 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;
|
|
}
|
|
|
|
private void trackBar_Scroll(object sender, EventArgs e)
|
|
{
|
|
if (sender is TrackBar trackBar && _vmClient != null)
|
|
{
|
|
var channel = _channels.First(c => c.OwnsControl(trackBar));
|
|
SetStripGain(channel.CurrentStrip, trackBar.Value);
|
|
}
|
|
}
|
|
|
|
private void busCheckbox_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (sender is CheckBox { Tag: VMBus bus } checkBox && _vmClient != null)
|
|
{
|
|
var channel = _channels.First(c => c.OwnsControl(checkBox));
|
|
SetBusEnabled(channel.CurrentStrip, bus, checkBox.Checked);
|
|
}
|
|
}
|
|
|
|
private void SetStripGain(int strip, float value)
|
|
{
|
|
Remote.SetParameter($"Strip[{strip}].Gain", value);
|
|
}
|
|
|
|
private float GetStripGain(int index)
|
|
{
|
|
return Remote.GetParameter($"Strip[{index}].Gain");
|
|
}
|
|
|
|
private void vmRadio_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (vmRadio.Checked)
|
|
{
|
|
setMaxChannel(2);
|
|
}
|
|
}
|
|
|
|
private void vmBananaRadio_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (vmBananaRadio.Checked)
|
|
{
|
|
setMaxChannel(4);
|
|
}
|
|
}
|
|
|
|
private void setMaxChannel(int max)
|
|
{
|
|
numericUpDown1.Maximum = max;
|
|
numericUpDown2.Maximum = max;
|
|
numericUpDown3.Maximum = max;
|
|
numericUpDown4.Maximum = max;
|
|
numericUpDown5.Maximum = max;
|
|
}
|
|
|
|
private void vmPotatoRadio_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (vmPotatoRadio.Checked)
|
|
{
|
|
setMaxChannel(7);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void SetBusEnabled(int strip, VMBus bus, bool enabled)
|
|
{
|
|
Remote.SetParameter($"Strip[{strip}].{bus}", enabled ? 1 : 0);
|
|
}
|
|
|
|
private bool GetBusEnabled(int strip, VMBus bus)
|
|
{
|
|
return (int)Remote.GetParameter($"Strip[{strip}].{bus}") == 1;
|
|
}
|
|
|
|
private void SetChannelSolo(int strip, bool enabled)
|
|
{
|
|
Remote.SetParameter($"Strip[{strip}].Solo", enabled ? 1 : 0);
|
|
}
|
|
|
|
private bool GetChannelSolo(int strip)
|
|
{
|
|
return (int)Remote.GetParameter($"Strip[{strip}].Solo") == 1;
|
|
}
|
|
|
|
private void SetChannelMute(int strip, bool enabled)
|
|
{
|
|
Remote.SetParameter($"Strip[{strip}].Mute", enabled ? 1 : 0);
|
|
}
|
|
|
|
private bool GetChannelMute(int strip)
|
|
{
|
|
return (int)Remote.GetParameter($"Strip[{strip}].Mute") == 1;
|
|
}
|
|
|
|
private void numericUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (sender is NumericUpDown numericUpDown)
|
|
{
|
|
var channel = _channels.First(c => c.OwnsControl(numericUpDown));
|
|
if (_vmClient != null)
|
|
{
|
|
SyncChannelControls(channel);
|
|
}
|
|
var index = _channels.FindIndex(c => c == channel);
|
|
var settingsType = Properties.Settings.Default.GetType();
|
|
settingsType.GetProperty($"Channel{index + 1}Strip").SetValue(Properties.Settings.Default, (int)numericUpDown.Value);
|
|
}
|
|
}
|
|
|
|
private void soloCheckBox_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (sender is CheckBox checkBox && _vmClient != null)
|
|
{
|
|
var channel = _channels.First(c => c.OwnsControl(checkBox));
|
|
SetChannelSolo(channel.CurrentStrip, checkBox.Checked);
|
|
}
|
|
}
|
|
|
|
private void muteCheckBox_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (sender is CheckBox checkBox && _vmClient != null)
|
|
{
|
|
var channel = _channels.First(c => c.OwnsControl(checkBox));
|
|
SetChannelMute(channel.CurrentStrip, checkBox.Checked);
|
|
}
|
|
}
|
|
|
|
private void autoConnectCheckBox_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
Properties.Settings.Default.AutoConnect = autoConnectCheckBox.Checked;
|
|
}
|
|
|
|
private void checkBox43_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
Properties.Settings.Default.MixerAutoConnect = mixerAutoConnectCheckbox.Checked;
|
|
}
|
|
|
|
private void Form1_Resize(object sender, EventArgs e)
|
|
{
|
|
if (FormWindowState.Minimized == this.WindowState)
|
|
{
|
|
notifyIcon1.Visible = true;
|
|
this.Hide();
|
|
}
|
|
else if (FormWindowState.Normal == this.WindowState)
|
|
{
|
|
notifyIcon1.Visible = false;
|
|
}
|
|
}
|
|
|
|
private void notifyIcon1_Click(object sender, EventArgs e)
|
|
{
|
|
this.Show();
|
|
WindowState = FormWindowState.Normal;
|
|
}
|
|
}
|
|
}
|