mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 06:39:17 +00:00
MIDI: Fix XMIDI custom timbre loading
XMIDI files have an optional header defining custom timbres used for each track. Before playback these timbres have to be sent to the MIDI device. The old implementation of this functionality had two problems: - The custom timbres were only sent during loading of the XMIDI data, for the first track. If another track was played, the custom timbres for that track would not be loaded. - The custom timbres were sent after starting playback of the track. This caused the sending of the timbres to sometimes overlap with the start of the playback of the track, causing wrong instruments and bad timing. If fixed these issues by moving the loading of the timbres to a new event handler which is triggered during the setTrack function, before playback is started. This fixes problems with some MT-32 tracks in The 7th Guest, f.e. the second track that plays on the main menu after starting the game.
This commit is contained in:
parent
2f4937bd6d
commit
50772c1fbc
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user