diff options
author | Tom Tsou <tom.tsou@ettus.com> | 2016-06-22 16:16:30 -0700 |
---|---|---|
committer | Tom Tsou <tom.tsou@ettus.com> | 2016-07-01 03:07:27 -0700 |
commit | 35222296fef378977a83a4ee89d8c3ef9bc62a3f (patch) | |
tree | c5551e02f5e9f30e970de1fabdbefeb3bc4842aa /Transceiver52M/common | |
parent | 28670fb5dad8e48ff74051a5bbe0c8309b04c817 (diff) |
mcbts: Add multi-ARFCN channelizing filters
Introduce polyphase channelizer (Rx) and synthesis (Tx) filterbanks,
which serve as the signal processing backend for multi-carrier GSM.
Fast Fourier Transform (FFT) is used internally. FFTW is added as
a new build dependency.
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
Diffstat (limited to 'Transceiver52M/common')
-rw-r--r-- | Transceiver52M/common/fft.c | 112 | ||||
-rw-r--r-- | Transceiver52M/common/fft.h | 13 |
2 files changed, 125 insertions, 0 deletions
diff --git a/Transceiver52M/common/fft.c b/Transceiver52M/common/fft.c new file mode 100644 index 0000000..18b2de7 --- /dev/null +++ b/Transceiver52M/common/fft.c @@ -0,0 +1,112 @@ +/* + * Fast Fourier transform + * + * Copyright (C) 2012 Tom Tsou <tom@tsou.cc> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * See the COPYING file in the main directory for details. + */ + +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <fftw3.h> + +#include "fft.h" + +struct fft_hdl { + float *fft_in; + float *fft_out; + int len; + fftwf_plan fft_plan; +}; + +/*! \brief Initialize FFT backend + * \param[in] reverse FFT direction + * \param[in] m FFT length + * \param[in] istride input stride count + * \param[in] ostride output stride count + * \param[in] in input buffer (FFTW aligned) + * \param[in] out output buffer (FFTW aligned) + * \param[in] ooffset initial offset into output buffer + * + * If the reverse is non-NULL, then an inverse FFT will be used. This is a + * wrapper for advanced non-contiguous FFTW usage. See FFTW documentation for + * further details. + * + * http://www.fftw.org/doc/Advanced-Complex-DFTs.html + * + * It is currently unknown how the offset of the output buffer affects FFTW + * memory alignment. + */ +struct fft_hdl *init_fft(int reverse, int m, int istride, int ostride, + float *in, float *out, int ooffset) +{ + int rank = 1; + int n[] = { m }; + int howmany = istride; + int idist = 1; + int odist = 1; + int *inembed = n; + int *onembed = n; + fftwf_complex *obuffer, *ibuffer; + + struct fft_hdl *hdl = (struct fft_hdl *) malloc(sizeof(struct fft_hdl)); + if (!hdl) + return NULL; + + int direction = FFTW_FORWARD; + if (reverse) + direction = FFTW_BACKWARD; + + ibuffer = (fftwf_complex *) in; + obuffer = (fftwf_complex *) out + ooffset; + + hdl->fft_in = in; + hdl->fft_out = out; + hdl->fft_plan = fftwf_plan_many_dft(rank, n, howmany, + ibuffer, inembed, istride, idist, + obuffer, onembed, ostride, odist, + direction, FFTW_MEASURE); + return hdl; +} + +void *fft_malloc(size_t size) +{ + return fftwf_malloc(size); +} + +void fft_free(void *ptr) +{ + free(ptr); +} + +/*! \brief Free FFT backend resources + */ +void free_fft(struct fft_hdl *hdl) +{ + fftwf_destroy_plan(hdl->fft_plan); + free(hdl); +} + +/*! \brief Run multiple DFT operations with the initialized plan + * \param[in] hdl handle to an intitialized fft struct + * + * Input and output buffers are configured with init_fft(). + */ +int cxvec_fft(struct fft_hdl *hdl) +{ + fftwf_execute(hdl->fft_plan); + return 0; +} diff --git a/Transceiver52M/common/fft.h b/Transceiver52M/common/fft.h new file mode 100644 index 0000000..fb7bede --- /dev/null +++ b/Transceiver52M/common/fft.h @@ -0,0 +1,13 @@ +#ifndef _FFT_H_ +#define _FFT_H_ + +struct fft_hdl; + +struct fft_hdl *init_fft(int reverse, int m, int istride, int ostride, + float *in, float *out, int ooffset); +void *fft_malloc(size_t size); +void fft_free(void *ptr); +void free_fft(struct fft_hdl *hdl); +int cxvec_fft(struct fft_hdl *hdl); + +#endif /* _FFT_H_ */ |