Cleaned code with Lint

This commit is contained in:
oparviai 2009-02-21 16:00:14 +00:00
parent 8f880269e0
commit c17eb6821a
22 changed files with 146 additions and 172 deletions

View File

@ -108,9 +108,6 @@ protected:
/// FIFO-buffer for decimated processing samples. /// FIFO-buffer for decimated processing samples.
soundtouch::FIFOSampleBuffer *buffer; soundtouch::FIFOSampleBuffer *buffer;
/// Initialize the class for processing.
void init(int numChannels, int sampleRate);
/// Updates auto-correlation function for given number of decimated samples that /// Updates auto-correlation function for given number of decimated samples that
/// are read from the internal 'buffer' pipe (samples aren't removed from the pipe /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
/// though). /// though).

View File

@ -107,7 +107,7 @@ public:
/// When using this function to output samples, also remember to 'remove' the /// When using this function to output samples, also remember to 'remove' the
/// output samples from the buffer by calling the /// output samples from the buffer by calling the
/// 'receiveSamples(numSamples)' function /// 'receiveSamples(numSamples)' function
virtual SAMPLETYPE *ptrBegin() const; virtual SAMPLETYPE *ptrBegin();
/// Returns a pointer to the end of the used part of the sample buffer (i.e. /// Returns a pointer to the end of the used part of the sample buffer (i.e.
/// where the new samples are to be inserted). This function may be used for /// where the new samples are to be inserted). This function may be used for

View File

@ -66,7 +66,7 @@ public:
/// When using this function to output samples, also remember to 'remove' the /// When using this function to output samples, also remember to 'remove' the
/// output samples from the buffer by calling the /// output samples from the buffer by calling the
/// 'receiveSamples(numSamples)' function /// 'receiveSamples(numSamples)' function
virtual SAMPLETYPE *ptrBegin() const = 0; virtual SAMPLETYPE *ptrBegin() = 0;
/// Adds 'numSamples' pcs of samples from the 'samples' memory position to /// Adds 'numSamples' pcs of samples from the 'samples' memory position to
/// the sample buffer. /// the sample buffer.
@ -166,7 +166,7 @@ protected:
/// When using this function to output samples, also remember to 'remove' the /// When using this function to output samples, also remember to 'remove' the
/// output samples from the buffer by calling the /// output samples from the buffer by calling the
/// 'receiveSamples(numSamples)' function /// 'receiveSamples(numSamples)' function
virtual SAMPLETYPE *ptrBegin() const virtual SAMPLETYPE *ptrBegin()
{ {
return output->ptrBegin(); return output->ptrBegin();
} }

View File

@ -103,7 +103,7 @@ static int _toLowerCase(int c)
// Constructor // Constructor
RunParameters::RunParameters(const int nParams, const char *paramStr[]) RunParameters::RunParameters(const int nParams, const char * const paramStr[])
{ {
int i; int i;
int nFirstParam; int nFirstParam;
@ -213,7 +213,7 @@ float RunParameters::parseSwitchValue(const string &str) const
{ {
int pos; int pos;
pos = str.find_first_of('='); pos = (int)str.find_first_of('=');
if (pos < 0) if (pos < 0)
{ {
// '=' missing // '=' missing
@ -266,7 +266,7 @@ void RunParameters::parseSwitchParam(const string &str)
{ {
goalBPM = parseSwitchValue(str); goalBPM = parseSwitchValue(str);
} }
catch (runtime_error) catch (const runtime_error)
{ {
// illegal or missing bpm value => just calculate bpm // illegal or missing bpm value => just calculate bpm
goalBPM = 0; goalBPM = 0;

View File

@ -65,7 +65,7 @@ public:
float goalBPM; float goalBPM;
BOOL detectBPM; BOOL detectBPM;
RunParameters(const int nParams, const char *paramStr[]); RunParameters(const int nParams, const char * const paramStr[]);
}; };
#endif #endif

View File

@ -56,10 +56,10 @@
using namespace std; using namespace std;
const static char riffStr[] = "RIFF"; static const char riffStr[] = "RIFF";
const static char waveStr[] = "WAVE"; static const char waveStr[] = "WAVE";
const static char fmtStr[] = "fmt "; static const char fmtStr[] = "fmt ";
const static char dataStr[] = "data"; static const char dataStr[] = "data";
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -200,7 +200,8 @@ void WavInFile::init()
WavInFile::~WavInFile() WavInFile::~WavInFile()
{ {
close(); if (fptr) fclose(fptr);
fptr = NULL;
} }
@ -216,7 +217,7 @@ void WavInFile::rewind()
} }
int WavInFile::checkCharTags() int WavInFile::checkCharTags() const
{ {
// header.format.fmt should equal to 'fmt ' // header.format.fmt should equal to 'fmt '
if (memcmp(fmtStr, header.format.fmt, 4) != 0) return -1; if (memcmp(fmtStr, header.format.fmt, 4) != 0) return -1;
@ -244,10 +245,11 @@ int WavInFile::read(char *buffer, int maxElems)
if (afterDataRead > header.data.data_len) if (afterDataRead > header.data.data_len)
{ {
// Don't read more samples than are marked available in header // Don't read more samples than are marked available in header
numBytes = header.data.data_len - dataRead; numBytes = (int)header.data.data_len - (int)dataRead;
assert(numBytes >= 0); assert(numBytes >= 0);
} }
assert(buffer);
numBytes = fread(buffer, 1, numBytes, fptr); numBytes = fread(buffer, 1, numBytes, fptr);
dataRead += numBytes; dataRead += numBytes;
@ -261,6 +263,7 @@ int WavInFile::read(short *buffer, int maxElems)
int numBytes; int numBytes;
int numElems; int numElems;
assert(buffer);
if (header.format.bits_per_sample == 8) if (header.format.bits_per_sample == 8)
{ {
// 8 bit format // 8 bit format
@ -286,7 +289,7 @@ int WavInFile::read(short *buffer, int maxElems)
if (afterDataRead > header.data.data_len) if (afterDataRead > header.data.data_len)
{ {
// Don't read more samples than are marked available in header // Don't read more samples than are marked available in header
numBytes = header.data.data_len - dataRead; numBytes = (int)header.data.data_len - (int)dataRead;
assert(numBytes >= 0); assert(numBytes >= 0);
} }
@ -332,13 +335,6 @@ int WavInFile::eof() const
} }
void WavInFile::close()
{
fclose(fptr);
fptr = NULL;
}
// test if character code is between a white space ' ' and little 'z' // test if character code is between a white space ' ' and little 'z'
static int isAlpha(char c) static int isAlpha(char c)
@ -348,9 +344,9 @@ static int isAlpha(char c)
// test if all characters are between a white space ' ' and little 'z' // test if all characters are between a white space ' ' and little 'z'
static int isAlphaStr(char *str) static int isAlphaStr(const char *str)
{ {
int c; char c;
c = str[0]; c = str[0];
while (c) while (c)
@ -408,7 +404,7 @@ int WavInFile::readHeaderBlock()
header.format.format_len = nLen; header.format.format_len = nLen;
// calculate how much length differs from expected // calculate how much length differs from expected
nDump = nLen - (sizeof(header.format) - 8); nDump = nLen - ((int)sizeof(header.format) - 8);
// if format_len is larger than expected, read only as much data as we've space for // if format_len is larger than expected, read only as much data as we've space for
if (nDump > 0) if (nDump > 0)
@ -518,7 +514,8 @@ uint WavInFile::getDataSizeInBytes() const
uint WavInFile::getNumSamples() const uint WavInFile::getNumSamples() const
{ {
return header.data.data_len / header.format.byte_per_sample; if (header.format.byte_per_sample == 0) return 0;
return header.data.data_len / (unsigned short)header.format.byte_per_sample;
} }
@ -576,7 +573,9 @@ WavOutFile::WavOutFile(FILE *file, int sampleRate, int bits, int channels)
WavOutFile::~WavOutFile() WavOutFile::~WavOutFile()
{ {
close(); finishHeader();
if (fptr) fclose(fptr);
fptr = NULL;
} }
@ -601,11 +600,11 @@ void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
header.format.format_len = 0x10; header.format.format_len = 0x10;
header.format.fixed = 1; header.format.fixed = 1;
header.format.channel_number = (short)channels; header.format.channel_number = (short)channels;
header.format.sample_rate = sampleRate; header.format.sample_rate = (int)sampleRate;
header.format.bits_per_sample = (short)bits; header.format.bits_per_sample = (short)bits;
header.format.byte_per_sample = (short)(bits * channels / 8); header.format.byte_per_sample = (short)(bits * channels / 8);
header.format.byte_rate = header.format.byte_per_sample * sampleRate; header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
header.format.sample_rate = sampleRate; header.format.sample_rate = (int)sampleRate;
// fill in the 'data' part.. // fill in the 'data' part..
@ -658,14 +657,6 @@ void WavOutFile::writeHeader()
void WavOutFile::close()
{
finishHeader();
fclose(fptr);
fptr = NULL;
}
void WavOutFile::write(const char *buffer, int numElems) void WavOutFile::write(const char *buffer, int numElems)
{ {
int res; int res;

View File

@ -114,7 +114,7 @@ private:
/// Checks WAV file header tags. /// Checks WAV file header tags.
/// \return zero if all ok, nonzero if file format is invalid. /// \return zero if all ok, nonzero if file format is invalid.
int checkCharTags(); int checkCharTags() const;
/// Reads a single WAV file header block. /// Reads a single WAV file header block.
/// \return zero if all ok, nonzero if file format is invalid. /// \return zero if all ok, nonzero if file format is invalid.
@ -133,10 +133,6 @@ public:
/// Destructor: Closes the file. /// Destructor: Closes the file.
~WavInFile(); ~WavInFile();
/// Close the file. Notice that file is automatically closed also when the
/// class instance is deleted.
void close();
/// Rewind to beginning of the file /// Rewind to beginning of the file
void rewind(); void rewind();
@ -249,12 +245,6 @@ public:
void write(const float *buffer, ///< Pointer to sample data buffer. void write(const float *buffer, ///< Pointer to sample data buffer.
int numElems ///< How many array items are to be written to file. int numElems ///< How many array items are to be written to file.
); );
/// Finalize & close the WAV file. Automatically supplements the WAV file header
/// information according to written data etc.
///
/// Notice that file is automatically closed also when the class instance is deleted.
void close();
}; };
#endif #endif

View File

@ -91,9 +91,9 @@ static void openFiles(WavInFile **inFile, WavOutFile **outFile, const RunParamet
} }
// ... open output file with same sound parameters // ... open output file with same sound parameters
bits = (*inFile)->getNumBits(); bits = (int)(*inFile)->getNumBits();
samplerate = (*inFile)->getSampleRate(); samplerate = (int)(*inFile)->getSampleRate();
channels = (*inFile)->getNumChannels(); channels = (int)(*inFile)->getNumChannels();
if (params->outFileName) if (params->outFileName)
{ {
@ -122,8 +122,8 @@ static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunPar
int sampleRate; int sampleRate;
int channels; int channels;
sampleRate = inFile->getSampleRate(); sampleRate = (int)inFile->getSampleRate();
channels = inFile->getNumChannels(); channels = (int)inFile->getNumChannels();
pSoundTouch->setSampleRate(sampleRate); pSoundTouch->setSampleRate(sampleRate);
pSoundTouch->setChannels(channels); pSoundTouch->setChannels(channels);
@ -132,7 +132,7 @@ static void setup(SoundTouch *pSoundTouch, const WavInFile *inFile, const RunPar
pSoundTouch->setRateChange(params->rateDelta); pSoundTouch->setRateChange(params->rateDelta);
pSoundTouch->setSetting(SETTING_USE_QUICKSEEK, params->quick); pSoundTouch->setSetting(SETTING_USE_QUICKSEEK, params->quick);
pSoundTouch->setSetting(SETTING_USE_AA_FILTER, !params->noAntiAlias); pSoundTouch->setSetting(SETTING_USE_AA_FILTER, !(params->noAntiAlias));
// print processing information // print processing information
if (params->outFileName) if (params->outFileName)
@ -174,7 +174,8 @@ static void process(SoundTouch *pSoundTouch, WavInFile *inFile, WavOutFile *outF
if ((inFile == NULL) || (outFile == NULL)) return; // nothing to do. if ((inFile == NULL) || (outFile == NULL)) return; // nothing to do.
nChannels = inFile->getNumChannels(); nChannels = (int)inFile->getNumChannels();
assert(nChannels > 0);
buffSizeSamples = BUFF_SIZE / nChannels; buffSizeSamples = BUFF_SIZE / nChannels;
// Process samples read from the input file // Process samples read from the input file
@ -184,7 +185,7 @@ static void process(SoundTouch *pSoundTouch, WavInFile *inFile, WavOutFile *outF
// Read a chunk of samples from the input file // Read a chunk of samples from the input file
num = inFile->read(sampleBuffer, BUFF_SIZE); num = inFile->read(sampleBuffer, BUFF_SIZE);
nSamples = num / inFile->getNumChannels(); nSamples = num / (int)inFile->getNumChannels();
// Feed the samples into SoundTouch processor // Feed the samples into SoundTouch processor
pSoundTouch->putSamples(sampleBuffer, nSamples); pSoundTouch->putSamples(sampleBuffer, nSamples);
@ -228,7 +229,7 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
fprintf(stderr, "Detecting BPM rate..."); fprintf(stderr, "Detecting BPM rate...");
fflush(stderr); fflush(stderr);
nChannels = inFile->getNumChannels(); nChannels = (int)inFile->getNumChannels();
assert(BUFF_SIZE % nChannels == 0); assert(BUFF_SIZE % nChannels == 0);
// Process the 'inFile' in small blocks, repeat until whole file has // Process the 'inFile' in small blocks, repeat until whole file has
@ -272,7 +273,7 @@ static void detectBPM(WavInFile *inFile, RunParameters *params)
int main(const int nParams, const char *paramStr[]) int main(const int nParams, const char * const paramStr[])
{ {
WavInFile *inFile; WavInFile *inFile;
WavOutFile *outFile; WavOutFile *outFile;
@ -309,7 +310,7 @@ int main(const int nParams, const char *paramStr[])
fprintf(stderr, "Done!\n"); fprintf(stderr, "Done!\n");
} }
catch (runtime_error &e) catch (const runtime_error &e)
{ {
// An exception occurred during processing, display an error message // An exception occurred during processing, display an error message
fprintf(stderr, "%s\n", e.what()); fprintf(stderr, "%s\n", e.what());

View File

@ -82,17 +82,13 @@ using namespace soundtouch;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include "TDStretch.h" #include "TDStretch.h"
//#include <limits.h>
// these are declared in 'TDStretch.cpp'
// extern int scanOffsets[4][24];
// Calculates cross correlation of two buffers // Calculates cross correlation of two buffers
double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const
{ {
uint overlapLengthLocal = overlapLength; int overlapLengthLocal = overlapLength;
float corr; float corr = 0;
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
/* /*

View File

@ -66,8 +66,6 @@ using namespace soundtouch;
#define INPUT_BLOCK_SAMPLES 2048 #define INPUT_BLOCK_SAMPLES 2048
#define DECIMATED_BLOCK_SAMPLES 256 #define DECIMATED_BLOCK_SAMPLES 256
typedef unsigned short ushort;
/// decay constant for calculating RMS volume sliding average approximation /// decay constant for calculating RMS volume sliding average approximation
/// (time constant is about 10 sec) /// (time constant is about 10 sec)
const float avgdecay = 0.99986f; const float avgdecay = 0.99986f;
@ -77,18 +75,13 @@ const float avgnorm = (1 - avgdecay);
BPMDetect::BPMDetect(int numChannels, int sampleRate) BPMDetect::BPMDetect(int numChannels, int aSampleRate)
{ {
xcorr = NULL; this->sampleRate = aSampleRate;
this->channels = numChannels;
buffer = new FIFOSampleBuffer();
decimateSum = 0; decimateSum = 0;
decimateCount = 0; decimateCount = 0;
decimateBy = 0;
this->sampleRate = sampleRate;
this->channels = numChannels;
envelopeAccu = 0; envelopeAccu = 0;
@ -103,7 +96,26 @@ BPMDetect::BPMDetect(int numChannels, int sampleRate)
RMSVolumeAccu = (0.092f * 0.092f) / avgnorm; RMSVolumeAccu = (0.092f * 0.092f) / avgnorm;
#endif #endif
init(numChannels, sampleRate); // choose decimation factor so that result is approx. 500 Hz
decimateBy = sampleRate / 500;
assert(decimateBy > 0);
assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
// Calculate window length & starting item according to desired min & max bpms
windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
assert(windowLen > windowStart);
// allocate new working objects
xcorr = new float[windowLen];
memset(xcorr, 0, windowLen * sizeof(float));
// allocate processing buffer
buffer = new FIFOSampleBuffer();
// we do processing in mono mode
buffer->setChannels(1);
buffer->clear();
} }
@ -115,6 +127,7 @@ BPMDetect::~BPMDetect()
} }
/// convert to mono, low-pass filter & decimate to about 500 Hz. /// convert to mono, low-pass filter & decimate to about 500 Hz.
/// return number of outputted samples. /// return number of outputted samples.
/// ///
@ -131,7 +144,8 @@ int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
int count, outcount; int count, outcount;
LONG_SAMPLETYPE out; LONG_SAMPLETYPE out;
assert(decimateBy != 0); assert(channels > 0);
assert(decimateBy > 0);
outcount = 0; outcount = 0;
for (count = 0; count < numsamples; count ++) for (count = 0; count < numsamples; count ++)
{ {
@ -267,7 +281,7 @@ void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
int processLength; int processLength;
// how many samples are processed // how many samples are processed
processLength = buffer->numSamples() - windowLen; processLength = (int)buffer->numSamples() - windowLen;
// ... calculate autocorrelations for oldest samples... // ... calculate autocorrelations for oldest samples...
updateXCorr(processLength); updateXCorr(processLength);
@ -277,31 +291,6 @@ void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
} }
void BPMDetect::init(int numChannels, int sampleRate)
{
this->sampleRate = sampleRate;
// choose decimation factor so that result is approx. 500 Hz
decimateBy = sampleRate / 500;
assert(decimateBy > 0);
assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
// Calculate window length & starting item according to desired min & max bpms
windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
assert(windowLen > windowStart);
// allocate new working objects
xcorr = new float[windowLen];
memset(xcorr, 0, windowLen * sizeof(float));
// we do processing in mono mode
buffer->setChannels(1);
buffer->clear();
}
float BPMDetect::getBpm() float BPMDetect::getBpm()
{ {

View File

@ -63,6 +63,7 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
samplesInBuffer = 0; samplesInBuffer = 0;
bufferPos = 0; bufferPos = 0;
channels = (uint)numChannels; channels = (uint)numChannels;
ensureCapacity(32); // allocate initial capacity
} }
@ -151,8 +152,9 @@ SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
// When using this function to output samples, also remember to 'remove' the // When using this function to output samples, also remember to 'remove' the
// outputted samples from the buffer by calling the // outputted samples from the buffer by calling the
// 'receiveSamples(numSamples)' function // 'receiveSamples(numSamples)' function
SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
{ {
assert(buffer);
return buffer + bufferPos * channels; return buffer + bufferPos * channels;
} }
@ -175,6 +177,7 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
{ {
throw std::runtime_error("Couldn't allocate memory!\n"); throw std::runtime_error("Couldn't allocate memory!\n");
} }
// Align the buffer to begin at 16byte cache line boundary for optimal performance
temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16); temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16);
memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE)); memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
delete[] bufferUnaligned; delete[] bufferUnaligned;

View File

@ -181,7 +181,7 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
assert(length == newLength); assert(length == newLength);
resultDivFactor = uResultDivFactor; resultDivFactor = uResultDivFactor;
resultDivider = (SAMPLETYPE)::pow(2, resultDivFactor); resultDivider = (SAMPLETYPE)::pow(2, (int)resultDivFactor);
delete[] filterCoeffs; delete[] filterCoeffs;
filterCoeffs = new SAMPLETYPE[length]; filterCoeffs = new SAMPLETYPE[length];

View File

@ -42,6 +42,7 @@
#ifndef FIRFilter_H #ifndef FIRFilter_H
#define FIRFilter_H #define FIRFilter_H
#include <stddef.h>
#include "STTypes.h" #include "STTypes.h"
namespace soundtouch namespace soundtouch

View File

@ -51,6 +51,7 @@ using namespace soundtouch;
PeakFinder::PeakFinder() PeakFinder::PeakFinder()
{ {
minPos = maxPos = 0;
} }
@ -140,13 +141,15 @@ double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos)
sum += (float)i * data[i]; sum += (float)i * data[i];
wsum += data[i]; wsum += data[i];
} }
if (wsum < 1e-6) return 0;
return sum / wsum; return sum / wsum;
} }
/// get exact center of peak near given position by calculating local mass of center /// get exact center of peak near given position by calculating local mass of center
double PeakFinder::getPeakCenter(const float *data, int peakpos) double PeakFinder::getPeakCenter(const float *data, int peakpos) const
{ {
float peakLevel; // peak level float peakLevel; // peak level
int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level
@ -178,15 +181,15 @@ double PeakFinder::getPeakCenter(const float *data, int peakpos)
double PeakFinder::detectPeak(const float *data, int minPos, int maxPos) double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
{ {
int i; int i;
int peakpos; // position of peak level int peakpos; // position of peak level
double highPeak, peak; double highPeak, peak;
this->minPos = minPos; this->minPos = aminPos;
this->maxPos = maxPos; this->maxPos = amaxPos;
// find absolute peak // find absolute peak
peakpos = minPos; peakpos = minPos;

View File

@ -71,7 +71,7 @@ protected:
) const; ) const;
/// get exact center of peak near given position by calculating local mass of center /// get exact center of peak near given position by calculating local mass of center
double getPeakCenter(const float *data, int peakpos); double getPeakCenter(const float *data, int peakpos) const;
public: public:
/// Constructor. /// Constructor.

View File

@ -158,7 +158,7 @@ BOOL RateTransposer::isAAFilterEnabled() const
} }
AAFilter *RateTransposer::getAAFilter() const AAFilter *RateTransposer::getAAFilter()
{ {
return pAAFilter; return pAAFilter;
} }
@ -548,8 +548,8 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src,
} }
fSlopeCount -= 1.0f; fSlopeCount -= 1.0f;
if (nSamples == 1) goto end; if (nSamples > 1)
{
while (1) while (1)
{ {
while (fSlopeCount > 1.0f) while (fSlopeCount > 1.0f)
@ -562,6 +562,7 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src,
i++; i++;
fSlopeCount += fRate; fSlopeCount += fRate;
} }
}
end: end:
// Store the last sample for the next round // Store the last sample for the next round
sPrevSampleL = src[nSamples - 1]; sPrevSampleL = src[nSamples - 1];
@ -593,8 +594,8 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
// now always (iSlopeCount > 1.0f) // now always (iSlopeCount > 1.0f)
fSlopeCount -= 1.0f; fSlopeCount -= 1.0f;
if (nSamples == 1) goto end; if (nSamples > 1)
{
while (1) while (1)
{ {
while (fSlopeCount > 1.0f) while (fSlopeCount > 1.0f)
@ -613,6 +614,7 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
i++; i++;
fSlopeCount += fRate; fSlopeCount += fRate;
} }
}
end: end:
// Store the last sample for the next round // Store the last sample for the next round
sPrevSampleL = src[2 * nSamples - 2]; sPrevSampleL = src[2 * nSamples - 2];

View File

@ -45,6 +45,7 @@
#ifndef RateTransposer_H #ifndef RateTransposer_H
#define RateTransposer_H #define RateTransposer_H
#include <stddef.h>
#include "AAFilter.h" #include "AAFilter.h"
#include "FIFOSamplePipe.h" #include "FIFOSamplePipe.h"
#include "FIFOSampleBuffer.h" #include "FIFOSampleBuffer.h"
@ -90,7 +91,7 @@ protected:
virtual uint transposeMono(SAMPLETYPE *dest, virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples) = 0; uint numSamples) = 0;
uint transpose(SAMPLETYPE *dest, inline uint transpose(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples); uint numSamples);
@ -127,7 +128,7 @@ public:
FIFOSamplePipe *getStore() { return &storeBuffer; }; FIFOSamplePipe *getStore() { return &storeBuffer; };
/// Return anti-alias filter object /// Return anti-alias filter object
AAFilter *getAAFilter() const; AAFilter *getAAFilter();
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
void enableAAFilter(BOOL newMode); void enableAAFilter(BOOL newMode);

View File

@ -87,7 +87,7 @@ using namespace soundtouch;
#define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10) #define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10)
/// Print library version string /// Print library version string for autoconf
extern "C" void soundtouch_ac_test() extern "C" void soundtouch_ac_test()
{ {
printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION); printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
@ -149,8 +149,8 @@ void SoundTouch::setChannels(uint numChannels)
throw std::runtime_error("Illegal number of channels"); throw std::runtime_error("Illegal number of channels");
} }
channels = numChannels; channels = numChannels;
pRateTransposer->setChannels(numChannels); pRateTransposer->setChannels((int)numChannels);
pTDStretch->setChannels(numChannels); pTDStretch->setChannels((int)numChannels);
} }
@ -284,7 +284,7 @@ void SoundTouch::setSampleRate(uint srate)
{ {
bSrateSet = TRUE; bSrateSet = TRUE;
// set sample rate, leave other tempo changer parameters as they are. // set sample rate, leave other tempo changer parameters as they are.
pTDStretch->setParameters(srate); pTDStretch->setParameters((int)srate);
} }

View File

@ -331,6 +331,9 @@
<File <File
RelativePath="FIRFilter.h"> RelativePath="FIRFilter.h">
</File> </File>
<File
RelativePath=".\PeakFinder.h">
</File>
<File <File
RelativePath="RateTransposer.h"> RelativePath="RateTransposer.h">
</File> </File>

View File

@ -53,11 +53,7 @@
using namespace soundtouch; using namespace soundtouch;
#ifndef min #define max(x, y) (((x) > (y)) ? (x) : (y))
//#define min(a,b) (((a) > (b)) ? (b) : (a))
#define max(a,b) (((a) < (b)) ? (b) : (a))
#endif
/***************************************************************************** /*****************************************************************************
@ -513,7 +509,7 @@ void TDStretch::calcSeqParameters()
#define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) #define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
#define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW)) #define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW))
#define CHECK_LIMITS(x, mi, ma) ((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)) #define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
double seq, seek; double seq, seek;
@ -816,18 +812,18 @@ void TDStretch::precalcCorrReferenceMono()
// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
// version of the routine. // version of the routine.
void TDStretch::overlapStereo(short *output, const short *input) const void TDStretch::overlapStereo(short *poutput, const short *input) const
{ {
int i; int i;
short temp; short temp;
uint cnt2; int cnt2;
for (i = 0; i < (int)overlapLength ; i ++) for (i = 0; i < overlapLength ; i ++)
{ {
temp = (short)(overlapLength - i); temp = (short)(overlapLength - i);
cnt2 = 2 * i; cnt2 = 2 * i;
output[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength; poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength;
output[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength; poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength;
} }
} }
@ -841,15 +837,15 @@ static int _getClosest2Power(double value)
/// Calculates overlap period length in samples. /// Calculates overlap period length in samples.
/// Integer version rounds overlap length to closest power of 2 /// Integer version rounds overlap length to closest power of 2
/// for a divide scaling operation. /// for a divide scaling operation.
void TDStretch::calculateOverlapLength(int overlapMs) void TDStretch::calculateOverlapLength(int aoverlapMs)
{ {
int newOvl; int newOvl;
assert(overlapMs >= 0); assert(aoverlapMs >= 0);
overlapDividerBits = _getClosest2Power((sampleRate * overlapMs) / 1000.0); overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0);
if (overlapDividerBits > 9) overlapDividerBits = 9; if (overlapDividerBits > 9) overlapDividerBits = 9;
if (overlapDividerBits < 4) overlapDividerBits = 4; if (overlapDividerBits < 4) overlapDividerBits = 4;
newOvl = (int)pow(2, (double) overlapDividerBits); newOvl = (int)pow(2, overlapDividerBits);
acceptNewOverlapLength(newOvl); acceptNewOverlapLength(newOvl);

View File

@ -44,6 +44,7 @@
#ifndef TDStretch_H #ifndef TDStretch_H
#define TDStretch_H #define TDStretch_H
#include <stddef.h>
#include "STTypes.h" #include "STTypes.h"
#include "RateTransposer.h" #include "RateTransposer.h"
#include "FIFOSamplePipe.h" #include "FIFOSamplePipe.h"
@ -113,7 +114,6 @@ protected:
int overlapLength; int overlapLength;
int seekLength; int seekLength;
int seekWindowLength; int seekWindowLength;
int maxOffset;
int overlapDividerBits; int overlapDividerBits;
int slopingDivider; int slopingDivider;
float nominalSkip; float nominalSkip;

View File

@ -73,8 +73,9 @@ using namespace soundtouch;
double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) const double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) const
{ {
int i; int i;
float *pVec1; const float *pVec1;
__m128 vSum, *pVec2; const __m128 *pVec2;
__m128 vSum;
// Note. It means a major slow-down if the routine needs to tolerate // Note. It means a major slow-down if the routine needs to tolerate
// unaligned __m128 memory accesses. It's way faster if we can skip // unaligned __m128 memory accesses. It's way faster if we can skip
@ -104,8 +105,8 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
// Note: pV2 _must_ be aligned to 16-bit boundary, pV1 need not. // Note: pV2 _must_ be aligned to 16-bit boundary, pV1 need not.
pVec1 = (float*)pV1; pVec1 = (const float*)pV1;
pVec2 = (__m128*)pV2; pVec2 = (const __m128*)pV2;
vSum = _mm_setzero_ps(); vSum = _mm_setzero_ps();
// Unroll the loop by factor of 4 * 4 operations // Unroll the loop by factor of 4 * 4 operations
@ -300,13 +301,13 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2' // filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
for (j = 0; j < count; j += 2) for (j = 0; j < count; j += 2)
{ {
float *pSrc; const float *pSrc;
const __m128 *pFil; const __m128 *pFil;
__m128 sum1, sum2; __m128 sum1, sum2;
uint i; uint i;
pSrc = (float*)source; // source audio data pSrc = (const float*)source; // source audio data
pFil = (__m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
// are aligned to 16-byte boundary // are aligned to 16-byte boundary
sum1 = sum2 = _mm_setzero_ps(); sum1 = sum2 = _mm_setzero_ps();