void ODEfilter(double *data, int nsample, int nfft, ODEparams * pa) { int i, k; gsl_fft_real_wavetable *real; gsl_fft_halfcomplex_wavetable *hc; gsl_fft_real_workspace *work; work = gsl_fft_real_workspace_alloc(nfft); real = gsl_fft_real_wavetable_alloc(nfft); hc = gsl_fft_halfcomplex_wavetable_alloc(nfft); double *filter = (double *) calloc(nfft, sizeof(double)); double *vdata = (double *) calloc(nsample + nfft / 2, sizeof(double)); memcpy(vdata, data, nsample * sizeof(double)); for (i = 0; i < nfft; i++) { double ff = i * 44100.0 / nfft / 2; double fil = gsl_spline_eval(pa->f_spline, ff, pa->f_acc); if (ff > 8000.) fil = 0.0; filter[i] = fil; //printf("%e %e\n", ff, fil); } for (i = 0; i < nsample; i += nfft) { for (k = 0; k < nfft; k++) { (data + i)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); /* hamming window */ (vdata + i + nfft / 2)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); } gsl_fft_real_transform(data + i, 1, nfft, real, work); gsl_fft_real_transform(vdata + i + nfft / 2, 1, nfft, real, work); for (k = 0; k < nfft; k++) { (data + i)[k] = (data + i)[k] * filter[k]; (vdata + i + nfft / 2)[k] = (vdata + i + nfft / 2)[k] * filter[k]; } gsl_fft_halfcomplex_inverse(data + i, 1, nfft, hc, work); gsl_fft_halfcomplex_inverse(vdata + i + nfft / 2, 1, nfft, hc, work); for (k = 0; k < nfft; k++) (data + i)[k] = ((data + i)[k] + (vdata + i)[k]) / 2; } gsl_fft_real_workspace_free(work); gsl_fft_real_wavetable_free(real); gsl_fft_halfcomplex_wavetable_free(hc); }
/* calculates the inverse Fourier transform of signal data (half-complex), * and stores it into fft_results */ int inverse_fft (size_t N, double *data, double *fft_results) { size_t i; int retcode; double *fft_data = (double *) calloc (N, sizeof (double)); /* initialize the data for fft */ for (i=0; i<N; i++) fft_data [i] = data [i]; /* use the corresponding routine if N is power of 2 */ if (is_power_of_n (N,2)) { /* perform the fft */ retcode = gsl_fft_halfcomplex_radix2_inverse (fft_results, 1, N); gsl_fft_halfcomplex_radix2_unpack (fft_data, fft_results, 1, N); } else { /* alloc memory for real and half-complex wavetables, and workspace */ gsl_fft_halfcomplex_wavetable *hc_wavetable = gsl_fft_halfcomplex_wavetable_alloc (N); gsl_fft_real_workspace *ws = gsl_fft_real_workspace_alloc (N); /* perform the fft */ retcode = gsl_fft_halfcomplex_inverse (fft_data, 1, N, hc_wavetable, ws); gsl_fft_halfcomplex_unpack (fft_data, fft_results, 1, N); /* free memory */ gsl_fft_halfcomplex_wavetable_free (hc_wavetable); gsl_fft_real_workspace_free (ws); } free (fft_data); return retcode; }
void SLIfilter(double *data, int nfft, double * filter) { int i, k; gsl_fft_real_wavetable *real; gsl_fft_halfcomplex_wavetable *hc; gsl_fft_real_workspace *work; work = gsl_fft_real_workspace_alloc(nfft); real = gsl_fft_real_wavetable_alloc(nfft); hc = gsl_fft_halfcomplex_wavetable_alloc(nfft); double *vdata = (double *) calloc(2*nfft+nfft/2, sizeof(double)); memcpy(vdata, data, 2* nfft * sizeof(double)); for (i = 0; i < 2; i ++) { for (k = 0; k < nfft; k++) { (data + i*nfft)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); /* hamming window */ (vdata + i*nfft + nfft / 2)[k] *= (1 - k / (1. * nfft)) * k / (1. * nfft); } gsl_fft_real_transform(data + i*nfft, 1, nfft, real, work); gsl_fft_real_transform(vdata + i*nfft + nfft / 2, 1, nfft, real, work); for (k = 0; k < nfft; k++) { (data + i*nfft)[k] = (data + i)[k] * filter[k]; (vdata + i*nfft + nfft / 2)[k] = (vdata + i + nfft / 2)[k] * filter[k]; } gsl_fft_halfcomplex_inverse(data + i*nfft, 1, nfft, hc, work); gsl_fft_halfcomplex_inverse(vdata + i*nfft + nfft / 2, 1, nfft, hc, work); for (k = 0; k < nfft; k++) (data + i*nfft)[k] = ((data + i*nfft)[k] + (vdata + i*nfft)[k]) / 2; } gsl_fft_real_workspace_free(work); gsl_fft_real_wavetable_free(real); gsl_fft_halfcomplex_wavetable_free(hc); }
int FFTRealTransform::Main() { switch(params.dir) { case FORWARD: work = gsl_fft_real_workspace_alloc (n); real = gsl_fft_real_wavetable_alloc (n); status=gsl_fft_real_transform (y, 1, n, real, work); break; case BACKWARD: work = gsl_fft_real_workspace_alloc (n); hc = gsl_fft_halfcomplex_wavetable_alloc (n); status=gsl_fft_halfcomplex_inverse (y, 1, n, hc, work); break; default: return GSL_FAILURE; } return status; }
void SmoothFilter::smoothFFT(double *x, double *y) { gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(d_n); gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(d_n); gsl_fft_real_transform (y, 1, d_n, real, work);//FFT forward gsl_fft_real_wavetable_free (real); double df = 1.0/(double)(x[1] - x[0]); double lf = df/(double)d_smooth_points;//frequency cutoff df = 0.5*df/(double)d_n; for (int i = 0; i < d_n; i++){ x[i] = d_x[i]; y[i] = i*df > lf ? 0 : y[i];//filtering frequencies } gsl_fft_halfcomplex_wavetable *hc = gsl_fft_halfcomplex_wavetable_alloc (d_n); gsl_fft_halfcomplex_inverse (y, 1, d_n, hc, work);//FFT inverse gsl_fft_halfcomplex_wavetable_free (hc); gsl_fft_real_workspace_free (work); }
void FFTFilter::calculateOutputData(double *x, double *y) { // interpolate y to even spacing double delta=(d_x[d_n-1]-d_x[0])/d_n; double xi=d_x[0]; for (int i=0, j=0; j<d_n && xi<=d_x[d_n-1]; j++) { x[j]=xi; if (i<d_n-1) y[j]=((d_x[i+1]-xi)*d_y[i] + (xi-d_x[i])*d_y[i+1])/(d_x[i+1]-d_x[i]); else y[j]=d_y[d_n-1]; xi+=delta; while (i<d_n && xi>d_x[i]) i++; } double df = 1.0/(x[d_n-1]-x[0]); gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(d_n); gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(d_n); gsl_fft_real_transform (y, 1, d_n, real, work); gsl_fft_real_wavetable_free (real); d_explanation = QLocale().toString(d_low_freq) + " "; if (d_filter_type > 2) d_explanation += tr("to") + " " + QLocale().toString(d_high_freq) + " "; d_explanation += tr("Hz") + " "; switch ((int)d_filter_type) { case 1://low pass d_explanation += tr("Low Pass FFT Filter"); for (int i = d_n-1; i >= 0 && ((i+1)/2)*df > d_low_freq; i--) y[i] = 0; break; case 2://high pass d_explanation += tr("High Pass FFT Filter"); for (int i = 0; i < d_n && ((i+1)/2)*df < d_low_freq; i++) y[i] = 0; break; case 3://band pass d_explanation += tr("Band Pass FFT Filter"); for (int i = d_offset ? 1 : 0; i < d_n; i++) if ((((i+1)/2)*df <= d_low_freq ) || (((i+1)/2)*df >= d_high_freq )) y[i] = 0; break; case 4://band block d_explanation += tr("Band Block FFT Filter"); if(!d_offset) y[0] = 0;//substract DC offset for (int i = 1; i < d_n; i++) if ((((i+1)/2)*df > d_low_freq ) && (((i+1)/2)*df < d_high_freq )) y[i] = 0; break; } gsl_fft_halfcomplex_wavetable *hc = gsl_fft_halfcomplex_wavetable_alloc (d_n); gsl_fft_halfcomplex_inverse (y, 1, d_n, hc, work); gsl_fft_halfcomplex_wavetable_free (hc); gsl_fft_real_workspace_free (work); }
void FFTFilter::calculateOutputData(double *x, double *y) { for (int i = 0; i < d_points; i++) { x[i] = d_x[i]; y[i] = d_y[i]; } double df = 0.5 / (double)(d_n * (x[1] - x[0])); // half frequency sampling due to GSL storing gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(d_n); gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(d_n); gsl_fft_real_transform(y, 1, d_n, real, work); gsl_fft_real_wavetable_free(real); ApplicationWindow *app = dynamic_cast<ApplicationWindow *>(parent()); QLocale locale = app->locale(); d_explanation = locale.toString(d_low_freq) + " "; if (d_filter_type > 2) d_explanation += tr("to") + " " + locale.toString(d_high_freq) + " "; d_explanation += tr("Hz") + " "; switch ((int)d_filter_type) { case 1: // low pass d_explanation += tr("Low Pass FFT Filter"); for (int i = 0; i < d_n; i++) y[i] = i * df > d_low_freq ? 0 : y[i]; break; case 2: // high pass d_explanation += tr("High Pass FFT Filter"); for (int i = 0; i < d_n; i++) y[i] = i * df < d_low_freq ? 0 : y[i]; break; case 3: // band pass d_explanation += tr("Band Pass FFT Filter"); if (d_offset) { // keep DC offset for (int i = 1; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? y[i] : 0; } else { for (int i = 0; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? y[i] : 0; } break; case 4: // band block d_explanation += tr("Band Block FFT Filter"); if (!d_offset) y[0] = 0; // substract DC offset for (int i = 1; i < d_n; i++) y[i] = ((i * df > d_low_freq) && (i * df < d_high_freq)) ? 0 : y[i]; break; } gsl_fft_halfcomplex_wavetable *hc = gsl_fft_halfcomplex_wavetable_alloc(d_n); gsl_fft_halfcomplex_inverse(y, 1, d_n, hc, work); gsl_fft_halfcomplex_wavetable_free(hc); gsl_fft_real_workspace_free(work); }
inline int inverse( DATA& data, wavetable const& wavetable, real::workspace& work ){ return gsl_fft_halfcomplex_inverse( data.data(), 1, data.size(), wavetable.get(), work.get() ); }
/** * C++ version of gsl_fft_halfcomplex_inverse(). * @param data An array of halfcomplex values as an array of double values. * @param n The size of the array. * @param wavetable A wavetable of size n. * @param work A workspace of size n. * @return Error code on failure. */ inline int inverse( gsl::complex_packed_array data, size_t const n, wavetable const& wavetable, real::workspace& work ){ return gsl_fft_halfcomplex_inverse( data, 1, n, wavetable.get(), work.get() ); }