1 module iota.audio.midi; 2 3 public import iota.audio.types; 4 public import iota.audio.midiin; 5 public import iota.audio.midiout; 6 7 version (Windows) { 8 package import iota.audio.midiwin; 9 import core.sys.windows.windows; 10 import core.sys.windows.wtypes; 11 /** 12 * Te last error code that occured on the OS side. 13 */ 14 MMRESULT lastErrorCode; 15 } 16 17 /** 18 * The last error code that occured on middleware side. 19 */ 20 public int lastStatusCode; 21 package string[] inDevs; 22 package string[] outDevs; 23 /** 24 * Initializes MIDI subsystem. 25 * Returns: Zero on success, or a specific error code. 26 */ 27 public int initMIDI() { 28 version (Windows) { 29 import std.string : fromStringz; 30 import std.utf : toUTF8; 31 32 uint nOutDevices = midiOutGetNumDevs(); 33 uint nInDevices = midiInGetNumDevs(); 34 if (!(nInDevices | nOutDevices)) return lastStatusCode = MIDIInitializationStatus.DevicesNotFound; 35 inDevs.length = nInDevices; 36 for (int i ; i < inDevs.length ; i++) { 37 MIDIINCAPS caps; 38 size_t u = i; 39 lastErrorCode = midiInGetDevCaps(u, &caps, cast(UINT)MIDIINCAPS.sizeof); 40 if (lastErrorCode == MMSYSERR_NOERROR) 41 inDevs[i] = toUTF8(fromStringz(caps.szPname.ptr).idup); 42 else 43 return lastStatusCode = MIDIInitializationStatus.InitError; 44 } 45 outDevs.length = nOutDevices; 46 for (int i ; i < outDevs.length ; i++) { 47 MIDIOUTCAPS caps; 48 size_t u = i; 49 lastErrorCode = midiOutGetDevCaps(u, &caps, cast(UINT)MIDIOUTCAPS.sizeof); 50 if (lastErrorCode == MMSYSERR_NOERROR) 51 outDevs[i] = toUTF8(fromStringz(caps.szPname.ptr).idup); 52 else 53 return lastStatusCode = MIDIInitializationStatus.InitError; 54 } 55 return 0; 56 } else return lastStatusCode = MIDIInitializationStatus.OSNotSupported; 57 } 58 ///Returns the name of all MIDI input devices. 59 public string[] getMIDIInputDevs() @safe nothrow { 60 return inDevs.dup; 61 } 62 ///Returns the name of all MIDI output devices. 63 public string[] getMIDIOutputDevs() @safe nothrow { 64 return outDevs.dup; 65 } 66 /** 67 * Opens an input for a MIDI stream. 68 * Params: 69 * input = Stream returned here. 70 * num = The ID of the device. 71 * bufSize = The input buffer size if applicable (1024 by default). 72 * Returns: 0 if the operation is successful, or an error code. 73 */ 74 public int openMIDIInput(ref MIDIInput input, uint num, size_t bufSize = 1024) { 75 version (Windows) { 76 WindowsMIDIInput wmi = new WindowsMIDIInput(num, bufSize); 77 switch (wmi.lastErrorCode) { 78 case MMSYSERR_NOMEM: 79 return MIDIDeviceInitStatus.OutOfMemory; 80 case MMSYSERR_BADDEVICEID: 81 return MIDIDeviceInitStatus.InvalidDeviceID; 82 case MMSYSERR_NOERROR: 83 input = wmi; 84 return MIDIDeviceInitStatus.AllOk; 85 default: 86 return MIDIDeviceInitStatus.InitError; 87 } 88 } else return lastStatusCode = MIDIDeviceInitStatus.OSNotSupported; 89 } 90 /** 91 * Opens an output for a MIDI stream. 92 * Params: 93 * output = Stream returned here. 94 * num = The ID of the device. 95 * Returns: 96 */ 97 public int openMIDIOutput(ref MIDIOutput output, uint num) { 98 version (Windows) { 99 WindowsMIDIOutput wmi = new WindowsMIDIOutput(num); 100 switch (wmi.lastErrorCode) { 101 case MMSYSERR_NOMEM: 102 return MIDIDeviceInitStatus.OutOfMemory; 103 case MMSYSERR_BADDEVICEID: 104 return MIDIDeviceInitStatus.InvalidDeviceID; 105 case MMSYSERR_NOERROR: 106 output = wmi; 107 return MIDIDeviceInitStatus.AllOk; 108 default: 109 return MIDIDeviceInitStatus.InitError; 110 } 111 } else return lastStatusCode = MIDIDeviceInitStatus.OSNotSupported; 112 }