protected void HangingNote(int channel, int note, int timeLeft, bool recycle = true)
{
NoteTimer best = null;
if (HangingNotesCount >= HangingNotes.Length)
{
// Console.Error.WriteLine("MidiParser::hangingNote(): Exceeded polyphony");
return;
}
foreach (var hangingNote in HangingNotes.Reverse())
{
if (hangingNote.Channel == channel && hangingNote.Note == note)
{
if (hangingNote.TimeLeft != 0 && hangingNote.TimeLeft < timeLeft && recycle)
return;
best = hangingNote;
if (hangingNote.TimeLeft != 0)
{
if (recycle)
SendToDriver(0x80 | channel, note, 0);
--HangingNotesCount;
}
break;
}
else if (best == null && hangingNote.TimeLeft == 0)
{
best = hangingNote;
}
}
// Occassionally we might get a zero or negative note
// length, if the note should be turned on and off in
// the same iteration. For now just set it to 1 and
// we'll turn it off in the next cycle.
if (timeLeft == 0 || ((timeLeft & 0x80000000) != 0))
timeLeft = 1;
if (best != null)
{
best.Channel = channel;
best.Note = note;
best.TimeLeft = timeLeft;
++HangingNotesCount;
}
else
{
// We checked this up top. We should never get here!
// Console.Error.WriteLine("MidiParser::hangingNote(): Internal error");
}
}