From: David Olofson <david(a)olofson.net>
* Three states; created, initialized and activated.
This may be useful if plugins have to be instantiated
for hosts to get info from them. Why not just provide
metadata through the factory API?
What happens during 'created', and what transitions to initialized?
* Bypass mode seems to be a good idea for
stereo->surround.
if your plugin just does some sort of spatialization (mono to stereo, mono
to 5.1, stereo to quadra, whatever), then what does bypass mean? I lik ethe
idea of having a standardized bypass mechanism, but I want to know what it
means in that case? If your next plugin in the chain expects 6 channels,
you can't easily remove a 2->6 channel converter from the net. So does
bypass mean nothing for that plugin? If there is some notion (example:
stereo can be front-left and front-right in a 5.1, with the rest silent) of
how to translate, then it is OK, but can that be assumed?
* Assuming that audio and sequencer stuff is in
different
threads, and even have plugins deal with the sync sounds
like a *very* bad idea to me.
ick
* I think the VST style dispatcher idea is silly. A
table
of function pointers, with a bunch of reserved NULLs
would be simpler, faster and just as extensible for all
practical matters.
There is a certain cleanliness to not having to check for NULL methods in
the host, but I think that it does not warrant an extra level of
indirection. structs can grow cleanly. Stick with that, I say.
* UTF-8, rather than ASCII or UNICODE.
I don't know enough about localization - how does this affect standard use
of printf?
char *s = plugin->name;
printf("NAME: %s\n", s);
* Hosts assume all plugins to be in-place broken.
Why?
* No mix output mode; only replace. More overhead...
Can of worms - more below
* Buffers 16 byte aligned. Sufficient?
what is the point aligned at sizeof(double) should be sufficient. If we
want to impose more restrictions, they should be well justified. Or they
should be left to the host. But I don't know enough platforms to know if
this matters to some. Anyone have better feedback?
* Audio quality control. (Nice scalability feature.)
elucidate? I haven't read the spec yet...
* Plugin input->output latency.
* Host process return->audible output latency.
in my notes for XAP already
* Tail size. (Can be unknown!)
in my notes, in a different way, but this may just be simpler
* Process mode: Mixed/RT/Off-Line.
do we really want anything like this? I have a 1-10 'quality' level.
* Plugins send events specifically to the host...
We already have something like this - if the host is going to draw UIs, it
needs to snoop event traffic.
* Parameter sets for note default params?
Performance
hack - is it really worth it?
explain more?
* Why have normalized parameter values at all?
(Actual parameter values are [0, 1], like VST, but
then there are calls to convert back and forth.)
makes connecting any arbitrary output to any input easy.
* The "save state chunk" call seems cool,
but what's
the point, really?
Well, it is nice to be able to have a plugin store some random gunk for a
preset. This could just be a raw data block, except that we do not have
readable controls - we've been expecting that the host just remembers the
value of controls.
From: Steve Harris <S.W.Harris(a)ecs.soton.ac.uk>
* Hosts assume all plugins to be in-place
broken. Why?
It doesn't really matter what the default is as long as you can override
it. That way is probably safer.
Do we want to do this for XAP? I'd kind of hoped that XAP would dictate
that all plugins must be in-place safe.
From: David Olofson <david(a)olofson.net>
You don't necessarily *have* to implement both. Even the primitive FX
plugin API of Audiality have these variants:
void (*process)(struct ADY_plugin *p,
int *buf, unsigned frames);
void (*process_r)(struct ADY_plugin *p,
int *in, int *out, unsigned frames);
void (*process_m)(struct ADY_plugin *p,
int *in, int *out, unsigned frames);
...and you only *have* to provide *one* - any variant will do. If you
don't provide all of them, the host "SDK" will emulate the others
using the ones that are provided.
This seems like a lot. Where is the performance really going to go?
Unlike the above API, there isn't necessarily a direct input-output mapping.
What types of plugins use which modes?
Instruments: have no inputs (in general) and overwrite output
Effects with #ins = #outs: overwrite their output with:
(input * dry) + (fx * wet).
We can standardize a wet/dry gain control pair. But this becomes something
every plugin needs to provide. Uggh.
Better if they are just plugin specific. If a Plugin doesn't provide
wet/dry control, a simple send plugin can be inserted, right?
Which leaves us with LADSPAs run and run_adding. Which I can only see
useful for the return of send effects, and that can be handled with a simple
mixer plugin, but maybe shouldn't.
From: Sami P Perttu <perttu(a)cc.helsinki.fi>
...and you
only *have* to provide *one* - any variant will do. If you
don't provide all of them, the host "SDK" will emulate the others
using the ones that are provided.
I think this is bad. There should be just one process() function, which
could be given two gain values, one for previous output and another for
the plugin's own output. Plugins would do
out[i] = previous_gain * out[i] + gain * myoutput;
Then the gain (wet/dry gain is what you're saying) is not automatable.
What's the point?
PS Your point about static metadata is well made, but
some items that
could be considered as metadata (eg. port ranges) may depend on system
varaibles (sample rate etc.), though that should probably be discouraged.
Well, there also needs to be a way for a plugin to wrap other formats, and
change all it's metadata. I imagined that a plugin couls tell the host that
it needs to be re-examined - XAP_EV_GESTALT - or something.
Yeah, that's what I thought at first. However, if
you track the
previous_gain and gain controls, you can select between a number of
optimized inner loops internally. What you get is basically the same
thing as a bunch of different callbacks, except that it's not part of
the API, and plugins can handle it any way they like.
Oh, you *do* have to check the control events for those two controls,
of course.
do we really want to force this into all plugins? I'd rather see a send
effect that handles this. Not that run_adding isn't needed - it makes the
eventual ending just a bit simpler, but I am dubious of it's real value.
Simpler is better.
That said, I still think it seems easier to just
provide a few
different callbacks of which plugin authors can pick one or more. A
Can you elucidate on what different ones are needed, bearing in mind that
buffers are not passed to the run method, but rather connected to ports
beforehand?
However, your question gives me an idea: Transform the
dispatchers
into functions that just return direct function pointers by index.
Dead simple, and you can deal with unknown and unimplemented
functions in any way you like. You have to ask for all the call
you'll need at some point (say, right before activating the plugin,
so it has a chance to select specialized versions, if any), but it's
cleaner and simpler than dynamic size arrays on both sides, I think.
I don't mind this, but I don't know if I see the reason it is NEEDed.
This seems
like it would subsume plugin based settings saving,
Actually, I don't think it's related at all. Plugin state is the state
of voices, contents of delay buffers and other internal stuff; ie
everything that *isn't* available as parameters or controls.
It COULD. Rather than the host saving formatted data for controls, we could
certainly just have the plugin do it, and save per-plugin opaque blocks. No
reason to do that if we can accurately track control values. However, I
really do see a potential need for the plugin to store internally generated
data in an opaque manner. A Raw data block control works great for this -
except we don't have any way to READ a control. Just write.
Tim (who has no internet at home for some stupid reason and couldn't read
email all weekend)