mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Update SoundTouch to 2.3.2 commit 1eda9c0b01039f29d230a46cda9f2290bbd1f62b
This commit is contained in:
Vendored
+2
-16
@@ -12,13 +12,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-01-05 23:40:22 +0200 (Sun, 05 Jan 2014) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: AAFilter.cpp 177 2014-01-05 21:40:22Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -49,7 +42,7 @@
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#define PI 3.141592655357989
|
||||
#define PI 3.14159265358979323846
|
||||
#define TWOPI (2 * PI)
|
||||
|
||||
// define this to save AA filter coefficients to a file
|
||||
@@ -61,7 +54,7 @@ using namespace soundtouch;
|
||||
static void _DEBUG_SAVE_AAFIR_COEFFS(SAMPLETYPE *coeffs, int len)
|
||||
{
|
||||
FILE *fptr = fopen("aa_filter_coeffs.txt", "wt");
|
||||
if (fptr == NULL) return;
|
||||
if (fptr == nullptr) return;
|
||||
|
||||
for (int i = 0; i < len; i ++)
|
||||
{
|
||||
@@ -75,7 +68,6 @@ using namespace soundtouch;
|
||||
#define _DEBUG_SAVE_AAFIR_COEFFS(x, y)
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Implementation of the class 'AAFilter'
|
||||
@@ -90,14 +82,12 @@ AAFilter::AAFilter(uint len)
|
||||
}
|
||||
|
||||
|
||||
|
||||
AAFilter::~AAFilter()
|
||||
{
|
||||
delete pFIR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new anti-alias filter cut-off edge frequency, scaled to
|
||||
// sampling frequency (nyquist frequency = 0.5).
|
||||
// The filter will cut frequencies higher than the given frequency.
|
||||
@@ -108,7 +98,6 @@ void AAFilter::setCutoffFreq(double newCutoffFreq)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets number of FIR filter taps
|
||||
void AAFilter::setLength(uint newLength)
|
||||
{
|
||||
@@ -117,7 +106,6 @@ void AAFilter::setLength(uint newLength)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calculates coefficients for a low-pass FIR filter using Hamming window
|
||||
void AAFilter::calculateCoeffs()
|
||||
{
|
||||
@@ -177,12 +165,10 @@ void AAFilter::calculateCoeffs()
|
||||
for (i = 0; i < length; i ++)
|
||||
{
|
||||
temp = work[i] * scaleCoeff;
|
||||
//#if SOUNDTOUCH_INTEGER_SAMPLES
|
||||
// scale & round to nearest integer
|
||||
temp += (temp >= 0) ? 0.5 : -0.5;
|
||||
// ensure no overfloods
|
||||
assert(temp >= -32768 && temp <= 32767);
|
||||
//#endif
|
||||
coeffs[i] = (SAMPLETYPE)temp;
|
||||
}
|
||||
|
||||
|
||||
Vendored
-7
@@ -13,13 +13,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-01-07 21:41:23 +0200 (Tue, 07 Jan 2014) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: AAFilter.h 187 2014-01-07 19:41:23Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
|
||||
Vendored
+301
-101
File diff suppressed because it is too large
Load Diff
Vendored
+138
-97
@@ -26,13 +26,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2012-08-30 22:53:44 +0300 (Thu, 30 Aug 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: BPMDetect.h 150 2012-08-30 19:53:44Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -57,108 +50,156 @@
|
||||
#ifndef _BPMDetect_H_
|
||||
#define _BPMDetect_H_
|
||||
|
||||
#include <vector>
|
||||
#include "STTypes.h"
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
|
||||
#define MIN_BPM 29
|
||||
/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
|
||||
#define MIN_BPM 45
|
||||
|
||||
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
|
||||
#define MAX_BPM 200
|
||||
/// Maximum allowed BPM rate range. Used for calculating algorithm parametrs
|
||||
#define MAX_BPM_RANGE 200
|
||||
|
||||
/// Maximum allowed BPM rate range. Used to restrict accepted result below a reasonable limit.
|
||||
#define MAX_BPM_VALID 190
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float pos;
|
||||
float strength;
|
||||
} BEAT;
|
||||
|
||||
|
||||
/// Class for calculating BPM rate for audio data.
|
||||
class BPMDetect
|
||||
{
|
||||
protected:
|
||||
/// Auto-correlation accumulator bins.
|
||||
float *xcorr;
|
||||
|
||||
/// Amplitude envelope sliding average approximation level accumulator
|
||||
double envelopeAccu;
|
||||
class IIR2_filter
|
||||
{
|
||||
double coeffs[5];
|
||||
double prev[5];
|
||||
|
||||
/// RMS volume sliding average approximation level accumulator
|
||||
double RMSVolumeAccu;
|
||||
|
||||
/// Sample average counter.
|
||||
int decimateCount;
|
||||
|
||||
/// Sample average accumulator for FIFO-like decimation.
|
||||
soundtouch::LONG_SAMPLETYPE decimateSum;
|
||||
|
||||
/// Decimate sound by this coefficient to reach approx. 500 Hz.
|
||||
int decimateBy;
|
||||
|
||||
/// Auto-correlation window length
|
||||
int windowLen;
|
||||
|
||||
/// Number of channels (1 = mono, 2 = stereo)
|
||||
int channels;
|
||||
|
||||
/// sample rate
|
||||
int sampleRate;
|
||||
|
||||
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
|
||||
/// the first these many correlation bins.
|
||||
int windowStart;
|
||||
|
||||
/// FIFO-buffer for decimated processing samples.
|
||||
soundtouch::FIFOSampleBuffer *buffer;
|
||||
|
||||
/// 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
|
||||
/// though).
|
||||
void updateXCorr(int process_samples /// How many samples are processed.
|
||||
);
|
||||
|
||||
/// Decimates samples to approx. 500 Hz.
|
||||
///
|
||||
/// \return Number of output samples.
|
||||
int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
|
||||
const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
|
||||
int numsamples ///< Number of source samples.
|
||||
);
|
||||
|
||||
/// Calculates amplitude envelope for the buffer of samples.
|
||||
/// Result is output to 'samples'.
|
||||
void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
|
||||
int numsamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
/// remove constant bias from xcorr data
|
||||
void removeBias();
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
BPMDetect(int numChannels, ///< Number of channels in sample data.
|
||||
int sampleRate ///< Sample rate in Hz.
|
||||
);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BPMDetect();
|
||||
|
||||
/// Inputs a block of samples for analyzing: Envelopes the samples and then
|
||||
/// updates the autocorrelation estimation. When whole song data has been input
|
||||
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
|
||||
/// function.
|
||||
///
|
||||
/// Notice that data in 'samples' array can be disrupted in processing.
|
||||
void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
|
||||
int numSamples ///< Number of samples in buffer
|
||||
);
|
||||
public:
|
||||
IIR2_filter(const double *lpf_coeffs);
|
||||
float update(float x);
|
||||
};
|
||||
|
||||
|
||||
/// Analyzes the results and returns the BPM rate. Use this function to read result
|
||||
/// after whole song data has been input to the class by consecutive calls of
|
||||
/// 'inputSamples' function.
|
||||
///
|
||||
/// \return Beats-per-minute rate, or zero if detection failed.
|
||||
float getBpm();
|
||||
};
|
||||
/// Class for calculating BPM rate for audio data.
|
||||
class BPMDetect
|
||||
{
|
||||
protected:
|
||||
/// Auto-correlation accumulator bins.
|
||||
float *xcorr;
|
||||
|
||||
/// Sample average counter.
|
||||
int decimateCount;
|
||||
|
||||
/// Sample average accumulator for FIFO-like decimation.
|
||||
soundtouch::LONG_SAMPLETYPE decimateSum;
|
||||
|
||||
/// Decimate sound by this coefficient to reach approx. 500 Hz.
|
||||
int decimateBy;
|
||||
|
||||
/// Auto-correlation window length
|
||||
int windowLen;
|
||||
|
||||
/// Number of channels (1 = mono, 2 = stereo)
|
||||
int channels;
|
||||
|
||||
/// sample rate
|
||||
int sampleRate;
|
||||
|
||||
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
|
||||
/// the first these many correlation bins.
|
||||
int windowStart;
|
||||
|
||||
/// window functions for data preconditioning
|
||||
float *hamw;
|
||||
float *hamw2;
|
||||
|
||||
// beat detection variables
|
||||
int pos;
|
||||
int peakPos;
|
||||
int beatcorr_ringbuffpos;
|
||||
int init_scaler;
|
||||
float peakVal;
|
||||
float *beatcorr_ringbuff;
|
||||
|
||||
/// FIFO-buffer for decimated processing samples.
|
||||
soundtouch::FIFOSampleBuffer *buffer;
|
||||
|
||||
/// Collection of detected beat positions
|
||||
//BeatCollection beats;
|
||||
std::vector<BEAT> beats;
|
||||
|
||||
// 2nd order low-pass-filter
|
||||
IIR2_filter beat_lpf;
|
||||
|
||||
/// 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
|
||||
/// though).
|
||||
void updateXCorr(int process_samples /// How many samples are processed.
|
||||
);
|
||||
|
||||
/// Decimates samples to approx. 500 Hz.
|
||||
///
|
||||
/// \return Number of output samples.
|
||||
int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
|
||||
const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
|
||||
int numsamples ///< Number of source samples.
|
||||
);
|
||||
|
||||
/// Calculates amplitude envelope for the buffer of samples.
|
||||
/// Result is output to 'samples'.
|
||||
void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
|
||||
int numsamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
/// remove constant bias from xcorr data
|
||||
void removeBias();
|
||||
|
||||
// Detect individual beat positions
|
||||
void updateBeatPos(int process_samples);
|
||||
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
BPMDetect(int numChannels, ///< Number of channels in sample data.
|
||||
int sampleRate ///< Sample rate in Hz.
|
||||
);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BPMDetect();
|
||||
|
||||
/// Inputs a block of samples for analyzing: Envelopes the samples and then
|
||||
/// updates the autocorrelation estimation. When whole song data has been input
|
||||
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
|
||||
/// function.
|
||||
///
|
||||
/// Notice that data in 'samples' array can be disrupted in processing.
|
||||
void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
|
||||
int numSamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
/// Analyzes the results and returns the BPM rate. Use this function to read result
|
||||
/// after whole song data has been input to the class by consecutive calls of
|
||||
/// 'inputSamples' function.
|
||||
///
|
||||
/// \return Beats-per-minute rate, or zero if detection failed.
|
||||
float getBpm();
|
||||
|
||||
/// Get beat position arrays. Note: The array includes also really low beat detection values
|
||||
/// in absence of clear strong beats. Consumer may wish to filter low values away.
|
||||
/// - "pos" receive array of beat positions
|
||||
/// - "values" receive array of beat detection strengths
|
||||
/// - max_num indicates max.size of "pos" and "values" array.
|
||||
///
|
||||
/// You can query a suitable array sized by calling this with nullptr in "pos" & "values".
|
||||
///
|
||||
/// \return number of beats in the arrays.
|
||||
int getBeats(float *pos, float *strength, int max_num);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _BPMDetect_H_
|
||||
|
||||
Vendored
+3
-1
@@ -1,3 +1,6 @@
|
||||
# OSX meeds to know
|
||||
check_and_add_flag(CXX11 -std=c++11)
|
||||
|
||||
set(SRCS
|
||||
AAFilter.cpp
|
||||
BPMDetect.cpp
|
||||
@@ -17,4 +20,3 @@ set(SRCS
|
||||
|
||||
add_library(SoundTouch STATIC ${SRCS})
|
||||
dolphin_disable_warnings_msvc(SoundTouch)
|
||||
add_definitions(-w)
|
||||
|
||||
+16
-15
@@ -15,13 +15,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2012-11-08 20:53:01 +0200 (Thu, 08 Nov 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -57,8 +50,8 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
|
||||
{
|
||||
assert(numChannels > 0);
|
||||
sizeInBytes = 0; // reasonable initial value
|
||||
buffer = NULL;
|
||||
bufferUnaligned = NULL;
|
||||
buffer = nullptr;
|
||||
bufferUnaligned = nullptr;
|
||||
samplesInBuffer = 0;
|
||||
bufferPos = 0;
|
||||
channels = (uint)numChannels;
|
||||
@@ -70,8 +63,8 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
|
||||
FIFOSampleBuffer::~FIFOSampleBuffer()
|
||||
{
|
||||
delete[] bufferUnaligned;
|
||||
bufferUnaligned = NULL;
|
||||
buffer = NULL;
|
||||
bufferUnaligned = nullptr;
|
||||
buffer = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +73,8 @@ void FIFOSampleBuffer::setChannels(int numChannels)
|
||||
{
|
||||
uint usedBytes;
|
||||
|
||||
assert(numChannels > 0);
|
||||
if (!verifyNumberOfChannels(numChannels)) return;
|
||||
|
||||
usedBytes = channels * samplesInBuffer;
|
||||
channels = (uint)numChannels;
|
||||
samplesInBuffer = usedBytes / channels;
|
||||
@@ -131,7 +125,7 @@ void FIFOSampleBuffer::putSamples(uint nSamples)
|
||||
//
|
||||
// Parameter 'slackCapacity' tells the function how much free capacity (in
|
||||
// terms of samples) there _at least_ should be, in order to the caller to
|
||||
// succesfully insert all the required samples to the buffer. When necessary,
|
||||
// successfully insert all the required samples to the buffer. When necessary,
|
||||
// the function grows the buffer size to comply with this requirement.
|
||||
//
|
||||
// When using this function as means for inserting new samples, also remember
|
||||
@@ -158,7 +152,7 @@ SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
|
||||
}
|
||||
|
||||
|
||||
// Ensures that the buffer has enought capacity, i.e. space for _at least_
|
||||
// Ensures that the buffer has enough capacity, i.e. space for _at least_
|
||||
// 'capacityRequirement' number of samples. The buffer is grown in steps of
|
||||
// 4 kilobytes to eliminate the need for frequently growing up the buffer,
|
||||
// as well as to round the buffer size up to the virtual memory page size.
|
||||
@@ -172,7 +166,7 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
|
||||
assert(sizeInBytes % 2 == 0);
|
||||
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
||||
if (tempUnaligned == NULL)
|
||||
if (tempUnaligned == nullptr)
|
||||
{
|
||||
ST_THROW_RT_ERROR("Couldn't allocate memory!\n");
|
||||
}
|
||||
@@ -272,3 +266,10 @@ uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
|
||||
return samplesInBuffer;
|
||||
}
|
||||
|
||||
|
||||
/// Add silence to end of buffer
|
||||
void FIFOSampleBuffer::addSilent(uint nSamples)
|
||||
{
|
||||
memset(ptrEnd(nSamples), 0, sizeof(SAMPLETYPE) * nSamples * channels);
|
||||
samplesInBuffer += nSamples;
|
||||
}
|
||||
|
||||
+13
-17
@@ -15,13 +15,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-01-05 23:40:22 +0200 (Sun, 05 Jan 2014) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.h 177 2014-01-05 21:40:22Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -98,7 +91,7 @@ public:
|
||||
);
|
||||
|
||||
/// destructor
|
||||
~FIFOSampleBuffer();
|
||||
~FIFOSampleBuffer() override;
|
||||
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
@@ -107,7 +100,7 @@ public:
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin();
|
||||
virtual SAMPLETYPE *ptrBegin() override;
|
||||
|
||||
/// 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
|
||||
@@ -119,7 +112,7 @@ public:
|
||||
/// 'putSamples(numSamples)' function.
|
||||
SAMPLETYPE *ptrEnd(
|
||||
uint slackCapacity ///< How much free capacity (in samples) there _at least_
|
||||
///< should be so that the caller can succesfully insert the
|
||||
///< should be so that the caller can successfully insert the
|
||||
///< desired samples to the buffer. If necessary, the function
|
||||
///< grows the buffer size to comply with this requirement.
|
||||
);
|
||||
@@ -128,7 +121,7 @@ public:
|
||||
/// the sample buffer.
|
||||
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
|
||||
uint numSamples ///< Number of samples to insert.
|
||||
);
|
||||
) override;
|
||||
|
||||
/// Adjusts the book-keeping to increase number of samples in the buffer without
|
||||
/// copying any actual samples.
|
||||
@@ -146,7 +139,7 @@ public:
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
);
|
||||
) override;
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
@@ -154,10 +147,10 @@ public:
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
);
|
||||
) override;
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const;
|
||||
virtual uint numSamples() const override;
|
||||
|
||||
/// Sets number of channels, 1 = mono, 2 = stereo.
|
||||
void setChannels(int numChannels);
|
||||
@@ -169,14 +162,17 @@ public:
|
||||
}
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const;
|
||||
virtual int isEmpty() const override;
|
||||
|
||||
/// Clears all the samples.
|
||||
virtual void clear();
|
||||
virtual void clear() override;
|
||||
|
||||
/// allow trimming (downwards) amount of samples in pipeline.
|
||||
/// Returns adjusted amount of samples
|
||||
uint adjustAmountOfSamples(uint numSamples);
|
||||
uint adjustAmountOfSamples(uint numSamples) override;
|
||||
|
||||
/// Add silence to end of buffer
|
||||
void addSilent(uint nSamples);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+22
-26
@@ -17,13 +17,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2012-06-13 22:29:53 +0300 (Wed, 13 Jun 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIFOSamplePipe.h 143 2012-06-13 19:29:53Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -58,6 +51,18 @@ namespace soundtouch
|
||||
/// Abstract base class for FIFO (first-in-first-out) sample processing classes.
|
||||
class FIFOSamplePipe
|
||||
{
|
||||
protected:
|
||||
|
||||
bool verifyNumberOfChannels(int nChannels) const
|
||||
{
|
||||
if ((nChannels > 0) && (nChannels <= SOUNDTOUCH_MAX_CHANNELS))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
ST_THROW_RT_ERROR("Error: Illegal number of channels");
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
// virtual default destructor
|
||||
virtual ~FIFOSamplePipe() {}
|
||||
@@ -122,7 +127,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Base-class for sound processing routines working in FIFO principle. With this base
|
||||
/// class it's easy to implement sound processing stages that can be chained together,
|
||||
/// so that samples that are fed into beginning of the pipe automatically go through
|
||||
@@ -140,20 +144,18 @@ protected:
|
||||
/// Sets output pipe.
|
||||
void setOutPipe(FIFOSamplePipe *pOutput)
|
||||
{
|
||||
assert(output == NULL);
|
||||
assert(pOutput != NULL);
|
||||
assert(output == nullptr);
|
||||
assert(pOutput != nullptr);
|
||||
output = pOutput;
|
||||
}
|
||||
|
||||
|
||||
/// Constructor. Doesn't define output pipe; it has to be set be
|
||||
/// 'setOutPipe' function.
|
||||
FIFOProcessor()
|
||||
{
|
||||
output = NULL;
|
||||
output = nullptr;
|
||||
}
|
||||
|
||||
|
||||
/// Constructor. Configures output pipe.
|
||||
FIFOProcessor(FIFOSamplePipe *pOutput ///< Output pipe.
|
||||
)
|
||||
@@ -161,13 +163,11 @@ protected:
|
||||
output = pOutput;
|
||||
}
|
||||
|
||||
|
||||
/// Destructor.
|
||||
virtual ~FIFOProcessor()
|
||||
virtual ~FIFOProcessor() override
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
@@ -175,7 +175,7 @@ protected:
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin()
|
||||
virtual SAMPLETYPE *ptrBegin() override
|
||||
{
|
||||
return output->ptrBegin();
|
||||
}
|
||||
@@ -189,44 +189,40 @@ public:
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
)
|
||||
) override
|
||||
{
|
||||
return output->receiveSamples(outBuffer, maxSamples);
|
||||
}
|
||||
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
)
|
||||
) override
|
||||
{
|
||||
return output->receiveSamples(maxSamples);
|
||||
}
|
||||
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const
|
||||
virtual uint numSamples() const override
|
||||
{
|
||||
return output->numSamples();
|
||||
}
|
||||
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const
|
||||
virtual int isEmpty() const override
|
||||
{
|
||||
return output->isEmpty();
|
||||
}
|
||||
|
||||
/// allow trimming (downwards) amount of samples in pipeline.
|
||||
/// Returns adjusted amount of samples
|
||||
virtual uint adjustAmountOfSamples(uint numSamples)
|
||||
virtual uint adjustAmountOfSamples(uint numSamples) override
|
||||
{
|
||||
return output->adjustAmountOfSamples(numSamples);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Vendored
+58
-72
@@ -2,22 +2,21 @@
|
||||
///
|
||||
/// General FIR digital filter routines with MMX optimization.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// Notes : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// This source file contains OpenMP optimizations that allow speeding up the
|
||||
/// corss-correlation algorithm by executing it in several threads / CPU cores
|
||||
/// in parallel. See the following article link for more detailed discussion
|
||||
/// about SoundTouch OpenMP optimizations:
|
||||
/// http://www.softwarecoven.com/parallel-computing-in-embedded-mobile-devices
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIRFilter.cpp 202 2015-02-21 21:24:29Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -60,53 +59,43 @@ FIRFilter::FIRFilter()
|
||||
resultDivider = 0;
|
||||
length = 0;
|
||||
lengthDiv8 = 0;
|
||||
filterCoeffs = NULL;
|
||||
filterCoeffs = nullptr;
|
||||
filterCoeffsStereo = nullptr;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter::~FIRFilter()
|
||||
{
|
||||
delete[] filterCoeffs;
|
||||
delete[] filterCoeffsStereo;
|
||||
}
|
||||
|
||||
|
||||
// Usual C-version of the filter routine for stereo sound
|
||||
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
int j, end;
|
||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
// hint compiler autovectorization that loop length is divisible by 8
|
||||
uint ilength = length & -8;
|
||||
|
||||
assert(length != 0);
|
||||
assert(src != NULL);
|
||||
assert(dest != NULL);
|
||||
assert(filterCoeffs != NULL);
|
||||
assert((length != 0) && (length == ilength) && (src != nullptr) && (dest != nullptr) && (filterCoeffs != nullptr));
|
||||
assert(numSamples > ilength);
|
||||
|
||||
end = 2 * (numSamples - length);
|
||||
end = 2 * (numSamples - ilength);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (j = 0; j < end; j += 2)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
LONG_SAMPLETYPE suml, sumr;
|
||||
uint i;
|
||||
|
||||
suml = sumr = 0;
|
||||
ptr = src + j;
|
||||
|
||||
for (i = 0; i < length; i += 4)
|
||||
for (uint i = 0; i < ilength; i ++)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
|
||||
ptr[2 * i + 2] * filterCoeffs[i + 1] +
|
||||
ptr[2 * i + 4] * filterCoeffs[i + 2] +
|
||||
ptr[2 * i + 6] * filterCoeffs[i + 3];
|
||||
sumr += ptr[2 * i + 1] * filterCoeffs[i + 0] +
|
||||
ptr[2 * i + 3] * filterCoeffs[i + 1] +
|
||||
ptr[2 * i + 5] * filterCoeffs[i + 2] +
|
||||
ptr[2 * i + 7] * filterCoeffs[i + 3];
|
||||
suml += ptr[2 * i] * filterCoeffsStereo[2 * i];
|
||||
sumr += ptr[2 * i + 1] * filterCoeffsStereo[2 * i + 1];
|
||||
}
|
||||
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
@@ -116,54 +105,41 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||
suml = (suml < -32768) ? -32768 : (suml > 32767) ? 32767 : suml;
|
||||
// saturate to 16 bit integer limits
|
||||
sumr = (sumr < -32768) ? -32768 : (sumr > 32767) ? 32767 : sumr;
|
||||
#else
|
||||
suml *= dScaler;
|
||||
sumr *= dScaler;
|
||||
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)suml;
|
||||
dest[j + 1] = (SAMPLETYPE)sumr;
|
||||
}
|
||||
return numSamples - length;
|
||||
return numSamples - ilength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Usual C-version of the filter routine for mono sound
|
||||
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
int j, end;
|
||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
|
||||
assert(length != 0);
|
||||
// hint compiler autovectorization that loop length is divisible by 8
|
||||
int ilength = length & -8;
|
||||
|
||||
end = numSamples - length;
|
||||
assert(ilength != 0);
|
||||
|
||||
end = numSamples - ilength;
|
||||
#pragma omp parallel for
|
||||
for (j = 0; j < end; j ++)
|
||||
for (j = 0; j < end; j ++)
|
||||
{
|
||||
const SAMPLETYPE *pSrc = src + j;
|
||||
LONG_SAMPLETYPE sum;
|
||||
uint i;
|
||||
int i;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i += 4)
|
||||
for (i = 0; i < ilength; i ++)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
sum += pSrc[i + 0] * filterCoeffs[i + 0] +
|
||||
pSrc[i + 1] * filterCoeffs[i + 1] +
|
||||
pSrc[i + 2] * filterCoeffs[i + 2] +
|
||||
pSrc[i + 3] * filterCoeffs[i + 3];
|
||||
sum += pSrc[i] * filterCoeffs[i];
|
||||
}
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
sum >>= resultDivFactor;
|
||||
// saturate to 16 bit integer limits
|
||||
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
|
||||
#else
|
||||
sum *= dScaler;
|
||||
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)sum;
|
||||
}
|
||||
@@ -175,26 +151,24 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
||||
{
|
||||
int j, end;
|
||||
|
||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
|
||||
assert(length != 0);
|
||||
assert(src != NULL);
|
||||
assert(dest != NULL);
|
||||
assert(filterCoeffs != NULL);
|
||||
assert(src != nullptr);
|
||||
assert(dest != nullptr);
|
||||
assert(filterCoeffs != nullptr);
|
||||
assert(numChannels < 16);
|
||||
|
||||
end = numChannels * (numSamples - length);
|
||||
// hint compiler autovectorization that loop length is divisible by 8
|
||||
int ilength = length & -8;
|
||||
|
||||
end = numChannels * (numSamples - ilength);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (j = 0; j < end; j += numChannels)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
LONG_SAMPLETYPE sums[16];
|
||||
uint c, i;
|
||||
uint c;
|
||||
int i;
|
||||
|
||||
for (c = 0; c < numChannels; c ++)
|
||||
{
|
||||
@@ -203,7 +177,7 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
||||
|
||||
ptr = src + j;
|
||||
|
||||
for (i = 0; i < length; i ++)
|
||||
for (i = 0; i < ilength; i ++)
|
||||
{
|
||||
SAMPLETYPE coef=filterCoeffs[i];
|
||||
for (c = 0; c < numChannels; c ++)
|
||||
@@ -217,13 +191,11 @@ uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uin
|
||||
{
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
sums[c] >>= resultDivFactor;
|
||||
#else
|
||||
sums[c] *= dScaler;
|
||||
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||
dest[j+c] = (SAMPLETYPE)sums[c];
|
||||
}
|
||||
}
|
||||
return numSamples - length;
|
||||
return numSamples - ilength;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +207,13 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
|
||||
assert(newLength > 0);
|
||||
if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8");
|
||||
|
||||
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
// scale coefficients already here if using floating samples
|
||||
double scale = 1.0 / resultDivider;
|
||||
#else
|
||||
short scale = 1;
|
||||
#endif
|
||||
|
||||
lengthDiv8 = newLength / 8;
|
||||
length = lengthDiv8 * 8;
|
||||
assert(length == newLength);
|
||||
@@ -244,7 +223,16 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u
|
||||
|
||||
delete[] filterCoeffs;
|
||||
filterCoeffs = new SAMPLETYPE[length];
|
||||
memcpy(filterCoeffs, coeffs, length * sizeof(SAMPLETYPE));
|
||||
delete[] filterCoeffsStereo;
|
||||
filterCoeffsStereo = new SAMPLETYPE[length*2];
|
||||
for (uint i = 0; i < length; i ++)
|
||||
{
|
||||
filterCoeffs[i] = (SAMPLETYPE)(coeffs[i] * scale);
|
||||
// create also stereo set of filter coefficients: this allows compiler
|
||||
// to autovectorize filter evaluation much more efficiently
|
||||
filterCoeffsStereo[2 * i] = (SAMPLETYPE)(coeffs[i] * scale);
|
||||
filterCoeffsStereo[2 * i + 1] = (SAMPLETYPE)(coeffs[i] * scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +242,6 @@ uint FIRFilter::getLength() const
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Applies the filter to the given sequence of samples.
|
||||
//
|
||||
// Note : The amount of outputted samples is by value of 'filter_length'
|
||||
@@ -284,10 +271,9 @@ uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSample
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
// depending on if we've a MMX-capable CPU available or not.
|
||||
void * FIRFilter::operator new(size_t s)
|
||||
void * FIRFilter::operator new(size_t)
|
||||
{
|
||||
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
||||
ST_THROW_RT_ERROR("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
||||
|
||||
Vendored
+5
-11
@@ -11,13 +11,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIRFilter.h 202 2015-02-21 21:24:29Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -64,6 +57,7 @@ protected:
|
||||
|
||||
// Memory for filter coefficients
|
||||
SAMPLETYPE *filterCoeffs;
|
||||
SAMPLETYPE *filterCoeffsStereo;
|
||||
|
||||
virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
@@ -112,12 +106,12 @@ public:
|
||||
short *filterCoeffsUnalign;
|
||||
short *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const;
|
||||
virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const override;
|
||||
public:
|
||||
FIRFilterMMX();
|
||||
~FIRFilterMMX();
|
||||
|
||||
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
|
||||
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor) override;
|
||||
};
|
||||
|
||||
#endif // SOUNDTOUCH_ALLOW_MMX
|
||||
@@ -131,12 +125,12 @@ public:
|
||||
float *filterCoeffsUnalign;
|
||||
float *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
|
||||
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const override;
|
||||
public:
|
||||
FIRFilterSSE();
|
||||
~FIRFilterSSE();
|
||||
|
||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor) override;
|
||||
};
|
||||
|
||||
#endif // SOUNDTOUCH_ALLOW_SSE
|
||||
|
||||
+196
-200
@@ -1,200 +1,196 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Cubic interpolation routine.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $Id: InterpolateCubic.cpp 179 2014-01-06 18:41:42Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include "InterpolateCubic.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
// cubic interpolation coefficients
|
||||
static const float _coeffs[]=
|
||||
{ -0.5f, 1.0f, -0.5f, 0.0f,
|
||||
1.5f, -2.5f, 0.0f, 1.0f,
|
||||
-1.5f, 2.0f, 0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f, 0.0f};
|
||||
|
||||
|
||||
InterpolateCubic::InterpolateCubic()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
void InterpolateCubic::resetRegisters()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose mono audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateCubic::transposeMono(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 4;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
float out;
|
||||
const float x3 = 1.0f;
|
||||
const float x2 = (float)fract; // x
|
||||
const float x1 = x2*x2; // x^2
|
||||
const float x0 = x1*x2; // x^3
|
||||
float y0, y1, y2, y3;
|
||||
|
||||
assert(fract < 1.0);
|
||||
|
||||
y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
|
||||
y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
|
||||
y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
|
||||
y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
|
||||
|
||||
out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3];
|
||||
|
||||
pdest[i] = (SAMPLETYPE)out;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 4;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
const float x3 = 1.0f;
|
||||
const float x2 = (float)fract; // x
|
||||
const float x1 = x2*x2; // x^2
|
||||
const float x0 = x1*x2; // x^3
|
||||
float y0, y1, y2, y3;
|
||||
float out0, out1;
|
||||
|
||||
assert(fract < 1.0);
|
||||
|
||||
y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
|
||||
y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
|
||||
y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
|
||||
y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
|
||||
|
||||
out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6];
|
||||
out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7];
|
||||
|
||||
pdest[2*i] = (SAMPLETYPE)out0;
|
||||
pdest[2*i+1] = (SAMPLETYPE)out1;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += 2*whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose multi-channel audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 4;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
const float x3 = 1.0f;
|
||||
const float x2 = (float)fract; // x
|
||||
const float x1 = x2*x2; // x^2
|
||||
const float x0 = x1*x2; // x^3
|
||||
float y0, y1, y2, y3;
|
||||
|
||||
assert(fract < 1.0);
|
||||
|
||||
y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
|
||||
y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
|
||||
y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
|
||||
y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
|
||||
|
||||
for (int c = 0; c < numChannels; c ++)
|
||||
{
|
||||
float out;
|
||||
out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels];
|
||||
pdest[0] = (SAMPLETYPE)out;
|
||||
pdest ++;
|
||||
}
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += numChannels*whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Cubic interpolation routine.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include "InterpolateCubic.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
// cubic interpolation coefficients
|
||||
static const float _coeffs[]=
|
||||
{ -0.5f, 1.0f, -0.5f, 0.0f,
|
||||
1.5f, -2.5f, 0.0f, 1.0f,
|
||||
-1.5f, 2.0f, 0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f, 0.0f};
|
||||
|
||||
|
||||
InterpolateCubic::InterpolateCubic()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
void InterpolateCubic::resetRegisters()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose mono audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateCubic::transposeMono(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 4;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
float out;
|
||||
const float x3 = 1.0f;
|
||||
const float x2 = (float)fract; // x
|
||||
const float x1 = x2*x2; // x^2
|
||||
const float x0 = x1*x2; // x^3
|
||||
float y0, y1, y2, y3;
|
||||
|
||||
assert(fract < 1.0);
|
||||
|
||||
y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
|
||||
y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
|
||||
y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
|
||||
y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
|
||||
|
||||
out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3];
|
||||
|
||||
pdest[i] = (SAMPLETYPE)out;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 4;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
const float x3 = 1.0f;
|
||||
const float x2 = (float)fract; // x
|
||||
const float x1 = x2*x2; // x^2
|
||||
const float x0 = x1*x2; // x^3
|
||||
float y0, y1, y2, y3;
|
||||
float out0, out1;
|
||||
|
||||
assert(fract < 1.0);
|
||||
|
||||
y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
|
||||
y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
|
||||
y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
|
||||
y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
|
||||
|
||||
out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6];
|
||||
out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7];
|
||||
|
||||
pdest[2*i] = (SAMPLETYPE)out0;
|
||||
pdest[2*i+1] = (SAMPLETYPE)out1;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += 2*whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose multi-channel audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 4;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
const float x3 = 1.0f;
|
||||
const float x2 = (float)fract; // x
|
||||
const float x1 = x2*x2; // x^2
|
||||
const float x0 = x1*x2; // x^3
|
||||
float y0, y1, y2, y3;
|
||||
|
||||
assert(fract < 1.0);
|
||||
|
||||
y0 = _coeffs[0] * x0 + _coeffs[1] * x1 + _coeffs[2] * x2 + _coeffs[3] * x3;
|
||||
y1 = _coeffs[4] * x0 + _coeffs[5] * x1 + _coeffs[6] * x2 + _coeffs[7] * x3;
|
||||
y2 = _coeffs[8] * x0 + _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
|
||||
y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
|
||||
|
||||
for (int c = 0; c < numChannels; c ++)
|
||||
{
|
||||
float out;
|
||||
out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels];
|
||||
pdest[0] = (SAMPLETYPE)out;
|
||||
pdest ++;
|
||||
}
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += numChannels*whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
+69
-67
@@ -1,67 +1,69 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Cubic interpolation routine.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $Id: InterpolateCubic.h 225 2015-07-26 14:45:48Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _InterpolateCubic_H_
|
||||
#define _InterpolateCubic_H_
|
||||
|
||||
#include "RateTransposer.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class InterpolateCubic : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
virtual void resetRegisters();
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeMulti(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
|
||||
double fract;
|
||||
|
||||
public:
|
||||
InterpolateCubic();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Cubic interpolation routine.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _InterpolateCubic_H_
|
||||
#define _InterpolateCubic_H_
|
||||
|
||||
#include "RateTransposer.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class InterpolateCubic : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
virtual int transposeMulti(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
|
||||
double fract;
|
||||
|
||||
public:
|
||||
InterpolateCubic();
|
||||
|
||||
virtual void resetRegisters() override;
|
||||
|
||||
virtual int getLatency() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+296
-300
File diff suppressed because it is too large
Load Diff
+98
-92
@@ -1,92 +1,98 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Linear interpolation routine.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $Id: InterpolateLinear.h 225 2015-07-26 14:45:48Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _InterpolateLinear_H_
|
||||
#define _InterpolateLinear_H_
|
||||
|
||||
#include "RateTransposer.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Linear transposer class that uses integer arithmetics
|
||||
class InterpolateLinearInteger : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
int iFract;
|
||||
int iRate;
|
||||
|
||||
virtual void resetRegisters();
|
||||
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
|
||||
public:
|
||||
InterpolateLinearInteger();
|
||||
|
||||
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
||||
/// rate, larger faster rates.
|
||||
virtual void setRate(double newRate);
|
||||
};
|
||||
|
||||
|
||||
/// Linear transposer class that uses floating point arithmetics
|
||||
class InterpolateLinearFloat : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
double fract;
|
||||
|
||||
virtual void resetRegisters();
|
||||
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
|
||||
|
||||
public:
|
||||
InterpolateLinearFloat();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Linear interpolation routine.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _InterpolateLinear_H_
|
||||
#define _InterpolateLinear_H_
|
||||
|
||||
#include "RateTransposer.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Linear transposer class that uses integer arithmetic
|
||||
class InterpolateLinearInteger : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
int iFract;
|
||||
int iRate;
|
||||
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) override;
|
||||
public:
|
||||
InterpolateLinearInteger();
|
||||
|
||||
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
||||
/// rate, larger faster rates.
|
||||
virtual void setRate(double newRate) override;
|
||||
|
||||
virtual void resetRegisters() override;
|
||||
|
||||
virtual int getLatency() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Linear transposer class that uses floating point arithmetic
|
||||
class InterpolateLinearFloat : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
double fract;
|
||||
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
|
||||
|
||||
public:
|
||||
InterpolateLinearFloat();
|
||||
|
||||
virtual void resetRegisters();
|
||||
|
||||
int getLatency() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+181
-185
@@ -1,185 +1,181 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sample interpolation routine using 8-tap band-limited Shannon interpolation
|
||||
/// with kaiser window.
|
||||
///
|
||||
/// Notice. This algorithm is remarkably much heavier than linear or cubic
|
||||
/// interpolation, and not remarkably better than cubic algorithm. Thus mostly
|
||||
/// for experimental purposes
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $Id: InterpolateShannon.cpp 195 2014-04-06 15:57:21Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <math.h>
|
||||
#include "InterpolateShannon.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
|
||||
/// Kaiser window with beta = 2.0
|
||||
/// Values scaled down by 5% to avoid overflows
|
||||
static const double _kaiser8[8] =
|
||||
{
|
||||
0.41778693317814,
|
||||
0.64888025049173,
|
||||
0.83508562409944,
|
||||
0.93887857733412,
|
||||
0.93887857733412,
|
||||
0.83508562409944,
|
||||
0.64888025049173,
|
||||
0.41778693317814
|
||||
};
|
||||
|
||||
|
||||
InterpolateShannon::InterpolateShannon()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
void InterpolateShannon::resetRegisters()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
#define PI 3.1415926536
|
||||
#define sinc(x) (sin(PI * (x)) / (PI * (x)))
|
||||
|
||||
/// Transpose mono audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateShannon::transposeMono(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 8;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
double out;
|
||||
assert(fract < 1.0);
|
||||
|
||||
out = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
|
||||
out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
|
||||
out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
|
||||
if (fract < 1e-6)
|
||||
{
|
||||
out += psrc[3] * _kaiser8[3]; // sinc(0) = 1
|
||||
}
|
||||
else
|
||||
{
|
||||
out += psrc[3] * sinc(- fract) * _kaiser8[3];
|
||||
}
|
||||
out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
|
||||
out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
|
||||
out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
|
||||
out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
|
||||
|
||||
pdest[i] = (SAMPLETYPE)out;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 8;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
double out0, out1, w;
|
||||
assert(fract < 1.0);
|
||||
|
||||
w = sinc(-3.0 - fract) * _kaiser8[0];
|
||||
out0 = psrc[0] * w; out1 = psrc[1] * w;
|
||||
w = sinc(-2.0 - fract) * _kaiser8[1];
|
||||
out0 += psrc[2] * w; out1 += psrc[3] * w;
|
||||
w = sinc(-1.0 - fract) * _kaiser8[2];
|
||||
out0 += psrc[4] * w; out1 += psrc[5] * w;
|
||||
w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract)); // sinc(0) = 1
|
||||
out0 += psrc[6] * w; out1 += psrc[7] * w;
|
||||
w = sinc( 1.0 - fract) * _kaiser8[4];
|
||||
out0 += psrc[8] * w; out1 += psrc[9] * w;
|
||||
w = sinc( 2.0 - fract) * _kaiser8[5];
|
||||
out0 += psrc[10] * w; out1 += psrc[11] * w;
|
||||
w = sinc( 3.0 - fract) * _kaiser8[6];
|
||||
out0 += psrc[12] * w; out1 += psrc[13] * w;
|
||||
w = sinc( 4.0 - fract) * _kaiser8[7];
|
||||
out0 += psrc[14] * w; out1 += psrc[15] * w;
|
||||
|
||||
pdest[2*i] = (SAMPLETYPE)out0;
|
||||
pdest[2*i+1] = (SAMPLETYPE)out1;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += 2*whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
// not implemented
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sample interpolation routine using 8-tap band-limited Shannon interpolation
|
||||
/// with kaiser window.
|
||||
///
|
||||
/// Notice. This algorithm is remarkably much heavier than linear or cubic
|
||||
/// interpolation, and not remarkably better than cubic algorithm. Thus mostly
|
||||
/// for experimental purposes
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <math.h>
|
||||
#include "InterpolateShannon.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
|
||||
/// Kaiser window with beta = 2.0
|
||||
/// Values scaled down by 5% to avoid overflows
|
||||
static const double _kaiser8[8] =
|
||||
{
|
||||
0.41778693317814,
|
||||
0.64888025049173,
|
||||
0.83508562409944,
|
||||
0.93887857733412,
|
||||
0.93887857733412,
|
||||
0.83508562409944,
|
||||
0.64888025049173,
|
||||
0.41778693317814
|
||||
};
|
||||
|
||||
|
||||
InterpolateShannon::InterpolateShannon()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
void InterpolateShannon::resetRegisters()
|
||||
{
|
||||
fract = 0;
|
||||
}
|
||||
|
||||
|
||||
#define PI 3.1415926536
|
||||
#define sinc(x) (sin(PI * (x)) / (PI * (x)))
|
||||
|
||||
/// Transpose mono audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateShannon::transposeMono(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 8;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
double out;
|
||||
assert(fract < 1.0);
|
||||
|
||||
out = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
|
||||
out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
|
||||
out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
|
||||
if (fract < 1e-6)
|
||||
{
|
||||
out += psrc[3] * _kaiser8[3]; // sinc(0) = 1
|
||||
}
|
||||
else
|
||||
{
|
||||
out += psrc[3] * sinc(- fract) * _kaiser8[3];
|
||||
}
|
||||
out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
|
||||
out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
|
||||
out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
|
||||
out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
|
||||
|
||||
pdest[i] = (SAMPLETYPE)out;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest,
|
||||
const SAMPLETYPE *psrc,
|
||||
int &srcSamples)
|
||||
{
|
||||
int i;
|
||||
int srcSampleEnd = srcSamples - 8;
|
||||
int srcCount = 0;
|
||||
|
||||
i = 0;
|
||||
while (srcCount < srcSampleEnd)
|
||||
{
|
||||
double out0, out1, w;
|
||||
assert(fract < 1.0);
|
||||
|
||||
w = sinc(-3.0 - fract) * _kaiser8[0];
|
||||
out0 = psrc[0] * w; out1 = psrc[1] * w;
|
||||
w = sinc(-2.0 - fract) * _kaiser8[1];
|
||||
out0 += psrc[2] * w; out1 += psrc[3] * w;
|
||||
w = sinc(-1.0 - fract) * _kaiser8[2];
|
||||
out0 += psrc[4] * w; out1 += psrc[5] * w;
|
||||
w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract)); // sinc(0) = 1
|
||||
out0 += psrc[6] * w; out1 += psrc[7] * w;
|
||||
w = sinc( 1.0 - fract) * _kaiser8[4];
|
||||
out0 += psrc[8] * w; out1 += psrc[9] * w;
|
||||
w = sinc( 2.0 - fract) * _kaiser8[5];
|
||||
out0 += psrc[10] * w; out1 += psrc[11] * w;
|
||||
w = sinc( 3.0 - fract) * _kaiser8[6];
|
||||
out0 += psrc[12] * w; out1 += psrc[13] * w;
|
||||
w = sinc( 4.0 - fract) * _kaiser8[7];
|
||||
out0 += psrc[14] * w; out1 += psrc[15] * w;
|
||||
|
||||
pdest[2*i] = (SAMPLETYPE)out0;
|
||||
pdest[2*i+1] = (SAMPLETYPE)out1;
|
||||
i ++;
|
||||
|
||||
// update position fraction
|
||||
fract += rate;
|
||||
// update whole positions
|
||||
int whole = (int)fract;
|
||||
fract -= whole;
|
||||
psrc += 2*whole;
|
||||
srcCount += whole;
|
||||
}
|
||||
srcSamples = srcCount;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/// Transpose stereo audio. Returns number of produced output samples, and
|
||||
/// updates "srcSamples" to amount of consumed source samples
|
||||
int InterpolateShannon::transposeMulti(SAMPLETYPE *,
|
||||
const SAMPLETYPE *,
|
||||
int &)
|
||||
{
|
||||
// not implemented
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+74
-72
@@ -1,72 +1,74 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sample interpolation routine using 8-tap band-limited Shannon interpolation
|
||||
/// with kaiser window.
|
||||
///
|
||||
/// Notice. This algorithm is remarkably much heavier than linear or cubic
|
||||
/// interpolation, and not remarkably better than cubic algorithm. Thus mostly
|
||||
/// for experimental purposes
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $Id: InterpolateShannon.h 225 2015-07-26 14:45:48Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _InterpolateShannon_H_
|
||||
#define _InterpolateShannon_H_
|
||||
|
||||
#include "RateTransposer.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class InterpolateShannon : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
void resetRegisters();
|
||||
int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
int transposeMulti(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples);
|
||||
|
||||
double fract;
|
||||
|
||||
public:
|
||||
InterpolateShannon();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sample interpolation routine using 8-tap band-limited Shannon interpolation
|
||||
/// with kaiser window.
|
||||
///
|
||||
/// Notice. This algorithm is remarkably much heavier than linear or cubic
|
||||
/// interpolation, and not remarkably better than cubic algorithm. Thus mostly
|
||||
/// for experimental purposes
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _InterpolateShannon_H_
|
||||
#define _InterpolateShannon_H_
|
||||
|
||||
#include "RateTransposer.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class InterpolateShannon : public TransposerBase
|
||||
{
|
||||
protected:
|
||||
int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
int transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
int transposeMulti(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) override;
|
||||
|
||||
double fract;
|
||||
|
||||
public:
|
||||
InterpolateShannon();
|
||||
|
||||
void resetRegisters() override;
|
||||
|
||||
virtual int getLatency() const override
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Vendored
+3
-12
@@ -11,13 +11,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-05-18 18:22:02 +0300 (Mon, 18 May 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: PeakFinder.cpp 213 2015-05-18 15:22:02Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -149,7 +142,7 @@ int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, i
|
||||
peaklevel = data[peakpos];
|
||||
assert(peaklevel >= level);
|
||||
pos = peakpos;
|
||||
while ((pos >= minPos) && (pos < maxPos))
|
||||
while ((pos >= minPos) && (pos + direction < maxPos))
|
||||
{
|
||||
if (data[pos + direction] < level) return pos; // crossing found
|
||||
pos += direction;
|
||||
@@ -178,7 +171,6 @@ double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// get exact center of peak near given position by calculating local mass of center
|
||||
double PeakFinder::getPeakCenter(const float *data, int peakpos) const
|
||||
{
|
||||
@@ -218,7 +210,6 @@ double PeakFinder::getPeakCenter(const float *data, int peakpos) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
|
||||
{
|
||||
|
||||
@@ -249,12 +240,12 @@ double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
|
||||
// - sometimes the highest peak can be Nth harmonic of the true base peak yet
|
||||
// just a slightly higher than the true base
|
||||
|
||||
for (i = 3; i < 10; i ++)
|
||||
for (i = 1; i < 3; i ++)
|
||||
{
|
||||
double peaktmp, harmonic;
|
||||
int i1,i2;
|
||||
|
||||
harmonic = (double)i * 0.5;
|
||||
harmonic = (double)pow(2.0, i);
|
||||
peakpos = (int)(highPeak / harmonic + 0.5f);
|
||||
if (peakpos < minPos) break;
|
||||
peakpos = findTop(data, peakpos); // seek true local maximum index
|
||||
|
||||
Vendored
+2
-9
@@ -9,13 +9,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2011-12-30 22:33:46 +0200 (Fri, 30 Dec 2011) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: PeakFinder.h 132 2011-12-30 20:33:46Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -51,8 +44,8 @@ protected:
|
||||
|
||||
/// Calculates the mass center between given vector items.
|
||||
double calcMassCenter(const float *data, ///< Data vector.
|
||||
int firstPos, ///< Index of first vector item beloging to the peak.
|
||||
int lastPos ///< Index of last vector item beloging to the peak.
|
||||
int firstPos, ///< Index of first vector item belonging to the peak.
|
||||
int lastPos ///< Index of last vector item belonging to the peak.
|
||||
) const;
|
||||
|
||||
/// Finds the data vector index where the monotoniously decreasing signal crosses the
|
||||
|
||||
+30
-19
@@ -10,13 +10,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: RateTransposer.cpp 225 2015-07-26 14:45:48Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -57,15 +50,21 @@ TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
|
||||
// Constructor
|
||||
RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
|
||||
{
|
||||
bUseAAFilter = true;
|
||||
bUseAAFilter =
|
||||
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||
true;
|
||||
#else
|
||||
// Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
|
||||
false;
|
||||
#endif
|
||||
|
||||
// Instantiates the anti-alias filter
|
||||
pAAFilter = new AAFilter(64);
|
||||
pTransposer = TransposerBase::newInstance();
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RateTransposer::~RateTransposer()
|
||||
{
|
||||
delete pAAFilter;
|
||||
@@ -73,11 +72,14 @@ RateTransposer::~RateTransposer()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
|
||||
void RateTransposer::enableAAFilter(bool newMode)
|
||||
{
|
||||
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||
// Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
|
||||
bUseAAFilter = newMode;
|
||||
clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +96,6 @@ AAFilter *RateTransposer::getAAFilter()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
|
||||
// iRate, larger faster iRates.
|
||||
void RateTransposer::setRate(double newRate)
|
||||
@@ -130,8 +131,6 @@ void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||
// the 'set_returnBuffer_size' function.
|
||||
void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||
{
|
||||
uint count;
|
||||
|
||||
if (nSamples == 0) return;
|
||||
|
||||
// Store samples to input buffer
|
||||
@@ -141,7 +140,7 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||
// the filter
|
||||
if (bUseAAFilter == false)
|
||||
{
|
||||
count = pTransposer->transpose(outputBuffer, inputBuffer);
|
||||
(void)pTransposer->transpose(outputBuffer, inputBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -177,11 +176,10 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||
// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void RateTransposer::setChannels(int nChannels)
|
||||
{
|
||||
assert(nChannels > 0);
|
||||
if (!verifyNumberOfChannels(nChannels) ||
|
||||
(pTransposer->numChannels == nChannels)) return;
|
||||
|
||||
if (pTransposer->numChannels == nChannels) return;
|
||||
pTransposer->setChannels(nChannels);
|
||||
|
||||
inputBuffer.setChannels(nChannels);
|
||||
midBuffer.setChannels(nChannels);
|
||||
outputBuffer.setChannels(nChannels);
|
||||
@@ -194,6 +192,11 @@ void RateTransposer::clear()
|
||||
outputBuffer.clear();
|
||||
midBuffer.clear();
|
||||
inputBuffer.clear();
|
||||
pTransposer->resetRegisters();
|
||||
|
||||
// prefill buffer to avoid losing first samples at beginning of stream
|
||||
int prefill = getLatency();
|
||||
inputBuffer.addSilent(prefill);
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +211,14 @@ int RateTransposer::isEmpty() const
|
||||
}
|
||||
|
||||
|
||||
/// Return approximate initial input-output latency
|
||||
int RateTransposer::getLatency() const
|
||||
{
|
||||
return pTransposer->getLatency() +
|
||||
((bUseAAFilter) ? (pAAFilter->getLength() / 2) : 0);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TransposerBase - Base class for interpolation
|
||||
@@ -280,7 +291,7 @@ void TransposerBase::setRate(double newRate)
|
||||
TransposerBase *TransposerBase::newInstance()
|
||||
{
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
// Notice: For integer arithmetics support only linear algorithm (due to simplest calculus)
|
||||
// Notice: For integer arithmetic support only linear algorithm (due to simplest calculus)
|
||||
return ::new InterpolateLinearInteger;
|
||||
#else
|
||||
switch (algorithm)
|
||||
@@ -296,7 +307,7 @@ TransposerBase *TransposerBase::newInstance()
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+10
-25
@@ -14,13 +14,6 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: RateTransposer.h 225 2015-07-26 14:45:48Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
@@ -66,8 +59,6 @@ public:
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void resetRegisters() = 0;
|
||||
|
||||
virtual int transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
int &srcSamples) = 0;
|
||||
@@ -90,6 +81,9 @@ public:
|
||||
virtual int transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src);
|
||||
virtual void setRate(double newRate);
|
||||
virtual void setChannels(int channels);
|
||||
virtual int getLatency() const = 0;
|
||||
|
||||
virtual void resetRegisters() = 0;
|
||||
|
||||
// static factory function
|
||||
static TransposerBase *newInstance();
|
||||
@@ -130,23 +124,11 @@ protected:
|
||||
|
||||
public:
|
||||
RateTransposer();
|
||||
virtual ~RateTransposer();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we're to use integer or floating point arithmetics.
|
||||
// static void *operator new(size_t s);
|
||||
|
||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
||||
/// This function automatically chooses a correct implementation, depending on if
|
||||
/// integer ot floating point arithmetics are to be used.
|
||||
// static RateTransposer *newInstance();
|
||||
virtual ~RateTransposer() override;
|
||||
|
||||
/// Returns the output buffer object
|
||||
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
||||
|
||||
/// Returns the store buffer object
|
||||
// FIFOSamplePipe *getStore() { return &storeBuffer; };
|
||||
|
||||
/// Return anti-alias filter object
|
||||
AAFilter *getAAFilter();
|
||||
|
||||
@@ -165,13 +147,16 @@ public:
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object.
|
||||
void putSamples(const SAMPLETYPE *samples, uint numSamples);
|
||||
void putSamples(const SAMPLETYPE *samples, uint numSamples) override;
|
||||
|
||||
/// Clears all the samples in the object
|
||||
void clear();
|
||||
void clear() override;
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
int isEmpty() const;
|
||||
int isEmpty() const override;
|
||||
|
||||
/// Return approximate initial input-output latency
|
||||
int getLatency() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user