[LAD] "enhanced event port" LV2 extension proposal

Dave Robillard drobilla at connect.carleton.ca
Thu Nov 29 23:39:17 UTC 2007


On Wed, 2007-11-28 at 23:56 +0100, Lars Luthman wrote:
> On Wed, 2007-11-28 at 16:45 +0000, Krzysztof Foltman wrote:
> > Good. So let's postpone that part for now, it will go into different
> > extension(s).
> 
> OK, so what we have now is something like this:
> 
> 
> struct Event_Port_Buffer {
>   uint32_t capacity;            // number of elements in the array
>   uint32_t used_size;           // number of _used_ elements
>   uint32_t event_count;         // number of events (different from
>                                 // used_size if there are large events -
>                                 // would this really be needed?)
>   struct Event* events;         // an array allocated by the host
> };
> 
> struct Event {
>   uint32_t timestamp;
>   uint16_t size;
>   uint16_t event_type;
>   uint8_t data[8];              // or a union or whatever, as long
>                                 // as it's 8 bytes
> };
> 
> 
> A pointer to an Event_Port_Buffer is passed to connect_port() for every
> event port etc. And in the RDF file for the plugin there would be
> something like this:

er, I'm probably missing something here, but why the 8 bytes part?
Isn't that what the size member is for?


> <http://myplugin.example.com> a lv2:Plugin;
>   lv2:requiredFeature <http://lv2.example.com/midi-event-type>;
>   lv2:port [
>     a lv2:InputPort, <http://lv2.example.com/event-port>;
>     ...
>   ];
>   ...

Sounds about right.   If it's an optional feature, the plugin can just
ignore events of a type it doesn't understand (this should probably be
the default/common case).

> The host won't instantiate the plugin unless it knows how to handle
> event ports and MIDI events, and the plugin will fail to instantiate
> unless the host passes a URI -> integer map to instantiate using a
> LV2_Feature with the URI <http://lv2.example.com/uri-map> and a
> NULL-terminated array of event type URIs as data. The integer associated
> to each URI is simply the array index (my earlier suggestion was just a
> brain dump from a thought-in-progress, a simple array seems a lot
> cleaner).

Perfect.  As extensible as URIs, as fast as integers, ties in to the
RDF.

> Assuming that the host only supports MIDI events the data passed for
> this feature will be { "http://lv2.example.com/midi-event-type", NULL },
> the plugin will store the index 0 as the MIDI event identifier somewhere
> in its state, and everything is good to go. A basic loop for processing
> input events in a plugin could look something like this:
> 
> 
>   Event_Port_Buffer* buf = ports[EVENT_PORT];
>   uint32_t index;
>   uint32_t next_frame;
>   uint32_t frames_done = 0
>   while (index < buf->used_size) {
>     next_frame = events[index].timestamp >> 16;
>     render_audio(frames_done, next_frame);
>     frames_done = next_frame;
>     handle_event(events[index]);
>     index += 1 + (events[index].size - 8) / 16;
>   }
>   render_audio(frames_done, nframes);
> 
> 
> Should plugins have to list <http://lv2.example.com/uri-map> as a
> required feature, or should that be implicit whenever a plugin has an
> event port? Both methods have some drawbacks - if plugins are required
> to list it there is some redundancy, if they are not we have a required
> feature that isn't listed as one which can be a bit confusing.

I'm leaning towards listing it.  It's just one triple in the data file,
not a huge deal.  It's not out of the question that a more advanced (or
different, somehow) mechanism to do the same thing shows up at some
point in the future, though I don't see much of a reason why, can't
hurt to be explicit.

> Does anyone else see any other problems with this type of event port?
> Steve, Dave, Nedko?

Other than the size thing I don't really get (8 bytes), I think it's
pretty good.

Once we figure out the basics I'll have a look at working my indexing
thing for OSC into it (allows constant time random access for any
event, at the cost of a bit more complexity writing the buffer, but this
will probably be done by common code in a header/library anyway).
Ignoring that for now though....

FWIW I'm a really, really big fan of a generic event mechanism like
this.  One thing we might want is a way of saying "this port is /only/ a
MIDI port", mostly for UI issues.  That's just a touch of RDF though.
Code side seems good.

-DR-




More information about the Linux-audio-dev mailing list