[LV2] Idea for extension to handle Midi CC controls

David Robillard d at drobilla.net
Sat Jun 9 08:07:45 PDT 2012

On Sat, 2012-06-09 at 03:58 -0400, Jeremy Salwen wrote:
> [
> port 1;
>  name "midi in";
>  type midi;
> ],[
>  port 2; 
>  name "interpolated_controls_in"; //this port could be hidden, as it
> just transfers events for virtual ports
>  type atom_sequence;
> ],[

I think you'll find in the plugin (and elsewhere) that having multiple
event inputs is a real nuisance that causes all sorts of hassles for no
benefit whatsoever.  Best to just use one, unless you truly need
separate streams.

>  port 3;
>  name "pitch bend";
>  type virtual [
>            port 1;
>            channel 11;
>           ];
> ],[
>  port 4;
>   name "resonance";
>   type virtual [
>           port 2;
>           channel 23;
>           ];
>   ];
> If it's not clear, the idea is that port 3 is just a reference to a
> specific channel in port 1, and port 4 is just a reference to a
> specific channel in port 2.  So port 3 will be translated to midi CC
> events, and port 4 will be translated to precise interpolated atom
> events (of the sort you were discussing).  So in both cases if the
> host doesn't care about sample-accuracy, it can just blindly treat
> those ports like normal control ports

This "virtual port" business is not at all what I had in mind.  I guess
your intention is backwards compatibility with control ports?  The
problem with that is you basically lose all the advantages of 'dynamic'
controls anyway, so you might as well just use control ports.

You would also need a mechanism for the host to tell the plugin that it
supports event-based controls so the plugin knows what to expect (i.e.
to ignore the control port)... or perhaps just use connectionOptional?

That said, clever idea.  I guess backwards compatibility would be nice,
if it can be realized without too much work.  I don't think the 'basic'
idea here should be associated with ports, though, we can graft some
properties on to control ports as a backwards compatibility mechanism.
Isn't it kind of had for free if parameters have the same index/symbol
namespace as control ports?  You can just send a "set parameter 1 to
3.4" message if port 1 is a controlport.  No weird port business

To be discoverable, the default parameters would have to be listed in
the Turtle of course, but they are not ports, they are different things.
Something like:

    lv2:port [
        rdf:type lv2:Port , lv2:ControlPort ;
        lv2:index 0 ;
        lv2:symbol "some_control_port" ;
        lv2:default 21.0 ;
        lv2:minimum 0.0 ;
        lv2:maximum 42.0
    ] ;        
    lv2:param [
        rdf:type param:Parameter ;
        param:type atom:Float ;
        lv2:index 0 ;
        lv2:symbol "some_parameter" ;
        lv2:default 0.5 ;
        lv2:minimum 0.0 ;
        lv2:maximum 1.0
    ] .

> , and lilv will do the minor amount of work required to translate the
> controls.

Lilv doesn't really do anything like this related to run time (i.e. it
doesn't non-trivially wrap plugin instances).  I am not sure if a
library could do this, since mixing and such is likely to be involved;
very host specific.

>   On the other hand, in both cases, if the host cared to, it could
> access the additional level of control offered.  (i.e. in the midi
> case it could remap CC numbers, update the GUI, or enable/disable
> touch, and in the event-based control ports, it could provide the
> information for sample accurate interpolation).

In theory, I think MIDI binding should be left *entirely* to the host.
The host knows how to control the plugin, and it can do so however,
including via MIDI learn and such.

In practice, however, there are a few border cases where the plugin
would want to indicate its default MIDI bindings (e.g. plugins
associated with hardware).  For static ports, this can easily be
achieved by just tacking on the desired controller (or whatever) to the
port description.  I planned to add a standard predicate for this to the
next release.  For dynamic... we need stuff :/

I think that is kind of an esoteric border case, though.  These days
everything is either learn based (so a static default binding is
useless) or based on mapping known hardware controls to things
(inherently host based).  I could be wrong, do you have an example of a
plugin that really needs to specifically describe its own MIDI bindings
to the host?

> I forgot about that, this indeed adds the ability for plugins to
> modulate their own parameters.

> This actually seems like a simpler solution. The only downside I can
> think of is that the plugin could end up fighting the host for control
> of a port.  Then what happens?  Depending on what inside the plugin
> wants the port changed, the answer could be different.

I guess the plugin just knows it's modulating the port so it can ignore
incoming changes.  Not catastrophic, but some mechanism to broadcast
this fact is probably needed to make things work smoothly.

Anyway, I think to actually get this done the problem needs to be broken
down into easily understandable chunks.  The main one being: event-based
plugin controls (I have been calling "parameters", unfortunate overlap
with an existing extension name though).  Given that, I think:

* MIDI binding can be easily added, and would work the same way as MIDI
binding for normal ControlPorts which is also needed

* Backwards compatibility with ControlPorts is either easily added, or

Doing static parameters should be pretty straightforward.  Dynamic will
need to be able to announce arbitrary data, which is not so
straightforward, especially for the uninitiated.


More information about the Devel mailing list