[gmpi] Re: 3.11 topic: Dynamic plugin structure

  • From: Chris Grigg <gmpi-public@xxxxxxxxxxxxxx>
  • To: gmpi@xxxxxxxxxxxxx
  • Date: Wed, 28 Apr 2004 10:53:26 -0700

Couple more side-comments:

David wrote to Tim:

> > Either way, grouping in itself is IMHO just metadata. Apart from
 > dealing with variable size ranges of parameters or parameter
 > blocks, there's no need for the low level plugin API to deal with
 > this at all.

 Well, it's a matter of codifying it.  If we make it a simple
 OSC-like rule of parsing the string for '/' seperators to delineate
 groups, then that is OK.  I think we need a simple req to address
 this, though.

        GMPI must support grouping of associated parameters.  Grouping may
        be arbitrarily deeply nested.

Yes, sounds ok.


I was going to say we also need to decide how much of the resulting
tree structures hosts are really required to understand - but the
answer to that is trivial, I think: "Nothing!"

Provided the parameter list of a plugin includes the full name of each
parameter, a simple host can just treat the list as a plain 1D list
of unique parameter names. When the user wants to make a connection
(after picking a parameter from the long, messy and generally
annoying 1D list ;-), just grab the string and pass it to the
connect() method.

This works just as well if there's a separate slot index int kept with the param name string, and it's simpler to parse. If it's a struct, it's just as easy to pass as a string is.



...
 > > And do we codify MIDI-like channels?
 >
 > Optional hints, maybe? Plugins that care should mark the root
 > node of each "channel", and hint controls with their MIDI CC
 > equivalents where applicable.
>
 If we codify the 'channel' concept, then any plugin can have any
 number of channels.  One of the properties is 'num_channels' and
 the host must save the state for each channel.

Yeah, but it's only 1D, which IMHO, makes the whole OSC style addressing thing a lot less useful. Will 1D (channel) indexing make everyone happy? Does it really make anything easier? (What about plugins that don't have channels at all? Would be kewl if they could just ignore the whole thing.)

I would suggest it's a mistake to see channel-based internal organization primarily as a MIDI thing. Yes, MIDI has a channel-oriented message structure, but mixers have the same structure. Many synths have the same structure. Some effect processors have the same structure. You see it everywhere in music technology.


Saving state per channel shouldn't be necessary if the plug provides an overall save state API.

1D indexing makes it possible to orthogonalize your plug's param name lists, so you just keep one copy for each slot type and reference it for each slot instance -- that's easier than rebuilding the whole param names list at every reconfig and inserting index strings. And still permits completely dynamic param lists for plug authors that want to go that way.

I agreed before that plugs that don't care about channels/slots can ignore the indexing.

Allowing /-terminated parameter names inside each channel/slot doesn't cramp the style of the few, the brave, the adventursome plug authors to do wacky grouping of any desired type within each slot.

Also, with 1D indexing you could say index 0 corresponds to 'master' and do away with the whole 'master/' and 'channel[n]/' things -- needless string conversions.


> Example:
 num_channels = 3
 params_list[] = {
        "master/volume",      //flagged as global
        "master/pan",         //flagged as global
        "osc/shape",          //flagged as per-channel
        "osc/octave",          //flagged as per-channel
 };

Why not just plain:


params_list[] = {
        "master/volume",
        "master/pan",
        "channel[0]/osc/shape",
        "channel[0]/osc/octave",
        "channel[1]/osc/shape",
        "channel[1]/osc/octave",
        "channel[2]/osc/shape",
        "channel[2]/osc/octave",
};

?

(NAME '[' INUM ']' means the node is item INUM in array NAME.)

Yeah, OK, but, why not the much plainer?:


numChannels = 3; // Host queries this first
channelParamNamesLists[] = [0,1,1,1,-1]   //  Host queries this second

ParamNamesLists = { &masterParamNames, &synthChanParamNames] }

masterParamNames = { "volume", "pan" };
synthChanParamNames = { "shape", "octave" };

All that /-fu for channel indexing and slot type specification is unnecessary and just needs to get unpacked later. (Though if the plug needed/wanted to, it could go nuts with /-grouping within each slot-specific param names array.)

Minor point: There's more room for transcription errors in the one big literal string table you suggest, whereas this approach actually enforces the plug structure in the param names table.


...
[...]
 This means that every 'channel' must have the same parameter-list,
 but I *think* this is OK.  Am I correct or mistaken?

Not sure... I can see the motivation for keeping it at that level, but the restriction makes me a bit nervous.

No no, it's easy for each channel to have a distinct list -- see above.



> It means we
would be codifying a MIDI-ism, but for the sake of compatibility.

Does it really help in any significant way? We still have to use connect() to hook the "MIDI" event source up to the parameters, so as long as we can index by channels on that level, we should be fine, right?

Again, I would encourage seeing this in other terms besides MIDI.



> We should suggest that multi-channel synths don't make a ton of
sense in the virtual world and discourage them.

Yes... But hey! Then the whole idea of channels is basically a legacy hack. I think that's another argument for using "channel[N]/...", since it allows both hosts and plugins to completely ignore the thing at will, and still have them work together.

You can still ignore the index if it's a separate int in a struct, nothing about doing it in the string makes this any easier -- in fact, it makes it a lot harder because you have to parse the string and convert, yuk.



> Also - do we support multiple channels on instruments or any old
plugin?

For easier porting...? Well, yes, they could just (ab)use the same indexing notation, I guess. Even if hosts in general would only care about stuff that's hinted as MIDI channels and MIDI CCs, the notation makes sense to users and any hosts that organize parameters in trees according to the OSC style names. A host could keep nodes with the same base name but different indices together (in automatically generated GUIs or whatever), or just treat them like unrelated nodes with unique names.

I don't like having different plug types, like VSTi vs. VST fx. All GMPI plugs should IMHO have access to the same feature set. Simplifies the world for plug and host writers.



> GMPI must support multi-channel plugins, where each channel has an
        identical parameter and IO structure.  There may be an arbitrary
        number of channels per plugin.

Yes, that would do as the minimal requirement, I think, though if we use something like OSC style addressing, I don't see why we have to enforce that channels should be identical. That could be part of the requirements for a "fully GM compatible GMPI synth", but I think other plugins should be able to use channels while just ignoring this restriction, as long as it can be done without messing everything up.

I agree with David here, and I think that /-delimited parameter names within a 1D slot structure (i.e. struct with int channel index + string param name not including the channel index) both meets all of the other requirements (including index ignorability) and will be on balance easier to implement for everyone. Most plugs will be 1-slot, many will be n-identical-slots, some will be n-different-slots. Within a slot, doing or not doing /-grouping is completely up to the plug author in all of these cases.


-- Chris G.

----------------------------------------------------------------------
Generalized Music Plugin Interface (GMPI) public discussion list
Participation in this list is contingent upon your abiding by the
following rules:  Please stay on topic.  You are responsible for your own
words.  Please respect your fellow subscribers.  Please do not
redistribute anyone else's words without their permission.

Archive: //www.freelists.org/archives/gmpi
Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe

Other related posts: