* Pull across from main repo: Fix silent channel of output when processing with band-limited transients option; include libresample support. Also update copyright dates.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
186
src/dsp/FFT.cpp
186
src/dsp/FFT.cpp
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
@@ -59,18 +59,22 @@ public:
|
||||
virtual void initDouble() = 0;
|
||||
|
||||
virtual void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) = 0;
|
||||
virtual void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) = 0;
|
||||
virtual void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) = 0;
|
||||
virtual void forwardMagnitude(const double *R__ realIn, double *R__ magOut) = 0;
|
||||
|
||||
virtual void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) = 0;
|
||||
virtual void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) = 0;
|
||||
virtual void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) = 0;
|
||||
virtual void forwardMagnitude(const float *R__ realIn, float *R__ magOut) = 0;
|
||||
|
||||
virtual void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) = 0;
|
||||
virtual void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) = 0;
|
||||
virtual void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) = 0;
|
||||
virtual void inverseCepstral(const double *R__ magIn, double *R__ cepOut) = 0;
|
||||
|
||||
virtual void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) = 0;
|
||||
virtual void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) = 0;
|
||||
virtual void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) = 0;
|
||||
virtual void inverseCepstral(const float *R__ magIn, float *R__ cepOut) = 0;
|
||||
|
||||
@@ -162,10 +166,9 @@ public:
|
||||
|
||||
~D_FFTW() {
|
||||
if (m_fplanf) {
|
||||
m_commonMutex.lock();
|
||||
bool save = false;
|
||||
m_extantMutex.lock();
|
||||
if (m_extantf > 0 && --m_extantf == 0) save = true;
|
||||
m_extantMutex.unlock();
|
||||
#ifndef FFTW_DOUBLE_ONLY
|
||||
if (save) saveWisdom('f');
|
||||
#endif
|
||||
@@ -176,12 +179,12 @@ public:
|
||||
#ifdef FFTW_DOUBLE_ONLY
|
||||
if (m_frb) fftw_free(m_frb);
|
||||
#endif
|
||||
m_commonMutex.unlock();
|
||||
}
|
||||
if (m_dplanf) {
|
||||
m_commonMutex.lock();
|
||||
bool save = false;
|
||||
m_extantMutex.lock();
|
||||
if (m_extantd > 0 && --m_extantd == 0) save = true;
|
||||
m_extantMutex.unlock();
|
||||
#ifndef FFTW_FLOAT_ONLY
|
||||
if (save) saveWisdom('d');
|
||||
#endif
|
||||
@@ -192,15 +195,15 @@ public:
|
||||
#ifdef FFTW_FLOAT_ONLY
|
||||
if (m_drb) fftwf_free(m_drb);
|
||||
#endif
|
||||
m_commonMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void initFloat() {
|
||||
if (m_fplanf) return;
|
||||
bool load = false;
|
||||
m_extantMutex.lock();
|
||||
m_commonMutex.lock();
|
||||
if (m_extantf++ == 0) load = true;
|
||||
m_extantMutex.unlock();
|
||||
#ifdef FFTW_DOUBLE_ONLY
|
||||
if (load) loadWisdom('d');
|
||||
#else
|
||||
@@ -213,14 +216,14 @@ public:
|
||||
(m_size, m_fbuf, m_fpacked, FFTW_MEASURE);
|
||||
m_fplani = fftwf_plan_dft_c2r_1d
|
||||
(m_size, m_fpacked, m_fbuf, FFTW_MEASURE);
|
||||
m_commonMutex.unlock();
|
||||
}
|
||||
|
||||
void initDouble() {
|
||||
if (m_dplanf) return;
|
||||
bool load = false;
|
||||
m_extantMutex.lock();
|
||||
m_commonMutex.lock();
|
||||
if (m_extantd++ == 0) load = true;
|
||||
m_extantMutex.unlock();
|
||||
#ifdef FFTW_FLOAT_ONLY
|
||||
if (load) loadWisdom('f');
|
||||
#else
|
||||
@@ -233,6 +236,7 @@ public:
|
||||
(m_size, m_dbuf, m_dpacked, FFTW_MEASURE);
|
||||
m_dplani = fftw_plan_dft_c2r_1d
|
||||
(m_size, m_dpacked, m_dbuf, FFTW_MEASURE);
|
||||
m_commonMutex.unlock();
|
||||
}
|
||||
|
||||
void loadWisdom(char type) { wisdom(false, type); }
|
||||
@@ -361,6 +365,20 @@ public:
|
||||
unpackDouble(realOut, imagOut);
|
||||
}
|
||||
|
||||
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) {
|
||||
if (!m_dplanf) initDouble();
|
||||
const int sz = m_size;
|
||||
fft_double_type *const R__ dbuf = m_dbuf;
|
||||
#ifndef FFTW_FLOAT_ONLY
|
||||
if (realIn != dbuf)
|
||||
#endif
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
dbuf[i] = realIn[i];
|
||||
}
|
||||
fftw_execute(m_dplanf);
|
||||
v_convert(complexOut, (fft_double_type *)m_dpacked, sz + 2);
|
||||
}
|
||||
|
||||
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
|
||||
if (!m_dplanf) initDouble();
|
||||
fft_double_type *const R__ dbuf = m_dbuf;
|
||||
@@ -414,6 +432,20 @@ public:
|
||||
unpackFloat(realOut, imagOut);
|
||||
}
|
||||
|
||||
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) {
|
||||
if (!m_fplanf) initFloat();
|
||||
fft_float_type *const R__ fbuf = m_fbuf;
|
||||
const int sz = m_size;
|
||||
#ifndef FFTW_DOUBLE_ONLY
|
||||
if (realIn != fbuf)
|
||||
#endif
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
fbuf[i] = realIn[i];
|
||||
}
|
||||
fftwf_execute(m_fplanf);
|
||||
v_convert(complexOut, (fft_float_type *)m_fpacked, sz + 2);
|
||||
}
|
||||
|
||||
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
|
||||
if (!m_fplanf) initFloat();
|
||||
fft_float_type *const R__ fbuf = m_fbuf;
|
||||
@@ -467,6 +499,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) {
|
||||
if (!m_dplanf) initDouble();
|
||||
v_copy((double *)m_dpacked, complexIn, m_size + 2);
|
||||
fftw_execute(m_dplani);
|
||||
const int sz = m_size;
|
||||
fft_double_type *const R__ dbuf = m_dbuf;
|
||||
#ifndef FFTW_FLOAT_ONLY
|
||||
if (realOut != dbuf)
|
||||
#endif
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
realOut[i] = dbuf[i];
|
||||
}
|
||||
}
|
||||
|
||||
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
|
||||
if (!m_dplanf) initDouble();
|
||||
const int hs = m_size/2;
|
||||
@@ -523,6 +569,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) {
|
||||
if (!m_fplanf) initFloat();
|
||||
v_copy((float *)m_fpacked, complexIn, m_size + 2);
|
||||
fftwf_execute(m_fplani);
|
||||
const int sz = m_size;
|
||||
fft_float_type *const R__ fbuf = m_fbuf;
|
||||
#ifndef FFTW_DOUBLE_ONLY
|
||||
if (realOut != fbuf)
|
||||
#endif
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
realOut[i] = fbuf[i];
|
||||
}
|
||||
}
|
||||
|
||||
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
|
||||
if (!m_fplanf) initFloat();
|
||||
const int hs = m_size/2;
|
||||
@@ -607,7 +667,7 @@ private:
|
||||
const int m_size;
|
||||
static int m_extantf;
|
||||
static int m_extantd;
|
||||
static Mutex m_extantMutex;
|
||||
static Mutex m_commonMutex;
|
||||
};
|
||||
|
||||
int
|
||||
@@ -617,7 +677,7 @@ int
|
||||
D_FFTW::m_extantd = 0;
|
||||
|
||||
Mutex
|
||||
D_FFTW::m_extantMutex;
|
||||
D_FFTW::m_commonMutex;
|
||||
|
||||
#endif /* HAVE_FFTW3 */
|
||||
|
||||
@@ -720,14 +780,18 @@ public:
|
||||
|
||||
void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) {
|
||||
|
||||
for (int i = 0; i < m_size; ++i) {
|
||||
m_fbuf[i] = float(realIn[i]);
|
||||
}
|
||||
|
||||
v_convert(m_fbuf, realIn, m_size);
|
||||
kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
|
||||
unpackDouble(realOut, imagOut);
|
||||
}
|
||||
|
||||
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) {
|
||||
|
||||
v_convert(m_fbuf, realIn, m_size);
|
||||
kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
|
||||
v_convert(complexOut, (float *)m_fpacked, m_size + 2);
|
||||
}
|
||||
|
||||
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
|
||||
|
||||
for (int i = 0; i < m_size; ++i) {
|
||||
@@ -770,6 +834,11 @@ public:
|
||||
unpackFloat(realOut, imagOut);
|
||||
}
|
||||
|
||||
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) {
|
||||
|
||||
kiss_fftr(m_fplanf, realIn, (kiss_fft_cpx *)complexOut);
|
||||
}
|
||||
|
||||
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
|
||||
|
||||
kiss_fftr(m_fplanf, realIn, m_fpacked);
|
||||
@@ -809,6 +878,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) {
|
||||
|
||||
v_convert((float *)m_fpacked, complexIn, m_size + 2);
|
||||
|
||||
kiss_fftri(m_fplani, m_fpacked, m_fbuf);
|
||||
|
||||
for (int i = 0; i < m_size; ++i) {
|
||||
realOut[i] = m_fbuf[i];
|
||||
}
|
||||
}
|
||||
|
||||
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
|
||||
|
||||
const int hs = m_size/2;
|
||||
@@ -847,6 +927,12 @@ public:
|
||||
kiss_fftri(m_fplani, m_fpacked, realOut);
|
||||
}
|
||||
|
||||
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) {
|
||||
|
||||
v_copy((float *)m_fpacked, complexIn, m_size + 2);
|
||||
kiss_fftri(m_fplani, m_fpacked, realOut);
|
||||
}
|
||||
|
||||
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
|
||||
|
||||
const int hs = m_size/2;
|
||||
@@ -952,6 +1038,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) {
|
||||
basefft(false, realIn, 0, m_c, m_d);
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) complexOut[i*2] = m_c[i];
|
||||
for (int i = 0; i <= hs; ++i) complexOut[i*2+1] = m_d[i];
|
||||
}
|
||||
|
||||
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
|
||||
basefft(false, realIn, 0, m_c, m_d);
|
||||
const int hs = m_size/2;
|
||||
@@ -979,6 +1072,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) {
|
||||
for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
|
||||
basefft(false, m_a, 0, m_c, m_d);
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) complexOut[i*2] = m_c[i];
|
||||
for (int i = 0; i <= hs; ++i) complexOut[i*2+1] = m_d[i];
|
||||
}
|
||||
|
||||
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
|
||||
for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
|
||||
basefft(false, m_a, 0, m_c, m_d);
|
||||
@@ -1013,6 +1114,21 @@ public:
|
||||
basefft(true, m_a, m_b, realOut, m_d);
|
||||
}
|
||||
|
||||
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) {
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
double real = complexIn[i*2];
|
||||
double imag = complexIn[i*2+1];
|
||||
m_a[i] = real;
|
||||
m_b[i] = imag;
|
||||
if (i > 0) {
|
||||
m_a[m_size-i] = real;
|
||||
m_b[m_size-i] = -imag;
|
||||
}
|
||||
}
|
||||
basefft(true, m_a, m_b, realOut, m_d);
|
||||
}
|
||||
|
||||
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
@@ -1058,6 +1174,22 @@ public:
|
||||
for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i];
|
||||
}
|
||||
|
||||
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) {
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
float real = complexIn[i*2];
|
||||
float imag = complexIn[i*2+1];
|
||||
m_a[i] = real;
|
||||
m_b[i] = imag;
|
||||
if (i > 0) {
|
||||
m_a[m_size-i] = real;
|
||||
m_b[m_size-i] = -imag;
|
||||
}
|
||||
}
|
||||
basefft(true, m_a, m_b, m_c, m_d);
|
||||
for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i];
|
||||
}
|
||||
|
||||
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
@@ -1327,6 +1459,12 @@ FFT::forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut)
|
||||
d->forward(realIn, realOut, imagOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardInterleaved(const double *R__ realIn, double *R__ complexOut)
|
||||
{
|
||||
d->forwardInterleaved(realIn, complexOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut)
|
||||
{
|
||||
@@ -1345,6 +1483,12 @@ FFT::forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut)
|
||||
d->forward(realIn, realOut, imagOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardInterleaved(const float *R__ realIn, float *R__ complexOut)
|
||||
{
|
||||
d->forwardInterleaved(realIn, complexOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut)
|
||||
{
|
||||
@@ -1363,6 +1507,12 @@ FFT::inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ rea
|
||||
d->inverse(realIn, imagIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverseInterleaved(const double *R__ complexIn, double *R__ realOut)
|
||||
{
|
||||
d->inverseInterleaved(complexIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut)
|
||||
{
|
||||
@@ -1381,6 +1531,12 @@ FFT::inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOu
|
||||
d->inverse(realIn, imagIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverseInterleaved(const float *R__ complexIn, float *R__ realOut)
|
||||
{
|
||||
d->inverseInterleaved(complexIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
@@ -30,11 +30,14 @@ class FFTImpl;
|
||||
* complex conjugates half is omitted), so the "complex" arrays need
|
||||
* room for size/2+1 elements.
|
||||
*
|
||||
* Not thread safe: use a separate instance per thread, or use a mutex.
|
||||
* The "interleaved" functions use the format sometimes called CCS --
|
||||
* size/2+1 real+imaginary pairs. So, the array elements at indices 1
|
||||
* and size+1 will always be zero (since the signal is real).
|
||||
*
|
||||
* This class is reentrant but not thread safe: use a separate
|
||||
* instance per thread, or use a mutex.
|
||||
*/
|
||||
|
||||
//!!! it would be nice if we could redefine forwardMagnitude as forwardPower (i.e. square of magnitude)
|
||||
|
||||
class FFT
|
||||
{
|
||||
public:
|
||||
@@ -44,18 +47,22 @@ public:
|
||||
~FFT();
|
||||
|
||||
void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut);
|
||||
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut);
|
||||
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut);
|
||||
void forwardMagnitude(const double *R__ realIn, double *R__ magOut);
|
||||
|
||||
void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut);
|
||||
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut);
|
||||
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut);
|
||||
void forwardMagnitude(const float *R__ realIn, float *R__ magOut);
|
||||
|
||||
void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut);
|
||||
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut);
|
||||
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut);
|
||||
void inverseCepstral(const double *R__ magIn, double *R__ cepOut);
|
||||
|
||||
void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut);
|
||||
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut);
|
||||
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut);
|
||||
void inverseCepstral(const float *R__ magIn, float *R__ cepOut);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
@@ -23,9 +23,20 @@
|
||||
#include "system/Allocators.h"
|
||||
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
#include <samplerate.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
#include <libresample.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_LIBSAMPLERATE
|
||||
#ifndef HAVE_LIBRESAMPLE
|
||||
#error No resampler implementation selected!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace RubberBand {
|
||||
|
||||
@@ -54,6 +65,7 @@ public:
|
||||
namespace Resamplers {
|
||||
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
|
||||
class D_SRC : public ResamplerImpl
|
||||
{
|
||||
@@ -130,8 +142,8 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
D_SRC::~D_SRC()
|
||||
{
|
||||
src_delete(m_src);
|
||||
deallocate<float>(m_iin);
|
||||
deallocate<float>(m_iout);
|
||||
deallocate(m_iin);
|
||||
deallocate(m_iout);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -222,6 +234,195 @@ D_SRC::reset()
|
||||
src_reset(m_src);
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBSAMPLERATE */
|
||||
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
|
||||
class D_Resample : public ResamplerImpl
|
||||
{
|
||||
public:
|
||||
D_Resample(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int m_debugLevel);
|
||||
~D_Resample();
|
||||
|
||||
int resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final);
|
||||
|
||||
int resampleInterleaved(const float *const R__ in,
|
||||
float *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final);
|
||||
|
||||
int getChannelCount() const { return m_channels; }
|
||||
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
void *m_src;
|
||||
float *m_iin;
|
||||
float *m_iout;
|
||||
float m_lastRatio;
|
||||
int m_channels;
|
||||
int m_iinsize;
|
||||
int m_ioutsize;
|
||||
int m_debugLevel;
|
||||
};
|
||||
|
||||
D_Resample::D_Resample(Resampler::Quality quality, int channels, int maxBufferSize,
|
||||
int debugLevel) :
|
||||
m_src(0),
|
||||
m_iin(0),
|
||||
m_iout(0),
|
||||
m_lastRatio(1.f),
|
||||
m_channels(channels),
|
||||
m_iinsize(0),
|
||||
m_ioutsize(0),
|
||||
m_debugLevel(debugLevel)
|
||||
{
|
||||
if (m_debugLevel > 0) {
|
||||
std::cerr << "Resampler::Resampler: using libresample implementation"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
float min_factor = 0.125f;
|
||||
float max_factor = 8.0f;
|
||||
|
||||
m_src = resample_open(quality == Resampler::Best ? 1 : 0, min_factor, max_factor);
|
||||
|
||||
if (!m_src) {
|
||||
std::cerr << "Resampler::Resampler: failed to create libresample resampler: "
|
||||
<< std::endl;
|
||||
throw Resampler::ImplementationError; //!!! of course, need to catch this!
|
||||
}
|
||||
|
||||
if (maxBufferSize > 0 && m_channels > 1) {
|
||||
m_iinsize = maxBufferSize * m_channels;
|
||||
m_ioutsize = maxBufferSize * m_channels * 2;
|
||||
m_iin = allocate<float>(m_iinsize);
|
||||
m_iout = allocate<float>(m_ioutsize);
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
D_Resample::~D_Resample()
|
||||
{
|
||||
resample_close(m_src);
|
||||
if (m_iinsize > 0) {
|
||||
deallocate(m_iin);
|
||||
}
|
||||
if (m_ioutsize > 0) {
|
||||
deallocate(m_iout);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
D_Resample::resample(const float *const R__ *const R__ in,
|
||||
float *const R__ *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
float *data_in;
|
||||
float *data_out;
|
||||
int input_frames, output_frames, end_of_input, source_used;
|
||||
float src_ratio;
|
||||
|
||||
int outcount = lrintf(ceilf(incount * ratio));
|
||||
|
||||
if (m_channels == 1) {
|
||||
data_in = const_cast<float *>(*in); //!!!???
|
||||
data_out = *out;
|
||||
} else {
|
||||
if (incount * m_channels > m_iinsize) {
|
||||
m_iin = reallocate<float>(m_iin, m_iinsize, incount * m_channels);
|
||||
m_iinsize = incount * m_channels;
|
||||
}
|
||||
if (outcount * m_channels > m_ioutsize) {
|
||||
m_iout = reallocate<float>(m_iout, m_ioutsize, outcount * m_channels);
|
||||
m_ioutsize = outcount * m_channels;
|
||||
}
|
||||
v_interleave(m_iin, in, m_channels, incount);
|
||||
data_in = m_iin;
|
||||
data_out = m_iout;
|
||||
}
|
||||
|
||||
input_frames = incount;
|
||||
output_frames = outcount;
|
||||
src_ratio = ratio;
|
||||
end_of_input = (final ? 1 : 0);
|
||||
|
||||
int output_frames_gen = resample_process(m_src,
|
||||
src_ratio,
|
||||
data_in,
|
||||
input_frames,
|
||||
end_of_input,
|
||||
&source_used,
|
||||
data_out,
|
||||
output_frames);
|
||||
|
||||
if (output_frames_gen < 0) {
|
||||
std::cerr << "Resampler::process: libresample error: "
|
||||
<< std::endl;
|
||||
throw Resampler::ImplementationError; //!!! of course, need to catch this!
|
||||
}
|
||||
|
||||
if (m_channels > 1) {
|
||||
v_deinterleave(out, m_iout, m_channels, output_frames_gen);
|
||||
}
|
||||
|
||||
m_lastRatio = ratio;
|
||||
|
||||
return output_frames_gen;
|
||||
}
|
||||
|
||||
int
|
||||
D_Resample::resampleInterleaved(const float *const R__ in,
|
||||
float *const R__ out,
|
||||
int incount,
|
||||
float ratio,
|
||||
bool final)
|
||||
{
|
||||
int input_frames, output_frames, end_of_input, source_used;
|
||||
float src_ratio;
|
||||
|
||||
int outcount = lrintf(ceilf(incount * ratio));
|
||||
|
||||
input_frames = incount;
|
||||
output_frames = outcount;
|
||||
src_ratio = ratio;
|
||||
end_of_input = (final ? 1 : 0);
|
||||
|
||||
int output_frames_gen = resample_process(m_src,
|
||||
src_ratio,
|
||||
const_cast<float *>(in),
|
||||
input_frames,
|
||||
end_of_input,
|
||||
&source_used,
|
||||
out,
|
||||
output_frames);
|
||||
|
||||
if (output_frames_gen < 0) {
|
||||
std::cerr << "Resampler::process: libresample error: "
|
||||
<< std::endl;
|
||||
throw Resampler::ImplementationError; //!!! of course, need to catch this!
|
||||
}
|
||||
|
||||
m_lastRatio = ratio;
|
||||
|
||||
return output_frames_gen;
|
||||
}
|
||||
|
||||
void
|
||||
D_Resample::reset()
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBRESAMPLE */
|
||||
|
||||
|
||||
} /* end namespace Resamplers */
|
||||
@@ -234,15 +435,30 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
switch (quality) {
|
||||
|
||||
case Resampler::Best:
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
m_method = 3;
|
||||
#endif
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
m_method = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Resampler::FastestTolerable:
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
m_method = 3;
|
||||
#endif
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
m_method = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Resampler::Fastest:
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
m_method = 3;
|
||||
#endif
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
m_method = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -262,7 +478,14 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
break;
|
||||
|
||||
case 1:
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
d = new Resamplers::D_SRC(quality, channels, maxBufferSize, debugLevel);
|
||||
#else
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -271,6 +494,17 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
<< std::endl;
|
||||
abort();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
#ifdef HAVE_LIBRESAMPLE
|
||||
d = new Resamplers::D_Resample(quality, channels, maxBufferSize, debugLevel);
|
||||
#else
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize << "): No implementation available!"
|
||||
<< std::endl;
|
||||
abort();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Rubber Band
|
||||
An audio time-stretching and pitch-shifting library.
|
||||
Copyright 2007-2010 Chris Cannam.
|
||||
Copyright 2007-2011 Chris Cannam.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
@@ -16,7 +16,6 @@
|
||||
#define _RUBBERBAND_WINDOW_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
|
||||
@@ -81,7 +80,6 @@ public:
|
||||
total += m_cache[i] * m_cache[i];
|
||||
}
|
||||
T rms = sqrt(total / m_size);
|
||||
std::cerr << "rms = " << rms << std::endl;
|
||||
return rms;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user