Closed EarthenSky closed 2 years ago
Each block can contain an arbitrary number of events, and they can happen at any time during the block. The offset within the block is given by the delta_frames
field of the event. The sine_synth does not handle events correctly. It only computes the state of the oscillator at the end of the block and generates sound from that state for the entire block.
Take a look at this synth for an example of correct event handling. In process_events()
, the events are pushed to the back of a queue with information about the time at which they happen. In process()
, the event at the front of the queue is popped when the current time matches the timestamp of the event.
This code assumes that events are given in chronological order by the host. Any well-behaved host will do this, but I have heard rumors that some hosts are broken and can sometimes give events out of order. For the plugin to work with such broken hosts, it will need a priority queue instead of a queue.
Thanks! Sorry for responding so late, but that really clears things up. Turns out the project I was using as reference had this same bug, but it was only because I was looking at an old commit...
I'm finding it confusing that
process_events()
is called before everyprocess()
block, yet in the sine_synth example https://github.com/RustAudio/vst-rs/blob/master/examples/sine_synth.rs only 1 note is ever stored & we don't care how long it is.I though two notes played right after each other (perhaps with a small rest between them) would commonly be part of the same block sent to
process()
.I couldn't find any documentation on this, however my initial assumption before was that the host gets to choose the block size (say 512 samples) then we need to know the time at which each note is played inside that block so we can know when to start adding samples, etc. However, should I actually assume that process() is only called on segments between midi event changes?
For example, would the following grid be valid, where
=
represents a note being played at a certain pitch and|
represents the separation between blocks (akaprocess_events()
&process()
calls)?