On Mon, 2012-05-28 at 19:48 +0000, Fons Adriaensen wrote: > On Mon, May 28, 2012 at 01:30:37PM -0400, David Robillard wrote: > > > > Take a filter plugin. Calculating the actual filter coefficients > > > from the 'user' parameters (frequency, gain, etc..) can easily be > > > 10..1000 times more complex than actually using those coefficients > > > to process one sample. So you really don't want to do that at the > > > audio sample rate. A normal EQ as used in a DAW could do this once > > > every 10 ms or so and use simple linear interpolation in between. > > > And even that doesn't mean the filter should accept arbitrary > > > 'user' parameters on each such update - these have to be rate > > > limited first as well. > > > > This is also an argument for not using signals for controls at all. > > Assuming that by 'signals' you mean audio rate controls, yes. > Again, the exception is 'synthesis' modules. You'd expect a > VCA in a modular synth to do what the ADSR tells it to do, > even if that results in artefacts. But you wouldn't want a > fader in a DAW (essentially the same thing if implemented as > a plugin) to do the same.
Sorry, that term isn't clear. By 'signals' I meant basically a single numeric value (float), whatever the rate. As opposed to an 'event' (also an ambiguous term) which actually says "hey, this control changed to 4.0 now" when it changes - and only when it changes. An 'event' could also have ramp information for interpolation and whatever else. > > It's better in many cases to be explicitly told when the control value > > changes. > > Yes, but if that 'when' is not a regular period Well, in the event case we are *not* regularly sampling a single value (which is a signal), we are describing a parameter change over time. If it didn't change this time, it's the same as last time, but of course: > , and assuming you > want to actually reach the value, there's little you can do excecpt > linearly interpolate from the previous value. This makes the control > value continuous, but not its derivative(s). And that can be more > than enought to generate clicks, zipper noise, etc. Not only you > don't know what the next value will be, you don't even know when > it will arrive. It could be one millisecond later or one minute. > So the only thing you can do to have click and zipper-free output > is to apply enough filtering to guarantee this, whatever the input. > Which means ignoring most of the 'detail' in the input. Which in > turn means it's futile to provide such input in the first place. (The following is my perspective on the issue with respect to the plugin interface, not a rebuttal: I agree completely) Right, you need not only 'now' information in the event, but 'future' information in that event to make it work. I see these issues as more evidence that a single value just isn't good enough, since getting the requisite information when the control itself is just a single float involves mandated latency (i.e. the value this cycle is actually for the future, and the value now is actually one that came earlier). With the right rules, that can works, but it's screwy: the control value at frame 32 doesn't actually correspond to frame 32, the 'synchronous' feel of run() has been ruined, and more importantly, sample accurate offline rendering just breaks outright (unless you start tacking on a bunch of additional crap to work around that with special cases). I think the same requirements can be better met by moving past a single float. Or: potentially flexible buffer size is not the error in LV2; the use of a single float for controls is. The buffer size feature is mostly orthogonal and simple to add; ControlPort is the thing that probably shouldn't have been inherited from LADSPA at all. To reframe slightly what you've said: in order for interpolation to work correctly the value must be known for 'now', and at 'now plus 1 block' (see below for more on 'block'). This is basically the eventey equivalent to saying you need a "regular period", but slightly different to a sampled signal for a control. Most notably, the value described now indeed represents *now*. Of course, in some cases (like the ones you are thinking of, I believe) you may not be able to actually affect the sample at t=32 with the value at t=32; the interpolation or other factors might add some additional hidden control latency by necessity. This is fine. The important distinction is that what the host is describing is a single synchronous stream of control and audio, where t=32 is t=32 for both control and audio. The big tangible difference is that the latency is *optional*. With this scheme, you could e.g. write a trivial amplifier plugin that simply multiplies by the gain control, and there would be no additional latency whatsoever. The host can describe a step-wise function and have it actually applied to the audio (in whatever way) without latency. This is crucial if you want to build stuff out of lower-level plugins in modular synths and such (but is not limited to synthesis), a case where a "float value with guaranteed control latency" scheme completely fails. (There is the question of what to do in live situations where future values do not exist, but there are only two possible things to do, and the solution is obvious, so I will ignore that and stay on topic) Relating back to buffer size, there is one time parameter here: how far into the future the plugin must know controls in advance (L). This raises a big question: ignoring convolution and such, is that value actually related to the audio block size at all? If you have a description of a continuous parameter where you know values at least L frames in advance (for sufficiently large L), you can interpolate that parameter smoothly, in whatever way is appropriate for the plugin. It seems the desire for a restricted block size (in cases where it is not otherwise necessary) is actually just a consequence of the control description (i.e. a single float) sucking. I think the actual problem is inadequate controls, and fixing that seems like a dramatically better solution than restricting the block size and mandating latency to work around it. The latter is more of a kludge than an ideal solution and has many downsides; not the least of which being that it's dramatically less feasible. The only thing every person in this thread has agreed on is that restricting the buffer size (to make controls work properly) is a massive difficulty for hosts. As far as I can tell, we don't have to. -dr _______________________________________________ Linux-audio-dev mailing list [email protected] http://lists.linuxaudio.org/listinfo/linux-audio-dev
