summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2014-10-24 17:10:52 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2014-10-24 22:22:07 +0200
commitdd429ea2a7d98ba3a6b5806734db347a1bed1924 (patch)
tree1e3f7aa57f1faef63247d5fc3361b9fe860fda61
parentfc199a7284c5f3a5a84631583ea704748d50b28e (diff)
downloaddabmod-dd429ea2a7d98ba3a6b5806734db347a1bed1924.tar.gz
dabmod-dd429ea2a7d98ba3a6b5806734db347a1bed1924.tar.bz2
dabmod-dd429ea2a7d98ba3a6b5806734db347a1bed1924.zip
Make KISS entirely optional
The Resampler block can also use fftw, and the Makefile only does the kiss fft compilation when --enable-fftw is not given.
-rw-r--r--src/GainControl.cpp10
-rw-r--r--src/Makefile.am9
-rw-r--r--src/OfdmGenerator.cpp4
-rw-r--r--src/Resampler.cpp102
-rw-r--r--src/Resampler.h22
-rw-r--r--src/kiss_fftsimd.h8
6 files changed, 103 insertions, 52 deletions
diff --git a/src/GainControl.cpp b/src/GainControl.cpp
index a34dcf2..03d8aa6 100644
--- a/src/GainControl.cpp
+++ b/src/GainControl.cpp
@@ -27,12 +27,20 @@
#include "GainControl.h"
#include "PcDebug.h"
-#include "kiss_fftsimd.h"
#include <stdio.h>
#include <stdexcept>
#include <string>
+#ifdef __SSE__
+# include <xmmintrin.h>
+union __u128 {
+ __m128 m;
+ float f[4];
+};
+#endif
+
+
using namespace std;
diff --git a/src/Makefile.am b/src/Makefile.am
index b7095c8..3d1eefc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,6 +42,7 @@ endif
bin_PROGRAMS = odr-dabmod
+if USE_KISS_FFT
FFT_DIR=$(top_builddir)/lib/kiss_fft129
FFT_INC=-I$(FFT_DIR) -I$(FFT_DIR)/tools
FFT_SRC=$(FFT_DIR)/kiss_fft.c $(FFT_DIR)/kiss_fft.h $(FFT_DIR)/tools/kiss_fftr.c $(FFT_DIR)/tools/kiss_fftr.h kiss_fftsimd.c kiss_fftsimd.h
@@ -53,10 +54,13 @@ DabModulator.cpp: $(FFT_DIR)
BUILT_SOURCES: $(FFT_DIR)
-if USE_KISS_FFT
FFT_LDADD=
else
FFT_LDADD=-lfftw3f -lm
+FFT_DIR=
+FFT_INC=
+FFT_SRC=
+FFT_FLG=
endif
$(FFT_DIR):
@@ -116,8 +120,11 @@ nodist_odr_dabmod_SOURCES =$(FFT_SRC)
dist_bin_SCRIPTS =crc-dwap.py
+if USE_KISS_FFT
EXTRA_DIST =kiss_fftsimd.c kiss_fftsimd.h
clean-local:
rm -rf $(FFT_DIR)
+endif
+
diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp
index 90527d4..7044249 100644
--- a/src/OfdmGenerator.cpp
+++ b/src/OfdmGenerator.cpp
@@ -102,8 +102,8 @@ OfdmGenerator::OfdmGenerator(size_t nbSymbols,
FFTW_BACKWARD, FFTW_MEASURE);
if (sizeof(complexf) != sizeof(FFT_TYPE)) {
- printf("sizeof(complexf) %d\n", sizeof(complexf));
- printf("sizeof(FFT_TYPE) %d\n", sizeof(FFT_TYPE));
+ printf("sizeof(complexf) %zu\n", sizeof(complexf));
+ printf("sizeof(FFT_TYPE) %zu\n", sizeof(FFT_TYPE));
throw std::runtime_error(
"OfdmGenerator::process complexf size is not FFT_TYPE size!");
}
diff --git a/src/Resampler.cpp b/src/Resampler.cpp
index 334be99..cda4ff4 100644
--- a/src/Resampler.cpp
+++ b/src/Resampler.cpp
@@ -1,6 +1,11 @@
/*
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty
the Queen in Right of Canada (Communications Research Center Canada)
+
+ Copyright (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://opendigitalradio.org
*/
/*
This file is part of ODR-DabMod.
@@ -22,17 +27,16 @@
#include "Resampler.h"
#include "PcDebug.h"
-
-#if HAVE_DECL__MM_MALLOC
-# include <mm_malloc.h>
-#else
-# define memalign(a, b) malloc(b)
-#endif
+#include <malloc.h>
#include <sys/types.h>
#include <string.h>
#include <stdexcept>
#include <assert.h>
+#if USE_FFTW
+# define FFT_REAL(x) x[0]
+# define FFT_IMAG(x) x[1]
+#endif
unsigned gcd(unsigned a, unsigned b)
{
@@ -59,6 +63,9 @@ 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"
@@ -92,6 +99,7 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) :
"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;
@@ -119,6 +127,22 @@ 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,
+ myFftIn, myFront,
+ FFTW_FORWARD, FFTW_MEASURE);
+
+ myBack = (FFT_TYPE*)fftwf_malloc(sizeof(FFT_TYPE) * myFftSizeOut);
+ myFftOut = (FFT_TYPE*)fftwf_malloc(sizeof(FFT_TYPE) * myFftSizeOut);
+ myFftPlan2 = fftwf_plan_dft_1d(myFftSizeOut,
+ myBack, myFftOut,
+ FFTW_BACKWARD, FFTW_MEASURE);
+
+ 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));
@@ -127,6 +151,7 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) :
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));
@@ -137,34 +162,30 @@ Resampler::~Resampler()
{
PDEBUG("Resampler::~Resampler() @ %p\n", this);
- 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);
- }
+#if USE_FFTW
+ if (myFftPlan1 != NULL) { fftwf_free(myFftPlan1); }
+ if (myFftPlan2 != NULL) { fftwf_free(myFftPlan2); }
+ if (myFftIn != NULL) { fftwf_free(myFftIn); }
+ if (myFftOut != NULL) { fftwf_free(myFftOut); }
+ if (myBufferIn != NULL) { fftwf_free(myBufferIn); }
+ if (myBufferOut != NULL) { fftwf_free(myBufferOut); }
+ if (myFront != NULL) { fftwf_free(myFront); }
+ if (myBack != NULL) { fftwf_free(myBack); }
+ 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
}
@@ -179,7 +200,7 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
FFT_TYPE* out = reinterpret_cast<FFT_TYPE*>(dataOut->getData());
size_t sizeIn = dataIn->getLength() / sizeof(complexf);
-#ifdef USE_SIMD
+#if defined(USE_SIMD) && !USE_FFTW
size_t sizeOut = dataOut->getLength() / sizeof(complexf);
typedef struct {
@@ -263,7 +284,9 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
j += myFftSizeOut / 2;
}
}
-#else
+#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));
@@ -273,7 +296,11 @@ 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));
@@ -304,7 +331,11 @@ 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]);
@@ -316,3 +347,4 @@ int Resampler::process(Buffer* const dataIn, Buffer* dataOut)
return 1;
}
+
diff --git a/src/Resampler.h b/src/Resampler.h
index a19b14e..392d0a6 100644
--- a/src/Resampler.h
+++ b/src/Resampler.h
@@ -1,6 +1,11 @@
/*
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty
the Queen in Right of Canada (Communications Research Center Canada)
+
+ Copyright (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://opendigitalradio.org
*/
/*
This file is part of ODR-DabMod.
@@ -28,12 +33,19 @@
#include "porting.h"
#include "ModCodec.h"
-#include "kiss_fftsimd.h"
+#if USE_FFTW
+# include <sys/types.h>
+# include <fftw3.h>
+# define FFT_TYPE fftwf_complex
+# define FFT_PLAN fftwf_plan
-#include <sys/types.h>
-#include <kiss_fft.h>
-#include <tools/kiss_fftr.h>
+#else
+# include "kiss_fftsimd.h"
+# include <sys/types.h>
+# include <kiss_fft.h>
+# include <tools/kiss_fftr.h>
+#endif
#include <complex>
typedef std::complex<float> complexf;
@@ -68,5 +80,5 @@ protected:
float myFactor;
};
-
#endif // RESAMPLER_H
+
diff --git a/src/kiss_fftsimd.h b/src/kiss_fftsimd.h
index 6d38dc7..90ee435 100644
--- a/src/kiss_fftsimd.h
+++ b/src/kiss_fftsimd.h
@@ -36,14 +36,6 @@
#define FFT_IMAG(a) (a).i
-#ifdef __SSE__
-#include <xmmintrin.h>
-union __u128 {
- __m128 m;
- float f[4];
-};
-#endif
-
#ifdef USE_SIMD