Paul Davis wrote:
* Host sends
buffers of N samples to plugins, with a starting timestamp
* Things send timestamped events to plugins
* Timestamps are measured in whole audio samples
* Host/timeline must export/deliver:
- SAMPLE RATE (samples/sec - passed at instantiation)
- TEMPO (sec/tick - event?)
- PPQN (ticks/qn - host-global? event? fixed?)
i suggest forgetting this. VST sets it to 1 PPQN, and treats "QN" as
"1 beat", so the information is really quite useless. there's no need
for it given TEMPO and METER.
you absolutely need ppq for the tick system to properly map
different measures (5/4 time, 6/8 time etc) as per previous
post.
* units for
meter (I don't know enough music theory to answer properly)
after much discussion about this on ardour-dev, we settled on beats
per minute, where beats are whatever unit the time signature is
using. for some music, the unit is irrelevant, because nothing else
uses subdivisions of the beat note value in any coherent way (i.e. you
can decide that a beat is a quarter note, or a half note or a whole
note, and nothing else will care). for other music, its important that
the beat value is known.
you're better off specifying tempo as quarter beats/minute
uniformly for the above reasons.
the TEMPO event needs to include:
samples-per-beat (as a floating point value) [ time between beats ]
ramp slope (possibly 0) [ for accelerando and ritard ]
ramp target (irrelevant if ramp slope is zero) [ ditto ]
add seconds-per-beat for plugins that are not limited to
audio purposes.
the METER event needs to include
beats-per-measure (floating point value) [ 3, 5, 7, 9.5 etc ]
beat-note-value (floating point value) [quarter,1/16th, etc]
i wouldn't make either a float, it is by far too uncommon
to be justified and makes some arithmetic cumbersome.
in addition to this, the host/API needs to provide two
other
functions:
"get current time information"
- the structure needs to be based on the VST time info structure.
it will indicate the sample position of the next beat, and
the next bar. it will indicate the state of the transport,
including loop information in the way that JACK's time info
structure does. it can only be called from the "process"
handler of the plugin, because the information is all
specific to the current block being processed.
"convert musical time"
- passed a musical time (B|b|t) and an indicator of which
timeline to use, it returns the audio frame at which
the event will occur, independent of transport state.
if transport state matters, the plugin will have to
handle that itself. this function doesn't require host
information, but it does require a way to access
a (possibly) shared timeline and it needs to be implemented
only once :)
from my experience, more conversion functions are needed, in
effect you need to map from any of these domains to any other:
* bar.beat.fractional (or .tick if you will),
* tick
* time in seconds
* audio frame
you may want to implement it using one call and a structure
with flags denoting your interest, or offer any of these as
a separate function. i have opted for the latter -- to keep
things sane, b.b.f conversion is only done for ticks and
vice versa though.
tim