-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
synthesize() clips notes when they overlap in time and pitch #62
Comments
I think what I did to resolve this was to create a MIDI file with this behavior (overlapping same-note-same-instrument notes) and played it back in a few DAWs, and found that the common behavior was that when there was a note off to kill all notes with that instrument and pitch, so that's the behavior I replicate here. Personally, I wouldn't commit to saying LIFO or FIFO is correct here, so my inclination is just to kill both because MIDI data has no built-in way to indicate precedence. If there's a MIDI spec somewhere indicating what the "standard" way to do things is though, or your experience is different with different DAWs, I would be happy with making the change. |
tbh I haven't surveyed many DAWs in this regard, and you're probably right that there's no established convention. I've been working primarily with Logic Pro, where if two midi notes overlap in time/pitch they both just get synthesized (both the offset of the current note and the onset of the new note), as if they were just notes with different pitches. I found this functionality very useful, since being aware of every note onset was of the utmost importance when creating manual annotations. It also so happens that some of the midi files I got from you already contained this type of overlap, and if it weren't for this functionality in Logic I may have missed the presence of these notes altogether. This is what they say in the Nyquist docs:
Despite the lack of convention, my intuition says that the synthesis should match the concept of "note" as closely as possible, i.e. if there's a note between 1-3s and another between 2-4s, both should be audible, despite the overlap. The fact that the second note might get cancelled due to the note-off message of the first note feels more like an artifact of the midi protocol than a desired functionality. But again, that's just my personal preference. EDIT: the occurrence of overlapping notes with the same pitch is perfectly plausible musically (in most string instruments), so I don't see why it should be considered a "corner" or "erroneous" case other than an artefact of the limitations in the design of the midi protocol. |
So, I just reviewed the code for In [1]: import pretty_midi
In [2]: pm = pretty_midi.PrettyMIDI()
In [3]: pm.instruments.append(pretty_midi.Instrument(0, 0))
In [4]: pm.instruments[0].notes = [pretty_midi.Note(100, 60, .1, 1.3), pretty_midi.Note(100, 60, 1.1, 4.5)]
In [5]: a = pm.synthesize(fs=44100) Listening to Now, if were to load in this data from a MIDI file instead of constructing it in
They are both audible, one just gets cut off at 3s instead of 4s.
It is certainly an artifact of the MIDI protocol. To me, the "desired functionality" is the convention, which I had sort of concluded was "kill all notes on this channel/pitch when a note off is received". At the very least, it could be a bit confusing if someone read in a MIDI file with FIFO behavior, and then used |
I guess I am, at least for synthesize(). But think letting the user decide via an optional parameter might indeed be the best option here.
I'm not entirely sure you can call it a convention if Logic (which is not as popular as e.g. Pro Tools but still one of the biggies) doesn't follow it. From the Nyquist docs it also seems like DAWs are divided on this. In the absence of a convention, I think it makes sense to choose one option as the default but support the alternative too. In any case, this is a relatively minor issue, but I know you'd make at least one person happy if you supported FIFO synthesis too :) |
Just to be clear,
I think the ideal solution, because there is indeed a lack of convention, is to allow the user to decide. This would take a good bit of work though, I think, but I will leave this issue open as a reminder when I have some time to work on it. |
Sorry, yes. Doesn't this mean that creating a midi file from scratch with
👍 |
Yes, but there's no way to avoid this in general. |
If the MIDI file contains two notes (in the same instrument) that have the same pitch and overlap in time, the second of the two will not get synthesized. I.e., say I have a C4 from 1-3s, and another C4 from 2.5-4s: the second note gets "killed" during synthesis.
Admittedly two overlapping notes by the same instrument is not physically possible for all instruments (it is for a guitar for example though), but I think that the correct behavior should be to give the onset of the second note priority over the offset of the first note?
The text was updated successfully, but these errors were encountered: