The host struct is the plugin's interface to
various host provided
resources. Unfortunately, making these resources thread-safe would
result in a major performance hit. (Consider the event system, for
example.)
The easy way to deal with this is to just give plugins another host
struct when you want to mess with them in another thread. The plugins
won't be able to tell the difference, unless you want them to.
At what time do we need to change out the Host struct? I'm not seeing where
or why we need to do that. Concrete example, please?
We can track
silence per Port, or just per Plugin (simpler, I
think).
_
Simple, but insufficient for any but the simplest plugins. If you have_
Again, I think we are speaking of slightly different things. I am talking
about the time when (for example) the synth at the head of the chain has
stopped playing notes. A reverb with this as it's input would be told 'your
input is now silent'. It has a tail, of course. It can be marked silent
when it's tail is done. Once it is silent, it does not need to be
processed._
I don't know what use it is to mark individual buffers/Ports in this case.
What is the point of having 'Silent' or NULL buffers? I mean, I guess it
can be a minor optimization. Maybe silence is a per-channel thing? I don't
know that finer grain flags buy anything at all..
cases means return instantly from process(). If
you're doing
something that results in no output (ie you're mixing silence into a
buffer), just don't touch your output buffer. If it's marked as
silent, it just stays that way.
The disadvantage is that everyone with an output has to be aware of
this, because a buffer marked as silent is intended to be *ignored*.
That is, it may (and generally will) contain garbage, which you'll
have to clear out first, unless you have a replacing version of your
inner loop.
hrrm, I'll need to reconsider this mode. hrrmm....
Then the
host can hot the bypass switch (is bypass optional?) or remove it
from the net, or just stop processing it.
No, that won't work. A plugin being silent doesn't mean it's passive,
or even that it won't start generating output again in a moment, even
if there's no new input. A long feed-back delay fed with a short
sound would intermittently generate non-silent buffers for a good
while, and plugins following it could still have use for the "silence
flag".
In my view this is not silence. A silent plugin is one that is totally
passive.
Besides, you cannot safely stop calling a connected
plugin. If it has
inputs directly connected to outputs of other plugins, there's no way
you can know when to start calling the plugin again, since you won't
even know about the events sent to it's Queues. What you get is a
dead plugin draining your event pool. :-)
Agagin, hrrm. I always envision the host snooping events. I'll think some
more about this.
*
EventTarget:
A tuple of an EventQueue and a cookie. Plugins have an
EventTarget for each Control, as well as a master and per-Channel
EventTarget.
Not quite. Targets aren't really "input objects" in the API, but
rather two other things:
I'm not following you - what did I say wrong?
* The physical struct that you get filled in or
returned when you ask a plugin for one of it's
input controls.
* An abstract object inside a plugin, representing
a control output.
right - did I say something different?
Plugins will most probably keep these in arrays or
other structures
internally, for their output controls, but the get_control_input()
call will nearly always construct targets on the fly. All it does is
pick the right Queue and transform the "full adress" of the control
into something handy for internal decoding; ie a cookie.
right - I'll use this or something like it for the detail section of
EventTargets.
Adjusted to
get/set_event_target(). Good?
Still feels wrong... I have another idea, inspired by what's actually
going on, as well as this "do we notify inputs after connection?"
thing:
Looong names those, though... I don't want
"event" in them, because
events are not equivalent with controls; they're just used to operate
them. Leaving out "control" might cause confusion with audio stuff,
and dropping the "input" and "output" part would be generally
confusing.
I don't mind the model. The names I object to. Targets aren't just
control. Controls are the biggest user, but there needs to be a master
target and a per-channel target. Targets are, in fact, event targets.
{open,close}_event_input()
{connect,disconnect}_event_output() or {open,close}_event_output().
Process all
events up to and including 'now'. For a 0 frame run(),
all timestamps are 'now'.
No, timestamps are still valid, so there's no way to guarantee this.
All events in the queue that match the current time will be
processed, but any future events will be left in the queue.
Sorry, I wasn't clear. If you want to change a control immediately, set the
change event to the current time, and run() 0 frames. It will process
events for 'now' which will get the change. It will then see that there are
0 frames to process. Alternatively, 0-frame runs are kind of special.
nframes=0, timestamps can be 0, too.
Tim