On Tue, Jun 03, 2008 at 11:22:15PM +0200, Wolfgang Woehl wrote:
Paul Davis:
but think about what this actually means in
practice: it means that
your chaining logic is actually responsible for plugin
instantiation (and destruction). a given plugin "unit" might have
1, 2 or more actual plugin instances within it. but if plugin
instantiation is being done from within the chaining logic, how
does it share code that the host might use that overlaps with this
in some way?
My gut reaction is to think that it's a bad thing if there were
overlaps in handling connections; that there should be 1 plumber in
the house to handle all the connections a signal route could imply.
The plumber would know from a chain members's properties whether it
needs to bring in jack logic, inter-plugin logic ... The house would
only ask for new chain members, not set them up. Refactor?
I had the same 'gut reaction' when reading Paul's post.
But it's by no means a simple thing. Remember that the
plumber can't do his work in Jack's thread (since he has
to do non RT-safe work), and 'users' (the Jack thread)
will try to use the things being plumbed behind his back
unless they are told not to.
I've had similar problems in some clients that allow the
user to reconfigure all or part of the processing in a more
invasive way than just change a parameter value. The solution
I adopted amounts to:
1. the main thread receives an event saying that processing
has to be reconfigured (e.g. a user clicking a button).
2. It changes state and sends a message to the processing
thread to bypass the processing (producing silence if
there's no other alternative).
3. This message is seen in the next callback. The processing
code changes state and sends a message to the main thread
saying it's now safe to modify the processing chain.
4. The main thread receives this message, reconfigures the
processing code, and when ready sends a message to Jack's
thread to resume normal processing.
5. This message is seen in the next callback. The processing
code changes state and sends a message back the the main
thread.
6. The main thread receives this message and changes state
to accept new reconfiguration requests.
This can be simplified, e.g. the messages to the RT thread
can just be flags that are set by the main thread and tested
in the callback, and if the main thread has a periodic wakeup
the same can be done with the replies. And most of this can
be hidden inside the processing 'object' that is shared by
the two contexts. But even then it remains somewhat invasive,
requiring state management at both ends, and it won't be easy
to hide all of it into a simple-to-use 'support library'.
Which in the end means that anyone wanting to do this sort
of thing should really understand what is involved, even if
he/she doesn't have to write all the code to implement it.
Which in turn means that it's probably a futile exercise to
try and make it 'easy' to would-be programmers wanting to
write the ultimate media player without even having an hint
of how complex such a thing can be.
Ciao,
--
FA
Laboratorio di Acustica ed Elettroacustica
Parma, Italia
Lascia la spina, cogli la rosa.