public static IEnumerable <MIDIEvent> MergeWithBuffer(IEnumerable <MIDIEvent> sequence, FastList <MIDIEvent> buffer) { double bdeltasub = 0; foreach (var _e in sequence) { var e = _e.Clone(); while (!buffer.ZeroLen && buffer.First.DeltaTime - bdeltasub < e.DeltaTime) { var be = buffer.Pop().Clone(); be.DeltaTime -= bdeltasub; bdeltasub = 0; e.DeltaTime -= be.DeltaTime; yield return(be); } yield return(e); bdeltasub += e.DeltaTime; } while (!buffer.ZeroLen) { var be = buffer.Pop().Clone(); be.DeltaTime -= bdeltasub; bdeltasub = 0; yield return(be); } }
public static IEnumerable <Note> ExtractNotes(IEnumerable <MIDIEvent> sequence, FastList <MIDIEvent> otherEvents = null) { double time = 0; FastList <DecodedNote>[] unendedNotes = new FastList <DecodedNote> [256 * 16]; FastList <DecodedNote> notesQueue = new FastList <DecodedNote>(); for (int i = 0; i < unendedNotes.Length; i++) { unendedNotes[i] = new FastList <DecodedNote>(); } double delta = 0; foreach (var e in sequence) { time += e.DeltaTime; if (e is NoteOnEvent) { var n = e as NoteOnEvent; var note = new DecodedNote() { note = new Note(n.Channel, n.Key, n.Velocity, time, double.PositiveInfinity) }; unendedNotes[n.Key * 16 + n.Channel].Add(note); notesQueue.Add(note); delta += e.DeltaTime; } else if (e is NoteOffEvent) { var n = e as NoteOffEvent; var arr = unendedNotes[n.Key * 16 + n.Channel]; if (arr.ZeroLen) { continue; } var note = arr.Pop(); note.ended = true; note.note.End = time; delta += e.DeltaTime; } else { if (otherEvents != null) { var ev = e.Clone(); ev.DeltaTime += delta; delta = 0; otherEvents.Add(ev); } } if (notesQueue.First != null && notesQueue.First.ended) { yield return(notesQueue.Pop().note); } } foreach (DecodedNote un in notesQueue) { if (!un.ended) { un.note.End = time; } yield return(un.note); } notesQueue.Unlink(); foreach (var s in unendedNotes) { s.Unlink(); } }