diff options
-rw-r--r-- | backends/midi/adlib.cpp | 21 | ||||
-rw-r--r-- | backends/midi/alsa.cpp | 82 | ||||
-rw-r--r-- | backends/midi/coreaudio.cpp | 15 | ||||
-rw-r--r-- | backends/midi/null.cpp | 6 | ||||
-rw-r--r-- | backends/midi/quicktime.cpp | 30 | ||||
-rw-r--r-- | backends/midi/windows.cpp | 196 | ||||
-rw-r--r-- | scumm/imuse.cpp | 4 | ||||
-rw-r--r-- | simon/midi.cpp | 4 | ||||
-rw-r--r-- | simon/midi.h | 3 | ||||
-rw-r--r-- | sound/mididrv.cpp | 212 | ||||
-rw-r--r-- | sound/mididrv.h | 41 | ||||
-rw-r--r-- | sound/midistreamer.cpp | 20 | ||||
-rw-r--r-- | sound/midistreamer.h | 20 |
13 files changed, 123 insertions, 531 deletions
diff --git a/backends/midi/adlib.cpp b/backends/midi/adlib.cpp index affa88afd8..dfa3d9aab1 100644 --- a/backends/midi/adlib.cpp +++ b/backends/midi/adlib.cpp @@ -488,11 +488,9 @@ class MidiDriver_ADLIB : public MidiDriver { public: MidiDriver_ADLIB(); - int open(int mode); + int open(); void close(); void send(uint32 b); - void pause(bool p) { } - void set_stream_callback(void *param, StreamCallback *sc) { } // No streaming support. Use MidiStreamer wrapper uint32 property (int prop, uint32 param); void setPitchBendRange (byte channel, uint range); @@ -511,7 +509,7 @@ public: MidiChannel *getPercussionChannel() { return NULL; } // Percussion currently not supported private: - int _mode; + bool _isOpen; bool _game_SmallHeader; FM_OPL *_opl; @@ -720,15 +718,14 @@ MidiDriver_ADLIB::MidiDriver_ADLIB() _parts[i].init (this); } _game_SmallHeader = false; + _isOpen = false; } -int MidiDriver_ADLIB::open (int mode) +int MidiDriver_ADLIB::open () { - if (_mode != 0) + if (_isOpen) return MERR_ALREADY_OPEN; - if (mode != MO_SIMPLE) - return MERR_STREAMING_NOT_AVAILABLE; - _mode = mode; + _isOpen = true; int i; MidiChannelAdl *mc; @@ -750,6 +747,7 @@ int MidiDriver_ADLIB::open (int mode) _mixer = g_mixer; _mixer->setupPremix(this, premix_proc); + return 0; } @@ -763,13 +761,12 @@ void MidiDriver_ADLIB::close() // Detach the premix callback handler _mixer->setupPremix (0, 0); + + _isOpen = false; } void MidiDriver_ADLIB::send (uint32 b) { - if (_mode != MO_SIMPLE) - error("MidiDriver_ADLIB::send called but driver is not in simple mode"); - //byte param3 = (byte) ((b >> 24) & 0xFF); byte param2 = (byte) ((b >> 16) & 0xFF); byte param1 = (byte) ((b >> 8) & 0xFF); diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index 538b0cd74b..c150dc11a8 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -51,72 +51,33 @@ class MidiDriver_ALSA:public MidiDriver_MPU401 { public: MidiDriver_ALSA(); - int open(int mode); + int open(); void close(); void send(uint32 b); - void pause(bool p); - void set_stream_callback(void *param, StreamCallback *sc); - // void setPitchBendRange (byte channel, uint range); private: void send_event(int do_flush); + bool _isOpen; snd_seq_event_t ev; - StreamCallback *_stream_proc; - void *_stream_param; - int _mode; snd_seq_t *seq_handle; int seq_client, seq_port; int my_client, my_port; static int parse_addr(char *arg, int *client, int *port); }; -MidiDriver_ALSA::MidiDriver_ALSA():_mode(0), seq_handle(0), seq_client(0), seq_port(0), my_client(0), -my_port(0) +MidiDriver_ALSA::MidiDriver_ALSA() + : _isOpen(false), seq_handle(0), seq_client(0), seq_port(0), my_client(0), my_port(0) { } -int MidiDriver_ALSA::parse_addr(char *arg, int *client, int *port) -{ - char *p; - - if (isdigit(*arg)) { - if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) - return -1; - *client = atoi(arg); - *port = atoi(p + 1); - } else { - if (*arg == 's' || *arg == 'S') { - *client = SND_SEQ_ADDRESS_SUBSCRIBERS; - *port = 0; - } else - return -1; - } - return 0; -} - -void MidiDriver_ALSA::send_event(int do_flush) -{ - snd_seq_ev_set_direct(&ev); - snd_seq_ev_set_source(&ev, my_port); - snd_seq_ev_set_dest(&ev, seq_client, seq_port); - - snd_seq_event_output(seq_handle, &ev); - if (do_flush) - snd_seq_flush_output(seq_handle); -} - -int MidiDriver_ALSA::open(int mode) +int MidiDriver_ALSA::open() { char *var; unsigned int caps; - if (_mode != 0) + if (_isOpen) return MERR_ALREADY_OPEN; - - if (mode != MO_SIMPLE) - return MERR_STREAMING_NOT_AVAILABLE; - - _mode = mode; + _isOpen = true; if (!(var = getenv("SCUMMVM_PORT"))) { // default alsa port if none specified @@ -225,17 +186,34 @@ void MidiDriver_ALSA::send(uint32 b) } } -void MidiDriver_ALSA::pause(bool p) +int MidiDriver_ALSA::parse_addr(char *arg, int *client, int *port) { - if (_mode == MO_STREAMING) { - /* Err... and what? */ + char *p; + + if (isdigit(*arg)) { + if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) + return -1; + *client = atoi(arg); + *port = atoi(p + 1); + } else { + if (*arg == 's' || *arg == 'S') { + *client = SND_SEQ_ADDRESS_SUBSCRIBERS; + *port = 0; + } else + return -1; } + return 0; } -void MidiDriver_ALSA::set_stream_callback(void *param, StreamCallback *sc) +void MidiDriver_ALSA::send_event(int do_flush) { - _stream_param = param; - _stream_proc = sc; + snd_seq_ev_set_direct(&ev); + snd_seq_ev_set_source(&ev, my_port); + snd_seq_ev_set_dest(&ev, seq_client, seq_port); + + snd_seq_event_output(seq_handle, &ev); + if (do_flush) + snd_seq_flush_output(seq_handle); } MidiDriver *MidiDriver_ALSA_create() diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index 00cc81e4f5..879162290e 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -39,30 +39,21 @@ class MidiDriver_CORE : public MidiDriver_MPU401 { public: MidiDriver_CORE() : au_MusicDevice(0), au_output(0) { } - int open(int mode); + int open(); void close(); void send(uint32 b); - void pause(bool p) { } - void set_stream_callback(void *param, StreamCallback *sc) { } private: AudioUnit au_MusicDevice; AudioUnit au_output; - - int _mode; }; -int MidiDriver_CORE::open(int mode) +int MidiDriver_CORE::open() { if (au_output != NULL) return MERR_ALREADY_OPEN; - if (mode == MO_STREAMING) - return MERR_STREAMING_NOT_AVAILABLE; - - _mode = mode; - int err; AudioUnitConnection auconnect; ComponentDescription compdesc; @@ -106,8 +97,6 @@ void MidiDriver_CORE::close() // Cleanup CloseComponent(au_output); CloseComponent(au_MusicDevice); - - _mode = 0; } void MidiDriver_CORE::send(uint32 b) diff --git a/backends/midi/null.cpp b/backends/midi/null.cpp index 80e30735c2..74612d18cf 100644 --- a/backends/midi/null.cpp +++ b/backends/midi/null.cpp @@ -25,14 +25,12 @@ /* NULL driver */ class MidiDriver_NULL : public MidiDriver_MPU401 { public: - int open(int mode); + int open(); void close() { } void send(uint32 b) { } - void pause(bool p) { } - void set_stream_callback(void *param, StreamCallback *sc) { } }; -int MidiDriver_NULL::open(int mode) +int MidiDriver_NULL::open() { warning("Music not enabled - MIDI support selected with no MIDI driver available. Try Adlib"); return 0; diff --git a/backends/midi/quicktime.cpp b/backends/midi/quicktime.cpp index f08f3e2d79..e447208bf0 100644 --- a/backends/midi/quicktime.cpp +++ b/backends/midi/quicktime.cpp @@ -46,11 +46,11 @@ */ class MidiDriver_QT : public MidiDriver_MPU401 { public: - int open(int mode); + MidiDriver_QT(); + + int open(); void close(); void send(uint32 b); - void pause(bool p) { } - void set_stream_callback(void *param, StreamCallback *sc); void setPitchBendRange (byte channel, uint range); private: @@ -58,33 +58,24 @@ private: NoteChannel qtNoteChannel[16]; NoteRequest simpleNoteRequest; - StreamCallback *_stream_proc; - void *_stream_param; - int _mode; - // Pitch bend tracking. Necessary since QTMA handles // pitch bending so differently from MPU401. uint16 _pitchbend [16]; byte _pitchbend_range [16]; }; -void MidiDriver_QT::set_stream_callback(void *param, StreamCallback *sc) +MidiDriver_QT::MidiDriver_QT() { - _stream_param = param; - _stream_proc = sc; + qtNoteAllocator = NULL; } -int MidiDriver_QT::open(int mode) +int MidiDriver_QT::open() { ComponentResult qtErr = noErr; int i; - qtNoteAllocator = NULL; - - if (mode == MO_STREAMING) - return MERR_STREAMING_NOT_AVAILABLE; - - _mode = mode; + if (qtNoteAllocator != NULL) + return MERR_ALREADY_OPEN; for (i = 0; i < 15; i++) qtNoteChannel[i] = NULL; @@ -126,8 +117,6 @@ bail: void MidiDriver_QT::close() { - _mode = 0; - for (int i = 0; i < 15; i++) { if (qtNoteChannel[i] != NULL) NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]); @@ -142,9 +131,6 @@ void MidiDriver_QT::close() void MidiDriver_QT::send(uint32 b) { - if (_mode != MO_SIMPLE) - error("MidiDriver_QT:send called but driver is not in simple mode"); - MusicMIDIPacket midPacket; unsigned char *midiCmd = midPacket.data; midPacket.length = 3; 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(); diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index d46cfe336d..36d2b9cef8 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -3743,9 +3743,9 @@ void IMuseGM::init(IMuseInternal *eng, OSystem *syst) _system = syst; // Open MIDI driver - int result = _md->open(MidiDriver::MO_SIMPLE); + int result = _md->open(); if (result) - error("IMuseGM::error = %s", MidiDriver::get_error_name(result)); + error("IMuseGM::error = %s", MidiDriver::getErrorName(result)); // Connect to the driver's timer _se = eng; diff --git a/simon/midi.cpp b/simon/midi.cpp index 134c03d688..e80021d6a9 100644 --- a/simon/midi.cpp +++ b/simon/midi.cpp @@ -185,9 +185,9 @@ void MidiPlayer::initialize() _midiDriver->property(MidiDriver::PROP_TIMEDIV, _songs[0].ppqn); - res = _midiDriver->open(MidiDriver::MO_STREAMING); + res = _midiDriver->open(); if (res != 0) - error("MidiPlayer::initializer, got %s", MidiDriver::get_error_name(res)); + error("MidiPlayer::initializer, got %s", MidiDriver::getErrorName(res)); if (_paused) _midiDriver->pause (true); diff --git a/simon/midi.h b/simon/midi.h index 3653a37316..9b3cfc7a6a 100644 --- a/simon/midi.h +++ b/simon/midi.h @@ -23,6 +23,7 @@ #define SIMON_MIDI_H class MidiDriver; +class MidiStreamer; class File; struct MidiEvent; @@ -67,7 +68,7 @@ private: byte *sysex_data; }; - MidiDriver *_midiDriver; + MidiStreamer *_midiDriver; uint _lastDelay; Song *_currentSong; Song _songs[8]; diff --git a/sound/mididrv.cpp b/sound/mididrv.cpp index d473ed128b..d8d0db83ac 100644 --- a/sound/mididrv.cpp +++ b/sound/mididrv.cpp @@ -42,7 +42,7 @@ uint32 MidiDriver::property(int prop, uint32 param) /* retrieve a string representation of an error code */ -const char *MidiDriver::get_error_name(int error_code) +const char *MidiDriver::getErrorName(int error_code) { static const char *const midi_errors[] = { "No error", @@ -69,14 +69,12 @@ const char *MidiDriver::get_error_name(int error_code) #include "morphos_sound.h" /* MorphOS MIDI driver */ -class MidiDriver_ETUDE:public MidiDriver_MPU401 { +class MidiDriver_ETUDE : public MidiDriver_MPU401 { public: + MidiDriver_ETUDE(); int open(int mode); void close(); void send(uint32 b); - void pause(bool p); - void set_stream_callback(void *param, StreamCallback *sc); - // void setPitchBendRange (byte channel, uint range); private: enum { @@ -85,88 +83,37 @@ private: BUFFER_SIZE = MIDI_EVENT_SIZE * 12, }; - static void midi_callback(ULONG msg, struct IOMidiRequest *req, APTR user_data); - void fill_all(); uint32 property(int prop, uint32 param); - StreamCallback *_stream_proc; - void *_stream_param; - IOMidiRequest *_stream_req[NUM_BUFFERS]; - void *_stream_buf[NUM_BUFFERS]; - bool _req_sent[NUM_BUFFERS]; - int _mode; - uint16 _time_div; + bool _isOpen; }; -void MidiDriver_ETUDE::set_stream_callback(void *param, StreamCallback *sc) +MidiDriver_ETUDE::MidiDriver_ETUDE() { - _stream_param = param; - _stream_proc = sc; + _isOpen = false; } -int MidiDriver_ETUDE::open(int mode) +int MidiDriver_ETUDE::open() { - if (_mode != 0) + if (_isOpen) return MERR_ALREADY_OPEN; - _mode = mode; - if (!init_morphos_music(0, _mode == MO_STREAMING ? ETUDEF_STREAMING : ETUDEF_DIRECT)) + _isOpen = true; + if (!init_morphos_music(0, ETUDEF_DIRECT)) return MERR_DEVICE_NOT_AVAILABLE; - if (_mode == MO_STREAMING && ScummMidiRequest) { - _stream_req[0] = ScummMidiRequest; - _stream_req[1] = (IOMidiRequest *) AllocVec(sizeof (IOMidiRequest), MEMF_PUBLIC); - _stream_buf[0] = AllocVec(BUFFER_SIZE, MEMF_PUBLIC); - _stream_buf[1] = AllocVec(BUFFER_SIZE, MEMF_PUBLIC); - _req_sent[0] = _req_sent[1] = false; - - if (_stream_req[1] == NULL || _stream_buf[0] == NULL || _stream_buf[1] == NULL) { - close(); - return MERR_DEVICE_NOT_AVAILABLE; - } - - if (ScummMidiRequest) - { - memcpy(_stream_req[1], _stream_req[0], sizeof (IOMidiRequest)); - struct TagItem MidiStreamTags[] = { { ESA_Callback, (ULONG) &midi_callback }, - { ESA_UserData, (ULONG) this }, - { ESA_TimeDiv, _time_div }, - { TAG_DONE, 0 } - }; - SetMidiStreamAttrsA(ScummMidiRequest, MidiStreamTags); - fill_all(); - } - } - return 0; } void MidiDriver_ETUDE::close() { - if (_mode == MO_STREAMING) { - if (_req_sent[0]) { - AbortIO((IORequest *) _stream_req[0]); - WaitIO((IORequest *) _stream_req[0]); - _req_sent[0] = false; - } - if (_req_sent[1]) { - AbortIO((IORequest *) _stream_req[1]); - WaitIO((IORequest *) _stream_req[1]); - _req_sent[1] = false; - } - - if (_stream_req[1]) FreeVec(_stream_req[1]); - if (_stream_buf[0]) FreeVec(_stream_buf[0]); - if (_stream_buf[1]) FreeVec(_stream_buf[1]); - } - exit_morphos_music(); - _mode = 0; + _isOpen = false; } void MidiDriver_ETUDE::send(uint32 b) { - if (_mode != MO_SIMPLE) - error("MidiDriver_ETUDE::send called but driver is not in simple mode"); + if (_isOpen) + error("MidiDriver_ETUDE::send called but driver was no opened"); if (ScummMidiRequest) { ULONG midi_data = READ_LE_UINT32(&b); @@ -174,103 +121,12 @@ void MidiDriver_ETUDE::send(uint32 b) } } -void MidiDriver_ETUDE::midi_callback(ULONG msg, struct IOMidiRequest *req, APTR user_data) -{ - switch (msg) { - case ETUDE_STREAM_MSG_BLOCKEND: { - MidiDriver_ETUDE *md = ((MidiDriver_ETUDE *) user_data); - if (md && md->_mode) - md->fill_all(); - break; - } - } -} - -void MidiDriver_ETUDE::fill_all() -{ - if (_stream_proc == NULL) { - error("MidiDriver_ETUDE::fill_all() called, but _stream_proc == NULL"); - } - - uint buf; - MidiEvent my_evs[64]; - - for (buf = 0; buf < NUM_BUFFERS; buf++) { - if (!_req_sent[buf] || CheckIO((IORequest *) _stream_req[buf])) { - int num = _stream_proc(_stream_param, my_evs, 64); - - if (_req_sent[buf]) { - WaitIO((IORequest *) _stream_req[buf]); - _req_sent[buf] = false; - } - - /* end of stream? */ - if (num == 0) - break; - - MIDIEVENT *ev = (MIDIEVENT *) _stream_buf[buf]; - MidiEvent *my_ev = my_evs; - - for (int i = 0; i < num; i++, my_ev++) { - ev->me_StreamID = 0; - ev->me_DeltaTime = my_ev->delta; - - switch (my_ev->event >> 24) { - case 0: - ev->me_Event = my_ev->event; - break; - case ME_TEMPO: - /* change tempo event */ - ev->me_Event = (MEVT_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); - } - - ConvertWindowsMidiStream(_stream_buf[buf], num * 12); - - _stream_req[buf]->emr_Std.io_Command = CMD_WRITE; - _stream_req[buf]->emr_Std.io_Data = _stream_buf[buf]; - _stream_req[buf]->emr_Std.io_Length = num * 12; - SendIO((IORequest *) _stream_req[buf]); - _req_sent[buf] = true; - } - } -} - -void MidiDriver_ETUDE::pause(bool p) -{ - if (_mode == MO_STREAMING && ScummMidiRequest) { - if (p) - PauseMidiStream(ScummMidiRequest); - else - RestartMidiStream(ScummMidiRequest); - } -} - -uint32 MidiDriver_ETUDE::property(int prop, uint32 param) -{ - switch (prop) { - /* 16-bit time division according to standard midi specification */ - case PROP_TIMEDIV: - _time_div = (uint16)param; - return 1; - } - - return 0; -} - -extern MidiDriver* EtudeMidiDriver; +extern MidiDriver* EtudeMidiDriver = NULL; MidiDriver *MidiDriver_ETUDE_create() { - EtudeMidiDriver = new MidiDriver_ETUDE(); + if (!EtudeMidiDriver) + EtudeMidiDriver = new MidiDriver_ETUDE(); return EtudeMidiDriver; } @@ -280,39 +136,31 @@ MidiDriver *MidiDriver_ETUDE_create() #define SEQ_MIDIPUTC 5 #define SPECIAL_CHANNEL 9 -class MidiDriver_SEQ:public MidiDriver_MPU401 { +class MidiDriver_SEQ : public MidiDriver_MPU401 { public: MidiDriver_SEQ(); - int open(int mode); + int open(); void close(); void send(uint32 b); - void pause(bool p); - void set_stream_callback(void *param, StreamCallback *sc); - // void setPitchBendRange (byte channel, uint range); private: - StreamCallback *_stream_proc; - void *_stream_param; - int _mode; + bool _isOpen; int device, _device_num; }; MidiDriver_SEQ::MidiDriver_SEQ() { - _mode = 0; + _isOpen = false; device = 0; _device_num = 0; } -int MidiDriver_SEQ::open(int mode) +int MidiDriver_SEQ::open() { - if (_mode != 0) + if (_isOpen) return MERR_ALREADY_OPEN; + _isOpen = true; device = 0; - if (mode != MO_SIMPLE) - return MERR_STREAMING_NOT_AVAILABLE; - - _mode = mode; char *device_name = getenv("SCUMMVM_MIDI"); if (device_name != NULL) { @@ -339,7 +187,7 @@ int MidiDriver_SEQ::open(int mode) void MidiDriver_SEQ::close() { ::close(device); - _mode = 0; + _isOpen = false; } @@ -385,18 +233,6 @@ void MidiDriver_SEQ::send(uint32 b) write(device, buf, position); } -void MidiDriver_SEQ::pause(bool p) -{ - if (_mode == MO_STREAMING) { - } -} - -void MidiDriver_SEQ::set_stream_callback(void *param, StreamCallback *sc) -{ - _stream_param = param; - _stream_proc = sc; -} - MidiDriver *MidiDriver_SEQ_create() { return new MidiDriver_SEQ(); diff --git a/sound/mididrv.h b/sound/mididrv.h index 2783b6c651..e503aef0cd 100644 --- a/sound/mididrv.h +++ b/sound/mididrv.h @@ -36,19 +36,6 @@ struct MidiEvent { class MidiDriver { public: - /* called whenever the midi driver is in streaming mode, - * and more midi commands need to be generated - * return 0 to tell the mididriver that the end of stream was reached - */ - typedef int StreamCallback (void *param, MidiEvent * ev, int num); - - - /* open modes, pass one of those to open() */ - enum { - MO_SIMPLE = 1, - MO_STREAMING = 2, - }; - /* Special events that can be inserted in a MidiEvent. * event = (ME_xxx<<24) | <24-bit data associated with event> */ @@ -58,11 +45,11 @@ public: }; /* error codes returned by open. - * can be converted to a string with get_error_name() + * can be converted to a string with getErrorName() */ enum { MERR_CANNOT_CONNECT = 1, - MERR_STREAMING_NOT_AVAILABLE = 2, +// MERR_STREAMING_NOT_AVAILABLE = 2, MERR_DEVICE_NOT_AVAILABLE = 3, MERR_ALREADY_OPEN = 4, }; @@ -73,33 +60,21 @@ public: }; - /* open the midi driver. - * returns 0 if successful. - * otherwise an error code. */ - virtual int open(int mode) = 0; + // open the midi driver. + // returns 0 if successful, otherwise an error code. + virtual int open() = 0; - /* close the midi driver */ + // close the midi driver virtual void close() = 0; - /* output a packed midi command to the midi stream - * valid only if mode is MO_SIMPLE - */ + // output a packed midi command to the midi stream virtual void send(uint32 b) = 0; - /* set callback when more streams need to be generated. - * valid only when mode==MO_STREAMING - */ - virtual void set_stream_callback(void *param, StreamCallback *sc) = 0; - - /* Pause or resume streaming MIDI */ - virtual void pause(bool pause) = 0; - - /* Get or set a property */ virtual uint32 property(int prop, uint32 param); /* retrieve a string representation of an error code */ - static const char *get_error_name(int error_code); + static const char *getErrorName(int error_code); // HIGH-LEVEL SEMANTIC METHODS virtual void setPitchBendRange (byte channel, uint range) diff --git a/sound/midistreamer.cpp b/sound/midistreamer.cpp index ed32ef7934..c8863028ab 100644 --- a/sound/midistreamer.cpp +++ b/sound/midistreamer.cpp @@ -27,7 +27,7 @@ MidiStreamer::MidiStreamer (MidiDriver *target) : _target (target), _stream_proc (0), _stream_param (0), -_mode (0), +_isOpen (false), _paused (false), _event_count (0), _event_index (0), @@ -41,7 +41,7 @@ void MidiStreamer::set_stream_callback (void *param, StreamCallback *sc) _stream_param = param; _stream_proc = sc; - if (_mode) { + if (_isOpen) { _event_count = _stream_proc (_stream_param, _events, ARRAYSIZE (_events)); _event_index = 0; } @@ -80,23 +80,19 @@ void MidiStreamer::on_timer() } // end while } -int MidiStreamer::open (int mode) +int MidiStreamer::open() { - if (_mode != 0) + if (_isOpen) close(); - int res = _target->open (MidiDriver::MO_SIMPLE); + int res = _target->open(); if (res && res != MERR_ALREADY_OPEN) return res; _event_index = _event_count = _delay = 0; - _mode = mode; + _isOpen = true; _paused = false; - if (mode == MO_SIMPLE) - return 0; - -// g_system->create_thread (timer_thread, this); _driver_tempo = _target->getBaseTempo() / 500; _target->setTimerCallback (this, &timer_thread); @@ -105,7 +101,7 @@ int MidiStreamer::open (int mode) void MidiStreamer::close() { - if (!_mode) + if (!_isOpen) return; _target->setTimerCallback (NULL, NULL); @@ -116,7 +112,7 @@ void MidiStreamer::close() for (i = 0; i < 16; ++i) _target->send ((0x7B << 8) | 0xB0 | i); - _mode = 0; + _isOpen = false; _paused = true; } diff --git a/sound/midistreamer.h b/sound/midistreamer.h index d2b70bed86..f1158e8b45 100644 --- a/sound/midistreamer.h +++ b/sound/midistreamer.h @@ -27,11 +27,19 @@ class MidiStreamer; #include "mididrv.h" class MidiStreamer : public MidiDriver { +public: + /* called whenever the midi driver is in streaming mode, + * and more midi commands need to be generated + * return 0 to tell the mididriver that the end of stream was reached + */ + typedef int StreamCallback (void *param, MidiEvent * ev, int num); + private: + MidiDriver *_target; StreamCallback *_stream_proc; void *_stream_param; - int _mode; + bool _isOpen; bool _paused; MidiEvent _events [64]; @@ -43,19 +51,21 @@ private: uint16 _ticks_per_beat; long _delay; - uint32 property(int prop, uint32 param); static void timer_thread (void *param); void on_timer(); public: + MidiStreamer (MidiDriver *target); - int open(int mode); + int open(); void close(); - void send(uint32 b) { if (_mode) _target->send (b); } + void send(uint32 b) { if (_isOpen) _target->send (b); } + uint32 property(int prop, uint32 param); + void setPitchBendRange (byte channel, uint range) { _target->setPitchBendRange (channel, range); } + void pause(bool p) { _paused = p; } void set_stream_callback(void *param, StreamCallback *sc); - void setPitchBendRange (byte channel, uint range) { _target->setPitchBendRange (channel, range); } void setTimerCallback (void *timer_param, void (*timer_proc) (void *)) { } uint32 getBaseTempo (void) { return _target->getBaseTempo(); } |