On Friday 13 December 2002 14.04, Paul Davis wrote:
Maybe I
don't get all the issues, but the following thoughts occur
to me wrt time.
* A tempo delay that starts a delayed sound just before the host
loops the play back in (musical) time does not really want to
know about absolute musical time, but DIFFERENCES in musical
time. More precisely, it wants to be aware of the passing of
ticks (where the duration of a tick is defined by the host).
* What if plugins that care about musical time have a TICKS
control. Whenever the host crosses a tick boundary, it sends a
(sample-accurate)
ardour uses 1920 ticks per beat. if the beat is 180 bpm, that's
5760 ticks per second, or 1 tick every 8 samples at 48kHz. thats a
ridiculously dense event stream when most of those ticks have no
significance at all.
Yeah, that's what I'm thinking. One should probably only send the
first tick of each block, and the first tick after a tempo change. If
even that.
event to the
TICKS control, with the value being the # of ticks
(ever-running time or track-time?). Plugins can look at
host->ticks_per_beat.
if you make ticks_per_second constant, then ticks_per_beat is not
constant. if ticks_per_beat is constant, then ticks_per_second is
not constant. computing the number of ticks between two arbitrary
times is (theoretically, at least) quite complex. imagine a
situation where a piece shifts time signatures a few times, has
some decelerando and accelerando sections and a few sudden tempo
changes (think prog-rock, for a start :).
Think, *any* kind of music, practically. Slight tempo changes during
verse or chorus, tempo ramping during breaks and that kind of stuff
is every now and then, even in normal pop music. It's just subtle
enough that most people won't notice until you tell them! :-) (That's
why it works; you're not *supposed* to conciously notice it.)
how many ticks between a
given point in one "section" and "another" ? if you make
ticks_per_beat constant, its easy to compute the tick count, but
hard to compute the interval between ticks. if you make
ticks_per_second constant, its easy to compute (hah!) the interval
between ticks, but knowing how many ticks are between two musical
times is fairly tricky.
Right. This is why you always have to think in term of a timeline as
either an abstract non-linear function, or a list of ranges;
potentially more than one per sample frame. If you want to be
absolutely correct, you cannot get around this.
* Pre-queuing
becomes:
- Plugin: I have an event 100 ticks from now
- Host sends ticks as they happen, even if we loop in time
- Plugin decrements the counter on future events
- If time jumps plugin can discard future events or not, as it
wishes - when the counter hits 0, plugin does whatever
* We can provide SDK code to make this pre-queuing easy.
i like this basic idea, but i don't think that you can send one
event per tick. i think that david is not far from the mark. i
think it should probably work more like this:
Plugin: i have an event at "bar|beat|ticks", what transport
frame is that ... [ computes ].
Host: sends a running audio frame count
Plugin: defines a particular audio frame count as "zero" on
the transport frame scale (e.g. when playback
starts), then executes the event at the correct offset. when the
plugin considers the transport to be not moving, no events get
executed.
something like that.
Yeah, that's basically it. The important thing to keep in mind is
that you cannot trust anything said about the time beyond the end of
the current block, and that you cannot assume anything about the part
of the timeline that's inside the current block - it can be
non-linear, contain skips or whatever.
the hard part here is that plugins needs to be able to
share the
tempo map, because they need to be able to look ahead to compute an
audio frame (offset) that corresponds to a given B|b|t time.
Actually, they only really need to know whether that time is inside
the current block or not. If it's before, it's already too late (all
you can do is try to hide the mistake...), and if it's in the future,
you're strictly speaking not allowed to care, since *no one* knows
what will actually happen. You'll have to wait until the event is
inside the block - if that ever happens, that is.
So, what you need is the part of the timeline corresponding to the
current block.
this
is going to be a critical problem with JACK as well. its all very
well saying that a particular plugin can do this, but if you want
several plugins operating in sync with the same notion of tempo,
there needs to be a way to share the information between them.
And if you have plugins working with a few *different* timelines,
you'll also need a way to tell which one to look at.
VST
does this in a rather crude way, JACK currently doesn't do it at
all. if you put it in the host, that helps a lot, but it now
requires ways to edit the tempo map, which would typically be in
the domain of a sequencer, and the vibe here is that the host is
not necessarily a sequencer ...
Right... I've been thinking of implementing tempo maps as separate
plugins, that driver both sequencers and synths. Either way; same
problem - plugins need a way to export timeline data so that other
plugins can access it.
Tick events, tempo change events and transport events would "work",
but it's extremely inefficient for high tick resolutions, obviously.
*heh*
//David Olofson - Programmer, Composer, Open Source Advocate
.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`--------------------------->
http://olofson.net/audiality -'
.- M A I A -------------------------------------------------.
| The Multimedia Application Integration Architecture |
`---------------------------->
http://www.linuxdj.com/maia -'
---
http://olofson.net ---
http://www.reologica.se ---