remove a bunch of explicit uses of '/' as a directory separator; use Glib::build_file...
[ardour2.git] / libs / soundtouch / BPMDetect.h
blob8cdd4df184ecdb288348107ec02996cae01c7987
1 ////////////////////////////////////////////////////////////////////////////////
2 ///
3 /// Beats-per-minute (BPM) detection routine.
4 ///
5 /// The beat detection algorithm works as follows:
6 /// - Use function 'inputSamples' to input a chunks of samples to the class for
7 /// analysis. It's a good idea to enter a large sound file or stream in smallish
8 /// chunks of around few kilosamples in order not to extinguish too much RAM memory.
9 /// - Input sound data is decimated to approx 500 Hz to reduce calculation burden,
10 /// which is basically ok as low (bass) frequencies mostly determine the beat rate.
11 /// Simple averaging is used for anti-alias filtering because the resulting signal
12 /// quality isn't of that high importance.
13 /// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
14 /// taking absolute value that's smoothed by sliding average. Signal levels that
15 /// are below a couple of times the general RMS amplitude level are cut away to
16 /// leave only notable peaks there.
17 /// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
18 /// autocorrelation function of the enveloped signal.
19 /// - After whole sound data file has been analyzed as above, the bpm level is
20 /// detected by function 'getBpm' that finds the highest peak of the autocorrelation
21 /// function, calculates it's precise location and converts this reading to bpm's.
22 ///
23 /// Author : Copyright (c) Olli Parviainen
24 /// Author e-mail : oparviai @ iki.fi
25 /// SoundTouch WWW: http://www.iki.fi/oparviai/soundtouch
26 ///
27 ////////////////////////////////////////////////////////////////////////////////
29 // Last changed : $Date$
30 // File revision : $Revision$
32 // $Id$
34 ////////////////////////////////////////////////////////////////////////////////
36 // License :
38 // SoundTouch audio processing library
39 // Copyright (c) Olli Parviainen
41 // This library is free software; you can redistribute it and/or
42 // modify it under the terms of the GNU Lesser General Public
43 // License as published by the Free Software Foundation; either
44 // version 2.1 of the License, or (at your option) any later version.
46 // This library is distributed in the hope that it will be useful,
47 // but WITHOUT ANY WARRANTY; without even the implied warranty of
48 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49 // Lesser General Public License for more details.
51 // You should have received a copy of the GNU Lesser General Public
52 // License along with this library; if not, write to the Free Software
53 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
55 ////////////////////////////////////////////////////////////////////////////////
57 #ifndef _BPMDetect_H_
58 #define _BPMDetect_H_
60 #include "STTypes.h"
61 #include "FIFOSampleBuffer.h"
63 /// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
64 #define MIN_BPM 45
66 /// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
67 #define MAX_BPM 230
70 /// Class for calculating BPM rate for audio data.
71 class BPMDetect
73 protected:
74 /// Auto-correlation accumulator bins.
75 float *xcorr;
77 /// Amplitude envelope sliding average approximation level accumulator
78 float envelopeAccu;
80 /// RMS volume sliding average approximation level accumulator
81 float RMSVolumeAccu;
83 /// Sample average counter.
84 int decimateCount;
86 /// Sample average accumulator for FIFO-like decimation.
87 soundtouch::LONG_SAMPLETYPE decimateSum;
89 /// Decimate sound by this coefficient to reach approx. 500 Hz.
90 int decimateBy;
92 /// Auto-correlation window length
93 int windowLen;
95 /// Number of channels (1 = mono, 2 = stereo)
96 int channels;
98 /// sample rate
99 int sampleRate;
101 /// Beginning of auto-correlation window: Autocorrelation isn't being updated for
102 /// the first these many correlation bins.
103 int windowStart;
105 /// FIFO-buffer for decimated processing samples.
106 soundtouch::FIFOSampleBuffer *buffer;
108 /// Initialize the class for processing.
109 void init(int numChannels, int sampleRate);
111 /// Updates auto-correlation function for given number of decimated samples that
112 /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
113 /// though).
114 void updateXCorr(int process_samples /// How many samples are processed.
117 /// Decimates samples to approx. 500 Hz.
119 /// \return Number of output samples.
120 int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
121 const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
122 int numsamples ///< Number of source samples.
125 /// Calculates amplitude envelope for the buffer of samples.
126 /// Result is output to 'samples'.
127 void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
128 int numsamples ///< Number of samples in buffer
131 public:
132 /// Constructor.
133 BPMDetect(int numChannels, ///< Number of channels in sample data.
134 int sampleRate ///< Sample rate in Hz.
137 /// Destructor.
138 virtual ~BPMDetect();
140 /// Inputs a block of samples for analyzing: Envelopes the samples and then
141 /// updates the autocorrelation estimation. When whole song data has been input
142 /// in smaller blocks using this function, read the resulting bpm with 'getBpm'
143 /// function.
144 ///
145 /// Notice that data in 'samples' array can be disrupted in processing.
146 void inputSamples(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
147 int numSamples ///< Number of samples in buffer
151 /// Analyzes the results and returns the BPM rate. Use this function to read result
152 /// after whole song data has been input to the class by consecutive calls of
153 /// 'inputSamples' function.
155 /// \return Beats-per-minute rate, or zero if detection failed.
156 float getBpm();
159 #endif // _BPMDetect_H_