aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/midiparser.cpp22
-rw-r--r--sound/midiparser.h2
2 files changed, 14 insertions, 10 deletions
diff --git a/sound/midiparser.cpp b/sound/midiparser.cpp
index 4f083b6566..6caae0508b 100644
--- a/sound/midiparser.cpp
+++ b/sound/midiparser.cpp
@@ -100,7 +100,7 @@ void MidiParser::activeNote (byte channel, byte note, bool active) {
}
}
-void MidiParser::hangingNote (byte channel, byte note, uint32 time_left) {
+void MidiParser::hangingNote (byte channel, byte note, uint32 time_left, bool recycle) {
NoteTimer *best = 0;
NoteTimer *ptr = _hanging_notes;
int i;
@@ -112,11 +112,11 @@ void MidiParser::hangingNote (byte channel, byte note, uint32 time_left) {
for (i = ARRAYSIZE(_hanging_notes); i; --i, ++ptr) {
if (ptr->channel == channel && ptr->note == note) {
- if (ptr->time_left && ptr->time_left < time_left)
+ if (ptr->time_left && ptr->time_left < time_left && recycle)
return;
best = ptr;
if (ptr->time_left) {
- _driver->send (0x80 | channel | note << 8);
+ if (recycle) _driver->send (0x80 | channel | note << 8);
--_hanging_notes_count;
}
break;
@@ -272,28 +272,32 @@ bool MidiParser::setTrack (int track) {
void MidiParser::hangAllActiveNotes() {
// Search for note off events until we have
// accounted for every active note.
+ uint16 temp_active [128];
+ memcpy (temp_active, _active_notes, sizeof (temp_active));
+
uint32 advance_tick = _position._last_event_tick;
while (true) {
int i, j;
for (i = 0; i < 128; ++i)
- if (_active_notes[i] != 0) break;
+ if (temp_active[i] != 0) break;
if (i == 128) break;
parseNextEvent (_next_event);
advance_tick += _next_event.delta;
if (_next_event.command() == 0x8) {
- if (_active_notes [_next_event.basic.param1] & (1 << _next_event.channel())) {
- hangingNote (_next_event.channel(), _next_event.basic.param1, (advance_tick - _position._last_event_tick) * _psec_per_tick);
- _active_notes [_next_event.basic.param1] &= ~ (1 << _next_event.channel());
+ if (temp_active[_next_event.basic.param1] & (1 << _next_event.channel())) {
+ hangingNote (_next_event.channel(), _next_event.basic.param1, (advance_tick - _position._last_event_tick) * _psec_per_tick, false);
+ temp_active[_next_event.basic.param1] &= ~ (1 << _next_event.channel());
}
} else if (_next_event.event == 0xFF && _next_event.ext.type == 0x2F) {
// printf ("MidiParser::hangAllActiveNotes(): Hit End of Track with active notes left!\n");
for (i = 0; i < 128; ++i) {
for (j = 0; j < 16; ++j) {
- if (_active_notes[i] & (1 << j))
+ if (temp_active[i] & (1 << j)) {
+ activeNote (j, i, false);
_driver->send (0x80 | j | i << 8);
+ }
}
}
- memset (_active_notes, 0, sizeof (_active_notes));
break;
}
}
diff --git a/sound/midiparser.h b/sound/midiparser.h
index 4ac4a69746..c5fad965d5 100644
--- a/sound/midiparser.h
+++ b/sound/midiparser.h
@@ -182,7 +182,7 @@ protected:
virtual void parseNextEvent (EventInfo &info) = 0;
void activeNote (byte channel, byte note, bool active);
- void hangingNote (byte channel, byte note, uint32 ticks_left);
+ void hangingNote (byte channel, byte note, uint32 ticks_left, bool recycle = true);
void hangAllActiveNotes();
//! Platform independent BE uint32 read-and-advance.