/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. #ifndef _BPMDetect_H_
  57. #define _BPMDetect_H_
  58. #include "STTypes.h"
  59. #include "FIFOSampleBuffer.h"
  60. //namespace soundtouch
  61. //{
  62. /// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
  63. #define MIN_BPM 29
  64. /// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
  65. #define MAX_BPM 230
  66. /// Class for calculating BPM rate for audio data.
  67. class BPMDetect
  68. {
  69. protected:
  70. /// Auto-correlation accumulator bins.
  71. float *xcorr;
  72. /// Amplitude envelope sliding average approximation level accumulator
  73. float envelopeAccu;
  74. /// RMS volume sliding average approximation level accumulator
  75. float RMSVolumeAccu;
  76. /// Sample average counter.
  77. int decimateCount;
  78. /// Sample average accumulator for FIFO-like decimation.
  79. soundtouch::LONG_SAMPLETYPE decimateSum;
  80. /// Decimate sound by this coefficient to reach approx. 500 Hz.
  81. int decimateBy;
  82. /// Auto-correlation window length
  83. int windowLen;
  84. /// Number of channels (1 = mono, 2 = stereo)
  85. int channels;
  86. /// sample rate
  87. int sampleRate;
  88. /// Beginning of auto-correlation window: Autocorrelation isn't being updated for
  89. /// the first these many correlation bins.
  90. int windowStart;
  91. /// FIFO-buffer for decimated processing samples.
  92. soundtouch::FIFOSampleBuffer *buffer;
  93. /// Initialize the class for processing.
  94. void init(int numChannels, int sampleRate);
  95. /// Updates auto-correlation function for given number of decimated samples that
  96. /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
  97. /// though).
  98. void updateXCorr(int process_samples /// How many samples are processed.
  99. );
  100. /// Decimates samples to approx. 500 Hz.
  101. ///
  102. /// \return Number of output samples.
  103. int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
  104. const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
  105. int numsamples ///< Number of source samples.
  106. );
  107. /// Calculates amplitude envelope for the buffer of samples.
  108. /// Result is output to 'samples'.
  109. void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
  110. int numsamples ///< Number of samples in buffer
  111. );
  112. public:
  113. /// Constructor.
  114. BPMDetect(int numChannels, ///< Number of channels in sample data.
  115. int sampleRate ///< Sample rate in Hz.
  116. );
  117. /// Destructor.
  118. virtual ~BPMDetect();
  119. /// Inputs a block of samples for analyzing: Envelopes the samples and then
  120. /// updates the autocorrelation estimation. When whole song data has been input
  121. /// in smaller blocks using this function, read the resulting bpm with 'getBpm'
  122. /// function.
  123. ///
  124. /// Notice that data in 'samples' array can be disrupted in processing.
  125. void inputSamples(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
  126. int numSamples ///< Number of samples in buffer
  127. );
  128. /// Analyzes the results and returns the BPM rate. Use this function to read result
  129. /// after whole song data has been input to the class by consecutive calls of
  130. /// 'inputSamples' function.
  131. ///
  132. /// \return Beats-per-minute rate, or zero if detection failed.
  133. float getBpm();
  134. };
  135. //}
  136. #endif // _BPMDetect_H_