How to Keep Only the Longest Notes at Specific Note-On Times #305
-
Hello, how have you been? Thanks to DryWetMIDI, I could easily implement a MIDI reader feature. For example, overlapping notes with zero lengths. Thankfully, I could easily filter those notes with this one-line code: However, I still encounter MIDI files with overlapping notes whose lengths are greater than zero. For instance, if we have four C4 notes with lengths of 10, 100, 1000, and 1000 within the same channel at timestamp 0, I want to remove the 10 and 100 ones and then keep ONLY ONE of the two 1000 notes since they are duplicates. I want to apply this logic to all notes so that only the longest notes remain within each channel. Is this possible? Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 11 replies
-
Hi! Well, if you don't worry about performance, this approach should work: foreach (var trackChunk in midiFile.GetTrackChunks())
{
using (var notesManager = trackChunk.ManageNotes())
{
var notesGroups = notesManager
.Objects
.GroupBy(n => (n.Time, n.NoteNumber, n.Channel));
foreach (var notesGroup in notesGroups)
{
var maxLength = notesGroup.Max(n => n.Length);
var singleMaxLengthNote = notesGroup.First(n => n.Length == maxLength);
foreach (var note in notesGroup)
{
if (note != singleMaxLengthNote)
notesManager.Objects.Remove(note);
}
}
}
} But be aware this code will work only if overlapping notes start at the same time. Because if they don't, things will be non-deterministic. You can read more here. Also I probably should think about adding such functionality in the Sanitizer tool. Thank you for interesting case. |
Beta Was this translation helpful? Give feedback.
Hi!
Well, if you don't worry about performance, this approach should work: