diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/midiparser.h | 4 | ||||
-rw-r--r-- | sound/midiparser_smf.cpp | 17 | ||||
-rw-r--r-- | sound/midiparser_xmidi.cpp | 83 | ||||
-rw-r--r-- | sound/module.mk | 2 |
4 files changed, 50 insertions, 56 deletions
diff --git a/sound/midiparser.h b/sound/midiparser.h index 3324f4e268..c46c5789d6 100644 --- a/sound/midiparser.h +++ b/sound/midiparser.h @@ -34,7 +34,7 @@ protected: uint32 _timer_rate; public: - virtual bool loadMusic (byte *data) = 0; + virtual bool loadMusic (byte *data, uint32 size) = 0; virtual void unloadMusic() = 0; void setMidiDriver (MidiDriver *driver) { _driver = driver; } @@ -44,7 +44,7 @@ public: virtual void setTrack (byte track) = 0; virtual void jumpToTick (uint32 tick) = 0; - static MidiParser *createParser_RIFF(); + static MidiParser *createParser_SMF(); static MidiParser *createParser_XMIDI(); }; diff --git a/sound/midiparser_smf.cpp b/sound/midiparser_smf.cpp index b429f7484a..5c72ceb21b 100644 --- a/sound/midiparser_smf.cpp +++ b/sound/midiparser_smf.cpp @@ -48,8 +48,6 @@ protected: uint32 _ppqn; uint32 _psec_per_tick; // Microseconds per delta tick - int _lock; - protected: uint32 read4high (byte * &data) { uint32 val = 0; @@ -109,16 +107,9 @@ uint32 MidiParser_SMF::readVLQ (byte * &data) { } void MidiParser_SMF::onTimer() { - if (_lock++) { - --_lock; - return; - } - if (!_play_pos || !_driver) return; - playToTime (_play_time + _timer_rate, true); - _lock = 0; } void MidiParser_SMF::playToTime (uint32 psec, bool transmit) { @@ -215,7 +206,6 @@ void MidiParser_SMF::playToTime (uint32 psec, bool transmit) { if (transmit) { _driver->metaEvent (event, pos, (uint16) length); } - _lock = 0; return; } else if (event == 0x51) { if (length >= 3) { @@ -238,8 +228,6 @@ void MidiParser_SMF::playToTime (uint32 psec, bool transmit) { _play_pos = pos; } -// This code was adapted from the exult methods -// XMIDI::ExtractTracks and XMIDI::ExtractTracksFromXmi bool MidiParser_SMF::loadMusic (byte *data, uint32 size) { uint32 len; bool isGMD = false; // Indicates an older GMD file without block headers @@ -465,9 +453,6 @@ void MidiParser_SMF::allNotesOff() { } void MidiParser_SMF::unloadMusic() { - while (_lock); - ++_lock; - _play_pos = NULL; _data = NULL; _num_tracks = 0; @@ -476,8 +461,6 @@ void MidiParser_SMF::unloadMusic() { _last_event_time = 0; _running_status = 0; allNotesOff(); - - _lock = 0; } void MidiParser_SMF::setTrack (byte track) { diff --git a/sound/midiparser_xmidi.cpp b/sound/midiparser_xmidi.cpp index cc165c854c..6e7a40f295 100644 --- a/sound/midiparser_xmidi.cpp +++ b/sound/midiparser_xmidi.cpp @@ -51,8 +51,6 @@ protected: NoteTimer _notes_cache[32]; - int _lock; - protected: uint32 read4high (byte * &data) { uint32 val = 0; @@ -69,8 +67,10 @@ protected: uint32 readVLQ (byte * &data); uint32 readVLQ2 (byte * &data); + void playToTime (uint32 psec, bool transmit); + public: - bool loadMusic (byte *data); + bool loadMusic (byte *data, uint32 size); void unloadMusic(); void setMidiDriver (MidiDriver *driver) { _driver = driver; } @@ -130,6 +130,12 @@ uint32 MidiParser_XMIDI::readVLQ2 (byte * &pos) { } void MidiParser_XMIDI::onTimer() { + if (!_play_pos || !_driver) + return; + playToTime (_play_time + _timer_rate, true); +} + +void MidiParser_XMIDI::playToTime (uint32 psec, bool transmit) { uint32 delta; uint32 end_time; uint32 event_time; @@ -143,15 +149,7 @@ void MidiParser_XMIDI::onTimer() { byte vel; uint32 note_length; - if (_lock++) { - --_lock; - return; - } - - if (!_play_pos || !_driver) - return; - - end_time = _play_time + _timer_rate; + end_time = psec; pos = _play_pos; // Send any necessary note off events. @@ -159,7 +157,8 @@ void MidiParser_XMIDI::onTimer() { for (i = ARRAYSIZE(_notes_cache); i; --i, ++ptr) { if (ptr->time_left) { if (ptr->time_left <= _timer_rate) { - _driver->send (0x80 | ptr->channel | (ptr->note << 8)); + if (transmit) + _driver->send (0x80 | ptr->channel | (ptr->note << 8)); ptr->time_left = 0; } else { ptr->time_left -= _timer_rate; @@ -191,7 +190,8 @@ void MidiParser_XMIDI::onTimer() { ptr->time_left = note_length; ptr->channel = event & 0x0F; ptr->note = note; - _driver->send (event | (note << 8) | (vel << 16)); + if (transmit) + _driver->send (event | (note << 8) | (vel << 16)); break; } } @@ -199,7 +199,8 @@ void MidiParser_XMIDI::onTimer() { case 0xC: // Program Change case 0xD: // Channel Aftertouch - _driver->send (event | (pos[0] << 8)); + if (transmit) + _driver->send (event | (pos[0] << 8)); ++pos; break; @@ -207,19 +208,22 @@ void MidiParser_XMIDI::onTimer() { case 0xA: // Key Aftertouch case 0xB: // Control Change case 0xE: // Pitch Bender Change - _driver->send (event | (pos[0] << 8) | (pos[1] << 16)); + if (transmit) + _driver->send (event | (pos[0] << 8) | (pos[1] << 16)); pos += 2; break; case 0xF: // Meta or SysEx event switch (event & 0x0F) { case 0x2: // Song Position Pointer - _driver->send (event | (pos[0] << 8) | (pos[1] << 16)); + if (transmit) + _driver->send (event | (pos[0] << 8) | (pos[1] << 16)); pos += 2; break; case 0x3: // Song Select - _driver->send (event | (pos[0] << 8)); + if (transmit) + _driver->send (event | (pos[0] << 8)); ++pos; break; @@ -229,37 +233,42 @@ void MidiParser_XMIDI::onTimer() { case 0xB: // Sequencer Continue case 0xC: // Sequencer Stop case 0xE: // Active Sensing - _driver->send (event); + if (transmit) + _driver->send (event); + break; case 0x0: // SysEx length = readVLQ (pos); - _driver->sysEx (pos, (uint16)(length - 1)); + if (transmit) + _driver->sysEx (pos, (uint16)(length - 1)); pos += length; break; case 0xF: // META event event = *pos++; length = readVLQ (pos); - _driver->metaEvent (event, pos, (uint16) length); - // End of song must be processed by us, - // as well as sending it to the output device. if (event == 0x2F) { - // End of song. See if there are still holding notes - // we need to wait for. + // End of song must be processed by us, + // as well as sending it to the output device. ptr = &_notes_cache[0]; for (i = ARRAYSIZE(_notes_cache); i; --i, ++ptr) { if (ptr->time_left) { - _driver->send (0x80 | ptr->channel | (ptr->note << 8)); + if (transmit) + _driver->send (0x80 | ptr->channel | (ptr->note << 8)); ptr->time_left = 0; } } _play_pos = 0; - _lock = 0; + if (transmit) + _driver->metaEvent (event, pos, (uint16) length); return; } + if (transmit) + _driver->metaEvent (event, pos, (uint16) length); pos += length; + break; } } @@ -268,12 +277,9 @@ void MidiParser_XMIDI::onTimer() { _play_time = end_time; _play_pos = pos; - _lock = 0; } -// This code was adapted from the exult methods -// XMIDI::ExtractTracks and XMIDI::ExtractTracksFromXmi -bool MidiParser_XMIDI::loadMusic (byte *data) { +bool MidiParser_XMIDI::loadMusic (byte *data, uint32 size) { uint32 i = 0; byte *start; uint32 len; @@ -419,9 +425,6 @@ void MidiParser_XMIDI::unloadMusic() { int i; NoteTimer *ptr; - while (_lock); - ++_lock; - _play_pos = NULL; _data = NULL; _num_tracks = 0; @@ -437,8 +440,6 @@ void MidiParser_XMIDI::unloadMusic() { ptr->time_left = 0; } } - - _lock = 0; } void MidiParser_XMIDI::setTrack (byte track) { @@ -451,7 +452,15 @@ void MidiParser_XMIDI::setTrack (byte track) { } void MidiParser_XMIDI::jumpToTick (uint32 tick) { - // TODO: Implement this. + if (_active_track >= _num_tracks) + return; + _play_pos = _tracks[_active_track]; + _play_time = 0; + _last_event_time = 0; + if (tick > 0) { + printf ("jumpToTick (%ld) not completely implemented!\n", tick); + playToTime (tick * MICROSECONDS_PER_TICK - 1, false); + } } MidiParser *MidiParser::createParser_XMIDI() { return new MidiParser_XMIDI; } diff --git a/sound/module.mk b/sound/module.mk index b83973ed8b..ed7a090a2c 100644 --- a/sound/module.mk +++ b/sound/module.mk @@ -2,6 +2,8 @@ MODULE := sound MODULE_OBJS = \ sound/fmopl.o \ + sound/midiparser_smf.o \ + sound/midiparser_xmidi.o \ sound/midistreamer.o \ sound/midiparser_xmidi.o \ sound/mixer.o \ |