diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp index 15de9cab5d7..0fecc5e0484 100644 --- a/audio/midiparser.cpp +++ b/audio/midiparser.cpp @@ -372,6 +372,9 @@ bool MidiParser::setTrack(int track) { memset(_activeNotes, 0, sizeof(_activeNotes)); if (_disableAutoStartPlayback) _doParse = false; + + onTrackStart(track); + _activeTrack = track; _position._playPos = _tracks[track]; parseNextEvent(_nextEvent); diff --git a/audio/midiparser.h b/audio/midiparser.h index 94ef5ad366d..0a18c2c3e07 100644 --- a/audio/midiparser.h +++ b/audio/midiparser.h @@ -307,6 +307,13 @@ protected: void hangingNote(byte channel, byte note, uint32 ticksLeft, bool recycle = true); void hangAllActiveNotes(); + /** + * Called before starting playback of a track. + * Can be implemented by subclasses if they need to + * perform actions at this point. + */ + virtual void onTrackStart(uint8 track) { }; + virtual void sendToDriver(uint32 b); void sendToDriver(byte status, byte firstOp, byte secondOp) { sendToDriver(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16)); diff --git a/audio/midiparser_xmidi.cpp b/audio/midiparser_xmidi.cpp index 2be44729415..1a6acd58577 100644 --- a/audio/midiparser_xmidi.cpp +++ b/audio/midiparser_xmidi.cpp @@ -73,8 +73,6 @@ protected: byte *_tracksTimbreList[120]; ///< Timbre-List for each track. uint32 _tracksTimbreListSize[120]; ///< Size of the Timbre-List for each track. - byte *_activeTrackTimbreList; - uint32 _activeTrackTimbreListSize; protected: uint32 readVLQ2(byte * &data); @@ -92,6 +90,7 @@ protected: MidiParser::resetTracking(); _loopCount = -1; } + void onTrackStart(uint8 track) override; void sendToDriver(uint32 b) override; void sendMetaEventToDriver(byte type, byte *data, uint16 length) override; @@ -102,9 +101,7 @@ public: _newTimbreListProc(newTimbreListProc), _newTimbreListDriver(newTimbreListDriver), _source(source), - _loopCount(-1), - _activeTrackTimbreList(NULL), - _activeTrackTimbreListSize(0) { + _loopCount(-1) { memset(_loop, 0, sizeof(_loop)); memset(_trackBranches, 0, sizeof(_trackBranches)); memset(_tracksTimbreList, 0, sizeof(_tracksTimbreList)); @@ -438,6 +435,9 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) { int tracksRead = 0; uint32 branchOffsets[128]; memset(branchOffsets, 0, sizeof(branchOffsets)); + memset(_trackBranches, 0, sizeof(_trackBranches)); + memset(_tracksTimbreList, 0, sizeof(_tracksTimbreList)); + memset(_tracksTimbreListSize, 0, sizeof(_tracksTimbreListSize)); while (tracksRead < _numTracks) { if (!memcmp(pos, "FORM", 4)) { // Skip this plus the 4 bytes after it. @@ -511,12 +511,9 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) { _ppqn = 60; resetTracking(); setTempo(500000); - setTrack(0); - _activeTrackTimbreList = _tracksTimbreList[0]; - _activeTrackTimbreListSize = _tracksTimbreListSize[0]; - if (_newTimbreListProc) - _newTimbreListProc(_newTimbreListDriver, _activeTrackTimbreList, _activeTrackTimbreListSize); + // Start playback of the first track. + setTrack(0); return true; } @@ -524,6 +521,12 @@ bool MidiParser_XMIDI::loadMusic(byte *data, uint32 size) { return false; } +void MidiParser_XMIDI::onTrackStart(uint8 track) { + // Load custom timbres + if (_newTimbreListProc && _tracksTimbreListSize[track] > 0) + _newTimbreListProc(_newTimbreListDriver, _tracksTimbreList[track], _tracksTimbreListSize[track]); +} + void MidiParser_XMIDI::sendToDriver(uint32 b) { if (_source < 0) { MidiParser::sendToDriver(b);