Beispiel #1
0
/* 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;
}
Beispiel #2
0
static VALUE rb_gsl_fft_halfcomplex_wavetable_new(VALUE klass, VALUE n)
{
  CHECK_FIXNUM(n);
  return Data_Wrap_Struct(klass, 0, gsl_fft_halfcomplex_wavetable_free,
			  gsl_fft_halfcomplex_wavetable_alloc(FIX2INT(n)));
  
}
	/**
	 * The default constructor creates a new workspace of size n.
	 * @param n The size of the workspace.
	 */
	explicit wavetable( size_t const n ){
	  ccgsl_pointer = gsl_fft_halfcomplex_wavetable_alloc( n );
	  // just plausibly we could allocate wavetable but not count
	  try { count = new size_t; } catch( std::bad_alloc& e ){
	    // try to tidy up before rethrowing
	    gsl_fft_halfcomplex_wavetable_free( ccgsl_pointer );
	    throw e;
	  }
	  *count = 1; // initially there is just one reference to ccgsl_pointer
	}
Beispiel #4
0
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);

}
Beispiel #5
0
// Parse argc, argv.  obj must be GSL::Vector of halfcomplex data
static int gsl_fft_get_argv_halfcomplex(int argc, VALUE *argv, VALUE obj,
			   double **ptr, size_t *stride,
			    size_t *n, gsl_fft_halfcomplex_wavetable **table,
			    gsl_fft_real_workspace **space, int *naflag)
{
  int flag = NONE_OF_TWO, flagtmp, i, itmp = argc, itmp2 = 0, ccc;
  int flagw = 0;

  *ptr = get_ptr_double3(obj, n, stride, naflag);

  ccc = argc;
  flagtmp = 0;
  flagw = 0;
  for (i = argc-1; i >= itmp2; i--) {
    if (rb_obj_is_kind_of(argv[i], cgsl_fft_real_workspace)) {
      Data_Get_Struct(argv[i], gsl_fft_real_workspace, *space);
      flagtmp = 1;
      flagw = 1;
      itmp = i;
      ccc--;
      break;
    }
  }
  flagtmp = 0;
  for (i = itmp-1; i >= itmp2; i--) {
    if (rb_obj_is_kind_of(argv[i], cgsl_fft_halfcomplex_wavetable)) {
      Data_Get_Struct(argv[i], gsl_fft_halfcomplex_wavetable, *table);
      flagtmp = 1;
      ccc--;
      break;
    }
  }
  if (flagw == 0) {
    *space = gsl_fft_real_workspace_alloc(*n);
    flag += ALLOC_SPACE;
  }
  if (flagtmp == 0) {
    *table = gsl_fft_halfcomplex_wavetable_alloc(*n);
    flag += ALLOC_TABLE;
  }
  if (*table == NULL) {
    rb_raise(rb_eRuntimeError, "something wrong with wavetable");
  }
  if (*space == NULL) {
    rb_raise(rb_eRuntimeError, "something wrong with workspace");
  }
  return flag;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);

}
Beispiel #8
0
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);
}
Beispiel #9
0
static PyObject* 
PyGSL_transform_space_init(PyObject *self, PyObject *args, const enum pygsl_transform_space_type type)
{
	PyGSL_transform_space *o=NULL;
	size_t n;
	FUNC_MESS_BEGIN();
	o =  (PyGSL_transform_space *) PyObject_NEW(PyGSL_transform_space, &PyGSL_transform_space_pytype);
	if(o == NULL){
		return NULL;
	}

	if (0==PyArg_ParseTuple(args,"l", &n))
		return NULL;


	if (n<=0) {
	     pygsl_error("dimension must be >0", filename, __LINE__, GSL_EINVAL);
	     return NULL;
	}
	o->type = type;
	switch(type){
	case COMPLEX_WORKSPACE:           o->space.cws  = gsl_fft_complex_workspace_alloc(n);            break;
	case COMPLEX_WAVETABLE:           o->space.cwt  = gsl_fft_complex_wavetable_alloc(n);            break;
	case REAL_WORKSPACE:              o->space.rws  = gsl_fft_real_workspace_alloc(n);               break;
	case REAL_WAVETABLE:	          o->space.rwt  = gsl_fft_real_wavetable_alloc(n);               break;
	case HALFCOMPLEX_WAVETABLE:       o->space.hcwt = gsl_fft_halfcomplex_wavetable_alloc(n);        break;
	case COMPLEX_WORKSPACE_FLOAT:     o->space.cwsf  = gsl_fft_complex_workspace_float_alloc(n);     break;
	case COMPLEX_WAVETABLE_FLOAT:     o->space.cwtf  = gsl_fft_complex_wavetable_float_alloc(n);     break;
	case REAL_WORKSPACE_FLOAT:        o->space.rwsf  = gsl_fft_real_workspace_float_alloc(n);        break;
	case REAL_WAVETABLE_FLOAT:	  o->space.rwtf  = gsl_fft_real_wavetable_float_alloc(n);        break;
	case HALFCOMPLEX_WAVETABLE_FLOAT: o->space.hcwtf = gsl_fft_halfcomplex_wavetable_float_alloc(n); break;
#ifdef _PYGSL_GSL_HAS_WAVELET
	case WAVELET_WORKSPACE          : o->space.wws   = gsl_wavelet_workspace_alloc(n);               break;
#endif
	default: pygsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY); return NULL; break;
	}
	assert(o->space.v);
	FUNC_MESS_END();
	return (PyObject *) o;
}
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);
}
Beispiel #11
0
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);
}