[LAD] "enhanced event port" LV2 extension proposal

Krzysztof Foltman wdev at foltman.com
Thu Nov 29 19:43:47 UTC 2007


Lars Luthman wrote:
> It's up to the host I suppose. If you pass the maximum capacity you get
> maximum flexibility, but also risk that a greedy plugin fills your
> entire buffer with 12412 MIDI CC's per audio frame. But at some point I
> guess you just have to assume that plugin writers aren't going to be
> maliciously stupid. =)
>   
Judging from my Buzz experience, I *have* to assume that plugin writers 
aren't going to know what they're doing - like a certain plugin 
developer who couldn't get the basic pitch-to-Hz formula right for 
several years, and many others (myself included).

But, unfortunately, there's little one can do to remedy that. You could 
draft the specs in such a way that nobody with IQ under 170 could write 
plugins (DirectShow, I'm looking at you ;) ), but then you'd end up with 
no plugins.
> According to the core spec, hosts are only required to pass the features
> to a plugin that the plugin lists as required in its RDF data. 
Unless certain features will need passing "personalized" pointers to 
plugins (separate host's objects per plugin).

And by the way - seems that the char array/union part creates more 
controversies than necessary. So we may get back to Dave's idea of 
payload being a zero-length array (no minimum length), and to 8 bytes of 
alignment instead of 16. If LV2_EVENT_HEADER is defined this way:

struct LV2_EVENT_HEADER
{
  uint32_t timestamp; // still wondering if fractional addresses should 
be a part of generic even transport spec, by the way
  uint16_t event_type;
  uint16_t size; // of payload, with space occupied rounded up to nearest 8
};

it's practically as convenient to use as the previous version, and may 
be preferable in some cases (when bit 3 in payload size is 0).

Then we may define (as another extension, perhaps) a MIDI event like this:

struct LV2_MIDI_EVENT
{
  LV2_EVENT_HEADER hdr; // or use as a base class in C++
  uint8_t command, arg1, arg2, subchannel;
  uint8_t padding[4];
};

Or maybe instead of dedicating one byte to subchannel we might allow 
dynamic arbitrary assignment of extra fields (host passes an 
offset-and-length-to-struct-uri mapping). Well, maybe not.

Or other possibility (WARNING: bit squeezing paranoia ahead):

struct LV2_EVENT_HEADER // 4 bytes :)
{
  uint16_t timestamp; // no fractional timestamps here
  uint8_t event_type; // 256 events are enough for everybody
  uint8_t size; // 256 bytes are enough for everybody
};

struct LV2_MIDI_EVENT
{
  LV2_EVENT_HEADER hdr; // or use as a base class in C++
  uint8_t command, arg1, arg2, padding;
};

// separate event type for those 3 instruments with per-note control changes
struct LV2_MIDI_EVENT_SUBCHANNEL
{
  LV2_EVENT_HEADER hdr; // or use as a base class in C++
  uint8_t command, arg1, arg2, subchannel;
};

// separate event type for those 3 specific granular synthesis hosts and 
plugins
struct LV2_MIDI_EVENT_FRACTIONAL
{
  LV2_EVENT_HEADER hdr; // or use as a base class in C++
  uint8_t command, arg1, arg2, subsample;
};

(1/256 of a sample should be good enough for everybody, too!)

Krzysztof




More information about the Linux-audio-dev mailing list