Exemplo n.º 1
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);

   }
   
}
Exemplo n.º 2
0
float qrsqrt(float f) {return (q8_rsqrt(f)); }