[LV2] self automating plugins - RFC

Robin Gareus robin at gareus.org
Sat Feb 20 03:44:59 PST 2016

Hi all,

Here's an idea that has been floating around for quite some time.

Many plugins only expose indirect controls.

Prime example is a Gate. You configure: threshold, attack, decay and
maybe a hysteresis parameter. The plugin does its thing and gates e.g. a
kick-drum. Except in the bridge of the song, it misses a kick...

Another example is automatic pitch correction.

For cases like this, it'd be great if the plugin would have a mode to
 - first, analyze the data
 - write its internal values to an automation track [of the plugin host]
 - the user can modify the data (here: manually open the gate or the
fixes note/pitch)
 - later, the plugin processes data using the [user modified] analysis

There are two ways this can be accomplished: online and offline.

The offline mechanism has the benefit that a plugin could analyze the
complete file (or region), do random seeks and take future data into
account (read-ahed, no latency).

Online analysis on the other is a lot more simple and very easy to
integrate into existing projects. A plugin is already analyzing the data
to process it live.  Also reporting those values to the host is in most
cases trivial, as is bypassing the internal analyzer and using
host-provided data instead.

Enter LV2,

Doing online analysis with LV2 is staggeringly easy! A plugin just sends
an Atom message sequence to the host in the form of

@prefix auto <some URI prefix>

<timestamp atom:Object>
 a auto:event;  auto:parameter <int> ; auto:value <float> ;

  <int> is the lv2:index of the parameter.

To complete the picture I propose the following protocol where all Atom
Objects are timestamped, sent in an Atom Sequence.

0) user initiates analysis mode (either via a standard control or a
dedicated plugin specific GUI)

1) The plugin tells the host that it entered analysis mode by sending:

  atom:Object a auto:setup;

2) the first time a plugin "touches" a parameter it sends

  atom:Object a auto:start; auto:parameter <int> ;

This is to allow the host to add guard-points. it's like to a user
touching a control-knob on a touch-sensitive control-surface.

3) plugin sends a sequence of

  a auto:event; auto:parameter <int> ; auto:value <float> ;

4) The plugin releases touch on a parameter by sending

  atom:Object a auto:end; auto:parameter <int> ;

5) the plugin may go back to step 2 anytime or tell the host to complete
the process (usually user initiated) by sending

  atom:Object a auto:finalize;

All in all this is very much like a midi control surface sending
control-data to a plugin host.

Plugins which support this flow must have

   lv2:optionalFeature auto:canWriteAutomatation;

lv2:AtomPort, lv2:OutputPort that send messages must have

  atom:bufferType atom:Sequence ;
  atom:supports auto:automationControl;

and lv2:InputPort, lv2:ControlPort which can be self-automated:

  lv2:portProperty auto:automationControlled ;

Any thoughts, comments so far?

A slight variation would replace  "auto:parameter <int>" with a mapped
URI. That would allow plugins to automate e.g host parameters or
parameters of other plugins  and needs a more complex setup sequence.
I'm not sure if this is useful or desirable.


PS. I'll address offline analysis in a separate proposal.

More information about the Devel mailing list