PageRenderTime 22ms CodeModel.GetById 13ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/external/pysoundtouch14/libsoundtouch/BPMDetect.h

http://echo-nest-remix.googlecode.com/
C++ Header | 164 lines | 41 code | 28 blank | 95 comment | 0 complexity | f333b72014d1ee54e97c71c8dc97667c MD5 | raw file
  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 'at' iki.fi
 25/// SoundTouch WWW: http://www.surina.net/soundtouch
 26///
 27////////////////////////////////////////////////////////////////////////////////
 28//
 29// Last changed  : $Date: 2008-12-25 14:20:01 +0200 (Thu, 25 Dec 2008) $
 30// File revision : $Revision: 4 $
 31//
 32// $Id: BPMDetect.h 33 2008-12-25 12:20:01Z oparviai $
 33//
 34////////////////////////////////////////////////////////////////////////////////
 35//
 36// License :
 37//
 38//  SoundTouch audio processing library
 39//  Copyright (c) Olli Parviainen
 40//
 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.
 45//
 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.
 50//
 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
 54//
 55////////////////////////////////////////////////////////////////////////////////
 56
 57#ifndef _BPMDetect_H_

 58#define _BPMDetect_H_

 59
 60#include "STTypes.h"

 61#include "FIFOSampleBuffer.h"

 62
 63//namespace soundtouch
 64//{
 65
 66/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
 67#define MIN_BPM 29

 68
 69/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
 70#define MAX_BPM 230

 71
 72
 73/// Class for calculating BPM rate for audio data.
 74class BPMDetect
 75{
 76protected:
 77    /// Auto-correlation accumulator bins.
 78    float *xcorr;
 79    
 80    /// Amplitude envelope sliding average approximation level accumulator
 81    float envelopeAccu;
 82
 83    /// RMS volume sliding average approximation level accumulator
 84    float RMSVolumeAccu;
 85
 86    /// Sample average counter.
 87    int decimateCount;
 88
 89    /// Sample average accumulator for FIFO-like decimation.
 90    soundtouch::LONG_SAMPLETYPE decimateSum;
 91
 92    /// Decimate sound by this coefficient to reach approx. 500 Hz.
 93    int decimateBy;
 94
 95    /// Auto-correlation window length
 96    int windowLen;
 97
 98    /// Number of channels (1 = mono, 2 = stereo)
 99    int channels;
100
101    /// sample rate
102    int sampleRate;
103
104    /// Beginning of auto-correlation window: Autocorrelation isn't being updated for
105    /// the first these many correlation bins.
106    int windowStart;
107 
108    /// FIFO-buffer for decimated processing samples.
109    soundtouch::FIFOSampleBuffer *buffer;
110
111    /// Initialize the class for processing.
112    void init(int numChannels, int sampleRate);
113
114    /// Updates auto-correlation function for given number of decimated samples that 
115    /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe 
116    /// though).
117    void updateXCorr(int process_samples      /// How many samples are processed.
118                     );
119
120    /// Decimates samples to approx. 500 Hz.
121    ///
122    /// \return Number of output samples.
123    int decimate(soundtouch::SAMPLETYPE *dest,      ///< Destination buffer
124                 const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
125                 int numsamples                     ///< Number of source samples.
126                 );
127
128    /// Calculates amplitude envelope for the buffer of samples.
129    /// Result is output to 'samples'.
130    void calcEnvelope(soundtouch::SAMPLETYPE *samples,  ///< Pointer to input/output data buffer
131                      int numsamples                    ///< Number of samples in buffer
132                      );
133
134public:
135    /// Constructor.
136    BPMDetect(int numChannels,  ///< Number of channels in sample data.
137              int sampleRate    ///< Sample rate in Hz.
138              );
139
140    /// Destructor.
141    virtual ~BPMDetect();
142
143    /// Inputs a block of samples for analyzing: Envelopes the samples and then
144    /// updates the autocorrelation estimation. When whole song data has been input
145    /// in smaller blocks using this function, read the resulting bpm with 'getBpm' 
146    /// function. 
147    /// 
148    /// Notice that data in 'samples' array can be disrupted in processing.
149    void inputSamples(soundtouch::SAMPLETYPE *samples,  ///< Pointer to input/working data buffer
150                      int numSamples                    ///< Number of samples in buffer
151                      );
152
153
154    /// Analyzes the results and returns the BPM rate. Use this function to read result
155    /// after whole song data has been input to the class by consecutive calls of
156    /// 'inputSamples' function.
157    ///
158    /// \return Beats-per-minute rate, or zero if detection failed.
159    float getBpm();
160};
161
162//}
163
164#endif // _BPMDetect_H_