diff options
author | Simon Howard | 2014-10-28 22:31:53 -0400 |
---|---|---|
committer | Simon Howard | 2014-10-28 22:31:53 -0400 |
commit | 563d83b675bf201bf1df5e626b81f9ddb568c8b7 (patch) | |
tree | 8ecfa122d323de2af2162e47086e4ab8c0953571 | |
parent | 5a7a5402f74361dee7f2c6109eb46b83b4d17c16 (diff) | |
parent | 4f4cfd902dcdf93e9db6043ddb080dd20b471c3d (diff) | |
download | chocolate-doom-563d83b675bf201bf1df5e626b81f9ddb568c8b7.tar.gz chocolate-doom-563d83b675bf201bf1df5e626b81f9ddb568c8b7.tar.bz2 chocolate-doom-563d83b675bf201bf1df5e626b81f9ddb568c8b7.zip |
Merge pull request #468 from khokh2001/opl-fix4
Fix voice allocation when there are no more free voices. This fixes a
long-standing (but minor) discrepancy between the OPL code and the DMX
library that was marked in the code with a TODO.
-rw-r--r-- | src/i_oplmusic.c | 79 |
1 files changed, 19 insertions, 60 deletions
diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index b7c22384..aa6a7a6d 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -364,6 +364,7 @@ static boolean LoadInstrumentTable(void) static opl_voice_t *GetFreeVoice(void) { opl_voice_t *result; + opl_voice_t **rover; // None available? @@ -379,8 +380,15 @@ static opl_voice_t *GetFreeVoice(void) // Add to allocated list - result->next = voice_alloced_list; - voice_alloced_list = result; + rover = &voice_alloced_list; + + while (*rover != NULL) + { + rover = &(*rover)->next; + } + + *rover = result; + result->next = NULL; return result; } @@ -636,22 +644,12 @@ static void KeyOffEvent(opl_track_data_t *track, midi_event_t *event) } } -// Compare the priorities of channels, returning either -1, 0 or 1. - -static int CompareChannelPriorities(opl_channel_data_t *chan1, - opl_channel_data_t *chan2) -{ - // TODO ... - - return 1; -} - // When all voices are in use, we must discard an existing voice to // play a new note. Find and free an existing voice. The channel // passed to the function is the channel for the new note to be // played. -static opl_voice_t *ReplaceExistingVoice(opl_channel_data_t *channel) +static void ReplaceExistingVoice() { opl_voice_t *rover; opl_voice_t *result; @@ -664,51 +662,19 @@ static opl_voice_t *ReplaceExistingVoice(opl_channel_data_t *channel) // than higher-numbered channels, eg. MIDI channel 1 is never // discarded for MIDI channel 2. - result = NULL; + result = voice_alloced_list; for (rover = voice_alloced_list; rover != NULL; rover = rover->next) { if (rover->current_instr_voice != 0 - || (rover->channel > channel - && CompareChannelPriorities(channel, rover->channel) > 0)) + || rover->channel >= result->channel) { result = rover; - break; } } - // If we didn't find a voice, find an existing voice being used to - // play a note on the same channel, and use that. - - if (result == NULL) - { - for (rover = voice_alloced_list; rover != NULL; rover = rover->next) - { - if (rover->channel == channel) - { - result = rover; - break; - } - } - } - - // Still nothing found? Give up and just use the first voice in - // the list. - - if (result == NULL) - { - result = voice_alloced_list; - } - - // Stop playing this voice playing and release it back to the free - // list. - VoiceKeyOff(result); ReleaseVoice(result); - - // Re-allocate the voice again and return it. - - return GetFreeVoice(); } @@ -822,21 +788,9 @@ static void VoiceKeyOn(opl_channel_data_t *channel, voice = GetFreeVoice(); - // If there are no more voices left, we must decide what to do. - // If this is the first voice of the instrument, free an existing - // voice and use that. Otherwise, if this is the second voice, - // it isn't as important; just discard it. - if (voice == NULL) { - if (instrument_voice == 0) - { - voice = ReplaceExistingVoice(channel); - } - else - { - return; - } + return; } voice->channel = channel; @@ -919,6 +873,11 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event) instrument = channel->instrument; } + if (voice_free_list == NULL) + { + ReplaceExistingVoice(); + } + // Find and program a voice for this instrument. If this // is a double voice instrument, we must do this twice. |