On 05/09/2013 10:46 PM, David Robillard wrote:
> (Sorry for the late reply, I don't monitor LAD very closely these days)
>
> You should be able to handle all the events in one loop.
>
> However here you seem to be iterating over all events *for every frame*?
> That would cause a problem with loading since you'll issue a ton of
> identical load requests, but it also probably isn't what you want for
> MIDI either. You'll trigger everything repeatedly and the timing is
> wrong. I think you need to unify your two loops here.
Nope, I do not iterate over all events in every frame. Before iterating
over the frames I get the first event and then on every frame I iterate
over those events that have that frame time.. This is similar to how the
jack_midi example code does it..
// First the worker events stuff ONCE per run() call
LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev)
{
[...]
}
// Then the iteration over the frames...
LV2_Atom_Event *ev =
lv2_atom_sequence_begin(&(self->control_port)->body); [...]
for (unsigned frame_index = 0; frame_index < sample_count; ++frame_index)
{
[...]
while (false == lv2_atom_sequence_is_end(&(self->control_port)->body,
self->control_port->atom.size, ev) && ev->time.frames == frame_index)
{
[...]
ev = lv2_atom_sequence_next(ev);
} [...]
// Did we reach the end of a chunk or the last of the sample_count?
if (0 == (frame_index + 1) % buffer_size || sample_count == frame_index + 1)
{
process(self, frame_index % buffer_size + 1, chunk_index * buffer_size);
++chunk_index;
}
}
> The general pattern for sample-accurate event receiving is work through
> time in the event loop, outputting everything up to the current event.
> So you start with t=0. The next event loop in the loop is at t=5, so
> render the output for 0..5, process the event (to e.g. trigger a voice
> or whatever), then continue. After the loop output everything from the
> last event to the end of the cycle.
>
> So your event processing loop is your processing loop, and proceeds in
> 'chunks' delimited by events.
>
> The magic of the worker extension is you can do non-RT things like load
> new sample banks, which will happen RT-safe (with latency) if running
> realtime, but if freewheeling (e.g. for export) the scheduled work will
> execute immediately/synchronously. Thus you can get sample accurate
> exporting, e.g. with a patch load at t=0 and a note on at t=1 the note
> is guaranteed to play with the new patch (in the export). You don't
> need to worry about this, but it's why things are the way they are...
> plus it's pretty cool :)
>
> Hopefully that makes sense, the simplest example of how to do this is in
> the metro example:
>
> http://lv2plug.in/browser/trunk/plugins/eg03-metro.lv2/metro.c#L296
I do use the worker extension. The only problem I saw was when I tried
to integrate the patch_set messages in that same loop.
Flo
-- Florian Paul Schmidt http://fps.io _______________________________________________ Linux-audio-dev mailing list Linux-audio-dev@email-addr-hidden http://lists.linuxaudio.org/listinfo/linux-audio-devReceived on Fri May 10 00:15:04 2013
This archive was generated by hypermail 2.1.8 : Fri May 10 2013 - 00:15:04 EEST