Skip to content

Instantly share code, notes, and snippets.

@grejppi
Last active August 29, 2015 14:04
Show Gist options
  • Save grejppi/9e5760bc746d5d176805 to your computer and use it in GitHub Desktop.
Save grejppi/9e5760bc746d5d176805 to your computer and use it in GitHub Desktop.
LV2: Atom-based note event proposal

Atom-based note event proposal

Revision Changes
2 Aug 2014, 21.10 UTC+3 Changed panning to stereoPanning
2 Aug 2014, 19.13 UTC+3 Added more comments to properties
2 Aug 2014, 18.40 UTC+3 Initial revision

While working on LV2 support for LMMS I started to think about a way to send note events to plugins without being restricted to MIDI.

LMMS supports the following properties for notes:

  • velocity (0..200%)
  • panning
  • pitch automation along time

I believe VST3 also has similar features; so does Bitwig Studio for its internal instruments.

Proposal

A thing to note (pun intended): this document is somewhat simplified; I am quite new to RDF but I hope this is still understandable.

note:NoteEvent
    a           rdfs:Class ;
    rdfs:label  "Note event" .

note:id
    a             rdf:Property ;
    rdfs:range    xsd:int ;
    rdfs:comment  "An unique identifier for a note." .

note:gate
    a             rdf:Property ;
    rdfs:range    xsd:boolean ;
    rdfs:comment  "Whether a note with a certain note:id is active." .

note:frequency
    a             rdf:Property ;
    rdfs:range    xsd:float ;
    rdfs:comment  "Frequency in Hz." .

note:velocity
    a             rdf:Property ;
    rdfs:range    xsd:float ;
    rdfs:comment  "Velocity as a multiplier, from 0 (silence) to 1 (100% or 0dB)" .

note:stereoPanning
    a             rdf:Property ;
    rdfs:range    xsd:float ;
    rdfs:comment  "Stereo panning from -1 (left) to 1 (right)." .

note:expects
    a             rdf:Property ;
    rdfs:range    rdf:Property ;
    rdfs:comment  "Any additional properties that the plugin may need." .

Explanation

[]
    a                  note:NoteEvent ;
    note:id            26523 ;
    note:gate          true ;
    note:frequency     440.0 ;
    note:velocity      0.7 ;
    note:stereoPanning 0.0 .

Assigning IDs is up to the host. Its value has absolutely no meaning other than to identify different notes.

Properties can be changed while a note is playing; that makes them inherently automatable.

[]
    a               note:NoteEvent ;
    note:id         26523 ;
    note:frequency  416.24 .

A note with a certain ID is invalidated after note:gate is set to false. This is equivalent to a MIDI note-off event: the plugin may release the volume envelope for that note, for example, but it must ignore any

[]
    a          note:NoteEvent ;
    note:id    26523 ;
    note:gate  false .

However, the same ID can be reused later. The plugin must treat it as a completely new note.

Another possible use for this extension could be singing synthesizers (like Vocaloid, UTAU, etc.) that have text data attached to notes:

[]
    a               note:NoteEvent ;
    note:id         7 ;
    note:gate       true ;
    note:frequency  440.0 ;
    eg:syllable     "e" .

To describe any additional properties that can be sent to a note, note:expects (better name pending?) must be defined for the lv2:port.

A plugin must ignore any properties it does not understand.

eg:syllable
    a           rdf:Property ;
    rdfs:range  xsd:string .

eg:plugin
    lv2:port [
        a                lv2:InputPort , lv2:AtomPort ;
        atom:bufferType  atom:Sequence ;
        atom:supports    note:NoteEvent ;
        note:expects     eg:syllable .
    ] .
@drobilla
Copy link

drobilla commented Nov 1, 2014

Thanks; this is a good proposal, and nice work writing up an ontology for it.

Probably what we need for something like this to become popular is a utility library that makes it very easy to map to/from MIDI (or OSC, or other things, in the future). Same goes for message-based controllers, which is similar but not included here.

One thing I would add is note numbers. Frequency is often nice, but in some cases numbers are actually better because it decouples notes from tuning, which can be changed without modifying the sequence itself. Plugins having to support both would be tedious, though, so I'm not sure what the best way to go is there.

Similarly, maybe a "full note" with duration would be useful for rendering non-live sequences. There are some cool things you can do with that, but again, it adds a second case plugins have to handle. Support for this stuff can be marked up in data files easily enough, but maybe it's not worth the complexity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment