On Fri, May 25, 2012 at 10:43:36PM -0400, David Robillard wrote:
I am making an LV2 extension for accessing and/or
restricting the buffer
size. This is straightforward, but I need to know just what
restrictions are actually needed by various sorts of DSP.
The sort of thing we're looking for here is "buffer size is always at
least 123 frames" or "buffer size is always a power of 2" or "buffer
size is always a multiple of 123".
I know "multiple of a power of two" is needed for convolution. Not sure
what else...
It's not really *needed*, an FFT-based process can be designed to
work with arbitrary and variable buffer sizes provided
* this is known at init time,
* and the user accepts the additional latency.
'Power of 2' in practice means 'a power of two that is not
too small to make things inefficient'. So the plugin should
have the option to require a minimum size as well, e.g. 64.
But I doubt very much if your extension is going to have much
impact. I expect most hosts to simply ignore it, as implementing
it could be quite invasive. Imagine a host having a chain a plugins
in e.g. a channel strip. If one of them requires this extension
and the host relies on variable buffer size to provide 'sample
accurate' control of the others, then the host is required to
implement extra buffering for that plugin. Probably no-go, some
hosts even refuse plugins that don't work 'in place', even if
the solution in that case is much simpler.
The following is part of a report on LV2 I was asked to
write some months ago:
======
Audio processing (on PCs) is usually done in blocks of frames,
so all components are designed to work that way, There are at
least 4 possible ways the block size of a module or plugin
could be defined:
1. Fixed at compile time.
2. Fixed at instantiation, power of 2 [*]
3. Fixed at instantiation, any (reasonable) value.
4. Variable - can be different in each process() call.
[*] Or a similar restriction, e.g. either 2^N or 3*2^N.
For example some FFT based processes could be designed to
allow a block size of 3*2^N, or even 5*2^N, while making
it accept any size would be out of the question in many
cases.
Clearly (1) is undesirable, and it will not be considered
further. Some algorithms require (2) in order to meet their
specs. They could be made to work with any block size, but
this usually means extra latency, or some other form of loss
of performance.
Almost all more sophisticated audio processing algorithms can
be implemented more easily and usually more efficiently if (3)
is guaranteed, even if the block size itself plays no role in
their definition and does not affect their output in any way.
This is in particular true for algorithms that partially run
using some internal block size (determined by e.g. the sample
rate and some combination of parameters), or those that have
to manage a long history or complex state as part of their
operation.
It is almost always possible to allow (4), the exceptions are
the cases mentioned above that require (2). But an algorithm
that should perform well will have to be designed so that the
output it produces does not in any way depend on the actual
block sizes used at run time.
This includes ignoring any attempt to e.g. control the rate of
change of its internal parameters by a caller playing with the
block size for each process() call. The idea that one could
achieve 'sample accurate' control of an audio process in this
way is a either a fallacy or irrelevant, depending on the case
and how you look at it.
All this means that there is *no reason* to ever require (4),
of a plugin or module, and no serious plugin standard or
modular audio application should ever do this.
Yet that is precisely what LV2 does. While it is designed
to be flexible and extensible, the one and only part of its
specs that is fixed but shouldn't have been gets it wrong.
And allowing an extension to override this is not going to
work, because such an extension can be very invasive to a
host. If a host, e.g. Ardour, is from the start designed to
exploit the freedom of (4), be it for the wrong reasons, it
is never going to adopt an extension that would cripple major
parts of its functionality, e.g. automation, or force them
to be redesigned. Even less so if the plugin system does not
provide an alternative way, guaranteed to work with any plugin,
to obtain the same result.
This is the really sad aspect of the situation: LV2 requires
so little of a plugin that in order to make things like e.g.
automation possible it must allow hacks such as playing with
the block size of each call. So hosts will do this, and that
wart will never go away.
Things should have been the other way round: allowing hosts
to use variable block sizes should have been the extenstion.
Of course nobody would ever use it, because in a well designed
system or application it is not necessary (not even for the
things e.g. Ardour uses it for).
======
Ciao,
--
FA
A world of exhaustive, reliable metadata would be an utopia.
It's also a pipe-dream, founded on self-delusion, nerd hubris
and hysterically inflated market opportunities. (Cory Doctorow)