diff options
-rw-r--r-- | INSTALL | 10 | ||||
-rw-r--r-- | Makefile.am | 34 | ||||
-rw-r--r-- | configure.ac | 31 | ||||
-rw-r--r-- | lib/kiss_fft129.tar.gz | bin | 41981 -> 0 bytes | |||
-rw-r--r-- | src/DabMod.cpp | 12 | ||||
-rw-r--r-- | src/OfdmGenerator.cpp | 104 | ||||
-rw-r--r-- | src/OfdmGenerator.h | 14 | ||||
-rw-r--r-- | src/Resampler.cpp | 164 | ||||
-rw-r--r-- | src/Resampler.h | 19 | ||||
-rw-r--r-- | src/Utils.cpp | 4 | ||||
-rw-r--r-- | src/kiss_fftsimd.c | 44 | ||||
-rw-r--r-- | src/kiss_fftsimd.h | 60 |
12 files changed, 17 insertions, 479 deletions
@@ -3,9 +3,9 @@ Required dependencies: * A C++11 capable compiler * Boost 1.41 or later + * FFTW 3.x * Optional UHD for USRP * Optional ZeroMQ http://www.zeromq.org - * Optional FFTW 3.x (included KISS FFT is used as fallback) Simple install procedure: ========================= @@ -26,14 +26,6 @@ The configure script can be launch with a variety of options: output and remotecontrol. --disable-output-uhd Disable the binding to the UHD driver for USRPs -You have the choice between two FFT libraries: KISS FFT and FFTW. KISS FFT is a -proven library, but it's performance is worse than with the new FFTW. With KISS -FFT, you have the choice between using the normal version, or the SIMD -accelerated version, which is a bit faster. The corresponding options are: - - --enable-kiss-fft Prefer KISS FFT over FFTW - --enable-fft-simd Enable SIMD instructions for KISS FFT - Debugging options: You should not enable debug if you need good performance. By default, debug is disabled. --enable-debug Do not compile with debugging, and enable optimisations diff --git a/Makefile.am b/Makefile.am index 65c48c5..90fc577 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,39 +33,10 @@ endif bin_PROGRAMS = odr-dabmod -FFT_DIR=lib/kiss_fft129 FFT_LDADD= -if USE_KISS_FFT -FFT_INC=-I$(FFT_DIR) -I$(FFT_DIR)/tools -FFT_FLG=-ffast-math - -.PHONY: lib/kiss_fft129 - -BUILT_SOURCES=lib/kiss_fft129 - -lib/kiss_fft129: - if [ ! -e lib/kiss_fft129/kiss_fft.c ]; then \ - tar xzf lib/kiss_fft129.tar.gz -C lib; \ - fi - -nodist_odr_dabmod_SOURCES = lib/kiss_fft129/kiss_fft.c \ - lib/kiss_fft129/kiss_fft.h \ - lib/kiss_fft129/tools/kiss_fftr.c \ - lib/kiss_fft129/tools/kiss_fftr.h \ - src/kiss_fftsimd.c \ - src/kiss_fftsimd.h - -clean-local: - rm -rf $(FFT_DIR) - -else -FFT_INC= -FFT_FLG= -endif - odr_dabmod_CPPFLAGS = -Wall -Isrc \ - $(FFT_INC) $(FFT_FLG) $(GITVERSION_FLAGS) + $(GITVERSION_FLAGS) odr_dabmod_LDADD = $(FFT_LDADD) odr_dabmod_SOURCES = src/DabMod.cpp \ src/PcDebug.h \ @@ -165,6 +136,3 @@ odr_dabmod_SOURCES = src/DabMod.cpp \ dist_bin_SCRIPTS = src/crc-dwap.py -EXTRA_DIST += lib/kiss_fft129.tar.gz -EXTRA_DIST += src/kiss_fftsimd.c src/kiss_fftsimd.h - diff --git a/configure.ac b/configure.ac index b71fb2e..60b1e4e 100644 --- a/configure.ac +++ b/configure.ac @@ -64,15 +64,6 @@ AC_ARG_ENABLE([trace], [AS_HELP_STRING([--enable-trace], [Enable trace output])], [], [enable_trace=no]) -# Which FFT library to use -AC_ARG_ENABLE([fft_simd], - [AS_HELP_STRING([--enable-fft-simd], - [Enable SIMD instructions for kiss-fft (unstable)])], - [], [enable_fft_simd=no]) -AC_ARG_ENABLE([kiss_fft], - [AS_HELP_STRING([--enable-kiss-fft], [Prefer KISS FFT over FFTW3])], - [], [enable_kiss=no]) - # ZeroMQ message queue input AC_ARG_ENABLE([zeromq], [AS_HELP_STRING([--disable-zeromq], [Disable ZeroMQ input, output and remote control])], @@ -83,13 +74,7 @@ AC_ARG_ENABLE([output_uhd], [AS_HELP_STRING([--disable-output-uhd], [Disable UHD output])], [], [enable_output_uhd=yes]) -AS_IF([test "x$enable_kiss" = "xno"], - [PKG_CHECK_MODULES([FFTW], [fftw3f], enable_fftw=yes, enable_fftw=no)], - [enable_fftw=no]) - -AS_IF([test "x$enable_fftw" = "xyes"], - AC_MSG_NOTICE([Found FFTW3]), - AC_MSG_NOTICE([Using Kiss FFT]) ) +PKG_CHECK_MODULES([FFTW], [fftw3f], enable_fftw=yes, enable_fftw=no) echo "Checking zeromq" @@ -103,22 +88,10 @@ AS_IF([test "x$enable_prof" != "xno"], [EXTRA="$EXTRA -pg"]) # Define conditionals for Makefile.am -AM_CONDITIONAL([USE_KISS_FFT], [test "x$enable_fftw" = "xno"]) AM_CONDITIONAL([DEBUG], [test "x$enable_trace" = "xyes"]) AM_CONDITIONAL([IS_GIT_REPO], [test -d '.git']) # Defines for config.h -AS_IF([test "x$enable_fft_simd" = "xyes"], - [AC_DEFINE(USE_SIMD, [1], [Define to enable KISS FFT SIMD])]) -AS_IF([test "x$enable_fftw" = "xno"], - [AC_DEFINE(USE_KISS_FFT, [1], [Define to enable KISS])]) -AS_IF([test "x$enable_fftw" = "xyes"], - [AC_DEFINE(USE_FFTW, [1], [Define to enable FFTW])]) - -AS_IF([test "x$enable_fftw" = "xno"], - AC_MSG_ERROR([KISS FFT is currently broken. Please use FFTW. Any debugging help is appreciated]) ) - - AX_PTHREAD([], AC_MSG_ERROR([requires pthread])) AC_SUBST([CFLAGS], ["$EXTRA $FFTW_CFLAGS $PTHREAD_CFLAGS"]) @@ -205,7 +178,7 @@ echo "***********************************************" echo enabled="" disabled="" -for feat in debug prof trace fftw fft_simd output_uhd zeromq +for feat in debug prof trace output_uhd zeromq do eval var=\$enable_$feat AS_IF([test "x$var" = "xyes"], diff --git a/lib/kiss_fft129.tar.gz b/lib/kiss_fft129.tar.gz Binary files differdeleted file mode 100644 index 6399710..0000000 --- a/lib/kiss_fft129.tar.gz +++ /dev/null diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 43550c5..a60bdd6 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -291,18 +291,6 @@ int launch_modulator(int argc, char* argv[]) #endif << std::endl; - std::cerr << "Using FFT library " << -#if defined(USE_FFTW) - "FFTW" << -#endif -#if defined(USE_KISS_FFT) - "Kiss FFT" << -#endif -#if defined(USE_SIMD) - " (with fft_simd)" << -#endif - "\n"; - std::cerr << "Compiled with features: " << #if defined(HAVE_ZEROMQ) "zeromq " << diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index 3dc85a9..55dba0c 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -2,7 +2,7 @@ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2014 + Copyright (C) 2016 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -26,12 +26,8 @@ #include "OfdmGenerator.h" #include "PcDebug.h" -#if USE_FFTW -# include "fftw3.h" -# define FFT_TYPE fftwf_complex -#else -# include "kiss_fftsimd.h" -#endif +#include "fftw3.h" +#define FFT_TYPE fftwf_complex #include <stdio.h> #include <string.h> @@ -48,11 +44,7 @@ OfdmGenerator::OfdmGenerator(size_t nbSymbols, ModCodec(ModFormat(nbSymbols * nbCarriers * sizeof(FFT_TYPE)), ModFormat(nbSymbols * spacing * sizeof(FFT_TYPE))), myFftPlan(NULL), -#if USE_FFTW myFftIn(NULL), myFftOut(NULL), -#else - myFftBuffer(NULL), -#endif myNbSymbols(nbSymbols), myNbCarriers(nbCarriers), mySpacing(spacing) @@ -93,7 +85,6 @@ OfdmGenerator::OfdmGenerator(size_t nbSymbols, PDEBUG(" myZeroDst: %u\n", myZeroDst); PDEBUG(" myZeroSize: %u\n", myZeroSize); -#if USE_FFTW const int N = mySpacing; // The size of the FFT myFftIn = (FFT_TYPE*)fftwf_malloc(sizeof(FFT_TYPE) * N); myFftOut = (FFT_TYPE*)fftwf_malloc(sizeof(FFT_TYPE) * N); @@ -107,11 +98,6 @@ OfdmGenerator::OfdmGenerator(size_t nbSymbols, throw std::runtime_error( "OfdmGenerator::process complexf size is not FFT_TYPE size!"); } -#else - myFftPlan = kiss_fft_alloc(mySpacing, 1, NULL, NULL); - myFftBuffer = (FFT_TYPE*)memalign(16, mySpacing * sizeof(FFT_TYPE)); -#endif - } @@ -119,7 +105,6 @@ OfdmGenerator::~OfdmGenerator() { PDEBUG("OfdmGenerator::~OfdmGenerator() @ %p\n", this); -#if USE_FFTW if (myFftIn) { fftwf_free(myFftIn); } @@ -131,18 +116,6 @@ OfdmGenerator::~OfdmGenerator() if (myFftPlan) { fftwf_destroy_plan(myFftPlan); } - -#else - if (myFftPlan != NULL) { - kiss_fft_free(myFftPlan); - } - - if (myFftBuffer != NULL) { - free(myFftBuffer); - } - - kiss_fft_cleanup(); -#endif } int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) @@ -175,8 +148,6 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) "OfdmGenerator::process output size not valid!"); } -#if USE_FFTW - // No SIMD/no-SIMD distinction, it's too early to optimize anything for (size_t i = 0; i < myNbSymbols; ++i) { myFftIn[0][0] = 0; myFftIn[0][1] = 0; @@ -194,75 +165,6 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) in += myNbCarriers; out += mySpacing; } -#else -# ifdef USE_SIMD - for (size_t i = 0, j = 0; i < sizeIn; ) { - // Pack 4 fft operations - typedef struct { - float r[4]; - float i[4]; - } fft_data; - assert(sizeof(FFT_TYPE) == sizeof(fft_data)); - complexf *cplxIn = (complexf*)in; - complexf *cplxOut = (complexf*)out; - fft_data *dataBuffer = (fft_data*)myFftBuffer; - - FFT_REAL(myFftBuffer[0]) = _mm_setzero_ps(); - FFT_IMAG(myFftBuffer[0]) = _mm_setzero_ps(); - for (size_t k = 0; k < myZeroSize; ++k) { - FFT_REAL(myFftBuffer[myZeroDst + k]) = _mm_setzero_ps(); - FFT_IMAG(myFftBuffer[myZeroDst + k]) = _mm_setzero_ps(); - } - for (int k = 0; k < 4; ++k) { - if (i < sizeIn) { - for (size_t l = 0; l < myPosSize; ++l) { - dataBuffer[myPosDst + l].r[k] = cplxIn[i + myPosSrc + l].real(); - dataBuffer[myPosDst + l].i[k] = cplxIn[i + myPosSrc + l].imag(); - } - for (size_t l = 0; l < myNegSize; ++l) { - dataBuffer[myNegDst + l].r[k] = cplxIn[i + myNegSrc + l].real(); - dataBuffer[myNegDst + l].i[k] = cplxIn[i + myNegSrc + l].imag(); - } - i += myNbCarriers; - } - else { - for (size_t l = 0; l < myNbCarriers; ++l) { - dataBuffer[l].r[k] = 0.0f; - dataBuffer[l].i[k] = 0.0f; - } - } - } - - kiss_fft(myFftPlan, myFftBuffer, myFftBuffer); - - for (int k = 0; k < 4; ++k) { - if (j < sizeOut) { - for (size_t l = 0; l < mySpacing; ++l) { - cplxOut[j + l] = complexf(dataBuffer[l].r[k], dataBuffer[l].i[k]); - } - j += mySpacing; - } - } - } -# else - for (size_t i = 0; i < myNbSymbols; ++i) { - FFT_REAL(myFftBuffer[0]) = 0; - FFT_IMAG(myFftBuffer[0]) = 0; - bzero(&myFftBuffer[myZeroDst], myZeroSize * sizeof(FFT_TYPE)); - memcpy(&myFftBuffer[myPosDst], &in[myPosSrc], - myPosSize * sizeof(FFT_TYPE)); - memcpy(&myFftBuffer[myNegDst], &in[myNegSrc], - myNegSize * sizeof(FFT_TYPE)); - - kiss_fft(myFftPlan, myFftBuffer, out); - - in += myNbCarriers; - out += mySpacing; - - } -# endif -#endif - return sizeOut; } diff --git a/src/OfdmGenerator.h b/src/OfdmGenerator.h index ec9f14a..061ad91 100644 --- a/src/OfdmGenerator.h +++ b/src/OfdmGenerator.h @@ -2,7 +2,7 @@ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2014 + Copyright (C) 2016 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -34,12 +34,7 @@ #include "porting.h" #include "ModCodec.h" -#if USE_FFTW -# include "fftw3.h" -#else -# include "kiss_fftsimd.h" -# include <kiss_fft.h> -#endif +#include "fftw3.h" #include <sys/types.h> @@ -57,13 +52,8 @@ public: const char* name() { return "OfdmGenerator"; } protected: -#if USE_FFTW fftwf_plan myFftPlan; fftwf_complex *myFftIn, *myFftOut; -#else - FFT_PLAN myFftPlan; - FFT_TYPE *myFftBuffer; -#endif size_t myNbSymbols; size_t myNbCarriers; size_t mySpacing; 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; } diff --git a/src/Resampler.h b/src/Resampler.h index 392d0a6..f8388ee 100644 --- a/src/Resampler.h +++ b/src/Resampler.h @@ -33,19 +33,12 @@ #include "porting.h" #include "ModCodec.h" -#if USE_FFTW -# include <sys/types.h> -# include <fftw3.h> - -# define FFT_TYPE fftwf_complex -# define FFT_PLAN fftwf_plan - -#else -# include "kiss_fftsimd.h" -# include <sys/types.h> -# include <kiss_fft.h> -# include <tools/kiss_fftr.h> -#endif +#include <sys/types.h> +#include <fftw3.h> + +#define FFT_TYPE fftwf_complex +#define FFT_PLAN fftwf_plan + #include <complex> typedef std::complex<float> complexf; diff --git a/src/Utils.cpp b/src/Utils.cpp index 1560e07..4805374 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -110,10 +110,6 @@ void printVersion(void) " You should have received a copy of the GNU General Public License along\n" " with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>.\n" "\n" -#if USE_KISS_FFT - "ODR-DabMod makes use of the following open source packages:\n" - " Kiss FFT v1.2.9 (Revised BSD) - http://kissfft.sourceforge.net/\n" -#endif ); } diff --git a/src/kiss_fftsimd.c b/src/kiss_fftsimd.c deleted file mode 100644 index 83f2e4a..0000000 --- a/src/kiss_fftsimd.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2011, 2012 - Her Majesty the Queen in Right of Canada (Communications Research - Center Canada) - */ -/* - This file is part of ODR-DabMod. - - ODR-DabMod is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMod 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "kiss_fftsimd.h" - - -#ifdef USE_SIMD -void kiss_fft_pack(kiss_fft_complex *in, size_t in_size, size_t in_offset, - kiss_fft_complex *out, size_t out_size, size_t out_offset, - size_t stride, size_t n) -{ - size_t i, j; - complex_float *in_cplx = (complex_float*)in; - - for (i = 0; i < 4; ++i) { - if (in_offset < in_size) { - for (j = 0; j < n; ++j) { - out[out_offset + j].r[i] = in_cplx[in_offset + j].r; - out[out_offset + j].i[i] = in_cplx[in_offset + j].i; - } - in_offset += stride; - } - } -} -#endif diff --git a/src/kiss_fftsimd.h b/src/kiss_fftsimd.h deleted file mode 100644 index 90ee435..0000000 --- a/src/kiss_fftsimd.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2011, 2012 - Her Majesty the Queen in Right of Canada (Communications Research - Center Canada) - */ -/* - This file is part of ODR-DabMod. - - ODR-DabMod is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMod 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef KISS_FFTSIMD_H -#define KISS_FFTSIMD_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <kiss_fft.h> - - -#define FFT_TYPE kiss_fft_cpx -#define FFT_PLAN kiss_fft_cfg -#define FFT_REAL(a) (a).r -#define FFT_IMAG(a) (a).i - - - -#ifdef USE_SIMD - -typedef struct { - float r[4]; - float i[4]; -} kiss_fft_complex; - -typedef struct { - float r; - float i; -} complex_float; - -void kiss_fft_pack(kiss_fft_complex *in, size_t in_size, size_t in_offset, - kiss_fft_complex *out, size_t out_size, size_t out_offset, - size_t stride, size_t n); -void kiss_fft_unpack(kiss_fft_complex *dst, kiss_fft_complex *src, size_t n, size_t offset, size_t stride); - -#endif - - -#endif // KISS_FFTSIMD_H |