[LAD] "enhanced event port" LV2 extension proposal
wdev at foltman.com
Sat Dec 1 22:23:50 UTC 2007
Dave Robillard wrote:
> Taking a step back, it would be nice to have these events (being
> generic) able to use something other than frame timestamps, for future
> dispatching/scheduled type event systems.
I think there's certain advantage to using sample frames for events in
the typical audio plugin situations. On the other hand, it doesn't cover
all weird stuff people will want to do.
I could even think of two event ports - one for typical frame-based
stuff, other for absolute nanosecond time or what not. Keep in mind that
converting nanoseconds to frames in typical case would be very very slow
(64-bit divisions, or at least multiplications)
So, if we need something else than sample-based timing, we should do it
elsewhere (by defining another event type, or something). Trying to fit
everything in - audio, video, networking, industrial equipment, car
engine control etc - is highly likely to fail.
> OSC uses 64 big fixed point
> absolute time stamps, giving a resolution of about 200 picoseconds
> absolute time (epoch January 1, 1900). This is equivalent to NTP time
> stamps apparently - ie huge precedent.
Also, huge overkill, in my opinion :) It might be needed in some cases,
but demanding everyone to use this resolution is bad.
> Whether stamps are in frames or absolute time could be a property of the
You may not like it, but I would actually like two kinds of ports:
- one for experimental weird stuff (may be even 64-bit integer in
200-picosecond units, why not); this could be nice for certain uses but
overkill/inefficient in most situations
- one for bread-and-butter stuff, sample based; and here you could even
use just 32-bit integers, not fixed point numbers, the certain events
that would indeed require fractional part of the timestamp (grain
start), would define it as a part of payload
The structures will probably be very similar, the event types carried
inside might be the exactly same (including URI-to-number mapping
scheme!). The experimental plugins and hosts would implement the
extended event transport, most of the everyday stuff would just stick to
the basic sample-based one.
That kind of fits the "do one thing and do it well" rule. Both ports
wouldn't be directly compatible anyway (because they use different
timing schemes) so why not keep them separate? :)
> Maybe we should up it to 64 bits fixed point? The additional 32
> bits aside, doing that gives us all the range or precision in frames
> needed, and the ability to map to a widespread absolute timestamp
> format, and parity with OSC. That's a lot of pros...
I'm more comfortable with 8-byte header, just because it lets us use
headers as unit of data (payload is always padded to 8 bytes, think
pointers on 64-bit machines). As in the code example I've posted (minus
With 12-byte headers, we get some ugly pointer arithmetic (and pointer
alignment problems on 64-bit machines). With 16-byte headers, we either
count in 16-byte units (just think of 1-byte MIDI messages here :) ), or
align to 8 and get ugly pointer arithmetic.
You can't just write anything as brief as:
i += (event[i].size + 7) >> 3;
when you have 12-byte headers. And losing 15 bytes for 1 byte messages
in 16-byte solution without pointer arithmetic may be acceptable, but
gives me certain discomfort :)
Yet another solution would be to keep header 12-byte + 4 bytes of
data/padding (for short messages). But I think we've already been there,
and you didn't like it much, right? :)
Everything that allows plugin loops to be simple and readable and
doesn't waste CPU/bus cycles or (whether on misalignment penalties, long
divisions, float-to-int, 32 bytes per average event) is going to be fine
to me. It's just that... well, you can see for yourself, there are not
many solutions that satisfy all of those criteria.
Those are my reasons for "bit paranoia" which annoys you so much :)
> (This may sound a bit esoteric, but to do something like Max right, you
> need absolute time stamps).
Absolute time stamps can still be done by keeping some sort of state
between process calls, plus optionally some "set absolute time (resync)"
kind of events.
> Currently in MIDI we have 64 bits in there anyway.. I never thought of
> using fixed point, but the OSC/NTP parity and potential for very precise
> absolute time stamps is very, very tasty to me.
Tastes like 64-bit division, which as far as I know involves a function
call on average x86 platform ;) Good for some stuff (networking, audio
plus video), absolutely horrible for others (think granular synthesis
which has dense events).
> Also, the frame part would be a uint32_t - equivalent to Jack MIDI
> timestamps, another win (and cutting out more conversion overhead).
I like this - just don't like the consequences on header size :) Hard to
find a clear winner here.
By the way, what about 48-bit timestamp as another candidate? (32 int,
16 fract) Still leaves 2 bytes for other stuff (size, type) in 8-byte
header. Restricting payload size to 255 bytes max doesn't sound like a
total disaster. Larger data will be likely passed by reference anyway,
doing otherwise in a realtime system usually smells like bad design :)
Just think of memcpying those data back and forth when those 20 reverbs
wait for their turn :)
More information about the Linux-audio-dev