FluidSynth / fluidsynth

Software synthesizer based on the SoundFont 2 specifications
https://www.fluidsynth.org
GNU Lesser General Public License v2.1
1.76k stars 246 forks source link

Sequencer really should use FIFO event ordering #1110

Closed bunnylin closed 2 years ago

bunnylin commented 2 years ago

Referencing this comment block: https://github.com/FluidSynth/fluidsynth/blob/f06619e0793bd1901d7b487b23e6da126840bc0f/src/midi/fluid_seq_queue.cpp#L57

The sequencer queue in FluidSynth was changed not too long ago to re-order events unpredictably within the same tick. The reason for this change was to get a faster implementation, and because one user in the linked discussion insisted that the MIDI spec doesn't explicitly mandate FIFO event ordering, even though that's what every other MIDI player uses.

I'm now writing a program that sends MIDI events to FluidSynth's sequencer for rendering in small batches, and indeed, events within the same tick are not applied in strict FIFO order. My source data has occasional cases where Channel Volume is set twice on the same tick; the order they are applied in depends on how many other events are queued at the same tick, as per the sorting implementation. Thus instruments play at an unexpected volume sometimes. I could scan and remove such events before sending them to the sequencer, but I believe it is actually a violation of the MIDI spec not to use FIFO ordering.

Although the MIDI spec does not explicitly say in which order incoming events are to be processed, the existence of registered parameter controller events absolutely proves that FIFO is the only possible order to correctly interpret MIDI events. Please consider:

I propose that the event queue should not change the order of events posted at the same tick.

derselbst commented 2 years ago

the existence of registered parameter controller events absolutely proves that FIFO is the only possible order to correctly interpret MIDI events

Fluidsynth's sequencer doesn't support RPNs. Therefore, this requirement for FIFO ordering as you argued, doesn't has to be considered when implementing the sequencer.

My source data has occasional cases where Channel Volume is set twice on the same tick

Sending events at the same tick and expecting it to behave well is not considered to be use-case for the sequencer. That's why, I am arguing that your data is broken, and you should fix it in a way whatever you consider to be correct behavior.

bunnylin commented 2 years ago

Ah, my apologies. If the sequencer is not meant to be MIDI-compliant, then the issue is of course invalid. I'll have to find a different way to interact with the software in this case.