Re: [linux-audio-dev] plugin questions

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

Subject: Re: [linux-audio-dev] plugin questions
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: su loka   10 1999 - 13:47:29 EDT


here's the heart of the matter, i think:

>> other plugins have no business thinking that they
>> can directly request a state change in another plugin - they should
>> just be communicated how *they* see the world, and hope that everybody
>> else agrees with them.
>
>...but that doesn't conflict with a way of saying "I listen to CC
>98 and CC 99 - I'll ignore anything else you send, in case you care."

no, it doesn't conflict. but there are two ways of saying this, one of
them as you just did, and one like this :

    cc_port[0] = subscribe (engine->get_port ("MIDI CC 98"));
    cc_port[1] = subscribe (engine->get_port ("MIDI CC 99"));

the big difference is that if the plugin changes its mind
(e.g. someone pressed the GUI controller for the CC it should use),
the plugin just does:
    
    unsubscribe (cc_port[0]);
    unsubscribe (cc_port[1]);

    cc_port[0] = subscribe (engine->get_port ("New ID"));
    cc_port[1] = subscribe (engine->get_port ("New ID"));
    
and nobody else has to care.

in your scheme, when a plugin changes it mind (and the example above
is a *very* likely one in my experience), you have to broadcast the
change to everyone who might care, which actually means everyone.

>> This is (subtly)
>> opposite, and i think that your version is a bad design pattern. the
>> linkage between a plugin that wants to receive events and another
>> source that sends them should be based on the event types of the
>> source, not the nature of the destination.
>
>True, but how do you know what you can actually connect without just
>being ignored?

>The fact that I see event ports as quite similar to audio ports may
>explain why we have very different views on this.

Yes, I think it may, as the following example illustrates:

>User: "Why the h*ll can I connect this output to that plug-in, when
>the plug-in doesn't care anyway?"

this is a good case in point.

there is a big difference between port connections that are driven by
a user metaphorically (or literally, I don't know :) dragging a patch
cord from one place to another, and those that happen because the user
presses a button on a plugin GUI which says "Controller ID".

in the latter case, when the plugin does its stuff to respond to a
message from the GUI ("multiway switch XXX now has value 64"), it
doesn't don't connect to anything as the *source*. it connects to
another port as the *destination*. thats a key difference that ensures
the connections "matter".

in the former case (user dragging patch cords): when you're dealing
with typed events, which we're proposing, you (the user) can only
connect meaningfully two ports of the same type. if you connect an
audio port to an audio port, you're guaranteed that the destination
will care. but if you connect an audio port to a MIDI port, you can be
certain that you'll be ignored, if you can do it all.

so think about this a little bit more: what are the different event
types ? if you have only a few of them, then you'll be asking plugins
to process all kinds of events that they *just don't care about*. if
you have a lot, and you enforce type equivalency when connecting, you
know you'll be paid attention to.

>Don't you want to know what MIDI events a synth supports?

Well, yes and no. If the synth comes with a MIDI IN port, and I connect
some MIDI OUT port to it, then in order to use it effectively, I need
to know which MIDI events make a difference.

But if the synth has a button which says "MIDI Controller ID" and
controls, say, the controller that sets pitch bend, then I don't care
to know anymore: when I press the button, the plugin will do the right
thing.

So again, it comes back to event types. If ports can only be
distinguished on the basis of being Audio or MIDI, then somebody will
have to tell us which MIDI events the plugin will use if we are to
usefully use a MIDI connection.

If, on the other hand, a port comes with a more specific type, say
"Audio level above XXdB" or "MIDI controller 32", then we need know
very little about a plugin to use it - the plugin will be able to
establish its own connections based on its current state ("Oh, the GUI
wants me to start monitoring audio levels above XXdB. OK, I'd better
establish a connection to ...")

Please note: the audio level example is a deliberately extreme
example. I am not sure that anyone would ever want to create such a
port, let alone subscribe to its events. But its an illustration of
what is possible.

>I think we're too much out of sync for me to give a sensible answer
>to that question... :-) (Or the answer might be in the above?)

I do think we're looking at this from opposite ends. I'm not sure that
what we're looking at is different, though.

I feel really strongly convinced that the model used by GTK, Qt, Gtk--
and libsigc++, and written about in many software engineering/pattern
language articles, is the one to use. Its a highly successful, well
thought out, multiply implemented, and widely used.

I also have implemented a multiport MIDI library that uses libsigc++
in this way, and has "events" for every MIDI message type. Its been a
joy to work with, one of the best and most useful pieces of code
development I've ever done. The MIDIPort objects have no idea who is
listening to them, they just do their stuff, and when it matters, the
right objects get to hear about it.

--p


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

This archive was generated by hypermail 2b28 : pe maalis 10 2000 - 07:27:13 EST