Re: [linux-audio-dev] Plugin APIs (again)

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] Plugin APIs (again)
From: Tim Hockin (thockin_AT_hockin.org)
Date: Sun Dec 08 2002 - 07:00:46 EET


> I think we're actually talking about *three* kinds of controls, while
> everyone is still talking about their own set of two kinds of
> controls. What I'm thinking is:

> Master Controls:
> Channel/Part Controls:
> Voice/Note Controls

So if we support multi-timbral (multi-part, multi-channel - too many words)
instruments, then yes, this is true.

Aside: I propose the following for naming stuff:

* Plugin: a chunk of code, loaded or not, that implements this API (a .so file
  or a running instance).
* Instrument: an instance of a plugin that supports the instrument API bits
  (analogous to a chunk of hardware from Roland).
* Channel: a 'part', 'channel' or 'instrument' from MIDI. Instruments have
  1 or more Channels.
* Control: a knob, button, slider, or virtual control withing a Channel or
  Instrument. Controls can be master (e.g. master volume), per-Channel (e.g.
  channel pressure) or per-Voice (e.g. aftertouch).
* Preset: a stored or loaded set of values for all Controls in a Channel
* Voice: a playing sound within a Channel. Channels may have multiple voices.
* Port: an input/output connection on a Plugin. Audio data goes over ports.

> I don't think this has much to do with the API - and I don't see the
> possibility of a clash. If you take any two controls, they may have
> any relation whatsoever, *defined by the synth*, and the host should

I agree with that IF we say you have to have a separate control struct for
per-voice and per-part controls. If we define a control and say it has a
flag which identifies it as MASTER, PART, VOICE, then we do need to suggest
a relationship. I like defining a control once, but it's becoming more
obvious to NOT do that. They range of valid values may be wildly different.

Do we want to provide a suggested range of values for MIDI compatible
controls. For example Controls that are labelled CONTROL_AFTERTOUCH should
expect values between 0 and 1.0, and the host can map MIDI onto that? Or 0
and 127, like MIDI? or 0 and MAX_INT and let the synth blow up when you
pass a VELOCITY of 10000, and it expects 127?

> You're thinking entirely in keyboardist terms here. :-) You're
> forgetting that some instruments really don't have anything like
> attack and release in real life, but rather "bow speed", "air speed"
> and that kind of stuff.

umm, speed == velocity, no? But I get your point, and I concede this point.
Velocity is an event.

> I think so, but I'm not 100% determined. (Audiality is still mostly a
> monolith, and I'm not completely sure how to best split it up into
> real plugins.)

> plugins from being multipart doesn't make much sense. Just reserve
> one control/event port for the whole instrument/plugin, and then
> allow the instrument/plugin to have as many other control/event ports
> as it likes - just like audio in and out ports.

I had been assuming a single event-queue per instance. Two questions: why
would a plugin (assuming not multi-timbral for now) have more than one
event-queue? Assuming we do support multi-timbral synths, is there an
advantage to having events per-channel event-queues? Do you envision each
Channel getting the ->run() method seperately, or does ->run() loop? If it
is looping anyway, is there an advantage to multiple event-queues?

> > > ports. As of now, there is one event port for each Channel, and
> > > one event port for each physical Voice. "Virtual Voices" (ie
> > > Voices as

I know you've done some exploring - do we really want one event-queue per
voice + one for each channel + one for master? or is one per instance
simpler?

> > > As to the "gets a voice ID" thing, no, I think this is a bad
> > > idea. The host should *pick* a voice ID from a previously
> > > allocated pool of Virtual Voice IDs. That way, you eliminate the
> > > host-plugin or plugin-plugin (this is where it starts getting
> > > interesting) roundtrip, which means you can, amond other things:
> >
> > I'm still not clear on this. What plugin would trigger another
> > plugin?
>
> Any plugin that processes events rather than (or in addition to)
> audio. They're usually called "MIDI plugins".

I can see controller plugins (It's another extension to this API, perhaps)
which deal with sending events to other plugins. And I guess an arppegiator
plugin could be a controller..

> > If so, how do you reconcile that they
> > will each have a pool of VVIDs - I suppose they can get VVIDs from
> > the host, but we're adding a fair bit of complexity now.
>
> Where? They have to get the VVIDs from somewhere anyway. It's
> probably not a great idea to just assume that plugins can accept any
> integer number as a valid VVID, since that complicates/slows down
> voice lookup.

you don't send just ANY integer, you get the integer to id a voice FROM the
plug. But if VOICE_ON is an event, it gets much uglier. Do let me see if I
get this right:

Host allocates the VVID pool (perhaps a bitmask or some other way of
indicating usage)
Host wants to send a VOICE_ON:
        allocates an unused VVID
        sends VOICE_ON with that VVID
        when it sends a VOICE_OFF or receives a VOICE_OFF it can mark that
           VVID as unused again.
Plugin wants to send a VOICE_ON:
        calls host->get_vvids(32)
        host allocates it 32 VVIDs
        sends VOICE_ON with any of those, and must manage them itself
        (alternatively, management is simpler if it just allocates one VVID
        at a time and frees it when it is done)

Or does the HOST ask the INSTRUMENT for VVIDs? If so, why? Explain? :)

> I'd much rather require that events sent to a port are sent in
> timestamp order, so the host can just merge sorted event lists. In
> cases where you have multiple connections to the same event port, you
> just use "shadow ports", so the host gets a number of ordered event
> lists that it merges into one just before running the plugin that
> owns the real input port.

I agree - this is the host's job, not the plugin's

> > host has to handle syncronization issues (one recv event-queue per
> > thread, or it has to be plugin -> host callback, or something), but
> > that's OK.
>
> Well, if your threads are not in sample sync, you're in trouble...

I meant threading sync issues. Host can't just pass one event-queue to all
plugins in a multi-thread environment. But again, that is the HOSTs
problem. So the host can pass the address of it's event-queue during
activate(), or the plugin can make a host->send_event() callback.


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Sun Dec 08 2002 - 07:04:08 EET