Re: [LAD] Plugin buffer size restrictions

From: Jeff McClintock <jef@email-addr-hidden>
Date: Wed May 30 2012 - 21:59:38 EEST

> From: David Robillard <d@email-addr-hidden>
>
> I'm a modular head, I remain convinced that control ports are nothing
> but a pain in the ass and CV for everything would be a wonderful
> fantasy land :)

It's called "SynthEdit land" *everything* is CV ;) (not on Linux sorry).

> As it happens, I am currently porting the blop plugins to LV2, and
> making a new extension in order to drop the many plugin variants (which
> are a nightmare from the user POV). This simple extension lets you
> switch a port from its default type (e.g. Control) to another type
> (e.g.
> CV). The pattern looks something like this:
>
> /* plugin->frequency_is_cv is 1 if a CV buffer, 0 if a single float */
> for (uint32_t i = 0; i < sample_count; ++i) {
> const float freq = frequency[s * plugin->frequency_is_cv];
> if (freq != plugin->last_frequency) {
> recalculate_something(freq);
> plugin->last_frequency = freq;
> }
>
> /* Do stuff */
> }

That's smart. In a simple example this doesn't seem like much of a win.
Because A 1 port plugin has only two possible variants (frequency as
single-float/ buffer). But..
* A 2-port plugin has 4 varients.
* A 3-port plugin has 8 varients.
* A 10 port plugin has 1024 varients!

So you're avoiding that combinatorial nightmare.

I do something similar. The port is flagged as either 'streaming' (use the
entire buffer) or 'static' use a single float. My point of difference is -
the entire buffer is provided either way. So you have the option of writing
the plugin like..

     const float freq = frequency[s];

..OR...

     const float freq = frequency[s * plugin->frequency_is_cv];

.. and it works transparently either way. So the extension is backward
compatible with 'dumb' plugins, or 'dumb' plugin standards like VST (I can
interface VST plugins with modular components).

> Doing those comparisons to see if the value actually changed since the
> last sample in order to recalculate is not so great (branching).

I don't know if you can implement what I do. Once I know which ports are
single floats I 'switch' processing functions. i.e. use a function pointer
to select 1 of several optimised functions. So you write a general purpose
loop like the one above, this is your fallback. Then you write an optimised
one that assumes 'frequency' is a single float - This one has no branching
and no extra multiplication, it's super efficient. You get the best of both
worlds. Note I don't write loops optimised for every possible combination,
just pick a few key ones. The function pointer is one extra level of
indirection, but it's much faster than branching, esp when there's several
ports involved in the decision.

> personally my interest in a solution here is very real. More people
> care about normal high level parameters and being able to interpolate
> than low-level modular synth CV stuff, but to me it's telling that (it
> seems...) one solution can solve both problems nicely.

<high five> ;)

Best Regards,
Jeff

_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Thu May 31 00:15:02 2012

This archive was generated by hypermail 2.1.8 : Thu May 31 2012 - 00:15:03 EEST