summaryrefslogtreecommitdiffstats
path: root/src/Resampler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Resampler.cpp')
-rw-r--r--src/Resampler.cpp164
1 files changed, 2 insertions, 162 deletions
diff --git a/src/Resampler.cpp b/src/Resampler.cpp
index f09a58d..38fea33 100644
--- a/src/Resampler.cpp
+++ b/src/Resampler.cpp
@@ -33,10 +33,8 @@
#include <stdexcept>
#include <assert.h>
-#if USE_FFTW
-# define FFT_REAL(x) x[0]
-# define FFT_IMAG(x) x[1]
-#endif
+#define FFT_REAL(x) x[0]
+#define FFT_IMAG(x) x[1]
template<class T>
T gcd(T a, T b)
@@ -64,44 +62,6 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) :
{
PDEBUG("Resampler::Resampler(%zu, %zu) @ %p\n", inputRate, outputRate, this);
-#if USE_FFTW
- fprintf(stderr, "This software uses the FFTW library.\n\n");
-#else
- fprintf(stderr, "This software uses KISS FFT.\n\n");
- fprintf(stderr, "Copyright (c) 2003-2004 Mark Borgerding\n"
- "\n"
- "All rights reserved.\n"
- "\n"
- "Redistribution and use in source and binary forms, with or "
- "without modification, are permitted provided that the following "
- "conditions are met:\n"
- "\n"
- " * Redistributions of source code must retain the above "
- "copyright notice, this list of conditions and the following "
- "disclaimer.\n"
- " * Redistributions in binary form must reproduce the above "
- "copyright notice, this list of conditions and the following "
- "disclaimer in the documentation and/or other materials provided "
- "with the distribution.\n"
- " * Neither the author nor the names of any contributors may be "
- "used to endorse or promote products derived from this software "
- "without specific prior written permission.\n"
- "\n"
- "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND "
- "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, "
- "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF "
- "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE "
- "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS "
- "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, "
- "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED "
- "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, "
- "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON "
- "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, "
- "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY "
- "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE "
- "POSSIBILITY OF SUCH DAMAGE.\n");
-#endif
-
size_t divisor = gcd(inputRate, outputRate);
L = outputRate / divisor;
M = inputRate / divisor;
@@ -128,7 +88,6 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) :
PDEBUG("Window[%zu] = %f\n", i, myWindow[i]);
}
-#if USE_FFTW
myFftIn = (FFT_TYPE*)fftwf_malloc(sizeof(FFT_TYPE) * myFftSizeIn);
myFront = (FFT_TYPE*)fftwf_malloc(sizeof(FFT_TYPE) * myFftSizeIn);
myFftPlan1 = fftwf_plan_dft_1d(myFftSizeIn,
@@ -143,16 +102,6 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) :
myBufferIn = (complexf*)fftwf_malloc(sizeof(FFT_TYPE) * myFftSizeIn / 2);
myBufferOut = (complexf*)fftwf_malloc(sizeof(FFT_TYPE) * myFftSizeOut / 2);
-#else
- myFftIn = (FFT_TYPE*)memalign(16, myFftSizeIn * sizeof(FFT_TYPE));
- myFftOut = (FFT_TYPE*)memalign(16, myFftSizeOut * sizeof(FFT_TYPE));
- myBufferIn = (complexf*)memalign(16, myFftSizeIn / 2 * sizeof(FFT_TYPE));
- myBufferOut = (complexf*)memalign(16, myFftSizeOut / 2 * sizeof(FFT_TYPE));
- myFront = (FFT_TYPE*)memalign(16, myFftSizeIn * sizeof(FFT_TYPE));
- myBack = (FFT_TYPE*)memalign(16, myFftSizeOut * sizeof(FFT_TYPE));
- myFftPlan1 = kiss_fft_alloc(myFftSizeIn, 0, NULL, NULL);
- myFftPlan2 = kiss_fft_alloc(myFftSizeOut, 1, NULL, NULL);
-#endif
memset(myBufferIn, 0, myFftSizeIn / 2 * sizeof(FFT_TYPE));
memset(myBufferOut, 0, myFftSizeOut / 2 * sizeof(FFT_TYPE));
@@ -163,7 +112,6 @@ Resampler::~Resampler()
{
PDEBUG("Resampler::~Resampler() @ %p\n", this);
-#if USE_FFTW
if (myFftPlan1 != NULL) { fftwf_free(myFftPlan1); }
if (myFftPlan2 != NULL) { fftwf_free(myFftPlan2); }
if (myFftIn != NULL) { fftwf_free(myFftIn); }
@@ -175,18 +123,6 @@ Resampler::~Resampler()
if (myWindow != NULL) { fftwf_free(myWindow); }
fftwf_destroy_plan(myFftPlan1);
fftwf_destroy_plan(myFftPlan2);
-#else
- if (myFftPlan1 != NULL) { free(myFftPlan1); }
- if (myFftPlan2 != NULL) { free(myFftPlan2); }
- if (myFftIn != NULL) { free(myFftIn); }
- if (myFftOut != NULL) { free(myFftOut); }
- if (myBufferIn != NULL) { free(myBufferIn); }
- if (myBufferOut != NULL) { free(myBufferOut); }
- if (myFront != NULL) { free(myFront); }
- if (myBack != NULL) { free(myBack); }
- if (myWindow != NULL) { free(myWindow); }
- kiss_fft_cleanup();
-#endif
}
@@ -201,93 +137,6 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
FFT_TYPE* out = reinterpret_cast<FFT_TYPE*>(dataOut->getData());
size_t sizeIn = dataIn->getLength() / sizeof(complexf);
-#if defined(USE_SIMD) && !USE_FFTW
- size_t sizeOut = dataOut->getLength() / sizeof(complexf);
-
- typedef struct {
- float r[4];
- float i[4];
- } fft_data;
- assert(sizeof(FFT_TYPE) == sizeof(fft_data));
- fft_data *fftDataIn = (fft_data*)myFftIn;
- fft_data *fftDataOut = (fft_data*)myFftOut;
- complexf *cplxIn = (complexf*)in;
- complexf *cplxOut = (complexf*)out;
- for (size_t i = 0, j = 0; i < sizeIn; ) {
- for (int k = 0; k < 4; ++k) {
- if (i < sizeIn) {
- for (size_t l = 0; l < myFftSizeIn / 2; ++l) {
- fftDataIn[l].r[k] = myBufferIn[l].real();
- fftDataIn[l].i[k] = myBufferIn[l].imag();
- fftDataIn[myFftSizeIn / 2 + l].r[k] = cplxIn[i + l].real();
- fftDataIn[myFftSizeIn / 2 + l].i[k] = cplxIn[i + l].imag();
- }
- memcpy(myBufferIn, cplxIn + i, myFftSizeIn / 2 * sizeof(complexf));
- i += myFftSizeIn / 2;
- } else {
- for (size_t l = 0; l < myFftSizeIn; ++l) {
- fftDataIn[l].r[k] = 0.0f;
- fftDataIn[l].i[k] = 0.0f;
- }
- }
- }
- for (size_t k = 0; k < myFftSizeIn; ++ k) {
- FFT_REAL(myFftIn[k]) = _mm_mul_ps(FFT_REAL(myFftIn[k]), _mm_set_ps1(myWindow[k]));
- FFT_IMAG(myFftIn[k]) = _mm_mul_ps(FFT_IMAG(myFftIn[k]), _mm_set_ps1(myWindow[k]));
- }
-
- kiss_fft(myFftPlan1, myFftIn, myFront);
-
- if (myFftSizeOut > myFftSizeIn) {
- memset(myBack, 0, myFftSizeOut * sizeof(FFT_TYPE));
- memcpy(myBack, myFront, myFftSizeIn / 2 * sizeof(FFT_TYPE));
- memcpy(&myBack[myFftSizeOut - (myFftSizeIn / 2)],
- &myFront[myFftSizeIn / 2],
- myFftSizeIn / 2 * sizeof(FFT_TYPE));
- // Copy input Fs
- FFT_REAL(myBack[myFftSizeIn / 2]) =
- FFT_REAL(myFront[myFftSizeIn / 2]);
- FFT_IMAG(myBack[myFftSizeIn / 2]) =
- FFT_IMAG(myFront[myFftSizeIn / 2]);
- } else {
- memcpy(myBack, myFront, myFftSizeOut / 2 * sizeof(FFT_TYPE));
- memcpy(&myBack[myFftSizeOut / 2],
- &myFront[myFftSizeIn - (myFftSizeOut / 2)],
- myFftSizeOut / 2 * sizeof(FFT_TYPE));
- // Average output Fs from input
- FFT_REAL(myBack[myFftSizeOut / 2]) =
- _mm_add_ps(FFT_REAL(myBack[myFftSizeOut / 2]),
- FFT_REAL(myFront[myFftSizeOut / 2]));
- FFT_IMAG(myBack[myFftSizeOut / 2]) =
- _mm_add_ps(FFT_IMAG(myBack[myFftSizeOut / 2]),
- FFT_IMAG(myFront[myFftSizeOut / 2]));
- FFT_REAL(myBack[myFftSizeOut / 2]) =
- _mm_mul_ps(FFT_REAL(myBack[myFftSizeOut / 2]), _mm_set_ps1(0.5f));
- FFT_IMAG(myBack[myFftSizeOut / 2]) =
- _mm_mul_ps(FFT_IMAG(myBack[myFftSizeOut / 2]), _mm_set_ps1(0.5f));
- }
- for (size_t k = 0; k < myFftSizeOut; ++k) {
- FFT_REAL(myBack[k]) = _mm_mul_ps(FFT_REAL(myBack[k]), _mm_set_ps1(myFactor));
- FFT_IMAG(myBack[k]) = _mm_mul_ps(FFT_IMAG(myBack[k]), _mm_set_ps1(myFactor));
- }
-
- kiss_fft(myFftPlan2, myBack, myFftOut);
-
- for (size_t k = 0; k < 4; ++k) {
- if (j < sizeOut) {
- for (size_t l = 0; l < myFftSizeOut / 2; ++l) {
- cplxOut[j + l] = complexf(myBufferOut[l].real() + fftDataOut[l].r[k],
- myBufferOut[l].imag() + fftDataOut[l].i[k]);
- myBufferOut[l] = complexf(fftDataOut[myFftSizeOut / 2 + l].r[k],
- fftDataOut[myFftSizeOut / 2 + l].i[k]);
- }
- }
- j += myFftSizeOut / 2;
- }
- }
-#endif
-
-#if USE_FFTW || (!defined(USE_SIMD))
for (size_t i = 0, j = 0; i < sizeIn; i += myFftSizeIn / 2, j += myFftSizeOut / 2) {
memcpy(myFftIn, myBufferIn, myFftSizeIn / 2 * sizeof(FFT_TYPE));
memcpy(myFftIn + (myFftSizeIn / 2), in + i, myFftSizeIn / 2 * sizeof(FFT_TYPE));
@@ -297,11 +146,7 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
FFT_IMAG(myFftIn[k]) *= myWindow[k];
}
-#if USE_FFTW
fftwf_execute(myFftPlan1);
-#else
- kiss_fft(myFftPlan1, myFftIn, myFront);
-#endif
if (myFftSizeOut > myFftSizeIn) {
memset(myBack, 0, myFftSizeOut * sizeof(FFT_TYPE));
@@ -332,11 +177,7 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
FFT_IMAG(myBack[k]) *= myFactor;
}
-#if USE_FFTW
fftwf_execute(myFftPlan2);
-#else
- kiss_fft(myFftPlan2, myBack, myFftOut);
-#endif
for (size_t k = 0; k < myFftSizeOut / 2; ++k) {
FFT_REAL(out[j + k]) = myBufferOut[k].real() + FFT_REAL(myFftOut[k]);
@@ -344,7 +185,6 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
}
memcpy(myBufferOut, myFftOut + (myFftSizeOut / 2), (myFftSizeOut / 2) * sizeof(FFT_TYPE));
}
-#endif
return 1;
}