diff options
Diffstat (limited to 'backends/midi/windows.cpp')
-rw-r--r-- | backends/midi/windows.cpp | 196 |
1 files changed, 11 insertions, 185 deletions
diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index e49c62bf27..10653eb928 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -32,189 +32,41 @@ class MidiDriver_WIN : public MidiDriver_MPU401 { public: + MidiDriver_WIN(); int open(int mode); void close(); void send(uint32 b); - void pause(bool p); - void set_stream_callback(void *param, StreamCallback *sc); private: - struct MyMidiHdr { - MIDIHDR hdr; - }; - - enum { - NUM_PREPARED_HEADERS = 2, - MIDI_EVENT_SIZE = 64, - BUFFER_SIZE = MIDI_EVENT_SIZE * 12, - }; - - StreamCallback *_stream_proc; - void *_stream_param; - int _mode; - HMIDIOUT _mo; - HMIDISTRM _ms; - - MyMidiHdr *_prepared_headers; - uint16 _time_div; - - void unprepare(); - void prepare(); void check_error(MMRESULT result); - void fill_all(); uint32 property(int prop, uint32 param); - - static void CALLBACK midi_callback(HMIDIOUT hmo, UINT wMsg, - DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); }; -void MidiDriver_WIN::set_stream_callback(void *param, StreamCallback *sc) -{ - _stream_param = param; - _stream_proc = sc; -} - -void CALLBACK MidiDriver_WIN::midi_callback(HMIDIOUT hmo, UINT wMsg, - DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) +MidiDriver_WIN::MidiDriver_WIN() { - switch (wMsg) { - case MM_MOM_DONE:{ - MidiDriver_WIN *md = ((MidiDriver_WIN *) dwInstance); - if (md->_mode) - md->fill_all(); - break; - } - } + _isOpen = false; } -int MidiDriver_WIN::open(int mode) +int MidiDriver_WIN::open() { - if (_mode != 0) + if (_isOpen) return MERR_ALREADY_OPEN; - _mode = mode; - - if (mode == MO_SIMPLE) { - MMRESULT res = midiOutOpen((HMIDIOUT *) & _mo, MIDI_MAPPER, 0, 0, 0); - if (res != MMSYSERR_NOERROR) - check_error(res); - } else { - // Streaming mode - MIDIPROPTIMEDIV mptd; - UINT _midi_device_id = 0; - - check_error(midiStreamOpen(&_ms, &_midi_device_id, 1, - (uint32)midi_callback, (uint32)this, CALLBACK_FUNCTION)); - - prepare(); - - mptd.cbStruct = sizeof(mptd); - mptd.dwTimeDiv = _time_div; + _isOpen = true; - check_error(midiStreamProperty(_ms, (byte *)&mptd, MIDIPROP_SET | MIDIPROP_TIMEDIV)); - - fill_all(); - } + MMRESULT res = midiOutOpen((HMIDIOUT *) &_mo, MIDI_MAPPER, 0, 0, 0); + if (res != MMSYSERR_NOERROR) + check_error(res); return 0; } -void MidiDriver_WIN::fill_all() -{ - if (_stream_proc == NULL) { - error("MidiDriver_WIN::fill_all() called, but _stream_proc==NULL"); - } - - uint i; - MyMidiHdr *mmh = _prepared_headers; - MidiEvent my_evs[64]; - - for (i = 0; i != NUM_PREPARED_HEADERS; i++, mmh++) { - if (!(mmh->hdr.dwFlags & MHDR_INQUEUE)) { - int num = _stream_proc(_stream_param, my_evs, 64); - int i; - - // End of stream? - if (num == 0) - break; - - MIDIEVENT *ev = (MIDIEVENT *)mmh->hdr.lpData; - MidiEvent *my_ev = my_evs; - - for (i = 0; i != num; i++, my_ev++) { - ev->dwStreamID = 0; - ev->dwDeltaTime = my_ev->delta; - - switch (my_ev->event >> 24) { - case 0: - ev->dwEvent = my_ev->event; - break; - case ME_TEMPO: - // Change tempo event - ev->dwEvent = (ME_TEMPO << 24) | (my_ev->event & 0xFFFFFF); - break; - default: - error("Invalid event type passed"); - } - - // Increase stream pointer by 12 bytes. - // (Need to be 12 bytes, and sizeof(MIDIEVENT) is 16) - ev = (MIDIEVENT *)((byte *)ev + 12); - } - - mmh->hdr.dwBytesRecorded = num * 12; - check_error(midiStreamOut(_ms, &mmh->hdr, sizeof(mmh->hdr))); - } - } -} - -void MidiDriver_WIN::prepare() -{ - int i; - MyMidiHdr *mmh; - - _prepared_headers = (MyMidiHdr *) calloc(sizeof(MyMidiHdr), 2); - - for (i = 0, mmh = _prepared_headers; i != NUM_PREPARED_HEADERS; i++, mmh++) { - mmh->hdr.dwBufferLength = BUFFER_SIZE; - mmh->hdr.lpData = (LPSTR) calloc(BUFFER_SIZE, 1); - - check_error(midiOutPrepareHeader((HMIDIOUT) _ms, &mmh->hdr, sizeof(mmh->hdr))); - } -} - -void MidiDriver_WIN::unprepare() -{ - uint i; - MyMidiHdr *mmh = _prepared_headers; - - for (i = 0; i != NUM_PREPARED_HEADERS; i++, mmh++) { - check_error(midiOutUnprepareHeader((HMIDIOUT) _ms, &mmh->hdr, sizeof(mmh->hdr))); - free(mmh->hdr.lpData); - mmh->hdr.lpData = NULL; - } - - free(_prepared_headers); -} - void MidiDriver_WIN::close() { - int mode_was = _mode; - _mode = 0; - - switch (mode_was) { - case MO_SIMPLE: - check_error(midiOutClose(_mo)); - break; - case MO_STREAMING:; - check_error(midiStreamStop(_ms)); - check_error(midiOutReset((HMIDIOUT) _ms)); - unprepare(); - check_error(midiStreamClose(_ms)); - break; - } + _isOpen = false; + check_error(midiOutClose(_mo)); } void MidiDriver_WIN::send(uint32 b) @@ -224,9 +76,6 @@ void MidiDriver_WIN::send(uint32 b) BYTE bData[4]; } u; - if (_mode != MO_SIMPLE) - error("MidiDriver_WIN:send called but driver is not in simple mode"); - u.bData[3] = (byte)((b & 0xFF000000) >> 24); u.bData[2] = (byte)((b & 0x00FF0000) >> 16); u.bData[1] = (byte)((b & 0x0000FF00) >> 8); @@ -236,16 +85,6 @@ void MidiDriver_WIN::send(uint32 b) check_error(midiOutShortMsg(_mo, u.dwData)); } -void MidiDriver_WIN::pause(bool p) -{ - if (_mode == MO_STREAMING) { - if (p) - check_error(midiStreamPause(_ms)); - else - check_error(midiStreamRestart(_ms)); - } -} - void MidiDriver_WIN::check_error(MMRESULT result) { char buf[200]; @@ -255,19 +94,6 @@ void MidiDriver_WIN::check_error(MMRESULT result) } } -uint32 MidiDriver_WIN::property(int prop, uint32 param) -{ - switch (prop) { - - // 16-bit time division per the standard MIDI specification - case PROP_TIMEDIV: - _time_div = (uint16)param; - return 1; - } - - return 0; -} - MidiDriver *MidiDriver_WIN_create() { return new MidiDriver_WIN(); |