BPMDetect.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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: 2012-08-30 22:53:44 +0300 (Thu, 30 Aug 2012) $
  30. // File revision : $Revision: 4 $
  31. //
  32. // $Id: BPMDetect.h 150 2012-08-30 19:53:44Z 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 200
  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. double envelopeAccu;
  74. /// RMS volume sliding average approximation level accumulator
  75. double 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. /// Updates auto-correlation function for given number of decimated samples that
  94. /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
  95. /// though).
  96. void updateXCorr(int process_samples /// How many samples are processed.
  97. );
  98. /// Decimates samples to approx. 500 Hz.
  99. ///
  100. /// \return Number of output samples.
  101. int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
  102. const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
  103. int numsamples ///< Number of source samples.
  104. );
  105. /// Calculates amplitude envelope for the buffer of samples.
  106. /// Result is output to 'samples'.
  107. void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
  108. int numsamples ///< Number of samples in buffer
  109. );
  110. /// remove constant bias from xcorr data
  111. void removeBias();
  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(const 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_