using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Midi; namespace LaunchpadNET { public class Interface { private Pitch[,] notes = new Pitch[8, 8] { { Pitch.A5, Pitch.ASharp5, Pitch.B5, Pitch.C6, Pitch.CSharp6, Pitch.D6, Pitch.DSharp6, Pitch.E6 }, { Pitch.B4, Pitch.C5, Pitch.CSharp5, Pitch.D5, Pitch.DSharp5, Pitch.E5, Pitch.F5, Pitch.FSharp5 }, { Pitch.CSharp4, Pitch.D4, Pitch.DSharp4, Pitch.E4, Pitch.F4, Pitch.FSharp4, Pitch.G4, Pitch.GSharp4 }, { Pitch.DSharp3, Pitch.E3, Pitch.F3, Pitch.FSharp3, Pitch.G3, Pitch.GSharp3, Pitch.A3, Pitch.ASharp3 }, { Pitch.F2, Pitch.FSharp2, Pitch.G2, Pitch.GSharp2, Pitch.A2, Pitch.ASharp2, Pitch.B2, Pitch.C3 }, { Pitch.G1, Pitch.GSharp1, Pitch.A1, Pitch.ASharp1, Pitch.B1, Pitch.C2, Pitch.CSharp2, Pitch.D2 }, { Pitch.A0, Pitch.ASharp0, Pitch.B0, Pitch.C1, Pitch.CSharp1, Pitch.D1, Pitch.DSharp1, Pitch.E1 }, { Pitch.BNeg1, Pitch.C0, Pitch.CSharp0, Pitch.D0, Pitch.DSharp0, Pitch.E0, Pitch.F0, Pitch.FSharp0 } }; private Pitch[] rightLEDnotes = new Pitch[] { Pitch.F6, Pitch.G5, Pitch.A4, Pitch.B3, Pitch.CSharp3, Pitch.DSharp2, Pitch.F1, Pitch.G0 }; public InputDevice targetInput; public OutputDevice targetOutput; public delegate void LaunchpadKeyEventHandler(object source, LaunchpadKeyEventArgs e); public delegate void LaunchpadCCKeyEventHandler(object source, LaunchpadCCKeyEventArgs e); /// /// Event Handler when a Launchpad Key is pressed. /// public event LaunchpadKeyEventHandler OnLaunchpadKeyPressed; public event LaunchpadCCKeyEventHandler OnLaunchpadCCKeyPressed; public class LaunchpadCCKeyEventArgs : EventArgs { private int val; public LaunchpadCCKeyEventArgs(int _val) { val = _val; } public int GetVal() { return val; } } /// /// EventArgs for pressed Launchpad Key /// public class LaunchpadKeyEventArgs : EventArgs { private int x; private int y; public LaunchpadKeyEventArgs(int _pX, int _pY) { x = _pX; y = _pY; } public int GetX() { return x; } public int GetY() { return y; } } /// /// Creates a text scroll. /// /// /// /// /// public void createTextScroll(string text, int speed, bool looping, int velo) { byte[] sysexHeader = { 240, 00, 32, 41, 2, 4 }; byte[] sysexStop = { 247 }; byte operation = 20; byte _velocity = (byte)velo; byte _speed = (byte)speed; byte _loop = Convert.ToByte(looping); byte[] _text = { }; byte[] finalArgs = { operation, _velocity, _loop, _speed }; List charList = new List(); foreach(char c in text) { int unicode = c; if (unicode < 128) charList.Add(Convert.ToByte(unicode)); } _text = charList.ToArray(); byte[] finalBytes = sysexHeader.Concat(finalArgs.Concat(_text.Concat(sysexStop))).ToArray(); targetOutput.SendSysEx(finalBytes); } public void stopLoopingTextScroll() { byte[] stop = { 240, 0, 32, 41, 2, 24, 20, 247 }; targetOutput.SendSysEx(stop); } private void sysExAnswer(SysExMessage m) { byte[] msg = m.Data; byte[] stopBytes = { 240, 0, 32, 41, 2, 24, 21, 247 }; } private void midiPress(Midi.NoteOnMessage msg) { if (OnLaunchpadKeyPressed != null && !rightLEDnotes.Contains(msg.Pitch)) { OnLaunchpadKeyPressed(this, new LaunchpadKeyEventArgs(midiNoteToLed(msg.Pitch)[0], midiNoteToLed(msg.Pitch)[1])); } else if (OnLaunchpadKeyPressed != null && rightLEDnotes.Contains(msg.Pitch)) { OnLaunchpadCCKeyPressed(this, new LaunchpadCCKeyEventArgs(midiNoteToSideLED(msg.Pitch))); } } public int midiNoteToSideLED(Pitch p) { for (int y = 0; y <= 7; y++) { if (rightLEDnotes[y] == p) { return y; } } return 0; } /// /// Returns the LED coordinates of a MIdi note /// /// The Midi Note. /// The X,Y coordinates. public int[] midiNoteToLed(Pitch p) { for (int x = 0; x <= 7; x++) { for (int y = 0; y <= 7; y++) { if (notes[x,y] == p) { int[] r1 = { x, y }; return r1; } } } int[] r2 = { 0, 0 }; return r2; } /// /// Returns the equilavent Midi Note to X and Y coordinates. /// /// The X coordinate of the LED /// The Y coordinate of the LED /// The midi note public Pitch ledToMidiNote(int x, int y) { return notes[x, y]; } public void clearAllLEDs() { for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { setLED(x, y, 0); } } for (int ry = 0; ry < 8; ry++) { setSideLED(ry, 0); } for (int tx = 1; tx < 9; tx++) { setTopLEDs(tx, 0); } } /// /// Fills Top Row LEDs. /// /// /// /// public void fillTopLEDs(int startX, int endX, int velo) { for (int x = 1; x < 9; x++) { if (x >= startX && x <= endX) { setTopLEDs(x, velo); } } } /// /// Fills a region of Side LEDs. /// /// /// /// public void fillSideLEDs(int startY, int endY, int velo) { for (int y = 0; y < rightLEDnotes.Length; y++) { if (y >= startY && y <= endY) { setSideLED(y, velo); } } } /// /// Creates a rectangular mesh of LEDs. /// /// Start X coordinate /// Start Y coordinate /// End X coordinate /// End Y coordinate /// Painting velocity public void fillLEDs(int startX, int startY, int endX, int endY, int velo) { for (int x = 0; x < notes.Length; x++) { for (int y = 0; y < notes.Length; y++) { if (x >= startX && y >= startY && x <= endX && y <= endY) setLED(x, y, velo); } } } /// /// Sets a Top LED of the launchpad /// /// /// public void setTopLEDs(int x, int velo) { byte[] data = { 240, 0, 32, 41, 2, 24, 10, Convert.ToByte(103+x), Convert.ToByte(velo), 247 }; targetOutput.SendSysEx(data); } /// /// Sets a Side LED of the Launchpad. /// /// The height of the right Side LED. /// Velocity index. public void setSideLED(int y, int velo) { targetOutput.SendNoteOn(Channel.Channel1, rightLEDnotes[y], velo); } /// /// Sets a LED of the Launchpad. /// /// The X coordinate. /// The Y coordinate. /// The velocity. public void setLED(int x, int y, int velo) { try { targetOutput.SendNoteOn(Channel.Channel1, notes[x, y], velo); } catch (Midi.DeviceException) { Console.WriteLine("<< LAUNCHPAD.NET >> Midi.DeviceException"); throw; } } /// /// Returns all connected and installed Launchpads. /// /// Returns LaunchpadDevice array. public LaunchpadDevice[] getConnectedLaunchpads() { List tempDevices = new List(); foreach (InputDevice id in Midi.InputDevice.InstalledDevices) { foreach (OutputDevice od in Midi.OutputDevice.InstalledDevices) { if (id.Name == od.Name) { if (id.Name.ToLower().Contains("launchpad")) { tempDevices.Add(new LaunchpadDevice(id.Name)); } } } } return tempDevices.ToArray(); } /// /// Function to connect with a LaunchpadDevice /// /// The Launchpad to connect to. /// Returns bool if connection was successful. public bool connect(LaunchpadDevice device) { foreach(InputDevice id in Midi.InputDevice.InstalledDevices) { if (id.Name.ToLower() == device._midiName.ToLower()) { targetInput = id; id.Open(); targetInput.NoteOn += new InputDevice.NoteOnHandler(midiPress); targetInput.StartReceiving(null); } } foreach (OutputDevice od in Midi.OutputDevice.InstalledDevices) { if (od.Name.ToLower() == device._midiName.ToLower()) { targetOutput = od; od.Open(); } } return true; // targetInput.IsOpen && targetOutput.IsOpen; } /// /// Disconnects a given LaunchpadDevice /// /// The Launchpad to disconnect. /// Returns bool if disconnection was successful. public bool disconnect(LaunchpadDevice device) { if (targetInput.IsOpen && targetOutput.IsOpen) { targetInput.StopReceiving(); targetInput.Close(); targetOutput.Close(); } return !targetInput.IsOpen && !targetOutput.IsOpen; } public class LaunchpadDevice { public string _midiName; //public int _midiDeviceId; public LaunchpadDevice(string name) { _midiName = name; } } } }