Ejemplo n.º 1
0
static t_int *sigrifft_perform(t_int *w)
{
    t_sample *in = (t_sample *)(w[1]);
    int n = (int)w[2];
    mayer_realifft(n, in);
    return (w+3);
}
Ejemplo n.º 2
0
// Perform inverse FFT, returning real data
// Accepts:
//   membvars - pointer to struct of FFT variables
//   input_re - pointer to an array of the real part of the output,
//     size nfft/2 + 1
//   input_im - pointer to an array of the imaginary part of the output,
//     size nfft/2 + 1
//   output - pointer to an array of (real) input values, size nfft
void
fft_inverse(fft_vars * membvars, float *input_re, float *input_im,
	    float *output)
{
	int ti;
	int nfft;
	int hnfft;
	int numfreqs;

	nfft = membvars->nfft;
	hnfft = nfft / 2;
	numfreqs = membvars->numfreqs;

	for (ti = 0; ti < hnfft; ti++) {
		membvars->fft_data[ti] = input_re[ti];
		membvars->fft_data[nfft - 1 - ti] = input_im[ti + 1];
	}
	membvars->fft_data[hnfft] = input_re[hnfft];

	mayer_realifft(nfft, membvars->fft_data);

	for (ti = 0; ti < nfft; ti++) {
		output[ti] = membvars->fft_data[ti];
	}
}
Ejemplo n.º 3
0
YSE::DSP::buffer & YSE::DSP::inverseRealFft::operator()(YSE::DSP::buffer & realIn, YSE::DSP::buffer & imaginaryIn) {
  if (realIn.getLength() != imaginaryIn.getLength()) {
    assert(false);
  }

  if (realIn.getLength() != real.getLength()) real.resize(realIn.getLength());

  int n = realIn.getLength();
  int n2 = (n >> 1);

  if (n < 4) {
    assert(false); // minimum length is 4
    return real;
  }

  if (imaginaryIn.getPtr() == real.getPtr()) {
    flip(n2 - 1, real.getPtr() + 1, real.getPtr() + n);
    real.copyFrom(realIn, 0, 0, n2 + 1);
  }
  else {
    if (realIn.getPtr() != real.getPtr()) real.copyFrom(realIn, 0, 0, n2 + 1);
    flip(n2 - 1, imaginaryIn.getPtr() + 1, real.getPtr() + n);
  }

  mayer_realifft(real.getLength(), real.getPtr());

  return real;
}
Ejemplo n.º 4
0
static void cepstrum_tilde_realifft(int n, int n_half, t_sample *real, t_sample *imag)
{
    int i, j;
    float n_recip;
    
	for(i=(n_half+1), j=(n_half-1); i<n; i++, j--)
		real[i] = imag[j];
			
    mayer_realifft(n, real);
    
    n_recip = 1.0/n;
    
// normalize by 1/N, since mayer apparently doesn't
	for(i=0; i<n; i++)
		real[i] *= n_recip;
}
Ejemplo n.º 5
0
Var* ff_realfft3(vfuncptr func, Var* arg)
{
	Var* obj = NULL;
	size_t i, n;
	double* in;

	Alist alist[3];
	alist[0]      = make_alist("obj", ID_VAL, NULL, &obj);
	alist[1].name = NULL;

	if (parse_args(func, arg, alist) == 0) return (NULL);

	if (obj == NULL) {
		parse_error("%s: No object specified\n", func->name);
		return (NULL);
	}

	n = V_DSIZE(obj);
	if (n > INT_MAX) {
		parse_error("%s: fft function does not handle objects greater than %ld bytes.\n",
		            func->name, INT_MAX);
		return NULL;
	}

	in = (double*)calloc(n, sizeof(double));
	if (in == NULL) {
		parse_error("%s: Unable to alloc %ld bytes.\n", func->name, n * sizeof(double));
		return NULL;
	}

	for (i = 0; i < n; i++) {
		in[i] = extract_double(obj, i);
	}

	if (func->fdata == (void*)1) {
		mayer_realfft(n, in);
	} else {
		mayer_realifft(n, in);
	}

	return (newVal(BSQ, 1, n, 1, DV_DOUBLE, in));
}
Ejemplo n.º 6
0
/*************process replacing************/
t_int *phasevoc_tilde_perform (t_int *w)
{
  t_phasevoc_tilde *x = (t_phasevoc_tilde *)(w[1]);
  t_sample  *in = (t_sample *)(w[2]);
  t_sample *out1 = (t_sample *)(w[3]);
  int n = (int)(w[4]);
  t_float n2 = (t_float)n;
  x->n = n;
  int i, j;
  t_float psfact = phasevoc_tilde_cents(x);
  t_float tsfact = x->timestretch;
  t_float buffpos;
  long maskFFT=x->fftSize-1;
 

  //unless samphold or pause is on, always fill the circBuff
  if(x->pause!=1)
    {
      for(i=0; i<n; i++)
	{
	  x->circBuff[x->circBuffIndex++] = in[i];
	  while(x->circBuffIndex > (x->circBuffLength-1))x->circBuffIndex-=(x->circBuffLength);
	  while(x->circBuffIndex < 0 )x->circBuffIndex += x->circBuffLength;
	  
	}
      x->delayCount+=n;
    }

 
 if(x->delayCount>x->fftSize)
    {
      if(!x->sampHoldBuffLength)
	{
	  //init the indeces for this read-out fromt the circ buff
	  x->circBuffWindowBackIndex = x->circBuffWindowStart;
	  x->circBuffWindowFrontIndex = x->circBuffWindowBackIndex + (x->hopSize*psfact);
	}

      else
	{
	  //init the indeces for this read-out fromt the sampholdbuff
	  x->sampHoldBuffWindowBackIndex = x->sampHoldBuffWindowStart;
	  x->sampHoldBuffWindowFrontIndex = x->sampHoldBuffWindowBackIndex + (x->hopSize*psfact);
	}


      //check for dsp_tick
      if(x->dsp_tick == (x->buffer_limit*x->overlap))
	x->dsp_tick = 0;
      
      
      if((x->dsp_tick%x->buffer_limit)==0)
	{
	  //buffer in the samples if no sampbuff
	  if(!x->sampHoldBuffLength)
	    {
	      for(i=0; i<x->fftSize; i++)
		{
		  x->inFrontBuff[i] =  phasevoc_tilde_interpolate(x->circBuff, x->circBuffLength, x->circBuffWindowFrontIndex);
		  x->inBackBuff[i] =  phasevoc_tilde_interpolate(x->circBuff, x->circBuffLength, x->circBuffWindowBackIndex);
		  
		  //increment the indices by the pitchshifting factor
		  x->circBuffWindowFrontIndex+=psfact;
		  x->circBuffWindowBackIndex+=psfact;
		  
		  //wrap 'em
		  while(x->circBuffWindowFrontIndex>(x->circBuffLength-1))
		      x->circBuffWindowFrontIndex-=(x->circBuffLength);
	
		  while(x->circBuffWindowFrontIndex<0)
		      x->circBuffWindowFrontIndex+=x->circBuffLength;
		  while(x->circBuffWindowBackIndex>(x->circBuffLength-1))x->circBuffWindowBackIndex-=(x->circBuffLength);
		  while(x->circBuffWindowBackIndex<0)x->circBuffWindowBackIndex+=x->circBuffLength;
		}
	    }
	  //buffer in the samples if sampbuff
	  else
	    {
	      for(i=0; i<x->fftSize; i++)
		{
		  x->inFrontBuff[i] =  phasevoc_tilde_interpolate(x->sampHoldBuff, x->sampHoldBuffLength, x->sampHoldBuffWindowFrontIndex);
		  x->inBackBuff[i] =  phasevoc_tilde_interpolate(x->sampHoldBuff, x->sampHoldBuffLength, x->sampHoldBuffWindowBackIndex);
		  
		  //increment the indices by the pitchshifting factor
		  x->sampHoldBuffWindowFrontIndex+=psfact;
		  x->sampHoldBuffWindowBackIndex+=psfact;
		  
		  //wrap 'em
		  while(x->sampHoldBuffWindowFrontIndex>(x->sampHoldBuffLength-1))
		      x->sampHoldBuffWindowFrontIndex-=(x->sampHoldBuffLength);
		   
		  while(x->sampHoldBuffWindowFrontIndex<0)
		      x->sampHoldBuffWindowFrontIndex+=x->sampHoldBuffLength;
		    
		  while(x->sampHoldBuffWindowBackIndex>(x->sampHoldBuffLength-1))x->sampHoldBuffWindowBackIndex-=(x->sampHoldBuffLength);
		  while(x->sampHoldBuffWindowBackIndex<0)x->sampHoldBuffWindowBackIndex+=x->sampHoldBuffLength;
		}
	    }

	  //window the signal
	  for(i=0; i<x->fftSize; i++)
	    {

	      x->inFrontBuff[i] *= x->analWindow[i];
	      x->inBackBuff[i] *= x->analWindow[i];

	    }
	  
	  
	  
	  //go to frequency domain
	  mayer_realfft(x->fftSize, x->inFrontBuff);
	  mayer_realfft(x->fftSize, x->inBackBuff);

	  
	  
	  //unpack the bizzarely packed mayer ffts
	  for(i=0; i<=x->fftHalfSize; i++)// halfSizeFFT = nyquist
	    {
	      x->frontReal[i] = x->inFrontBuff[i];
	      x->backReal[i] = x->inBackBuff[i];

	    }
	  x->frontImag[0] = x->backImag[0]= 0;  // 0 DC
	  
	  for(i=(x->fftSize-1), j=1; i>x->fftHalfSize; i--, j++)
	    {

	      x->frontImag[j] = x->inFrontBuff[i];
	      x->backImag[j] = x->inBackBuff[i];


	    }
	  
	  x->frontImag[x->fftHalfSize]=x->backImag[x->fftHalfSize]=0; //halfSizeFFT empty
	  
	  for(i = 0; i <= x->fftHalfSize; i++)
	    {
	      //first normalize over magnitude so we get phase only
	      x->rsqrt[i] = q8_rsqrt((x->prevReal[i] * x->prevReal[i]) +
				     (x->prevImag[i] * x->prevImag[i]) +
				     .000000000000000000001f);
	      x->prevReal[i] *= x->rsqrt[i];
	      x->prevImag[i] *= x->rsqrt[i];

	      x->conjReal[i] = (x->prevReal[i] * x->backReal[i]) + (x->prevImag[i] * x->backImag[i]) +
	      	.0000000000000001;
	      x->conjImag[i] = (x->prevImag[i] * x->backReal[i]) - (x->prevReal[i] * x->backImag[i]);

	    	      
	      x->rsqrt[i] = q8_rsqrt((x->conjReal[i] * x->conjReal[i]) +
	      			     (x->conjImag[i] * x->conjImag[i]));
	      x->conjReal[i] *= x->rsqrt[i];
	      x->conjImag[i] *= x->rsqrt[i];

	      //then add the front window (complex multiply) this time keeping magnitudes, and store the info for the next time around
	      x->outReal[i] = (x->conjReal[i] * x->frontReal[i]) - (x->conjImag[i] * x->frontImag[i]);
	      
	      x->outImag[i] = (x->conjReal[i] * x->frontImag[i]) + (x->conjImag[i] * x->frontReal[i]);
	      x->prevImag[i] = x->outImag[i];
	      x->prevReal[i] = x->outReal[i];
	    }

	  //phase has been propogated, repack for ifft
	  for(i=0; i<=x->fftHalfSize; i++)  // +1 to include Nyquist
	    x->outSpectra[i] = x->outReal[i];
	  
	  for(j = x->fftHalfSize -1, i = x->fftHalfSize + 1; i < x->fftSize; j--, i++)
	    x->outSpectra[i] = x->outImag[j];
	  
	  //back to time domain
	  mayer_realifft(x->fftSize, x->outSpectra);

	  //william brent's overlap/add function:
	  //window the synthesis
	  for(i=0; i<x->fftSize; i++)
	    x->outSpectra[i] *= x->synthWindow[i];//synthWindow is 2/3/fftSize*analWindow
	  
	  //  first shift output in nonoverlapped buffer
	  for(i=0; i<((x->overlap-1)*x->fftSize); i++)
	    x->nonoverlappedOutBuff[i] = x->nonoverlappedOutBuff[x->fftSize+i];
	 
	  //  then, write a new window in
	  for(i=0; i<x->fftSize; i++)
	    x->nonoverlappedOutBuff[((x->overlap-1)*x->fftSize)+i] = x->outSpectra[i];
	  
	  // init this chunk of the final output so it can be summed in the for() below
	  for(i=0; i<(x->hopSize); i++)
	    x->outBuff[i] = 0.0;
	  
	  // do the overlap/add: add the last hopsize of the first
	  for(i=0; i<x->overlap; i++)
	    for(j=0; j<(x->hopSize); j++)
	      x->outBuff[j] += x->nonoverlappedOutBuff[(i*x->fftSize)+((x->overlap-i-1)*x->hopSize)+j/*overlap_chunk*/];
	  x->fft_tick=0;
	}
      
      //output
      for(i=0; i<n; i++, out1++)
	*out1 = x->outBuff[(x->fft_tick*n)+i];
      if(!x->sampHoldBuffLength)
	buffpos = 1.0-(x->circBuffIndex - x->circBuffWindowStart) / x->circBuffLength;
      else
	buffpos = 1.0-(x->sampHoldBuffIndex - x->sampHoldBuffWindowStart) / x->sampHoldBuffLength;
      while(buffpos>=1.0)buffpos -= 1.0;
      while(buffpos<=0.0)buffpos += 1.0;
      outlet_float(x->buffPos, buffpos);
      x->fft_tick++;
      x->dsp_tick++;

      //increment the read start point and wrap it
      if(!x->sampHoldBuffLength)
	{
	  x->circBuffWindowStart+=n*tsfact;
	  while(x->circBuffWindowStart > (x->circBuffLength-1))x->circBuffWindowStart-=x->circBuffLength;
	  while(x->circBuffWindowStart<0)x->circBuffWindowStart+=x->circBuffLength;
	}

      else
	{
	  x->sampHoldBuffWindowStart+=n*tsfact;
	  while(x->sampHoldBuffWindowStart > (x->sampHoldBuffLength-1))x->sampHoldBuffWindowStart-=x->sampHoldBuffLength;
	  while(x->sampHoldBuffWindowStart<0)x->sampHoldBuffWindowStart+=x->sampHoldBuffLength;
	}

      return(w+5);
    }
 else
   {
     *out1++ = 0.0;
     return(w+5);

   }
   
}