From 28aaff6c99da4d035b14dde522aeb64bfb944e63 Mon Sep 17 00:00:00 2001
From: oparviai
Date: Thu, 12 Feb 2009 17:22:06 +0000
Subject: [PATCH] Fixed buffer overflow bug in BPMDetect.cpp & changed version
to 1.4.1
---
README.html | 9 ++++++-
include/SoundTouch.h | 4 +--
source/SoundStretch/main.cpp | 1 +
source/SoundTouch/BPMDetect.cpp | 44 +++++++++++++++++++--------------
4 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/README.html b/README.html
index 782429b..9a5afb2 100644
--- a/README.html
+++ b/README.html
@@ -18,7 +18,7 @@
-SoundTouch audio processing library v1.4.0
+SoundTouch audio processing library v1.4.1
SoundTouch library Copyright (c) Olli
Parviainen 2002-2009
@@ -538,6 +538,13 @@ estimates the BPM rate:
5. Change History
5.1. SoundTouch library Change History
+1.4.1:
+
+- Fixed a buffer overflow bug in BPM detect algorithm routines if processing
+ more than 2048 samples at one call
+
+
+
1.4.0:
- Improved sound quality by automatic calculation of time stretch algorithm
diff --git a/include/SoundTouch.h b/include/SoundTouch.h
index f9ea26b..8a5d2ac 100644
--- a/include/SoundTouch.h
+++ b/include/SoundTouch.h
@@ -79,10 +79,10 @@ namespace soundtouch
{
/// Soundtouch library version string
-#define SOUNDTOUCH_VERSION "1.4.0"
+#define SOUNDTOUCH_VERSION "1.4.1"
/// SoundTouch library version id
-#define SOUNDTOUCH_VERSION_ID (10400)
+#define SOUNDTOUCH_VERSION_ID (10401)
//
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
diff --git a/source/SoundStretch/main.cpp b/source/SoundStretch/main.cpp
index 559d881..3ad8619 100644
--- a/source/SoundStretch/main.cpp
+++ b/source/SoundStretch/main.cpp
@@ -229,6 +229,7 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
fflush(stderr);
nChannels = inFile->getNumChannels();
+ assert(BUFF_SIZE % nChannels == 0);
// Process the 'inFile' in small blocks, repeat until whole file has
// been processed
diff --git a/source/SoundTouch/BPMDetect.cpp b/source/SoundTouch/BPMDetect.cpp
index 972cd4c..b98b720 100644
--- a/source/SoundTouch/BPMDetect.cpp
+++ b/source/SoundTouch/BPMDetect.cpp
@@ -115,7 +115,8 @@ BPMDetect::~BPMDetect()
}
-/// low-pass filter & decimate to about 500 Hz. return number of outputted samples.
+/// convert to mono, low-pass filter & decimate to about 500 Hz.
+/// return number of outputted samples.
///
/// Decimation is used to remove the unnecessary frequencies and thus to reduce
/// the amount of data needed to be processed as calculating autocorrelation
@@ -134,13 +135,20 @@ int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
outcount = 0;
for (count = 0; count < numsamples; count ++)
{
- decimateSum += src[count];
+ int j;
+
+ // convert to mono and accumulate
+ for (j = 0; j < channels; j ++)
+ {
+ decimateSum += src[j];
+ }
+ src += j;
decimateCount ++;
if (decimateCount >= decimateBy)
{
// Store every Nth sample only
- out = (LONG_SAMPLETYPE)(decimateSum / decimateBy);
+ out = (LONG_SAMPLETYPE)(decimateSum / (decimateBy * channels));
decimateSum = 0;
decimateCount = 0;
#ifdef INTEGER_SAMPLES
@@ -231,27 +239,27 @@ void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples)
-void BPMDetect::inputSamples(SAMPLETYPE *samples, int numSamples)
+void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
{
SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES];
- // convert from stereo to mono if necessary
- if (channels == 2)
+ // iterate so that max INPUT_BLOCK_SAMPLES processed per iteration
+ while (numSamples > 0)
{
- int i;
+ int block;
+ int decSamples;
- for (i = 0; i < numSamples; i ++)
- {
- samples[i] = (samples[i * 2] + samples[i * 2 + 1]) / 2;
- }
+ block = (numSamples > INPUT_BLOCK_SAMPLES) ? INPUT_BLOCK_SAMPLES : numSamples;
+
+ // decimate. note that converts to mono at the same time
+ decSamples = decimate(decimated, samples, block);
+ samples += block * channels;
+ numSamples -= block;
+
+ // envelope new samples and add them to buffer
+ calcEnvelope(decimated, decSamples);
+ buffer->putSamples(decimated, decSamples);
}
-
- // decimate
- numSamples = decimate(decimated, samples, numSamples);
-
- // envelope new samples and add them to buffer
- calcEnvelope(decimated, numSamples);
- buffer->putSamples(decimated, numSamples);
// when the buffer has enought samples for processing...
if ((int)buffer->numSamples() > windowLen)