aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2014-10-24 16:20:20 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2014-10-24 16:30:05 +0200
commitfc199a7284c5f3a5a84631583ea704748d50b28e (patch)
treeeeb0566fc8498846caf5f0a7c495b40c8f303305 /src
parentde6eb96c71873fb23f0847424dca724b933ee399 (diff)
downloaddabmod-fc199a7284c5f3a5a84631583ea704748d50b28e.tar.gz
dabmod-fc199a7284c5f3a5a84631583ea704748d50b28e.tar.bz2
dabmod-fc199a7284c5f3a5a84631583ea704748d50b28e.zip
Add possibility to use FFTW for OfdmGenerator
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am13
-rw-r--r--src/OfdmGenerator.cpp85
-rw-r--r--src/OfdmGenerator.h20
3 files changed, 106 insertions, 12 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f6102e9..b7095c8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -40,6 +40,8 @@ else
SIMD_CFLAGS =
endif
+bin_PROGRAMS = odr-dabmod
+
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
@@ -47,19 +49,23 @@ FFT_FLG=-ffast-math
.PHONY: kiss_fft129 reed-solomon-4.0
-bin_PROGRAMS = odr-dabmod
-
DabModulator.cpp: $(FFT_DIR)
BUILT_SOURCES: $(FFT_DIR)
+if USE_KISS_FFT
+FFT_LDADD=
+else
+FFT_LDADD=-lfftw3f -lm
+endif
+
$(FFT_DIR):
if [ ! -e $(FFT_DIR) ]; then \
tar xzf $(top_srcdir)/lib/kiss_fft129.tar.gz -C $(top_builddir)/lib; \
fi
odr_dabmod_CPPFLAGS = -Wall $(FFT_INC) $(FFT_FLG) $(SIMD_CFLAGS) $(GITVERSION_FLAGS)
-odr_dabmod_LDADD = $(ZMQ_LIBS)
+odr_dabmod_LDADD = $(ZMQ_LIBS) $(FFT_LDADD)
odr_dabmod_SOURCES = DabMod.cpp \
PcDebug.h \
porting.c porting.h \
@@ -114,3 +120,4 @@ EXTRA_DIST =kiss_fftsimd.c kiss_fftsimd.h
clean-local:
rm -rf $(FFT_DIR)
+
diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp
index c7e8ebf..90527d4 100644
--- a/src/OfdmGenerator.cpp
+++ b/src/OfdmGenerator.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.
@@ -21,9 +26,15 @@
#include "OfdmGenerator.h"
#include "PcDebug.h"
-#include "kiss_fftsimd.h"
+#if USE_FFTW
+# include "fftw3.h"
+# define FFT_TYPE fftwf_complex
+#else
+# include "kiss_fftsimd.h"
+#endif
#include <stdio.h>
+#include <string.h>
#include <stdexcept>
#include <assert.h>
#include <complex>
@@ -37,7 +48,11 @@ 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)
@@ -57,7 +72,8 @@ OfdmGenerator::OfdmGenerator(size_t nbSymbols,
myNegDst = spacing - (nbCarriers / 2);
myNegSrc = (nbCarriers + 1) / 2;
myNegSize = nbCarriers / 2;
- } else {
+ }
+ else {
myPosDst = (nbCarriers & 1 ? 0 : 1);
myPosSrc = nbCarriers / 2;
myPosSize = (nbCarriers + 1) / 2;
@@ -77,8 +93,25 @@ 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);
+ myFftPlan = fftwf_plan_dft_1d(N,
+ myFftIn, myFftOut,
+ 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));
+ 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
+
}
@@ -86,16 +119,32 @@ OfdmGenerator::~OfdmGenerator()
{
PDEBUG("OfdmGenerator::~OfdmGenerator() @ %p\n", this);
+#if USE_FFTW
+ if (myFftIn) {
+ fftwf_free(myFftIn);
+ }
+
+ if (myFftOut) {
+ fftwf_free(myFftOut);
+ }
+
+ 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)
{
PDEBUG("OfdmGenerator::process(dataIn: %p, dataOut: %p)\n",
@@ -105,6 +154,7 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut)
FFT_TYPE* in = reinterpret_cast<FFT_TYPE*>(dataIn->getData());
FFT_TYPE* out = reinterpret_cast<FFT_TYPE*>(dataOut->getData());
+
size_t sizeIn = dataIn->getLength() / sizeof(complexf);
size_t sizeOut = dataOut->getLength() / sizeof(complexf);
@@ -125,7 +175,27 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut)
"OfdmGenerator::process output size not valid!");
}
-#ifdef USE_SIMD
+#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;
+
+ bzero(&myFftIn[myZeroDst], myZeroSize * sizeof(FFT_TYPE));
+ memcpy(&myFftIn[myPosDst], &in[myPosSrc],
+ myPosSize * sizeof(FFT_TYPE));
+ memcpy(&myFftIn[myNegDst], &in[myNegSrc],
+ myNegSize * sizeof(FFT_TYPE));
+
+ fftwf_execute(myFftPlan);
+
+ memcpy(out, myFftOut, mySpacing * sizeof(FFT_TYPE));
+
+ in += myNbCarriers;
+ out += mySpacing;
+ }
+#else
+# ifdef USE_SIMD
for (size_t i = 0, j = 0; i < sizeIn; ) {
// Pack 4 fft operations
typedef struct {
@@ -154,7 +224,8 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut)
dataBuffer[myNegDst + l].i[k] = cplxIn[i + myNegSrc + l].imag();
}
i += myNbCarriers;
- } else {
+ }
+ else {
for (size_t l = 0; l < myNbCarriers; ++l) {
dataBuffer[l].r[k] = 0.0f;
dataBuffer[l].i[k] = 0.0f;
@@ -174,7 +245,7 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut)
}
}
}
-#else
+# else
for (size_t i = 0; i < myNbSymbols; ++i) {
FFT_REAL(myFftBuffer[0]) = 0;
FFT_IMAG(myFftBuffer[0]) = 0;
@@ -189,7 +260,9 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut)
in += myNbCarriers;
out += mySpacing;
}
+# endif
#endif
return sizeOut;
}
+
diff --git a/src/OfdmGenerator.h b/src/OfdmGenerator.h
index 5be2d03..ec9f14a 100644
--- a/src/OfdmGenerator.h
+++ b/src/OfdmGenerator.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,10 +33,14 @@
#include "porting.h"
#include "ModCodec.h"
-#include "kiss_fftsimd.h"
+#if USE_FFTW
+# include "fftw3.h"
+#else
+# include "kiss_fftsimd.h"
+# include <kiss_fft.h>
+#endif
-#include <kiss_fft.h>
#include <sys/types.h>
@@ -48,8 +57,13 @@ 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;
@@ -63,5 +77,5 @@ protected:
unsigned myZeroSize;
};
-
#endif // OFDM_GENERATOR_H
+