Output Sample Type and Sample Rate¶
- Output Sample Type and Sample Rate
Who should read this document¶
This is a detailed document about the "sample type" and "sample rate" properties of a Vamp plugin's output descriptor.
- If you are new to the Vamp plugin API, look at the Programmer's Guide first. The section "Sample Types and Timestamps" starting on page 9 introduces this subject.
- Many of the requirements for these properties are also described in the inline documentation for the Plugin and PluginBase classes.
- Jean-Louis Durrieu has written a really helpful blog post explaining some of this from the perspective of a plugin implementer.
The original Vamp documentation sources leave some ambiguities, and this document hopes to help clear them up.
If you are writing a plugin, read the "Rules of Thumb" section (below) after the Programmer's Guide. You probably won't need to read the rest of this document. You should use the Vamp Plugin Tester to test your plugin.
If you are writing a host, you should probably read the whole of this as well as the Guide. You should also use the Vamp Test Plugin to test your host's interpretation of the feature structures.
Rules of Thumb for Plugin Developers¶
The quick summary section.
- If your output returns things that are always regularly-spaced in time, and there is one such thing returned for every
process
block, and the calculation is causal so that results are available immediately, and there is no latency added beyond the length of the processing block, then you probably want to useOneSamplePerStep
sample type and omit the feature timestamps.
- If your output returns things that are regularly-spaced in time but the other limitations above are not true, use
FixedSampleRate
sample type, set the output sample rate to the (perhaps fractional) number of returned features per second, and use a timestamp for each feature.
- If your output returns anything else, use
VariableSampleRate
sample type, set the output sample rate to zero unless you know better, and use a timestamp for each feature.
Introduction¶
A Vamp plugin receives audio and produces a series of descriptive feature structures.
The audio input is provided as a series of fixed-length sample blocks, equally spaced in time, provided to successive calls to the plugin's process
function. The plugin may return any number of features from each process
call, and may also return any number of features from getRemainingFeatures
after all the audio has been received.
Features are each associated with a particular output of the plugin. The plugin declares that each output has certain properties, which constrain the sort of feature data the host can expect to see. (See diagram.)
A feature may or may not have a timestamp (as well as, optionally, a duration). Whether a timestamp is needed -- and, if it is provided, what it means -- are determined by the sampleType
and sampleRate
properties of the output on which the feature is returned.
An output's sampleType
property may be either OneSamplePerStep
, FixedSampleRate
, or VariableSampleRate
. Here's what they mean, in order of complexity.
OneSamplePerStep¶
This is the simplest option.
If an output is declared as having a sampleType
of OneSamplePerStep
, then any features returned from a process
call are assumed to match up with the audio block provided to that process
call.
The sampleRate
and hasDuration
output properties are ignored for outputs of this type.
Timestamps and durations¶
For any features returned through an output declared with OneSamplePerStep
type,
- The plugin should not set timestamps on the features and should set their
hasTimestamp
property tofalse
; - The plugin should not set durations on the features and should set their
hasDuration
property tofalse
; - The host must ignore any timestamps or durations that the plugin may set on the features;
- The host must treat all features returned from a given
process
call as if they had the same timestamp as it passed to thatprocess
call; - The host must treat all features returned from
getRemainingFeatures
as if they were immediately following the finalprocess
block (i.e. with the same time as the next equally-spacedprocess
block would have had if the input had not ended); - The host must treat all features as spanning a duration equal to the spacing between process blocks.
Handling non-compliant plugins¶
There is no required behaviour from plugins for features on OneSamplePerStep
outputs. The host always ignores any timing information in these features whether present or not.
Examples¶
OneSamplePerStep
is most often used for simple measurements and visualisations, in which some internal calculation is updated on each process call and a new result returned. For example: envelope trackers; power calculations; spectrograms. These outputs are typically visualised using line graphs or colour matrix plots.
OneSamplePerStep
is often used for intermediate results calculated during processing of a more sophisticated feature. For example, a beat tracker might have an auxiliary output with OneSamplePerStep
type returning its internal onset detection function value.
VariableSampleRate¶
If the OneSamplePerStep
output type essentially means that the plugin leaves all time calculations up to the host, VariableSampleRate
is the opposite.
If an output is declared as having a SampleType
of VariableSampleRate
, the features returned through it will have timestamps set by the plugin, and they won't necessarily have any relationship to the process block timestamps provided by the host.
Timestamps¶
For any features returned through an output declared with VariableSampleRate
type,
- The plugin must set timestamps on these features and must set their
hasTimestamp
property totrue
; - The host must obtain the features' start times from their timestamps rather than calculating them itself.
Note that features do not have to go forward in time. A feature's timestamp is permitted to be earlier than its predecessor.
Durations¶
Features returned through VariableSampleRate
outputs may optionally have durations.
If the output's hasDuration
property is true
, then
- The plugin must set the
duration
property of features returned through this output and must set their thehasDuration
property totrue
; - The host must use the feature's
duration
property as the feature duration.
If the output's hasDuration
property is false
, then
- The plugin should not set the
duration
property of that output's features; - The host must ignore the
hasDuration
andduration
properties of the output's features, and treat them as having "minimal" duration (see below).
Sample rate and "minimal" duration¶
The plugin may optionally set a sampleRate
property for each VariableSampleRate
output. A sampleRate
of zero indicates no value.
If a sampleRate
is set,
- The host must use 1/
sampleRate
seconds as the "minimal" duration assigned to features that have no duration supplied.
If no sampleRate
is set, i.e. if the sampleRate
property is zero,
- The host must use zero as the "minimal" duration used for features with no duration supplied.
Handling non-compliant plugins¶
If a feature returned through a VariableSampleRate
output has hasTimestamp
set to false
, the host should ignore that feature entirely rather than attempt to read (or guess) its timestamp.
If a feature's hasDuration
value does not match the output's hasDuration
value, the host should assign the feature "minimal" duration.
Examples¶
VariableSampleRate
is most often used for features that primarily return timing information: beat or note onset times, notes, segmentation extents, event labels, etc.
FixedSampleRate¶
This is a more complex case than OneSamplePerStep
or VariableSampleRate
.
A OneSamplePerStep
output never uses individual feature timestamps; a VariableSampleRate
output always uses them; a FixedSampleRate
output sometimes does.
Timestamps¶
An output with FixedSampleRate
type must also have a non-zero sampleRate
property.
Conceptually the sampleRate
property defines a set of discrete sample times, spaced at sampleRate
points per second, starting at time zero. Every returned feature must start at one of these times, whether the time is calculated and assigned by the plugin (through the timestamp of the feature) or by the host (for features without timestamps).
For any features returned through an output declared with FixedSampleRate
type,
- The plugin may set timestamps on these features, and it must set the feature's corresponding
hasTimestamp
property totrue
orfalse
depending on whether it has set a timestamp; - Where a feature has a timestamp, the host must take that timestamp, round it to the nearest 1/
sampleRate
seconds, and use that as the time of the feature; - Where a feature has no timestamp, the host must take the time of the previous feature, add 1/
sampleRate
seconds to it, and use that as the time of the new feature; - Where the very first feature has no timestamp, the host must take its time as zero.
The Programmer's Guide leaves this behaviour incompletely defined, saying "The host may round the timestamp according to the sample rate given in the output descriptor's sampleRate field". Here we are declaring that the host must round the timestamp in this way. Note that the Vamp Test Plugin assumes this behaviour.
As with VariableSampleRate
outputs, the spec does not forbid features on FixedSampleRate
outputs from going backwards in time. A feature is technically allowed to have a timestamp earlier than its predecessor. As a pragmatic matter, though, plugins might be advised not to do this because it doesn't fit very well with users' expectations of what a fixed sample-rate feature looks like, so hosts might well have bugs in how they handle it. If you want to do this, reconsider, or at least use a VariableSampleRate
output. (If you're writing a host, though, do consider this case.)
Durations¶
Features returned through FixedSampleRate
outputs may optionally have durations.
If the output's hasDuration
property is true
, then
- The plugin must set the
duration
property of features returned through this output and must set their thehasDuration
property totrue
; - The host must take the value of the feature's
duration
property, round it to the nearest 1/sampleRate
seconds, and use that as the feature duration.
If the output's hasDuration
property is false
, then
- The plugin should not set the
duration
property of that output's features; - The host must ignore the
hasDuration
andduration
properties of the output's features, giving the features a duration of zero.
Handling non-compliant plugins¶
If a FixedSampleRate
output has a zero sampleRate
, the host should ignore all features from it.
If a FixedSampleRate
feature's hasDuration
value does not match its output's hasDuration
value, the host should assign the feature a duration of zero.
Examples¶
FixedSampleRate
is most often used in cases where OneSamplePerStep
won't work because the output can't return the features straight away. This may be because the plugin has some internal block size that differs from the processing block size, or because more than one process block's worth of history is needed to produce an output, or because the plugin works completely "offline" and produces no output at all until getRemainingFeatures
is called at the end of input.
The most likely uses, therefore, are similar to those for OneSamplePerStep
: block-by-block measurements, columnar visualisations, etc.
However, FixedSampleRate
is also sometimes used in cases where feature timestamps are not equally spaced (i.e. there may be more than one feature per sample time, or there may be gaps) and where VariableSampleRate
might be a reasonable alternative, except that the plugin author chooses to reflect explicitly the limited precision of some internal block-resolution processing step.
So, for example, a beat tracker that was constrained to processing-block resolution might choose to return beat times on a FixedSampleRate
output, although VariableSampleRate
plus a sampleRate
property is probably more usual in the wild.