annotate dsp/tempotracking/DownBeat.h @ 162:a2b3fd07d862

Avoid pathological FFT length of 1 in plugin tester
author Chris Cannam
date Tue, 03 Dec 2013 10:16:49 +0000
parents 915365c58758
children 701233f8ed41
rev   line source
cannam@54 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@54 2
cannam@54 3 /*
cannam@54 4 QM DSP Library
cannam@54 5
cannam@54 6 Centre for Digital Music, Queen Mary, University of London.
cannam@54 7 This file copyright 2008-2009 Matthew Davies and QMUL.
Chris@84 8
Chris@84 9 This program is free software; you can redistribute it and/or
Chris@84 10 modify it under the terms of the GNU General Public License as
Chris@84 11 published by the Free Software Foundation; either version 2 of the
Chris@84 12 License, or (at your option) any later version. See the file
Chris@84 13 COPYING included with this distribution for more information.
cannam@54 14 */
cannam@54 15
cannam@54 16 #ifndef DOWNBEAT_H
cannam@54 17 #define DOWNBEAT_H
cannam@54 18
cannam@54 19 #include <vector>
Chris@98 20 #include <cstddef>
cannam@54 21
cannam@54 22 #include "dsp/rateconversion/Decimator.h"
cannam@54 23
cannam@54 24 using std::vector;
cannam@54 25
cannam@64 26 class FFTReal;
cannam@64 27
cannam@54 28 /**
cannam@54 29 * This class takes an input audio signal and a sequence of beat
cannam@54 30 * locations (calculated e.g. by TempoTrackV2) and estimates which of
cannam@54 31 * the beat locations are downbeats (first beat of the bar).
cannam@54 32 *
cannam@54 33 * The input audio signal is expected to have been downsampled to a
cannam@54 34 * very low sampling rate (e.g. 2700Hz). A utility function for
cannam@54 35 * downsampling and buffering incoming block-by-block audio is
cannam@54 36 * provided.
cannam@54 37 */
cannam@54 38 class DownBeat
cannam@54 39 {
cannam@54 40 public:
cannam@54 41 /**
cannam@54 42 * Construct a downbeat locator that will operate on audio at the
cannam@54 43 * downsampled by the given decimation factor from the given
cannam@54 44 * original sample rate, plus beats extracted from the same audio
cannam@54 45 * at the given original sample rate with the given frame
cannam@54 46 * increment.
cannam@54 47 *
cannam@54 48 * decimationFactor must be a power of two no greater than 64, and
cannam@54 49 * dfIncrement must be a multiple of decimationFactor.
cannam@54 50 */
cannam@54 51 DownBeat(float originalSampleRate,
cannam@54 52 size_t decimationFactor,
cannam@54 53 size_t dfIncrement);
cannam@54 54 ~DownBeat();
cannam@54 55
cannam@55 56 void setBeatsPerBar(int bpb);
cannam@55 57
cannam@54 58 /**
cannam@54 59 * Estimate which beats are down-beats.
cannam@54 60 *
cannam@54 61 * audio contains the input audio stream after downsampling, and
cannam@54 62 * audioLength contains the number of samples in this downsampled
cannam@54 63 * stream.
cannam@54 64 *
cannam@54 65 * beats contains a series of beat positions expressed in
cannam@54 66 * multiples of the df increment at the audio's original sample
cannam@54 67 * rate, as described to the constructor.
cannam@54 68 *
cannam@54 69 * The returned downbeat array contains a series of indices to the
cannam@54 70 * beats array.
cannam@54 71 */
cannam@55 72 void findDownBeats(const float *audio, // downsampled
cannam@54 73 size_t audioLength, // after downsampling
cannam@54 74 const vector<double> &beats,
cannam@54 75 vector<int> &downbeats);
cannam@56 76
cannam@56 77 /**
cannam@56 78 * Return the beat spectral difference function. This is
cannam@56 79 * calculated during findDownBeats, so this function can only be
cannam@56 80 * meaningfully called after that has completed. The returned
cannam@56 81 * vector contains one value for each of the beat times passed in
cannam@56 82 * to findDownBeats, less one. Each value contains the spectral
cannam@56 83 * difference between region prior to the beat's nominal position
cannam@56 84 * and the region following it.
cannam@56 85 */
cannam@56 86 void getBeatSD(vector<double> &beatsd) const;
cannam@54 87
cannam@54 88 /**
cannam@54 89 * For your downsampling convenience: call this function
cannam@54 90 * repeatedly with input audio blocks containing dfIncrement
cannam@54 91 * samples at the original sample rate, to decimate them to the
cannam@54 92 * downsampled rate and buffer them within the DownBeat class.
cannam@54 93 *
cannam@54 94 * Call getBufferedAudio() to retrieve the results after all
cannam@54 95 * blocks have been processed.
cannam@54 96 */
cannam@55 97 void pushAudioBlock(const float *audio);
cannam@54 98
cannam@54 99 /**
cannam@54 100 * Retrieve the accumulated audio produced by pushAudioBlock calls.
cannam@54 101 */
cannam@55 102 const float *getBufferedAudio(size_t &length) const;
cannam@55 103
cannam@55 104 /**
cannam@55 105 * Clear any buffered downsampled audio data.
cannam@55 106 */
cannam@55 107 void resetAudioBuffer();
cannam@54 108
cannam@54 109 private:
cannam@54 110 typedef vector<int> i_vec_t;
cannam@54 111 typedef vector<vector<int> > i_mat_t;
cannam@54 112 typedef vector<double> d_vec_t;
cannam@54 113 typedef vector<vector<double> > d_mat_t;
cannam@54 114
cannam@54 115 void makeDecimators();
cannam@54 116 double measureSpecDiff(d_vec_t oldspec, d_vec_t newspec);
cannam@54 117
cannam@55 118 int m_bpb;
cannam@54 119 float m_rate;
cannam@54 120 size_t m_factor;
cannam@54 121 size_t m_increment;
cannam@54 122 Decimator *m_decimator1;
cannam@54 123 Decimator *m_decimator2;
cannam@55 124 float *m_buffer;
cannam@55 125 float *m_decbuf;
cannam@54 126 size_t m_bufsiz;
cannam@54 127 size_t m_buffill;
cannam@54 128 size_t m_beatframesize;
cannam@54 129 double *m_beatframe;
cannam@64 130 FFTReal *m_fft;
cannam@54 131 double *m_fftRealOut;
cannam@54 132 double *m_fftImagOut;
cannam@56 133 d_vec_t m_beatsd;
cannam@54 134 };
cannam@54 135
cannam@54 136 #endif