1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-22 22:43:01 +02:00

Update soundtouch to 1.7.1.

This commit is contained in:
lllucius
2013-10-24 06:36:42 +00:00
parent 8d97adecb1
commit f740766f37
107 changed files with 6813 additions and 60819 deletions

View File

@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Sample rate transposer. Changes sample rate by using linear interpolation
///
/// Sample rate transposer. Changes sample rate by using linear interpolation
/// together with anti-alias filtering (first order interpolation with anti-
/// alias filtering should be quite adequate for this application)
///
@@ -10,10 +10,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2006-09-18 22:29:22 $
// File revision : $Revision: 1.5 $
// Last changed : $Date: 2011-09-02 21:56:11 +0300 (Fri, 02 Sep 2011) $
// File revision : $Revision: 4 $
//
// $Id: RateTransposer.cpp,v 1.5 2006-09-18 22:29:22 martynshaw Exp $
// $Id: RateTransposer.cpp 131 2011-09-02 18:56:11Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -42,7 +42,6 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "RateTransposer.h"
#include "AAFilter.h"
@@ -55,23 +54,23 @@ class RateTransposerInteger : public RateTransposer
{
protected:
int iSlopeCount;
uint uRate;
int iRate;
SAMPLETYPE sPrevSampleL, sPrevSampleR;
virtual void resetRegisters();
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
public:
RateTransposerInteger();
virtual ~RateTransposerInteger();
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
/// rate, larger faster rates.
virtual void setRate(float newRate);
@@ -84,16 +83,15 @@ class RateTransposerFloat : public RateTransposer
{
protected:
float fSlopeCount;
float fRateStep;
SAMPLETYPE sPrevSampleL, sPrevSampleR;
virtual void resetRegisters();
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
public:
@@ -103,25 +101,19 @@ public:
#ifndef min
#define min(a,b) ((a > b) ? b : a)
#define max(a,b) ((a < b) ? b : a)
#endif
// Operator 'new' is overloaded so that it automatically creates a suitable instance
// Operator 'new' is overloaded so that it automatically creates a suitable instance
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
void * RateTransposer::operator new(size_t s)
{
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
assert(FALSE);
return NULL;
ST_THROW_RT_ERROR("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
return newInstance();
}
RateTransposer *RateTransposer::newInstance()
{
#ifdef INTEGER_SAMPLES
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
return ::new RateTransposerInteger;
#else
return ::new RateTransposerFloat;
@@ -132,8 +124,9 @@ RateTransposer *RateTransposer::newInstance()
// Constructor
RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
{
uChannels = 2;
numChannels = 2;
bUseAAFilter = TRUE;
fRate = 0;
// Instantiates the anti-alias filter with default tap length
// of 32
@@ -150,7 +143,7 @@ RateTransposer::~RateTransposer()
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
void RateTransposer::enableAAFilter(const BOOL newMode)
void RateTransposer::enableAAFilter(BOOL newMode)
{
bUseAAFilter = newMode;
}
@@ -163,27 +156,27 @@ BOOL RateTransposer::isAAFilterEnabled() const
}
AAFilter *RateTransposer::getAAFilter() const
AAFilter *RateTransposer::getAAFilter()
{
return pAAFilter;
}
// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
// uRate, larger faster uRates.
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposer::setRate(float newRate)
{
float fCutoff;
double fCutoff;
fRate = newRate;
// design a new anti-alias filter
if (newRate > 1.0f)
if (newRate > 1.0f)
{
fCutoff = 0.5f / newRate;
}
else
}
else
{
fCutoff = 0.5f * newRate;
}
@@ -197,45 +190,47 @@ void RateTransposer::setRate(float newRate)
//
// It's allowed for 'output' and 'input' parameters to point to the same
// memory position.
/*
void RateTransposer::flushStoreBuffer()
{
if (storeBuffer.isEmpty()) return;
outputBuffer.moveSamples(storeBuffer);
}
*/
// Adds 'numSamples' pcs of samples from the 'samples' memory position into
// Adds 'nSamples' pcs of samples from the 'samples' memory position into
// the input of the object.
void RateTransposer::putSamples(const SAMPLETYPE *samples, uint numSamples)
void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
{
processSamples(samples, numSamples);
processSamples(samples, nSamples);
}
// Transposes up the sample rate, causing the observed playback 'rate' of the
// sound to decrease
void RateTransposer::upsample(const SAMPLETYPE *src, uint numSamples)
void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
{
int count, sizeTemp, num;
uint count, sizeTemp, num;
// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
// the samples and then apply the anti-alias filter to remove aliasing.
// First check that there's enough room in 'storeBuffer'
// First check that there's enough room in 'storeBuffer'
// (+16 is to reserve some slack in the destination buffer)
sizeTemp = (int)((float)numSamples / fRate + 16.0f);
sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
// Transpose the samples, store the result into the end of "storeBuffer"
count = transpose(storeBuffer.ptrEnd(sizeTemp), src, numSamples);
count = transpose(storeBuffer.ptrEnd(sizeTemp), src, nSamples);
storeBuffer.putSamples(count);
// Apply the anti-alias filter to samples in "store output", output the
// result to "dest"
num = storeBuffer.numSamples();
count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
storeBuffer.ptrBegin(), num, uChannels);
count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
storeBuffer.ptrBegin(), num, (uint)numChannels);
outputBuffer.putSamples(count);
// Remove the processed samples from "storeBuffer"
@@ -245,96 +240,99 @@ void RateTransposer::upsample(const SAMPLETYPE *src, uint numSamples)
// Transposes down the sample rate, causing the observed playback 'rate' of the
// sound to increase
void RateTransposer::downsample(const SAMPLETYPE *src, uint numSamples)
void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
{
int count, sizeTemp;
uint count, sizeTemp;
// If the parameter 'uRate' value is larger than 'SCALE', first apply the
// anti-alias filter to remove high frequencies (prevent them from folding
// over the lover frequencies), then transpose. */
// over the lover frequencies), then transpose.
// Add the new samples to the end of the storeBuffer */
storeBuffer.putSamples(src, numSamples);
// Add the new samples to the end of the storeBuffer
storeBuffer.putSamples(src, nSamples);
// Anti-alias filter the samples to prevent folding and output the filtered
// Anti-alias filter the samples to prevent folding and output the filtered
// data to tempBuffer. Note : because of the FIR filter length, the
// filtering routine takes in 'filter_length' more samples than it outputs.
assert(tempBuffer.isEmpty());
sizeTemp = storeBuffer.numSamples();
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
storeBuffer.ptrBegin(), sizeTemp, uChannels);
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
if (count == 0) return;
// Remove the filtered samples from 'storeBuffer'
storeBuffer.receiveSamples(count);
// Transpose the samples (+16 is to reserve some slack in the destination buffer)
sizeTemp = (int)((float)numSamples / fRate + 16.0f);
sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
outputBuffer.putSamples(count);
}
// Transposes sample rate by applying anti-alias filter to prevent folding.
// Transposes sample rate by applying anti-alias filter to prevent folding.
// Returns amount of samples returned in the "dest" buffer.
// The maximum amount of samples that can be returned at a time is set by
// the 'set_returnBuffer_size' function.
void RateTransposer::processSamples(const SAMPLETYPE *src, uint numSamples)
void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
{
uint count;
uint sizeReq;
if (numSamples == 0) return;
if (nSamples == 0) return;
assert(pAAFilter);
// If anti-alias filter is turned off, simply transpose without applying
// the filter
if (bUseAAFilter == FALSE)
if (bUseAAFilter == FALSE)
{
sizeReq = (int)((float)numSamples / fRate + 1.0f);
count = transpose(outputBuffer.ptrEnd(sizeReq), src, numSamples);
sizeReq = (uint)((float)nSamples / fRate + 1.0f);
count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
outputBuffer.putSamples(count);
return;
}
// Transpose with anti-alias filter
if (fRate < 1.0f)
if (fRate < 1.0f)
{
upsample(src, numSamples);
}
else
upsample(src, nSamples);
}
else
{
downsample(src, numSamples);
downsample(src, nSamples);
}
}
// Transposes the sample rate of the given samples using linear interpolation.
// Transposes the sample rate of the given samples using linear interpolation.
// Returns the number of samples returned in the "dest" buffer
inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
if (uChannels == 2)
if (numChannels == 2)
{
return transposeStereo(dest, src, numSamples);
}
else
return transposeStereo(dest, src, nSamples);
}
else
{
return transposeMono(dest, src, numSamples);
return transposeMono(dest, src, nSamples);
}
}
// Sets the number of channels, 1 = mono, 2 = stereo
void RateTransposer::setChannels(const uint numchannels)
void RateTransposer::setChannels(int nChannels)
{
if (uChannels == numchannels) return;
assert(nChannels > 0);
if (numChannels == nChannels) return;
assert(numchannels == 1 || numchannels == 2);
uChannels = numchannels;
assert(nChannels == 1 || nChannels == 2);
numChannels = nChannels;
storeBuffer.setChannels(uChannels);
tempBuffer.setChannels(uChannels);
outputBuffer.setChannels(uChannels);
storeBuffer.setChannels(numChannels);
tempBuffer.setChannels(numChannels);
outputBuffer.setChannels(numChannels);
// Inits the linear interpolation registers
resetRegisters();
@@ -350,7 +348,7 @@ void RateTransposer::clear()
// Returns nonzero if there aren't any samples available for outputting.
uint RateTransposer::isEmpty()
int RateTransposer::isEmpty() const
{
int res;
@@ -363,7 +361,7 @@ uint RateTransposer::isEmpty()
//////////////////////////////////////////////////////////////////////////////
//
// RateTransposerInteger - integer arithmetic implementation
//
//
/// fixed-point interpolation routine precision
#define SCALE 65536
@@ -371,11 +369,10 @@ uint RateTransposer::isEmpty()
// Constructor
RateTransposerInteger::RateTransposerInteger() : RateTransposer()
{
// call these here as these are virtual functions; calling these
// from the base class constructor wouldn't execute the overloaded
// versions (<master yoda>peculiar C++ can be</my>).
resetRegisters();
setRate(1.0f);
// Notice: use local function calling syntax for sake of clarity,
// to indicate the fact that C++ constructor can't call virtual functions.
RateTransposerInteger::resetRegisters();
RateTransposerInteger::setRate(1.0f);
}
@@ -387,73 +384,75 @@ RateTransposerInteger::~RateTransposerInteger()
void RateTransposerInteger::resetRegisters()
{
iSlopeCount = 0;
sPrevSampleL =
sPrevSampleL =
sPrevSampleR = 0;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int i, used;
LONG_SAMPLETYPE temp, vol1;
used = 0;
if (nSamples == 0) return 0; // no samples, no work
used = 0;
i = 0;
// Process the last sample saved from the previous call first...
while (iSlopeCount <= SCALE)
while (iSlopeCount <= SCALE)
{
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
dest[i] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += uRate;
iSlopeCount += iRate;
}
// now always (iSlopeCount > SCALE)
iSlopeCount -= SCALE;
while (1)
{
while (iSlopeCount > SCALE)
while (iSlopeCount > SCALE)
{
iSlopeCount -= SCALE;
used ++;
if (used >= numSamples - 1) goto end;
if (used >= nSamples - 1) goto end;
}
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = src[used] * vol1 + iSlopeCount * src[used + 1];
dest[i] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += uRate;
iSlopeCount += iRate;
}
end:
// Store the last sample for the next round
sPrevSampleL = src[numSamples - 1];
sPrevSampleL = src[nSamples - 1];
return i;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Stereo' version of the routine. Returns the number of samples returned in
// Transposes the sample rate of the given samples using linear interpolation.
// 'Stereo' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int srcPos, i, used;
LONG_SAMPLETYPE temp, vol1;
if (numSamples == 0) return 0; // no samples, no work
if (nSamples == 0) return 0; // no samples, no work
used = 0;
used = 0;
i = 0;
// Process the last sample saved from the sPrevSampleLious call first...
while (iSlopeCount <= SCALE)
while (iSlopeCount <= SCALE)
{
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
@@ -461,18 +460,18 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += uRate;
iSlopeCount += iRate;
}
// now always (iSlopeCount > SCALE)
iSlopeCount -= SCALE;
while (1)
{
while (iSlopeCount > SCALE)
while (iSlopeCount > SCALE)
{
iSlopeCount -= SCALE;
used ++;
if (used >= numSamples - 1) goto end;
if (used >= nSamples - 1) goto end;
}
srcPos = 2 * used;
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
@@ -482,22 +481,22 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += uRate;
iSlopeCount += iRate;
}
end:
// Store the last sample for the next round
sPrevSampleL = src[2 * numSamples - 2];
sPrevSampleR = src[2 * numSamples - 1];
sPrevSampleL = src[2 * nSamples - 2];
sPrevSampleR = src[2 * nSamples - 1];
return i;
}
// Sets new target uRate. Normal uRate = 1.0, smaller values represent slower
// uRate, larger faster uRates.
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposerInteger::setRate(float newRate)
{
uRate = (int)(newRate * SCALE + 0.5f);
iRate = (int)(newRate * SCALE + 0.5f);
RateTransposer::setRate(newRate);
}
@@ -505,17 +504,16 @@ void RateTransposerInteger::setRate(float newRate)
//////////////////////////////////////////////////////////////////////////////
//
// RateTransposerFloat - floating point arithmetic implementation
//
//
//////////////////////////////////////////////////////////////////////////////
// Constructor
RateTransposerFloat::RateTransposerFloat() : RateTransposer()
{
// call these here as these are virtual functions; calling these
// from the base class constructor wouldn't execute the overloaded
// versions (<master yoda>peculiar C++ can be</my>).
resetRegisters();
setRate(1.0f);
// Notice: use local function calling syntax for sake of clarity,
// to indicate the fact that C++ constructor can't call virtual functions.
RateTransposerFloat::resetRegisters();
RateTransposerFloat::setRate(1.0f);
}
@@ -527,24 +525,24 @@ RateTransposerFloat::~RateTransposerFloat()
void RateTransposerFloat::resetRegisters()
{
fSlopeCount = 0;
sPrevSampleL =
sPrevSampleL =
sPrevSampleR = 0;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int i, used;
used = 0;
used = 0;
i = 0;
// Process the last sample saved from the previous call first...
while (fSlopeCount <= 1.0f)
while (fSlopeCount <= 1.0f)
{
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
i++;
@@ -552,42 +550,43 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src,
}
fSlopeCount -= 1.0f;
if (numSamples == 1) goto end;
while (1)
if (nSamples > 1)
{
while (fSlopeCount > 1.0f)
while (1)
{
fSlopeCount -= 1.0f;
used ++;
if (used >= numSamples - 1) goto end;
while (fSlopeCount > 1.0f)
{
fSlopeCount -= 1.0f;
used ++;
if (used >= nSamples - 1) goto end;
}
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
i++;
fSlopeCount += fRate;
}
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
i++;
fSlopeCount += fRate;
}
end:
// Store the last sample for the next round
sPrevSampleL = src[numSamples - 1];
sPrevSampleL = src[nSamples - 1];
return i;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples)
uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int srcPos, i, used;
if (numSamples == 0) return 0; // no samples, no work
if (nSamples == 0) return 0; // no samples, no work
used = 0;
used = 0;
i = 0;
// Process the last sample saved from the sPrevSampleLious call first...
while (fSlopeCount <= 1.0f)
while (fSlopeCount <= 1.0f)
{
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
@@ -597,30 +596,31 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
// now always (iSlopeCount > 1.0f)
fSlopeCount -= 1.0f;
if (numSamples == 1) goto end;
while (1)
if (nSamples > 1)
{
while (fSlopeCount > 1.0f)
while (1)
{
fSlopeCount -= 1.0f;
used ++;
if (used >= numSamples - 1) goto end;
while (fSlopeCount > 1.0f)
{
fSlopeCount -= 1.0f;
used ++;
if (used >= nSamples - 1) goto end;
}
srcPos = 2 * used;
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
+ fSlopeCount * src[srcPos + 2]);
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
+ fSlopeCount * src[srcPos + 3]);
i++;
fSlopeCount += fRate;
}
srcPos = 2 * used;
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
+ fSlopeCount * src[srcPos + 2]);
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
+ fSlopeCount * src[srcPos + 3]);
i++;
fSlopeCount += fRate;
}
end:
// Store the last sample for the next round
sPrevSampleL = src[2 * numSamples - 2];
sPrevSampleR = src[2 * numSamples - 1];
sPrevSampleL = src[2 * nSamples - 2];
sPrevSampleR = src[2 * nSamples - 1];
return i;
}