diff --git a/NK2Tray/Button.cs b/NK2Tray/Button.cs index 28e68bb..c23390f 100644 --- a/NK2Tray/Button.cs +++ b/NK2Tray/Button.cs @@ -20,9 +20,9 @@ public class Button public int channel; public MidiOut midiOut; - public Button(ref MidiOut midiOutRef, ButtonType butType, int cont, bool initialState) + public Button(ref MidiOut midiOutRef, ButtonType butType, int cont, bool initialState, MidiCommandCode code=MidiCommandCode.ControlChange) { - commandCode = MidiCommandCode.ControlChange; + commandCode = code; channel = 1; buttonType = butType; controller = cont; @@ -32,7 +32,10 @@ public Button(ref MidiOut midiOutRef, ButtonType butType, int cont, bool initial public void SetLight(bool state) { - midiOut.Send(new ControlChangeEvent(0, channel, (MidiController)(controller), state ? 127 : 0).GetAsShortMessage()); + if (commandCode == MidiCommandCode.ControlChange) + midiOut.Send(new ControlChangeEvent(0, channel, (MidiController)(controller), state ? 127 : 0).GetAsShortMessage()); + else if (commandCode == MidiCommandCode.NoteOn) + midiOut.Send(new NoteOnEvent(0, 1, controller, state ? 127 : 0, 0).GetAsShortMessage()); } public bool HandleEvent(MidiInMessageEventArgs e) @@ -40,12 +43,28 @@ public bool HandleEvent(MidiInMessageEventArgs e) if (e.MidiEvent.CommandCode != commandCode) return false; - ControlChangeEvent me = (ControlChangeEvent)e.MidiEvent; + int c; - if (me.Channel != channel || me.ControllerValue != 127) // Only on correct channel and button-down (127) - return false; + if (commandCode == MidiCommandCode.ControlChange) + { + var me = (ControlChangeEvent)e.MidiEvent; + + if (me.Channel != channel || me.ControllerValue != 127) // Only on correct channel and button-down (127) + return false; - int c = (int)me.Controller; + c = (int)me.Controller; + } + else if (commandCode == MidiCommandCode.NoteOn) + { + var me = (NoteEvent)e.MidiEvent; + + if (me.Channel != channel || me.Velocity != 127) // Only on correct channel and button-down (127) + return false; + + c = me.NoteNumber; + } + else + return false; if (c == controller) { diff --git a/NK2Tray/Fader.cs b/NK2Tray/Fader.cs index f0a8b49..704aff7 100644 --- a/NK2Tray/Fader.cs +++ b/NK2Tray/Fader.cs @@ -3,34 +3,77 @@ namespace NK2Tray { - public class Fader + public class FaderDef { - public MidiCommandCode commandCode; + public bool delta; + public float range; public int channel; + public bool selectPresent; + public bool mutePresent; + public bool recordPresent; + public int faderOffset; + public int selectOffset; + public int muteOffset; + public int recordOffset; + public MidiCommandCode faderCode; + public MidiCommandCode selectCode; + public MidiCommandCode muteCode; + public MidiCommandCode recordCode; + + public FaderDef(bool _delta, float _range, int _channel, + bool _selectPresent, bool _mutePresent, bool _recordPresent, + int _faderOffset, int _selectOffset, int _muteOffset, int _recordOffset, + MidiCommandCode _faderCode, MidiCommandCode _selectCode, MidiCommandCode _muteCode, MidiCommandCode _recordCode) + { + delta = _delta; + range = _range; + channel = _channel; + selectPresent = _selectPresent; + mutePresent = _mutePresent; + recordPresent = _recordPresent; + faderOffset = _faderOffset; + selectOffset = _selectOffset; + muteOffset = _muteOffset; + recordOffset = _recordOffset; + faderCode = _faderCode; + selectCode = _selectCode; + muteCode = _muteCode; + recordCode = _recordCode; + } + } + + public class Fader + { public int faderNumber; - public int inputController; - public int selectController; - public int muteController; - public int recordController; + public FaderDef faderDef; public MixerSession assignment; public bool assigned; public MidiOut midiOut; public MidiDevice parent; public string identifier; - public Fader(MidiDevice midiDevice, int faderNum, int inputOffst, int selectOffset, int muteOffset, int recordOffset) + public Fader(MidiDevice midiDevice, int faderNum) { parent = midiDevice; midiOut = midiDevice.midiOut; - commandCode = MidiCommandCode.ControlChange; - channel = 1; faderNumber = faderNum; - inputController = faderNum + inputOffst; - selectController = faderNum + selectOffset; - muteController = faderNum + muteOffset; - recordController = faderNum + recordOffset; + faderDef = parent.DefaultFaderDef; } + public Fader(MidiDevice midiDevice, int faderNum, FaderDef _faderDef) + { + parent = midiDevice; + midiOut = midiDevice.midiOut; + faderNumber = faderNum; + faderDef = _faderDef; + } + + private int inputController => faderNumber + faderDef.faderOffset; + private int selectController => faderNumber + faderDef.selectOffset; + private int muteController => faderNumber + faderDef.muteOffset; + private int recordController => faderNumber + faderDef.recordOffset; + + public void ResetLights() { SetSelectLight(false); @@ -45,6 +88,8 @@ public void Assign(MixerSession mixerSession) identifier = mixerSession.sessionIdentifier; SetSelectLight(true); SetRecordLight(false); + if (faderDef.delta) + parent.SetVolumeIndicator(faderNumber, mixerSession.GetVolume()); } public void AssignInactive(string ident) @@ -61,67 +106,129 @@ public void Unassign() assignment = null; SetSelectLight(false); identifier = ""; + if (faderDef.delta) + parent.SetVolumeIndicator(faderNumber, -1); } public void SetSelectLight(bool state) { - midiOut.Send(new ControlChangeEvent(0, 1, (MidiController)(selectController), state ? 127 : 0).GetAsShortMessage()); + parent.SetLight(selectController, state); } public void SetMuteLight(bool state) { - midiOut.Send(new ControlChangeEvent(0, 1, (MidiController)(muteController), state ? 127 : 0).GetAsShortMessage()); + parent.SetLight(muteController, state); } public void SetRecordLight( bool state) { - midiOut.Send(new ControlChangeEvent(0, 1, (MidiController)(recordController), state ? 127 : 0).GetAsShortMessage()); + parent.SetLight(recordController, state); } - public bool HandleEvent(MidiInMessageEventArgs e) + public bool Match(int faderNumber, MidiEvent midiEvent, MidiCommandCode code, int offset) { - if (e.MidiEvent.CommandCode != commandCode) + if (midiEvent.Channel != faderDef.channel) return false; + if (midiEvent.CommandCode != code) + return false; + if (code == MidiCommandCode.ControlChange) + { + var me = (ControlChangeEvent)midiEvent; + if ((int)me.Controller == faderNumber + offset) + return true; + } + else if (code == MidiCommandCode.NoteOn) + { + var me = (NoteEvent)midiEvent; + if (me.NoteNumber == faderNumber + offset) + return true; + } + else if (code == MidiCommandCode.PitchWheelChange) + { + return true; + } - ControlChangeEvent me = (ControlChangeEvent)e.MidiEvent; + return false; + } - if (me.Channel != channel) - return false; + public int GetValue(MidiEvent midiEvent) + { + if (midiEvent.CommandCode == MidiCommandCode.ControlChange) + { + var me = (ControlChangeEvent)midiEvent; + return me.ControllerValue; + } + else if (midiEvent.CommandCode == MidiCommandCode.NoteOn) + { + var me = (NoteEvent)midiEvent; + return me.Velocity; + } + else if (midiEvent.CommandCode == MidiCommandCode.PitchWheelChange) + { + var me = (PitchWheelChangeEvent)midiEvent; + return me.Pitch; + } - int controller = (int)me.Controller; + return 0; + } - if (controller == inputController) + public bool HandleEvent(MidiInMessageEventArgs e) + { + // Fader match + if (assigned && Match(faderNumber, e.MidiEvent, faderDef.faderCode, faderDef.faderOffset)) { - if (assigned) + if (faderDef.delta) { - assignment.SetVolume(me.ControllerValue / 127f); - if (assignment.IsDead()) - SetRecordLight(true); + float curVol; + var val = GetValue(e.MidiEvent); + if (val > faderDef.range / 2) + curVol = assignment.ChangeVolume((faderDef.range - val) / faderDef.range); + else + curVol = assignment.ChangeVolume(val / faderDef.range); + parent.SetVolumeIndicator(faderNumber, curVol); } + else + { + assignment.SetVolume(GetValue(e.MidiEvent) / faderDef.range); + } + + if (assignment.IsDead()) + SetRecordLight(true); + return true; } - else if (controller == selectController) + + // Select match + if (Match(faderNumber, e.MidiEvent, faderDef.selectCode, faderDef.selectOffset)) { - if (me.ControllerValue != 127) // Only on button-down + if (GetValue(e.MidiEvent) != 127) // Only on button-down return true; Console.WriteLine($@"Attempting to assign current window to fader {faderNumber}"); if (assigned) + { Unassign(); + parent.SaveAssignments(); + } else { var pid = WindowTools.GetForegroundPID(); var mixerSession = parent.audioDevice.FindMixerSessions(pid); if (mixerSession != null) + { Assign(mixerSession); + parent.SaveAssignments(); + } else Console.WriteLine($@"MixerSession not found for pid {pid}"); } return true; } - else if (controller == muteController) + + // Mute match + if (assigned && Match(faderNumber, e.MidiEvent, faderDef.muteCode, faderDef.muteOffset)) { - if (me.ControllerValue != 127) // Only on button-down + if (GetValue(e.MidiEvent) != 127) // Only on button-down return true; SetMuteLight(assignment.ToggleMute()); @@ -129,12 +236,15 @@ public bool HandleEvent(MidiInMessageEventArgs e) SetRecordLight(true); return true; } - else if (controller == recordController) + + // Record match + if (assigned && Match(faderNumber, e.MidiEvent, faderDef.recordCode, faderDef.recordOffset)) { SetRecordLight(assignment.IsDead()); return true; } return false; + } } -} \ No newline at end of file +} diff --git a/NK2Tray/MidiDevice.cs b/NK2Tray/MidiDevice.cs index 01a5d98..ec855a5 100644 --- a/NK2Tray/MidiDevice.cs +++ b/NK2Tray/MidiDevice.cs @@ -28,29 +28,26 @@ public class MidiDevice public AudioDevice audioDevice; - public string searchString = ""; + public virtual string SearchString => "wobbo"; - public MidiDevice(string search, AudioDevice audioDev) + public virtual FaderDef DefaultFaderDef => new FaderDef(false, 1f, 1, true, true, true, 0, 0, 0, 0, MidiCommandCode.ControlChange, MidiCommandCode.ControlChange, MidiCommandCode.ControlChange, MidiCommandCode.ControlChange); + + public MidiDevice() { - audioDevice = audioDev; - searchString = search; - FindMidiIn(); - FindMidiOut(); - ResetAllLights(); - InitFaders(); - InitButtons(); - LoadAssignments(); - ListenForMidi(); + Console.WriteLine($@"Initializing Midi Device {SearchString}"); } + public bool Found => (midiIn != null && midiOut != null); + public void FindMidiIn() { for (int i = 0; i < MidiIn.NumberOfDevices; i++) { - if (MidiIn.DeviceInfo(i).ProductName.ToLower().Contains(searchString)) + Console.WriteLine("MIDI IN: " + MidiIn.DeviceInfo(i).ProductName); + if (MidiIn.DeviceInfo(i).ProductName.ToLower().Contains(SearchString)) { midiIn = new MidiIn(i); - Console.WriteLine(MidiIn.DeviceInfo(i).ProductName); + Console.WriteLine($@"Assigning MidiIn: {MidiIn.DeviceInfo(i).ProductName}"); break; } } @@ -60,10 +57,11 @@ public void FindMidiOut() { for (int i = 0; i < MidiOut.NumberOfDevices; i++) { - if (MidiOut.DeviceInfo(i).ProductName.ToLower().Contains(searchString)) + Console.WriteLine("MIDI OUT: " + MidiOut.DeviceInfo(i).ProductName); + if (MidiOut.DeviceInfo(i).ProductName.ToLower().Contains(SearchString)) { midiOut = new MidiOut(i); - Console.WriteLine(MidiOut.DeviceInfo(i).ProductName); + Console.WriteLine($@"Assigning MidiOut: {MidiOut.DeviceInfo(i).ProductName}"); break; } } @@ -82,8 +80,10 @@ public void midiIn_ErrorReceived(object sender, MidiInMessageEventArgs e) e.Timestamp, e.RawMessage, e.MidiEvent)); } - public void midiIn_MessageReceived(object sender, MidiInMessageEventArgs e) + public virtual void midiIn_MessageReceived(object sender, MidiInMessageEventArgs e) { + WindowTools.Dump(e.MidiEvent); + foreach (var fader in faders) fader.HandleEvent(e); @@ -91,31 +91,20 @@ public void midiIn_MessageReceived(object sender, MidiInMessageEventArgs e) button.HandleEvent(e); } - public void ResetAllLights() - { - foreach (var i in Enumerable.Range(0, 128)) - midiOut.Send(new ControlChangeEvent(0, 1, (MidiController)i, 0).GetAsShortMessage()); - } + public virtual void ResetAllLights() { } + + public virtual void SetVolumeIndicator(int fader, float level) { } - public void InitFaders() + public virtual void SetLight(int controller, bool state) {} + + public virtual void InitFaders() { faders = new List(); - foreach (var i in Enumerable.Range(0, 8)) - { - Fader fader = new Fader(this, i, 0, 32, 48, 64); - fader.ResetLights(); - faders.Add(fader); - } } - public void InitButtons() + public virtual void InitButtons() { buttons = new List