Go to the documentation of this file.
54 D(
float inputSampleRate);
66 bool initialise(
size_t channels,
size_t stepSize,
size_t blockSize);
100 m_inputSampleRate(inputSampleRate),
106 m_priorMagnitudes(0),
117 delete[] m_priorMagnitudes;
131 d.
name =
"Minimum estimated tempo";
132 d.
description =
"Minimum beat-per-minute value which the tempo estimator is able to return";
141 d.
name =
"Maximum estimated tempo";
142 d.
description =
"Maximum beat-per-minute value which the tempo estimator is able to return";
147 d.
name =
"Input duration to study";
148 d.
description =
"Length of audio input, in seconds, which should be taken into account when estimating tempo. There is no need to supply the plugin with any further input once this time has elapsed since the start of the audio. The tempo estimator may use only the first part of this, up to eight times the slowest beat duration: increasing this value further than that is unlikely to improve results.";
161 if (
id ==
"minbpm") {
163 }
else if (
id ==
"maxbpm") {
165 }
else if (
id ==
"maxdflen") {
174 if (
id ==
"minbpm") {
176 }
else if (
id ==
"maxbpm") {
178 }
else if (
id ==
"maxdflen") {
209 d.
name =
"Tempo candidates";
210 d.
description =
"Possible tempo estimates, one per bin with the most likely in the first bin";
216 d.
name =
"Detection Function";
236 d.
name =
"Autocorrelation Function";
237 d.
description =
"Autocorrelation of onset detection function";
243 d.
name =
"Filtered Autocorrelation";
244 d.
description =
"Filtered autocorrelation of onset detection function";
254 m_stepSize = stepSize;
255 m_blockSize = blockSize;
257 float dfLengthSecs = m_maxdflen;
260 m_priorMagnitudes =
new float[m_blockSize/2];
261 m_df =
new float[m_dfsize];
263 for (
size_t i = 0; i < m_blockSize/2; ++i) {
264 m_priorMagnitudes[i] = 0.f;
266 for (
size_t i = 0; i < m_dfsize; ++i) {
278 if (!m_priorMagnitudes)
return;
280 for (
size_t i = 0; i < m_blockSize/2; ++i) {
281 m_priorMagnitudes[i] = 0.f;
283 for (
size_t i = 0; i < m_dfsize; ++i) {
298 m_start = RealTime::zeroTime;
299 m_lasttime = RealTime::zeroTime;
307 if (m_stepSize == 0) {
308 cerr <<
"ERROR: FixedTempoEstimator::process: "
309 <<
"FixedTempoEstimator has not been initialised"
314 if (m_n == 0) m_start = ts;
317 if (m_n == m_dfsize) {
320 fs = assembleFeatures();
334 for (
size_t i = 1; i < m_blockSize/2; ++i) {
336 float real = inputBuffers[0][i*2];
337 float imag = inputBuffers[0][i*2 + 1];
339 float sqrmag = real * real + imag * imag;
340 value += fabsf(sqrmag - m_priorMagnitudes[i]);
342 m_priorMagnitudes[i] = sqrmag;
355 if (m_n > m_dfsize)
return fs;
357 fs = assembleFeatures();
378 cerr <<
"FixedTempoEstimator::calculate: calculation already happened?" << endl;
382 if (m_n < m_dfsize / 9 &&
384 cerr <<
"FixedTempoEstimator::calculate: Input is too short" << endl;
395 m_r =
new float[n/2];
396 m_fr =
new float[n/2];
397 m_t =
new float[n/2];
399 for (
int i = 0; i < n/2; ++i) {
402 m_t[i] = lag2tempo(i);
407 for (
int i = 0; i < n/2; ++i) {
409 for (
int j = i; j < n; ++j) {
410 m_r[i] += m_df[j] * m_df[j - i];
418 float related[] = { 0.5, 2, 4, 8 };
420 for (
int i = 1; i < n/2-1; ++i) {
426 for (
int j = 0; j < int(
sizeof(related)/
sizeof(related[0])); ++j) {
430 int k0 = int(i * related[j] + 0.5);
432 if (k0 >= 0 && k0 <
int(n/2)) {
435 float kvmax = 0, kvmin = 0;
438 for (
int k = k0 - 1; k <= k0 + 1; ++k) {
440 if (k < 0 || k >= n/2)
continue;
442 if (!have || (m_r[k] > kvmax)) { kvmax = m_r[k]; kmax = k; }
443 if (!have || (m_r[k] < kvmin)) { kvmin = m_r[k]; }
451 m_fr[i] += m_r[kmax] / 5;
453 if ((kmax == 0 || m_r[kmax] > m_r[kmax-1]) &&
454 (kmax == n/2-1 || m_r[kmax] > m_r[kmax+1]) &&
455 kvmax > kvmin * 1.05) {
461 m_t[i] = m_t[i] + lag2tempo(kmax) * related[j];
472 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005;
473 if (weight < 0.f) weight = 0.f;
474 weight = weight * weight * weight;
476 m_fr[i] += m_fr[i] * (weight / 3);
491 feature.
values.push_back(0.f);
497 for (
int i = 0; i < n; ++i) {
503 feature.
values[0] = m_df[i];
508 for (
int i = 1; i < n/2; ++i) {
515 feature.
values[0] = m_r[i];
516 sprintf(buffer,
"%.1f bpm", lag2tempo(i));
517 if (i == n/2-1) feature.
label =
"";
518 else feature.
label = buffer;
525 int p0 = tempo2lag(t1);
526 int p1 = tempo2lag(t0);
528 std::map<float, int> candidates;
530 for (
int i = p0; i <= p1 && i+1 < n/2; ++i) {
534 if (m_fr[i] > m_fr[i-1] &&
535 m_fr[i] > m_fr[i+1]) {
541 candidates[m_fr[i]] = i;
548 feature.
values[0] = m_fr[i];
549 sprintf(buffer,
"%.1f bpm", lag2tempo(i));
550 if (i == p1 || i == n/2-2) feature.
label =
"";
551 else feature.
label = buffer;
555 if (candidates.empty()) {
556 cerr <<
"No tempo candidates!" << endl;
564 feature.
duration = m_lasttime - m_start;
569 std::map<float, int>::const_iterator ci = candidates.end();
571 int maxpi = ci->second;
573 if (m_t[maxpi] > 0) {
578 feature.
values[0] = m_t[maxpi];
585 feature.
values[0] = lag2tempo(maxpi);
586 cerr <<
"WARNING: No stored tempo for index " << maxpi << endl;
589 sprintf(buffer,
"%.1f bpm", feature.
values[0]);
590 feature.
label = buffer;
602 while (feature.
values.size() < 10) {
603 if (m_t[ci->second] > 0) {
604 feature.
values.push_back(m_t[ci->second]);
606 feature.
values.push_back(lag2tempo(ci->second));
608 if (ci == candidates.begin())
break;
621 m_d(new
D(inputSampleRate))
639 return "Simple Fixed Tempo Estimator";
645 return "Study a short section of audio and estimate its tempo, assuming the tempo is constant";
651 return "Vamp SDK Example Plugins";
663 return "Code copyright 2008 Queen Mary, University of London. Freely redistributable (BSD license)";
std::string description
A human-readable short text describing the parameter.
SampleType sampleType
Positioning in time of the output results.
void reset()
Reset the plugin after use, to prepare it for another clean run.
bool hasKnownExtents
True if the results in each output bin fall within a fixed numeric range (minimum and maximum values)...
Vamp::RealTime m_lasttime
float getParameter(string id) const
@ VariableSampleRate
Results are unevenly spaced and have individual timestamps.
float sampleRate
Sample rate of the output results, as samples per second.
std::vector< float > values
Results for a single sample of this feature.
FeatureSet getRemainingFeatures()
bool initialise(size_t channels, size_t stepSize, size_t blockSize)
Initialise a plugin to prepare it for use with the given number of input channels,...
std::string getName() const
Get a human-readable name or title of the plugin.
bool hasDuration
True if the returned results for this output are known to have a duration field.
float quantizeStep
Quantization resolution of the output values (e.g.
ParameterList getParameterDescriptors() const
Get the controllable parameters of this plugin.
std::string unit
The unit of the parameter, in human-readable form.
std::string label
Label for the sample of this feature.
FixedTempoEstimator(float inputSampleRate)
bool hasFixedBinCount
True if the output has the same number of values per sample for every output sample.
std::string getDescription() const
Get a human-readable description for the plugin, typically a line of text that may optionally be disp...
@ FixedSampleRate
Results are evenly spaced in time (sampleRate specified below)
std::string description
A human-readable short text describing the output.
FeatureSet getRemainingFeatures()
After all blocks have been processed, calculate and return any remaining features derived from the co...
Plugin(float inputSampleRate)
std::string identifier
The name of the output, in computer-usable form.
OutputList getOutputDescriptors() const
static int CandidatesOutput
bool isQuantized
True if the parameter values are quantized to a particular resolution.
FeatureSet process(const float *const *inputBuffers, Vamp::RealTime timestamp)
Process a single block of input data.
float minValue
Minimum value of the results in the output.
FeatureSet process(const float *const *, RealTime)
size_t getPreferredStepSize() const
int getPluginVersion() const
Get the version number of the plugin.
RealTime duration
Duration of the output feature.
virtual ~FixedTempoEstimator()
virtual size_t getMinChannelCount() const
Get the minimum supported number of input channels.
void setParameter(string id, float value)
void setParameter(std::string id, float value)
Set a named parameter.
virtual size_t getMaxChannelCount() const
Get the maximum supported number of input channels.
float maxValue
Maximum value of the results in the output.
std::string unit
The unit of the output, in human-readable form.
size_t getPreferredBlockSize() const
Get the preferred block size (window size – the number of sample frames passed in each block to the p...
size_t getPreferredBlockSize() const
float defaultValue
The default value of the parameter.
RealTime timestamp
Timestamp of the output feature.
bool initialise(size_t channels, size_t stepSize, size_t blockSize)
std::string name
The human-readable name of the output.
std::string getMaker() const
Get the name of the author or vendor of the plugin in human-readable form.
std::string getIdentifier() const
Get the computer-usable name of the plugin.
std::string identifier
The name of the parameter, in computer-usable form.
size_t getPreferredStepSize() const
Get the preferred step size (window increment – the distance in sample frames between the start frame...
float minValue
The minimum value of the parameter.
std::vector< OutputDescriptor > OutputList
bool hasTimestamp
True if an output feature has its own timestamp.
float * m_priorMagnitudes
std::vector< ParameterDescriptor > ParameterList
OutputList getOutputDescriptors() const
Get the outputs of this plugin.
bool hasDuration
True if an output feature has a specified duration.
ParameterList getParameterDescriptors() const
static int FilteredACFOutput
float maxValue
The maximum value of the parameter.
FeatureSet assembleFeatures()
size_t binCount
The number of values per result of the output.
bool isQuantized
True if the output values are quantized to a particular resolution.
std::string getCopyright() const
Get the copyright statement or licensing summary for the plugin.
float getParameter(std::string id) const
Get the value of a named parameter.
std::map< int, FeatureList > FeatureSet
std::string name
The human-readable name of the parameter.