1 module armos.communication.midi; 2 3 import derelict.portmidi.portmidi; 4 import derelict.portmidi.porttime; 5 6 struct MidiMessage{ 7 long timestamp; 8 long status; 9 long data1; 10 long data2; 11 } 12 13 /++ 14 +/ 15 class MidiStream { 16 public{ 17 this(int id = -1, in size_t bufferSize = 1024){ 18 DerelictPortMidi.load(); 19 DerelictPortTime.load(); 20 if(id == -1) id = defaultInputDeviceId(); 21 auto e = Pm_OpenInput(&_stream, 22 id, 23 null, 24 bufferSize, 25 null, 26 null); 27 } 28 29 static int defaultInputDeviceId(){ 30 return Pm_GetDefaultInputDeviceID(); 31 } 32 33 MidiStream close(){ 34 Pm_Close(this._stream); 35 _hasClosed = true; 36 return this; 37 } 38 39 MidiMessage[] popMessages(){ 40 immutable size_t max = 1024; 41 auto buffer = new PmEvent[](max); 42 auto numEvents = Pm_Read(_stream, buffer.ptr, max); 43 auto events = new MidiMessage[](numEvents); 44 foreach (size_t i, ref event; events) { 45 import std.conv:to; 46 event.timestamp = buffer[i].timestamp.to!long; 47 event.status = buffer[i].message.to!long & 0xFF; 48 event.data1 = (buffer[i].message.to!long>>8) & 0xFF; 49 event.data2 = (buffer[i].message.to!long>>16) & 0xFF; 50 } 51 return events; 52 } 53 }//public 54 55 private{ 56 ~this(){ 57 if(!_hasClosed){ 58 close; 59 } 60 } 61 62 PmStream* _stream; 63 PmDeviceID _deviceId; 64 bool _hasClosed = false; 65 }//private 66 }//class Stream 67 68