|Subject:||Re: [fluid-dev] We need a new, better sequencer!|
|Date:||Thu, 12 Dec 2019 12:02:55 +0100|
> one drawback that I see with the ordering you propose: you currently have the option to choose a different order in your client application because we currently process events in the order they were added.
Primarily, we process events according to timestamps. Here, we are talking about a corner-case, when events have the same timestamp. How fluidsynth treats those events with the same timestamp is currently not documented anywhere (AFAIK). It is only fluidsynth's current implementation that treats it FIFO. Implementations are subject to change. And because this corner-case hasn't been communicated to the user, I don't really consider it to be a change in behaviour. ATM, I only see the two advantages mentioned before. And I do believe that makes it "big" enough to justify the change.
> Still, the custom ordering of events might be at least surprising to sequencer users. And if I understand corrently, then it's a change of existing behaviour. I guess I still haven't understood whose problem you are actually trying to solve. If it is a problem specific to your usage of the sequencer, couldn't you ensure your preferred ordering of simultaneous events in your client application?
Right now, it seems to be only me experiencing this problem (... and Francesco Ariis, who I mentioned initially; just remove the multiple midi tracks by saving his hymn1.mid as SMF0). Admittedly, I am completely biased and selfish: Ofc, I could defer it to my client app. In this case, the MIDI parsing lib would manage its sorted event array internally. Then, my app would come along, sort/fix all events with the same tickvalue. And finally my app would pass everyting to the fluid_sequencer, which sorts the events again to manage its heap based structure. ...It's just redundant amount of work and I was thinking about how to turn this undefined behaviour in a well-defined one (at least for fluidsynth).
In the meantime, I did some real testing:
Attached is a (simplified) MIDI file illustrating the problem. It starts two different notes at the same time. After some delay it starts the same note pair again, after that but still at the same tick, it turns off the notes. After another delay, it starts the same two notes again and turns them off right at the same tick.
When playing it with fluidsynth you will only hear the first note pair sounding, ie. after 8 sec. there'll silence. When you import the MIDI in an editor like rosegarden, qtractor or MuSE, they correctly recognize that there are two note pairs, making the MIDI file sound for 16 sec. (The treatment of the zero length notepair at the end differs between the programs though... not of interest to us anyway). LMMS however, only recognized the first note pair.
For being absolutely sure, I went to the basement to fetch my old Emu Proteus FX hardware synth: It makes the first note pair sound as expected. The second and the third note pairs are so short that they are barely audible. Apparently both are treated as zero-duration notes. When changing the order of events (i.e. turn off the first note pair, then turn on the second pair, still both at the same tick) it works fine. This makes me believe that the FIFO ordering is a leftover from the 90s, where events were transmitted in real-time between different synths, without knowing what comes next. With fluidsynths sequencer however, we have the knowledge which event(s) are about to come next. So IMO, fluidsynth should handle events at the same tick in a smart(er) way.
In case somebody is interested in my progress with the C++ implementation, here's the current dev branch:
And unit tests for the sequencer are ready:
Description: MIDI audio
|[Prev in Thread]||Current Thread||[Next in Thread]|