Vector_double stf::filter( const Vector_double& data, std::size_t filter_start, std::size_t filter_end, const Vector_double &a, int SR, stf::Func func, bool inverse ) { if (data.size()<=0 || filter_start>=data.size() || filter_end > data.size()) { std::out_of_range e("subscript out of range in stf::filter()"); throw e; } std::size_t filter_size=filter_end-filter_start+1; Vector_double data_return(filter_size); double SI=1.0/SR; //the sampling interval double *in; //fftw_complex is a double[2]; hence, out is an array of //double[2] with out[n][0] being the real and out[n][1] being //the imaginary part. fftw_complex *out; fftw_plan p1, p2; //memory allocation as suggested by fftw: in =(double *)fftw_malloc(sizeof(double) * filter_size); out=(fftw_complex *)fftw_malloc(sizeof(fftw_complex) * ((int)(filter_size/2)+1)); // calculate the offset (a straight line between the first and last points): double offset_0=data[filter_start]; double offset_1=data[filter_end]-offset_0; double offset_step=offset_1 / (filter_size-1); //fill the input array with data removing the offset: for (std::size_t n_point=0;n_point<filter_size;++n_point) { in[n_point]=data[n_point+filter_start]-(offset_0 + offset_step*n_point); } //plan the fft and execute it: p1 =fftw_plan_dft_r2c_1d((int)filter_size,in,out,FFTW_ESTIMATE); fftw_execute(p1); for (std::size_t n_point=0; n_point < (unsigned int)(filter_size/2)+1; ++n_point) { //calculate the frequency (in kHz) which corresponds to the index: double f=n_point / (filter_size*SI); double rslt= (!inverse? func(f,a) : 1.0-func(f,a)); out[n_point][0] *= rslt; out[n_point][1] *= rslt; } //do the reverse fft: p2=fftw_plan_dft_c2r_1d((int)filter_size,out,in,FFTW_ESTIMATE); fftw_execute(p2); //fill the return array, adding the offset, and scaling by filter_size //(because fftw computes an unnormalized transform): data_return.resize(filter_size); for (std::size_t n_point=0; n_point < filter_size; ++n_point) { data_return[n_point]=(in[n_point]/filter_size + offset_0 + offset_step*n_point); } fftw_destroy_plan(p1); fftw_destroy_plan(p2); fftw_free(in);fftw_free(out); return data_return; }
InverseFftAdapter::InverseFftAdapter(unsigned int inFrameSize) : priv(new InverseFftAdapterPrivate) { frameSize = inFrameSize; priv->inputComplex = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * frameSize); priv->outputReal = (double*)fftw_malloc(sizeof(double) * frameSize); boost::mutex::scoped_lock lock(fftwPlanMutex); priv->plan = fftw_plan_dft_c2r_1d(frameSize, priv->inputComplex, priv->outputReal, FFTW_ESTIMATE); }
void Analyzer::init() { setState(Loading); if (m_sampleSize != (quint32)KTunerConfig::segmentLength()) { m_sampleSize = KTunerConfig::segmentLength(); m_outputSize = m_sampleSize + 1; m_window.resize(m_sampleSize); m_input.resize(2 * m_sampleSize); m_output.resize(m_outputSize); m_spectrum.resize(m_outputSize); m_noiseSpectrum.resize(m_outputSize); // FFTW and C++(99) complex types are binary compatible auto output = reinterpret_cast<fftw_complex*>(m_output.data()); m_plan = fftw_plan_dft_r2c_1d(m_input.size(), m_input.data(), output, FFTW_MEASURE); m_ifftPlan = fftw_plan_dft_c2r_1d(m_input.size(), output, m_input.data(), FFTW_ESTIMATE); } if (m_numSpectra != (quint32)KTunerConfig::numSpectra()) { m_numSpectra = KTunerConfig::numSpectra(); m_currentSpectrum %= m_numSpectra; m_spectrumHistory.fill(m_spectrum, m_numSpectra); } m_binFreq = qreal(KTunerConfig::sampleRate()) / m_input.size(); calculateWindow(); setNoiseFilter(KTunerConfig::enableNoiseFilter()); setFftFilter(); setState(Ready); }
int fft_backward(double* in, double* out, int N) { fftw_plan plan; fftw_complex* cin = (fftw_complex*)in; plan = fftw_plan_dft_c2r_1d( N, cin, out, FFTW_ESTIMATE ); fftw_execute(plan); return N; }
// Constructor which creates an inverse transform FFTRealInverse::FFTRealInverse(int size, Complex *in, rsFloat *out) { //Lock the planner Mutex boost::mutex::scoped_lock lock(plannerMutex); plan = fftw_plan_dft_c2r_1d(size, reinterpret_cast<fftw_complex *>(in), out, FFTW_ESTIMATE); //scoped_lock will unlock planner mutex here }
WindowedFFT(int size):size(size),size_c(size/2+1) { Data=(double*)fftw_malloc(sizeof(double)*size); Data_c=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*size_c); p1 = fftw_plan_dft_r2c_1d(size, Data, Data_c, FFTW_ESTIMATE); //FFTW_UNALIGNED p2 = fftw_plan_dft_c2r_1d(size, Data_c, Data, FFTW_ESTIMATE); }
WhistleRecognizer::WhistleRecognizer() { for(int i = 0; i < WHISTLE_BUFF_LEN; ++i) { inputChannel0.push_front(0); inputChannel1.push_front(0); } maxAutoCorrelationValue = 1522544.77f; // Default value for preconfigured whistle cmpCnt = 0; lastGameState = STATE_INITIAL; lastTimeWhistleDetectedInBothChannels = 0; // Allocate memeory for FFTW plans whistleInput8kHz = (double*) fftw_malloc(sizeof(double) * WHISTLE_FFT_LEN); fftDataIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (WHISTLE_BUFF_LEN + 1)); corrBuff = (double*) fftw_malloc(sizeof(double) * WHISTLE_FFT_LEN); // Create plans // - after plan has been created, in and out buffer are set to zero // - plan has to be created only once // Creation of FFTW plans is not thread-safe, thus we need to synchronize with the other threads // - This is only relevant for simulations that contain multiple robots SYNC; fft2048 = fftw_plan_dft_r2c_1d(WHISTLE_FFT_LEN, whistleInput8kHz, fftDataIn, FFTW_MEASURE); // build plan that fftw needs to compute the fft ifft2048 = fftw_plan_dft_c2r_1d(WHISTLE_FFT_LEN, fftDataIn, corrBuff, FFTW_MEASURE); // build plan that fftw needs to compute the fft // Load reference whistle (memory has already been allocated) loadReferenceWhistle(); }
void MarkovPlayer::GenerateSampleBuffers() { time_dom_signals = (double**)malloc(sizeof(double)*n_active_clusters); for(int i = 0 ; i < n_active_clusters; i++){ time_dom_signals[i] = (double*)malloc(sizeof(double)*fft_length_m2*grouping); } real_signal = (double*)malloc(sizeof(double)*fft_length_m2); memset(real_signal, 0, sizeof(double)*fft_length_m2); single_frame = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_length_2_m1); ifft = fftw_plan_dft_c2r_1d(fft_length_m2, single_frame, real_signal, FFTW_ESTIMATE); for(int i = 0 ; i < n_active_clusters; i++){ int time_offset = 0; int other_offset = 0; for(int j = 0 ; j < grouping; j++){ single_frame_interleaved = &fft_matrix[i][time_offset]; IntlvdToFFTW(single_frame_interleaved); InverseFFTW(); for(int p = 0; p < fft_length_m2; p++){ time_dom_signals[i][p+other_offset] = real_signal[p]/fft_length_m2; } time_offset = (j+1)*fft_length; other_offset =(j+1)*fft_length_m2; } RealHopOvrAddPushback(i); } WriteSignal(); }
//"reverse" fourier transforms complex array into real array void fftwb(int n, complex *in, double *out){ fftw_plan p = fftw_plan_dft_c2r_1d(n, (fftw_complex*)in, out, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); }
static void initialize_circulant(hankel_matrix *h, const double *F, R_len_t N, R_len_t L) { R_len_t K = N - L + 1, i; fftw_complex *ocirc; fftw_plan p1, p2; double *circ; /* Allocate needed memory */ circ = (double*) fftw_malloc(N * sizeof(double)); ocirc = (fftw_complex*) fftw_malloc((N/2 + 1) * sizeof(fftw_complex)); /* Estimate the best plans for given input length */ p1 = fftw_plan_dft_r2c_1d(N, circ, ocirc, FFTW_ESTIMATE); p2 = fftw_plan_dft_c2r_1d(N, ocirc, circ, FFTW_ESTIMATE); /* Fill input buffer */ for (i = K-1; i < N; ++i) circ[i - K + 1] = F[i]; for (i = 0; i < K-1; ++i) { circ[L + i] = F[i]; } /* Run the plan on input data */ fftw_execute(p1); /* Cleanup and return */ fftw_free(circ); h->circ_freq = ocirc; h->r2c_plan = p1; h->c2r_plan = p2; h->window = L; h->length = N; }
FFTWProxyImplDouble(int n, double* timespace, gendouble2* freqspace) { forwardPlan = fftw_plan_dft_r2c_1d( n, timespace, (fftw_complex*)freqspace, FFTW_ESTIMATE); inversePlan = fftw_plan_dft_c2r_1d( n, (fftw_complex*)freqspace, timespace, FFTW_ESTIMATE); }
int plggdn_fft_init_fftw(plggdn_fft_t *fft, void *opaque) { // init data memory, plggdn_fft_t stores only pointers, // all memory operations take place in this implementation fft->real_in = (plggdn_float*) fftw_malloc(sizeof(plggdn_float) * fft->N); fft->complex_in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft->N); fft->real_out = (plggdn_float*) fftw_malloc(sizeof(plggdn_float) * fft->N); fft->complex_out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft->N); plggdn_fft_fftw_attr *fftw_attr = (plggdn_fft_fftw_attr*) malloc(sizeof(plggdn_fft_fftw_attr)); memset(fftw_attr, 0, sizeof(plggdn_fft_fftw_attr)); fft->opaque = fftw_attr; // init plans fftw_attr->p[FWD_R2C] = fftw_plan_dft_r2c_1d(fft->N, fft->real_in, fft->complex_out, FFTW_MEASURE); fftw_attr->p[INV_C2R] = fftw_plan_dft_c2r_1d(fft->N, fft->complex_in, fft->real_out, FFTW_MEASURE); fftw_attr->p[FWD_C2C] = fftw_plan_dft_1d(fft->N, fft->complex_in, fft->complex_out, FFTW_FORWARD, FFTW_MEASURE); fftw_attr->p[INV_C2C] = fftw_plan_dft_1d(fft->N, fft->complex_in, fft->complex_out, FFTW_BACKWARD, FFTW_MEASURE); return 0; }
void fft_c2r_(fftw_plan* p, int* n, double complex* data, double* res) { *p = fftw_plan_dft_c2r_1d(*n, data, res, FFTW_ESTIMATE); fftw_execute(*p); }
FFTStream_r(int size):size(size),size_c(size/2+1) { buffer=(double*)fftw_malloc(sizeof(double)*size); buffer_c=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*size_c); phase=(double*)fftw_malloc(sizeof(double)*size_c); for(int i=0;i<size_c;i++) phase[i]=100; buffer_out=(double*)fftw_malloc(sizeof(double)*size); //p1 = fftw_plan_dft_r2c_1d(size, buffer, buffer_c, 0); //FFTW_UNALIGNED p1 = fftw_plan_dft_c2r_1d(size, buffer_c, buffer_out, 0); }
void NRLib::NRLibPrivate::ComputeFFTInv1D<double>(size_t n, std::complex<double>* in, double* out) { fftw_complex* in_data = reinterpret_cast<fftw_complex*>(in); fftw_plan p = fftw_plan_dft_c2r_1d(static_cast<int>(n), in_data, out, FFTW_ESTIMATE); assert (p != 0); fftw_execute(p); fftw_destroy_plan(p); }
inline void irfft(CDEVector<double>::Type &X, DEVector<double>::Type &x) { int fftsize = 2*(X.length()-1); // calc IFFT x.resize(fftsize); fftw_plan p1 = fftw_plan_dft_c2r_1d(fftsize, reinterpret_cast<fftw_complex*>( &X(1) ), &x(1), FFTW_ESTIMATE); fftw_execute(p1); fftw_destroy_plan(p1); }
void NAME(fft_filter)(data_out_t * out_data, const data_in_t * in_data, size_t len, int start, int stop, double *scale, double *offset) { double *in; fftw_complex *out; int i; /* allocate memory */ in = (double*) fftw_malloc(sizeof(double) * len + 2); out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (len / 2 + 1)); /* compute a new computation plan unless there is already one matching the input size */ if(len != fftw_plan_size) { if(fftw_plan_forward) fftw_destroy_plan(fftw_plan_forward); if(fftw_plan_backward) fftw_destroy_plan(fftw_plan_backward); fftw_plan_forward = fftw_plan_dft_r2c_1d(len, in, out, FFTW_ESTIMATE); fftw_plan_backward = fftw_plan_dft_c2r_1d(len, out, in, FFTW_ESTIMATE); } /* fill input data */ for(i=0;i<len;i++) in[i] = in_data[i]; fftw_execute(fftw_plan_forward); // do the fft /* band pass */ //fprintf(stderr, "band pass: %d to %d\n", start, stop); for(i=0;i<start;i++) out[i] = 0; for(i=stop;i<len/2+1;i++) out[i] = 0; fftw_execute(fftw_plan_backward); // reverse fft int autoscale = *scale == 0; if(autoscale) { double min, max; min = max = in[0]; for(i=1;i<len;i++) { if(in[i] < min) min = in[i]; if(in[i] > max) max = in[i]; } *offset = min; *scale = 255 / (max - min); //fprintf(stderr, "autoscale: %f (%f)\n", *scale, *offset); } else *scale /= len; for(i=0;i<len;i++) out_data[i] = (in[i] - *offset) * *scale; fftw_free(in); fftw_free(out); }
void FFTHandler::init(long arg_n){ //#ifndef DEBUG fftw_init_threads(); fftw_plan_with_nthreads(omp_get_max_threads()); //#endif n = arg_n; leased=0; //fprintf(stderr, "Initializing fft plan of size [%ld]\n", n); memoryPool.resize(1); memoryPool[0] = (double*)fftw_malloc(sizeof(double)*2*(n/2+1)); fftForwardPlan = fftw_plan_dft_r2c_1d(n, memoryPool[0], (fftw_complex*)memoryPool[0],FFTW_MEASURE); fftReversePlan = fftw_plan_dft_c2r_1d(n, (fftw_complex*)memoryPool[0], memoryPool[0],FFTW_MEASURE); }
realFFTW::realFFTW(int N){ _N = N; _in = (double *) fftw_malloc(sizeof(double) * _N); _out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (_N/2+1)); _fftCoef = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (_N/2+1)); _mag = (double *) malloc(_N*sizeof(double)); _phase = (double *) malloc(_N*sizeof(double)); _inversed = (double *) malloc(_N*sizeof(double)); //fftw plan for fft 1 dimensional, real signal _forward = fftw_plan_dft_r2c_1d(_N, _in, _out, FFTW_ESTIMATE); //Setup fftw plan for ifft 1 dimensional, complex signal _inverse = fftw_plan_dft_c2r_1d(_N, _fftCoef, _inversed, FFTW_ESTIMATE); }
void fft_init() { fft_real_in = malloc(sizeof(double) * audio_period_size_frames); fft_real_compressed = malloc(sizeof(double) * audio_period_size_frames); fft_real_out = malloc(sizeof(double) * audio_period_size_frames); fft_comp_in = fftw_malloc(sizeof(fftw_complex) * audio_period_size_frames); fft_comp_compressed = fftw_malloc(sizeof(fftw_complex) * audio_period_size_frames); fft_comp_equalized = fftw_malloc(sizeof(fftw_complex) * audio_period_size_frames); fft_comp_out = fftw_malloc(sizeof(fftw_complex) * audio_period_size_frames); fft_plan_forward = fftw_plan_dft_r2c_1d(audio_period_size_frames, fft_real_in, fft_comp_in, FFTW_ESTIMATE); fft_plan_forward_compressed = fftw_plan_dft_r2c_1d(audio_period_size_frames, fft_real_compressed, fft_comp_compressed, FFTW_ESTIMATE); fft_plan_backward = fftw_plan_dft_c2r_1d(audio_period_size_frames, fft_comp_equalized, fft_real_out, FFTW_ESTIMATE); }
/* * Prepare FFTW */ catalyzer_fftw_state * prepare_fftw(int inlen, int outlen) { catalyzer_fftw_state * mydata = NULL; mydata = (catalyzer_fftw_state *) malloc(sizeof(catalyzer_fftw_state)); mydata->raw_to_output = fftw_malloc(sizeof(double) * outlen); mydata->raw_from_input = fftw_malloc(sizeof(double) * inlen); mydata->fft_from_input = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * inlen); mydata->fft_to_output = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * outlen); mydata->fftplanin = fftw_plan_dft_r2c_1d(inlen, mydata->raw_from_input, mydata->fft_from_input, FFTW_MEASURE); mydata->fftplanout = fftw_plan_dft_c2r_1d(outlen, mydata->fft_to_output, mydata->raw_to_output, FFTW_MEASURE); return mydata; }
void fft_inverse(int N, double* real, double* imag, double* time_frame) { fftw_complex out[N / 2 + 1]; fftw_plan p2 = fftw_plan_dft_c2r_1d(N, out, time_frame, FFTW_ESTIMATE); for (int i = 0; i < (N / 2 + 1); i++) { out[i][0] = real[i]; out[i][1] = imag[i]; } fftw_execute(p2); fftw_destroy_plan(p2); return; }
/* 1-D IFFT */ void FFTW_(ifft)(real *r, real *x, long n) { #ifdef USE_FFTW #if defined(TH_REAL_IS_DOUBLE) fftw_complex *in = (fftw_complex*)x; fftw_plan p = fftw_plan_dft_c2r_1d(n, in, r, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); #else fftwf_complex *in = (fftwf_complex*)x; fftwf_plan p = fftwf_plan_dft_c2r_1d(n, in, r, FFTW_ESTIMATE); fftwf_execute(p); fftwf_destroy_plan(p); #endif #else THError("ifft : FFTW Library was not found in compile time\n"); #endif }
aubio_fft_t * new_aubio_fft (uint_t winsize) { aubio_fft_t * s = AUBIO_NEW(aubio_fft_t); #ifdef HAVE_FFTW3 uint_t i; s->winsize = winsize; /* allocate memory */ s->in = AUBIO_ARRAY(real_t,winsize); s->out = AUBIO_ARRAY(real_t,winsize); s->compspec = new_fvec(winsize); /* create plans */ pthread_mutex_lock(&aubio_fftw_mutex); #ifdef HAVE_COMPLEX_H s->fft_size = winsize/2 + 1; s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); s->pfw = fftw_plan_dft_r2c_1d(winsize, s->in, s->specdata, FFTW_ESTIMATE); s->pbw = fftw_plan_dft_c2r_1d(winsize, s->specdata, s->out, FFTW_ESTIMATE); #else s->fft_size = winsize; s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); s->pfw = fftw_plan_r2r_1d(winsize, s->in, s->specdata, FFTW_R2HC, FFTW_ESTIMATE); s->pbw = fftw_plan_r2r_1d(winsize, s->specdata, s->out, FFTW_HC2R, FFTW_ESTIMATE); #endif pthread_mutex_unlock(&aubio_fftw_mutex); for (i = 0; i < s->winsize; i++) { s->in[i] = 0.; s->out[i] = 0.; } for (i = 0; i < s->fft_size; i++) { s->specdata[i] = 0.; } #else s->winsize = winsize; s->fft_size = winsize / 2 + 1; s->compspec = new_fvec(winsize); s->in = AUBIO_ARRAY(double, s->winsize); s->out = AUBIO_ARRAY(double, s->winsize); s->ip = AUBIO_ARRAY(int , s->fft_size); s->w = AUBIO_ARRAY(double, s->fft_size); s->ip[0] = 0; #endif return s; }
void carmen_apply_inverse_fourrier_transform(double *input_real, double *input_imaginary, int input_size, double *output) { int i; fftw_plan p; fftw_complex *input; input = (fftw_complex *) fftw_malloc (sizeof(fftw_complex) * (input_size)); for(i = 0; i < input_size; i++) { input[i][0] = input_real[i]; input[i][1] = input_imaginary[i]; } p = fftw_plan_dft_c2r_1d(input_size, input, output, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); }
int MazurkaTransformer::initialize(int size) { if (fftSignalN == size) { return 1; } deinitialize(); if (size <= 0) { return 0; } fftSignalN = size; fftSignalNd2 = size/2; fftSpectrumN = size/2 + 1; fftSignal = (double*)fftw_malloc(fftSignalN * sizeof(double)); fftSpectrum = (fftw_complex*)fftw_malloc(fftSpectrumN * sizeof(fftw_complex)); // r2c_1d = real to complex, 1-dimensional // signal size = n, spectrum size = (n/2+1) complex numbers fftPlan = fftw_plan_dft_r2c_1d(size, fftSignal, fftSpectrum, FFTW_ESTIMATE); fftPlan_inverse = fftw_plan_dft_c2r_1d(size, fftSpectrum, fftSignal, FFTW_ESTIMATE); // Also can use: FFTW_ESTIMATE | FFTW_PRESERVE_INPUT // if you don't want the input to be destroyed // during the transform process. // http://www.fftw.org/fftw3_doc/Planner-Flags.html#Planner-Flags // FFTW_ESTIMATE // FFTW_MEASURE // FFTW_PATIENT // FFTW_EXHAUSTIVE if (fftPlan == NULL || fftPlan_inverse == NULL) { deinitialize(); return 0; // unsuccessful initialization } return 1; // successful initialization }
int MainWindow::fftback(std::vector<long double> vec1, std::vector<long double> vec2, std::vector<long double>& vec) { int N = vec1.size(); double* x = (double*)fftw_malloc(sizeof(double)*N); fftw_complex* in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N); for (int i = 0; i < N; i++) { in[i][0] = vec1[i]; in[i][1] = vec2[i]; } fftw_plan plan = fftw_plan_dft_c2r_1d(N, in, x, FFTW_ESTIMATE); fftw_execute(plan); for (int i = 0; i < N; i ++) { x[i] = x[i]; vec.push_back(x[i]); } fftw_destroy_plan(plan); fftw_free(x); fftw_free(in); return 0; }
static int mod_open(mod_handle_t* mod, size_t n) { mod->n = n; mod->buf = fftw_malloc((n / 2 + 1) * sizeof(fftw_complex)); if (mod->buf == NULL) goto on_error_0; mod->fplan = fftw_plan_dft_r2c_1d(n, mod->buf, mod->buf, FFTW_ESTIMATE); if (mod->fplan == NULL) goto on_error_1; mod->bplan = fftw_plan_dft_c2r_1d(n, mod->buf, mod->buf, FFTW_ESTIMATE); if (mod->bplan == NULL) goto on_error_2; return 0; on_error_2: fftw_destroy_plan(mod->fplan); on_error_1: fftw_free(mod->buf); on_error_0: return -1; }
FFTwrapper::FFTwrapper(int fftsize_) { //first one will spawn the mutex (yeah this may be a race itself) if(!mutex) { mutex = new pthread_mutex_t; pthread_mutex_init(mutex, NULL); } fftsize = fftsize_; time = new fftw_real[fftsize]; fft = new fftw_complex[fftsize + 1]; pthread_mutex_lock(mutex); planfftw = fftw_plan_dft_r2c_1d(fftsize, time, fft, FFTW_ESTIMATE); planfftw_inv = fftw_plan_dft_c2r_1d(fftsize, fft, time, FFTW_ESTIMATE); pthread_mutex_unlock(mutex); }
/* * Convolves 2 signals a and b by performing FFTs, multiplication and IFFT. * Assumes a and b are zero padded upto n = a_size + b_size - 1. */ void conv2(double* a, double* b, double* output, int n) { fftw_complex* aHat = (fftw_complex*) fftw_malloc( sizeof(fftw_complex)*n ); fftw_complex* bHat = (fftw_complex*) fftw_malloc( sizeof(fftw_complex)*n ); // Perform FFT on input a and b fftw_plan pa = fftw_plan_dft_r2c_1d(n, a, aHat, FFTW_ESTIMATE); fftw_execute(pa); fftw_destroy_plan(pa); fftw_plan pb = fftw_plan_dft_r2c_1d(n, b, bHat, FFTW_ESTIMATE); fftw_execute(pb); fftw_destroy_plan(pb); // Multiply FFTs of a and b in freq domain to perform convolution fftw_complex* abHat = (fftw_complex*) fftw_malloc( sizeof(fftw_complex)*n ); for(int i = 0; i < n; i++) { abHat[i][0] = (aHat[i][0]*bHat[i][0] - aHat[i][1]*bHat[i][1]); abHat[i][1] = (aHat[i][1]*bHat[i][0] + aHat[i][0]*bHat[i][1]); } // IFFT the convolution back into the time domain fftw_plan ipab = fftw_plan_dft_c2r_1d(n, abHat, output, FFTW_ESTIMATE); fftw_execute(ipab); fftw_destroy_plan(ipab); // Normalize output for (int i = 0; i < n; i++) { output[i] = output[i] / n; } // Free the malloc'd resources fftw_free(aHat); fftw_free(bHat); fftw_free(abHat); }