mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
				synced 2025-11-02 05:03:18 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			115 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Fast Fourier transform
 | |
|  *
 | |
|  * Copyright (C) 2012 Tom Tsou <tom@tsou.cc>
 | |
|  *
 | |
|  * SPDX-License-Identifier: LGPL-2.1+
 | |
|  *
 | |
|  * 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 initialized 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;
 | |
| }
 |