Example #1
0
int main()
{
    int n, ip[NMAXSQRT + 2];
    double a[NMAX + 1], w[NMAX * 5 / 4], t[NMAX / 2 + 1], err;

    printf("data length n=? (must be 2^m)\n");
    scanf("%d", &n);
    ip[0] = 0;

    /* check of CDFT */
    putdata(0, n - 1, a);
    cdft(n, 1, a, ip, w);
    cdft(n, -1, a, ip, w);
    err = errorcheck(0, n - 1, 2.0 / n, a);
    printf("cdft err= %g \n", err);

    /* check of RDFT */
    putdata(0, n - 1, a);
    rdft(n, 1, a, ip, w);
    rdft(n, -1, a, ip, w);
    err = errorcheck(0, n - 1, 2.0 / n, a);
    printf("rdft err= %g \n", err);

    /* check of DDCT */
    putdata(0, n - 1, a);
    ddct(n, 1, a, ip, w);
    ddct(n, -1, a, ip, w);
    a[0] *= 0.5;
    err = errorcheck(0, n - 1, 2.0 / n, a);
    printf("ddct err= %g \n", err);

    /* check of DDST */
    putdata(0, n - 1, a);
    ddst(n, 1, a, ip, w);
    ddst(n, -1, a, ip, w);
    a[0] *= 0.5;
    err = errorcheck(0, n - 1, 2.0 / n, a);
    printf("ddst err= %g \n", err);

    /* check of DFCT */
    putdata(0, n, a);
    a[0] *= 0.5;
    a[n] *= 0.5;
    dfct(n, a, t, ip, w);
    a[0] *= 0.5;
    a[n] *= 0.5;
    dfct(n, a, t, ip, w);
    err = errorcheck(0, n, 2.0 / n, a);
    printf("dfct err= %g \n", err);

    /* check of DFST */
    putdata(1, n - 1, a);
    dfst(n, a, t, ip, w);
    dfst(n, a, t, ip, w);
    err = errorcheck(1, n - 1, 2.0 / n, a);
    printf("dfst err= %g \n", err);

    return 0;
}
Example #2
0
// 音声コールバック関数
LRESULT CALLBACK CSpectrumAnalyzer::AudioCallback(short *pData,DWORD Samples,int Channels,void *pClientData)
{
	CSpectrumAnalyzer *pThis=static_cast<CSpectrumAnalyzer*>(pClientData);

	DWORD BufferUsed=pThis->m_BufferUsed;
	DWORD j=pThis->m_BufferPos;
	for (DWORD i=0;i<Samples;i++) {
		if (j==FFT_SIZE)
			j=0;
		pThis->m_pBuffer[j]=pData[i*Channels];
		j++;
		BufferUsed++;

		if (BufferUsed==FFT_SIZE) {
			pThis->m_FFTLock.Lock();
			// doubleに変換
			for (int k=0;k<FFT_SIZE;k++) {
				pThis->m_pFFTBuffer[k]=
					(double)pThis->m_pBuffer[(j+k)%FFT_SIZE]/32768.0;
			}

			// FFT処理実行
			rdft(FFT_SIZE,1,pThis->m_pFFTBuffer,
				 pThis->m_pFFTWorkBuffer,pThis->m_pFFTSinTable);
			pThis->m_FFTLock.Unlock();

			BufferUsed=0;
		}
	}

	pThis->m_BufferUsed=BufferUsed;
	pThis->m_BufferPos=j;

	return 0;
}
Example #3
0
void aubio_fft_rdo_complex(aubio_fft_t * s, fvec_t * compspec, fvec_t * output) {
  uint_t i;
#ifdef HAVE_FFTW3
  const smpl_t renorm = 1./(smpl_t)s->winsize;
#ifdef HAVE_COMPLEX_H
  s->specdata[0] = compspec->data[0];
  for (i=1; i < s->fft_size - 1; i++) {
    s->specdata[i] = compspec->data[i] +
      I * compspec->data[compspec->length - i];
  }
  s->specdata[s->fft_size - 1] = compspec->data[s->fft_size - 1];
#else
  for (i=0; i < s->fft_size; i++) {
    s->specdata[i] = compspec->data[i];
  }
#endif
  fftw_execute(s->pbw);
  for (i = 0; i < output->length; i++) {
    output->data[i] = s->out[i]*renorm;
  }
#else /* HAVE_FFTW3 */
  smpl_t scale = 2.0 / s->winsize;
  s->out[0] = compspec->data[0];
  s->out[1] = compspec->data[s->winsize / 2];
  for (i = 1; i < s->fft_size - 1; i++) {
    s->out[2 * i] = compspec->data[i];
    s->out[2 * i + 1] = - compspec->data[s->winsize - i];
  }
  rdft(s->winsize, -1, s->out, s->ip, s->w);
  for (i=0; i < s->winsize; i++) {
    output->data[i] = s->out[i] * scale;
  }
#endif /* HAVE_FFTW3 */
}
Example #4
0
void rfft(int n,int isign,REAL *x)
{
    static int ipsize = 0,wsize=0;
    static int *ip = NULL;
    static REAL *w = NULL;
    int newipsize,newwsize;
    if (n == 0) {
        free(ip); ip = NULL; ipsize = 0;
        free(w);  w  = NULL; wsize  = 0;
        return;
    }

    n = 1 << n;


    newipsize = 2+sqrt(n/2);
    if (newipsize > ipsize) {
        ipsize = newipsize;
        ip = (int *)realloc(ip,sizeof(int)*ipsize);
        ip[0] = 0;
    }

    newwsize = n/2;
    if (newwsize > wsize) {
        wsize = newwsize;
        w = (REAL *)realloc(w,sizeof(REAL)*wsize);
    }

    rdft(n,isign,x,ip,w);
}
Example #5
0
void aubio_fft_do_complex(aubio_fft_t * s, fvec_t * input, fvec_t * compspec) {
  uint_t i;
  for (i=0; i < s->winsize; i++) {
    s->in[i] = input->data[i];
  }
#ifdef HAVE_FFTW3
  fftw_execute(s->pfw);
#ifdef HAVE_COMPLEX_H
  compspec->data[0] = REAL(s->specdata[0]);
  for (i = 1; i < s->fft_size -1 ; i++) {
    compspec->data[i] = REAL(s->specdata[i]);
    compspec->data[compspec->length - i] = IMAG(s->specdata[i]);
  }
  compspec->data[s->fft_size-1] = REAL(s->specdata[s->fft_size-1]);
#else /* HAVE_COMPLEX_H  */
  for (i = 0; i < s->fft_size; i++) {
    compspec->data[i] = s->specdata[i];
  }
#endif /* HAVE_COMPLEX_H */
#else /* HAVE_FFTW3 */
  rdft(s->winsize, 1, s->in, s->ip, s->w);
  compspec->data[0] = s->in[0];
  compspec->data[s->winsize / 2] = s->in[1];
  for (i = 1; i < s->fft_size - 1; i++) {
    compspec->data[i] = s->in[2 * i];
    compspec->data[s->winsize - i] = - s->in[2 * i + 1];
  }
#endif /* HAVE_FFTW3 */
}
Example #6
0
void do_thresher(t_thresher *x)
{
	int i;
	
	t_fftease *fft = x->fft;
	t_float *channel = fft->channel;
	t_float damping_factor = x->damping_factor;
	int max_hold_frames = x->max_hold_frames;
	int *frames_left = x->frames_left;
	t_float *composite_frame = x->composite_frame;
	int N = fft->N;
	t_float move_threshold = x->move_threshold;

	fold(fft);
	rdft(fft,FFT_FORWARD);
	convert(fft);
	
	if( x->first_frame ){
		for ( i = 0; i < N+2; i++ ){
			composite_frame[i] = channel[i];
			frames_left[i] = max_hold_frames;
		}
		x->first_frame = 0;
	} else {
		for( i = 0; i < N+2; i += 2 ){
			if(fabs( composite_frame[i] - channel[i] ) > move_threshold || frames_left[i] <= 0 ){
				composite_frame[i] = channel[i];
				composite_frame[i+1] = channel[i+1];
				frames_left[i] = max_hold_frames;
			} else {
				--(frames_left[i]);
				composite_frame[i] *= damping_factor;
			}
		}
	}
	// try memcpy here
	for ( i = 0; i < N+2; i++ ){
		channel[i] = composite_frame[i];
	}
	if(fft->obank_flag){
		oscbank(fft);
	} else {
		unconvert(fft);
		rdft(fft,FFT_INVERSE);
		overlapadd(fft);
	}	
}
Example #7
0
void do_leaker(t_leaker *x)
{
	int i,odd,even;
	t_float a1,a2,b1,b2;
	t_fftease *fft = x->fft;
	t_fftease *fft2 = x->fft2;
	int N2 = fft->N2;
	t_float *buffer1 = fft->buffer;
	t_float *buffer2 = fft2->buffer;
	t_float *channel1 = fft->channel;
	int *sieve = x->sieve;
	t_float fade_value = x->fade_value;

	fold(fft);		
	fold(fft2);	
	rdft(fft,1);
	rdft(fft2,1);
	
	
	for ( i = 0; i <= N2; i++ ) {
		odd = ( even = i<<1 ) + 1;
		if( fade_value <= 0 || fade_value < sieve[i]  ){
			a1 = ( i == N2 ? *(buffer1+1) : *(buffer1+even) );
			b1 = ( i == 0 || i == N2 ? 0. : *(buffer1+odd) );
			
			*(channel1+even) = hypot( a1, b1 ) ;
			*(channel1+odd) = -atan2( b1, a1 );
			*(buffer1+even) = *(channel1+even) * cos(*(channel1+odd));
			if ( i != N2 ){
				*(buffer1+odd) = -(*(channel1+even)) * sin(*(channel1+odd));
			}
		} else {
			a2 = ( i == N2 ? *(buffer2+1) : *(buffer2+even) );
			b2 = ( i == 0 || i == N2 ? 0. : *(buffer2+odd) );
			*(channel1+even) = hypot( a2, b2 ) ;
			*(channel1+odd) = -atan2( b2, a2 );
			*(buffer1+even) = *(channel1+even) * cos(*(channel1+odd) );
			if ( i != N2 ){
				*(buffer1+odd) = -(*(channel1+even)) * sin( *(channel1+odd) );
			}
		}
	}
	rdft(fft,-1);
	overlapadd(fft);
}
Example #8
0
Var* ff_realfft2(vfuncptr func, Var* arg)
{
	Var* obj = NULL;
	int i, j, n, x;
	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);
	for (x = n; (x & 1) == 0; x >>= 1)
		;
	if (x != 1) {
		parse_error("dimension not a power of 2. Use version 0.\n");
		return (NULL);
	}

	in = (double*)calloc(n, sizeof(double));

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

	if (func->fdata == (void*)1) {
		rdft(n, cos(M_PI / n), sin(M_PI / n), in);
	} else {
		rdft(n, cos(M_PI / n), -sin(M_PI / n), in);
		for (j = 0; j <= n - 1; j++) {
			in[j] *= 2.0 / n;
		}
	}

	return (newVal(BSQ, 1, n, 1, DV_DOUBLE, in));
}
Example #9
0
// input : Signal *x
// output: energy spectrum *erg
void
PowSpec256 ( const float* x, float* erg )
{
    int i;
    // windowing
    for( i = 0; i < 256; ++i )
        a[i] = x[i] * Hann_256[i];

    rdft(256, a, ip, w); // perform FFT

    // calculate power
    for( i = 0; i < 128; ++i)
        erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1];
}
Example #10
0
// input : Signal *x
// output: energy spectrum *erg
void
PowSpec1024 ( const float* x, float* erg )
{
    int i;
    // windowing
    for( i = 0; i < 1024; ++i )
        a[i] = x[i] * Hann_1024[i];

    rdft(1024, a, ip, w); // perform FFT

    // calculate power
    for( i = 0; i < 512; ++i)
        erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1];
}
Example #11
0
// input : logarithmized energy spectrum *cep
// output: Cepstrum *cep (in-place)
void
Cepstrum2048 ( float* cep, const int MaxLine )
{
    int i, j;
    // generate real, even spectrum (symmetric around 1024, cep[2048-i] = cep[i])
    for( i = 0, j = 1024; i < 1024; ++i, --j )
        cep[1024 + j] = cep[i];
 
    rdft(2048, cep, ip, w);
 
    // only real part as outcome (all even indexes of cep[])
    for( i = 0; i < MaxLine + 1; ++i )
        cep[i] = cep[i*2] * (float) (0.9888 / 2048);
}
Example #12
0
// input : Signal *x
// output: energy spectrum *erg
void
PowSpec2048 ( const float* x, float* erg )
{
    int i;
    // windowing (only 1600 samples available -> centered in 2048!)
    memset(a, 0, 224 * sizeof *a);
    for( i = 0; i < 1600; ++i )
        a[i+224] = x[i] * Hann_1600[i];
    memset(a + 1824, 0, 224 * sizeof *a);

    rdft(2048, a, ip, w); // perform FFT

    // calculate power
    for( i = 0; i < 1024; ++i)
        erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1];
}
Example #13
0
// input : Signal *x
// output: energy spectrum *erg and phase spectrum *phs
void
PolarSpec1024 ( const float* x, float* erg, float* phs )
{
    int i;
    for( i = 0; i < 1024; i++ )
        a[i] = x[i] * Hann_1024[i];

    rdft( 1024, a, ip, w); // perform FFT

    // calculate power and phase
    for( i = 0; i < 512; ++i )
    {
        erg[i]  = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1];
        phs[i]  = ATAN2F( a[i*2+1], a[i*2] );  
    }
}
Example #14
0
void OouraFFT::fft(float* in, std::complex<float>* out)
{
	size_t nfft = buffer_.size();

	// copy input data to buffer used by ooura
	for (size_t i = 0; i < nfft; ++i)
		buffer_[i] = in[i];

	// perform forward DFT
	rdft((int)nfft, +1, buffer_.data(), ip_.data(), sineTable_.data());

	// copy to output from the ooura format
	for (size_t i = 0; i < nfft / 2; ++i)
	{
		out[i].real((float)buffer_[i * 2]); //real part
		out[i].imag((float)buffer_[i * 2 + 1]); // imag part
	}
	out[nfft / 2].real((float)buffer_[1]); // a[1] = R[n/2]
}
Example #15
0
void OouraFFT::ifft(std::complex<float>* in, float* out)
{
	size_t nfft = buffer_.size();

	// copy to the ooura format
	for (size_t i = 0; i < nfft / 2; ++i)
	{
		buffer_[i * 2] = in[i].real(); // real part
        buffer_[i * 2 + 1] = in[i].imag(); // imag part
	}
	buffer_[1] = in[nfft / 2].real(); // a[1] = R[n/2]

	// perform inverse DFT
	rdft((int)nfft, -1, buffer_.data(), ip_.data(), sineTable_.data());

	// copy to output
	for (size_t i = 0; i < nfft; ++i)
		out[i] = (float)buffer_[i];
}
Example #16
0
void PCM::getPCM(float *PCMdata, int samples, int channel, int freq, float smoothing, int derive)
{
   int i,index;

   index=start-1;

   if (index<0) index=maxsamples+index;

   PCMdata[0]=PCMd[channel][index];

   for(i=1;i<samples;i++)
     {
       index=start-1-i;
       if (index<0) index=maxsamples+index;

       PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
     }

   //return derivative of PCM data
   if(derive)
     {
       for(i=0;i<samples-1;i++)
	 {
	   PCMdata[i]=PCMdata[i]-PCMdata[i+1];
	 }
       PCMdata[samples-1]=0;
     }

   //return frequency data instead of PCM (perform FFT)

   if (freq)

     {
       double temppcm[1024];
       for (int i=0;i<samples;i++)
	 {temppcm[i]=(double)PCMdata[i];}
       rdft(samples, 1, temppcm, ip, w);
       for (int j=0;j<samples;j++)
	 {PCMdata[j]=(float)temppcm[j];}
     }
}
Example #17
0
      virtual void ifft(float* data, const float* re, const float* im) override
      {
        // Convert into the format as required by the Ooura FFT
        {
          double* b = &_buffer[0];
          double* bEnd = b + _size;
          const float *r = re;
          const float *i = im;
          while (b != bEnd)
          {
            *(b++) = static_cast<double>(*(r++));
            *(b++) = -static_cast<double>(*(i++));
          }
          _buffer[1] = re[_size / 2];
        }

        rdft(static_cast<int>(_size), -1, _buffer.data(), _ip.data(), _w.data());

        // Convert back to split-complex
        ScaleBuffer(data, &_buffer[0], 2.0 / static_cast<double>(_size), _size);
      }
Example #18
0
      virtual void fft(const float* data, float* re, float* im) override
      {
        // Convert into the format as required by the Ooura FFT
        ConvertBuffer(&_buffer[0], data, _size);

        rdft(static_cast<int>(_size), +1, _buffer.data(), _ip.data(), _w.data());

        // Convert back to split-complex
        {
          double* b = &_buffer[0];
          double* bEnd = b + _size;
          float *r = re;
          float *i = im;
          while (b != bEnd)
          {
            *(r++) = static_cast<float>(*(b++));
            *(i++) = static_cast<float>(-(*(b++)));
          }
        }
        const size_t size2 = _size / 2;
        re[size2] = -im[0];
        im[0] = 0.0;
        im[size2] = 0.0;
      }
Example #19
0
KstObject::UpdateType KstPSDCurve::update(int update_counter) {
  int i_subset, i_samp;
  int n_subsets;
  int v_len;
  int copyLen;
  double mean;
  double y;
  bool force = false;
  KstVectorPtr iv = _inputVectors[INVECTOR];

  double *psd;

  if (KstObject::checkUpdateCounter(update_counter))
    return NO_CHANGE;

  if (update_counter <= 0) {
    force = true;
  } else {
    iv->update(update_counter);
  }

  v_len = iv->sampleCount();

  n_subsets = v_len/PSDLen+1;

  last_n_new += iv->numNew();

  if ((last_n_new < PSDLen/16) && (n_subsets - last_n_subsets < 1) && !force) {
    return NO_CHANGE;
  }

  psd = (*_sVector)->value();

  for (i_samp = 0; i_samp < PSDLen; i_samp++) {
    psd[i_samp] = 0;
  }

  for (i_subset = 0; i_subset < n_subsets; i_subset++) {
    /* copy each chunk into a[] and find mean */
    if (i_subset*PSDLen + ALen <= v_len) {
      copyLen = ALen;
    } else {
      copyLen = v_len - i_subset*PSDLen;
    }
    mean = 0;
    for (i_samp = 0; i_samp < copyLen; i_samp++) {
      mean += (
        a[i_samp] =
        iv->interpolate(i_samp + i_subset*PSDLen, v_len)
        );
    }
    if (copyLen>1) mean/=(double)copyLen;

    /* Remove Mean and apodize */
    if (removeMean() && appodize()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        a[i_samp]= (a[i_samp]-mean)*w[i_samp];
      }
    } else if (removeMean()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        a[i_samp] -= mean;
      }
    } else if (appodize()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        a[i_samp] *= w[i_samp];
      }
    }
    for (;i_samp < ALen; i_samp++) a[i_samp] = 0.0;

    /* fft a */
    rdft(ALen, 1, a);
    /* sum each bin into psd[] */
    psd[0]+=a[0];
    psd[PSDLen-1] += a[1];
    for (i_samp=1; i_samp<PSDLen-1; i_samp++) {
      psd[i_samp]+= cabs(a[i_samp*2], a[i_samp*2+1]);
    }
  }

  last_f0 = 0;
  last_n_subsets = n_subsets;
  last_n_new = 0;

  norm_factor = 1.0/(sqrt(double(Freq)*double(PSDLen))*double(n_subsets));

  psd[0]*=norm_factor;

  MaxY = MinY = mean = psd[0];
  if (psd[0]>0)
    MinPosY = psd[0];
  else (MinPosY = 1.0e300);

  /* normalize psd */
  for (i_samp=1; i_samp<PSDLen; i_samp++) {
    y = (psd[i_samp]*=norm_factor);
    if (y>MaxY)
      MaxY=y;
    if (y<MinY)
      MinY=y;
    if ((y>0) && (y<MinPosY))
      MinPosY = y;
    mean +=y;
  }

  if (PSDLen > 0)
    MeanY = mean/PSDLen;
  else MeanY = 0; // should never ever happen...

  NS = PSDLen;

  if (Freq <= 0)
    Freq = 1.0;

  MaxX = Freq/2.0;
  MinX = 0;
  MinPosX = 1.0/double(NS) * MaxX;
  MeanX = MaxX/2.0;

  double *f = (*_fVector)->value();
  f[0] = 0;
  f[1] = Freq/2.0;

  (*_sVector)->update(update_counter);
  (*_fVector)->update(update_counter);

  return UPDATE;
}
Example #20
0
void do_cross(t_cross *x)
{
	t_fftease *fft = x->fft;
	t_fftease *fft2 = x->fft2;
	int i;
	int N2 = fft->N2;
	t_float a1, b1, a2, b2;
	t_float *buffer1 = fft->buffer;
	t_float *buffer2 = fft2->buffer;
	t_float *channel1 = fft->channel;
	short autonorm = x->autonorm;
	int N = fft->N;
	t_float mult = fft->mult;
	int even, odd;
	t_float gainer;
	t_float threshie = x->threshie;
	t_float ingain = 0;
	t_float outgain, rescale;
	t_float mymult;
		
	fold(fft);		
	fold(fft2);	
	rdft(fft,1);
	rdft(fft2,1);
	
	/* changing algorithm for window flexibility */
	if(autonorm){
		ingain = 0;
		for(i = 0; i < N; i+=2){
			ingain += hypot(buffer1[i], buffer1[i+1]);
		}
	}
	
	for ( i = 0; i <= N2; i++ ) {
		odd = ( even = i<<1 ) + 1;
		
		a1 = ( i == N2 ? *(buffer1+1) : *(buffer1+even) );
		b1 = ( i == 0 || i == N2 ? 0. : *(buffer1+odd) );
		a2 = ( i == N2 ? *(buffer2+1) : *(buffer2+even) );
		b2 = ( i == 0 || i == N2 ? 0. : *(buffer2+odd) );
		gainer = hypot(a2, b2);
		if( gainer > threshie ) 
			*(channel1+even) = hypot( a1, b1 ) * gainer;
		*(channel1+odd) = -atan2( b1, a1 );
		*(buffer1+even) = *(channel1+even) * cos( *(channel1+odd) );
		if ( i != N2 )
			*(buffer1+odd) = -(*(channel1+even)) * sin( *(channel1+odd) );
		
	}
	if(autonorm){
		outgain = 0;
		for(i = 0; i < N; i+=2){
			outgain += hypot(buffer1[i], buffer1[i+1]);
		}
		if(ingain <= .0000001){
			// post("gain emergency!");
			rescale = 1.0;
		} else {
			rescale = ingain / outgain;
		} 
		//post("ingain %f outgain %f rescale %f",ingain, outgain, rescale);
		x->normult = mult * rescale;
	}  else {
		x->normult = mult;
        //post("mymult: %f", mymult);
	}
	rdft(fft, -1);
	overlapadd(fft);
}
Example #21
0
void do_ether(t_ether *x)
{
	t_fftease *fft = x->fft;
	t_fftease *fft2 = x->fft2;
	int i;
	int N2 = fft->N2;
	float a1, b1, a2, b2;
	int even, odd;
	int invert = x->invert;
	t_float threshMult = x->threshMult;
	t_float *bufferOne = fft->buffer;
	t_float *bufferTwo = fft2->buffer;
	t_float *channelOne = fft->channel;
	t_float *channelTwo = fft2->channel;
	
	fold(fft);
	fold(fft2);
	rdft(fft,1);
	rdft(fft2,1);
	
	if (invert) {	
		
		
		for ( i = 0; i <= N2; i++ ) {
			odd = ( even = i<<1 ) + 1;
			
			a1 = ( i == N2 ? *(bufferOne+1) : *(bufferOne+even) );
			b1 = ( i == 0 || i == N2 ? 0. : *(bufferOne+odd) );
			
			a2 = ( i == N2 ? *(bufferTwo+1) : *(bufferTwo+even) );
			b2 = ( i == 0 || i == N2 ? 0. : *(bufferTwo+odd) );
			
			*(channelOne+even) = hypot( a1, b1 );
			*(channelOne+odd) = -atan2( b1, a1 );
			
			*(channelTwo+even) = hypot( a2, b2 );
			*(channelTwo+odd) = -atan2( b2, a2 );
						
			if ( *(channelOne+even) > *(channelTwo+even) * threshMult )
				*(channelOne+even) = *(channelTwo+even);
			
			if ( *(channelOne+odd) == 0. )
				*(channelOne+odd) = *(channelTwo+odd);	 
		}
	}
	
	else {
		for ( i = 0; i <= N2; i++ ) {
			
			odd = ( even = i<<1 ) + 1;
			
			a1 = ( i == N2 ? *(bufferOne+1) : *(bufferOne+even) );
			b1 = ( i == 0 || i == N2 ? 0. : *(bufferOne+odd) );
			
			a2 = ( i == N2 ? *(bufferTwo+1) : *(bufferTwo+even) );
			b2 = ( i == 0 || i == N2 ? 0. : *(bufferTwo+odd) );
			
			*(channelOne+even) = hypot( a1, b1 );
			*(channelOne+odd) = -atan2( b1, a1 );
			
			*(channelTwo+even) = hypot( a2, b2 );
			*(channelTwo+odd) = -atan2( b2, a2 );
			
			
			if ( *(channelOne+even) < *(channelTwo+even) * threshMult )
				*(channelOne+even) = *(channelTwo+even);
			
			if ( *(channelOne+odd) == 0. )
				*(channelOne+odd) = *(channelTwo+odd);	 
		}  
	}
	

	for ( i = 0; i <= N2; i++ ) {
		odd = ( even = i<<1 ) + 1;
		
		*(bufferOne+even) = *(channelOne+even) * cos( *(channelOne+odd) );
		
		if ( i != N2 )
			*(bufferOne+odd) = -(*(channelOne+even)) * sin( *(channelOne+odd) );
	}
	rdft(fft, -1);
	overlapadd(fft);
}
Example #22
0
//---------------------------------------------------------------------------
void tRisaPhaseVocoderDSP::ProcessCore_sse(int ch)
{
	unsigned int framesize_d2 = FrameSize / 2;
	float * analwork = AnalWork[ch];
	float * synthwork = SynthWork[ch];

	// 丸めモードを設定
	SetRoundingModeToNearest_SSE();

	// FFT を実行する
	rdft(FrameSize, 1, analwork, FFTWorkIp, FFTWorkW); // Real DFT
	analwork[1] = 0.0; // analwork[1] = nyquist freq. power (どっちみち使えないので0に)

	__m128 exact_time_scale = _mm_load1_ps(&ExactTimeScale);
	__m128 over_sampling_radian_v = _mm_load1_ps(&OverSamplingRadian);

	if(FrequencyScale != 1.0)
	{
		// ここでは 4 複素数 (8実数) ごとに処理を行う。
		__m128 over_sampling_radian_recp = _mm_load1_ps(&OverSamplingRadianRecp);
		__m128 frequency_per_filter_band = _mm_load1_ps(&FrequencyPerFilterBand);
		__m128 frequency_per_filter_band_recp = _mm_load1_ps(&FrequencyPerFilterBandRecp);

		for(unsigned int i = 0; i < framesize_d2; i += 4)
		{
			// インターリーブ解除 +  直交座標系→極座標系
			__m128 aw3120 = *(__m128*)(analwork + i*2    );
			__m128 aw7654 = *(__m128*)(analwork + i*2 + 4);

			__m128 re3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(2,0,2,0));
			__m128 im3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(3,1,3,1));

			__m128 mag = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(re3210,re3210), _mm_mul_ps(im3210,im3210)));
			__m128 ang = VFast_arctan2_F4_SSE(im3210, re3210);

			// 前回の位相との差をとる
			__m128 lastp = *(__m128*)(LastAnalPhase[ch] + i);
			*(__m128*)(LastAnalPhase[ch] + i) = ang;
			ang = _mm_sub_ps(lastp, ang);

			// over sampling の影響を考慮する
			__m128 i_3210;
			i_3210 = _mm_cvtsi32_ss(i_3210, i);
			i_3210 = _mm_shuffle_ps(i_3210, i_3210, _MM_SHUFFLE(0,0,0,0));
			i_3210 = _mm_add_ps( i_3210, PM128(PFV_INIT) );

			__m128 phase_shift = _mm_mul_ps(i_3210, over_sampling_radian_v);
			ang = _mm_sub_ps( ang, phase_shift );

			// unwrapping をする
			ang = Wrap_Pi_F4_SSE(ang);

			// -M_PI~+M_PIを-1.0~+1.0の変位に変換
			ang = _mm_mul_ps( ang, over_sampling_radian_recp );

			// tmp をフィルタバンド中央からの周波数の変位に変換し、
			// それにフィルタバンドの中央周波数を加算する
			__m128 freq = _mm_mul_ps( _mm_add_ps(ang, i_3210), frequency_per_filter_band );

			// analwork に値を格納する
			re3210 = mag;
			im3210 = freq;
			__m128 im10re10 = _mm_movelh_ps(re3210, im3210);
			__m128 im32re32 = _mm_movehl_ps(im3210, re3210);
			__m128 im1re1im0re0 = _mm_shuffle_ps(im10re10, im10re10, _MM_SHUFFLE(3,1,2,0));
			__m128 im3re3im2re2 = _mm_shuffle_ps(im32re32, im32re32, _MM_SHUFFLE(3,1,2,0));
			*(__m128*)(analwork + i*2    ) = im1re1im0re0;
			*(__m128*)(analwork + i*2 + 4) = im3re3im2re2;
		}


		//------------------------------------------------
		// 変換
		//------------------------------------------------
		// 周波数軸方向のリサンプリングを行う
		float FrequencyScale_rcp = 1.0f / FrequencyScale;
		for(unsigned int i = 0; i < framesize_d2; i ++)
		{
			// i に対応するインデックスを得る
			float fi = i * FrequencyScale_rcp;

			// floor(x) と floor(x) + 1 の間でバイリニア補間を行う
			unsigned int index = static_cast<unsigned int>(fi); // floor
			float frac = fi - index;

			if(index + 1 < framesize_d2)
			{
				synthwork[i*2  ] =
					analwork[index*2  ] +
					frac * (analwork[index*2+2]-analwork[index*2  ]);
				synthwork[i*2+1] =
					FrequencyScale * (
					analwork[index*2+1] +
					frac * (analwork[index*2+3]-analwork[index*2+1]) );
			}
			else if(index < framesize_d2)
			{
				synthwork[i*2  ] = analwork[index*2  ];
				synthwork[i*2+1] = analwork[index*2+1] * FrequencyScale;
			}
			else
			{
				synthwork[i*2  ] = 0.0;
				synthwork[i*2+1] = 0.0;
			}
		}

		//------------------------------------------------
		// 合成
		//------------------------------------------------

		// 各フィルタバンドごとに変換
		// 基本的には解析の逆変換である
		for(unsigned int i = 0; i < framesize_d2; i += 4)
		{
			// インターリーブ解除
			__m128 sw3120 = *(__m128*)(synthwork + i*2    );
			__m128 sw7654 = *(__m128*)(synthwork + i*2 + 4);

			__m128 mag  = _mm_shuffle_ps(sw3120, sw7654, _MM_SHUFFLE(2,0,2,0));
			__m128 freq = _mm_shuffle_ps(sw3120, sw7654, _MM_SHUFFLE(3,1,3,1));

			// i+3 i+2 i+1 i+0 を準備
			__m128 i_3210;
			i_3210 = _mm_cvtsi32_ss(i_3210, i);
			i_3210 = _mm_shuffle_ps(i_3210, i_3210, _MM_SHUFFLE(0,0,0,0));
			i_3210 = _mm_add_ps(i_3210, PM128(PFV_INIT));

			// 周波数から各フィルタバンドの中央周波数を減算し、
			// フィルタバンドの中央周波数からの-1.0~+1.0の変位
			// に変換する
			__m128 ang = _mm_sub_ps(_mm_mul_ps(freq, frequency_per_filter_band_recp), i_3210);

			// -1.0~+1.0の変位を-M_PI~+M_PIの位相に変換
			ang = _mm_mul_ps( ang, over_sampling_radian_v );

			// OverSampling による位相の補正
			ang = _mm_add_ps( ang, _mm_mul_ps( i_3210, over_sampling_radian_v ) );

			// TimeScale による位相の補正
			ang = _mm_mul_ps( ang, exact_time_scale );

			// 前回の位相と加算する
			// ここでも虚数部の符号が逆になるので注意
			ang = _mm_sub_ps( *(__m128*)(LastSynthPhase[ch] + i), ang );
			*(__m128*)(LastSynthPhase[ch] + i) = ang;

			// 極座標系→直交座標系
			__m128 sin, cos;
			VFast_sincos_F4_SSE(ang, sin, cos);
			__m128 re3210 = _mm_mul_ps( mag, cos );
			__m128 im3210 = _mm_mul_ps( mag, sin );

			// インターリーブ
			__m128 im10re10 = _mm_movelh_ps(re3210, im3210);
			__m128 im32re32 = _mm_movehl_ps(im3210, re3210);
			__m128 im1re1im0re0 = _mm_shuffle_ps(im10re10, im10re10, _MM_SHUFFLE(3,1,2,0));
			__m128 im3re3im2re2 = _mm_shuffle_ps(im32re32, im32re32, _MM_SHUFFLE(3,1,2,0));
			*(__m128*)(synthwork + i*2    ) = im1re1im0re0;
			*(__m128*)(synthwork + i*2 + 4) = im3re3im2re2;
		}
	}
	else
	{
		// 周波数軸方向にシフトがない場合
		// ここでも 4 複素数 (8実数) ごとに処理を行う。
		for(unsigned int i = 0; i < framesize_d2; i += 4)
		{
			// インターリーブ解除 +  直交座標系→極座標系
			__m128 aw3120 = *(__m128*)(analwork + i*2    );
			__m128 aw7654 = *(__m128*)(analwork + i*2 + 4);

			__m128 re3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(2,0,2,0));
			__m128 im3210 = _mm_shuffle_ps(aw3120, aw7654, _MM_SHUFFLE(3,1,3,1));

			__m128 mag = _mm_sqrt_ps( _mm_add_ps(_mm_mul_ps(re3210,re3210), _mm_mul_ps(im3210,im3210)) );
			__m128 ang = VFast_arctan2_F4_SSE(im3210, re3210);

			// 前回の位相との差をとる
			__m128 lastp = *(__m128*)(LastAnalPhase[ch] + i);
			*(__m128*)(LastAnalPhase[ch] + i) = ang;
			ang = _mm_sub_ps( lastp, ang );

			// over sampling の影響を考慮する
			__m128 i_3210;
			i_3210 = _mm_cvtsi32_ss(i_3210, i);
			i_3210 = _mm_shuffle_ps(i_3210, i_3210, _MM_SHUFFLE(0,0,0,0));
			i_3210 = _mm_add_ps( i_3210, PM128(PFV_INIT) );

			__m128 phase_shift = _mm_mul_ps( i_3210, over_sampling_radian_v );
			ang = _mm_sub_ps( ang, phase_shift );

			// unwrapping をする
			ang = Wrap_Pi_F4_SSE(ang);

			// OverSampling による位相の補正
			ang = _mm_add_ps( ang, phase_shift );

			// TimeScale による位相の補正
			ang = _mm_mul_ps( ang, exact_time_scale );

			// 前回の位相と加算する
			// ここでも虚数部の符号が逆になるので注意
			ang = _mm_sub_ps( *(__m128*)(LastSynthPhase[ch] + i), ang );
			*(__m128*)(LastSynthPhase[ch] + i) = ang;

			// 極座標系→直交座標系
			__m128 sin, cos;
			VFast_sincos_F4_SSE(ang, sin, cos);
			re3210 = _mm_mul_ps( mag, cos );
			im3210 = _mm_mul_ps( mag, sin );

			// インターリーブ
			__m128 im10re10 = _mm_movelh_ps(re3210, im3210);
			__m128 im32re32 = _mm_movehl_ps(im3210, re3210);
			__m128 im1re1im0re0 = _mm_shuffle_ps(im10re10, im10re10, _MM_SHUFFLE(3,1,2,0));
			__m128 im3re3im2re2 = _mm_shuffle_ps(im32re32, im32re32, _MM_SHUFFLE(3,1,2,0));
			*(__m128*)(synthwork + i*2    ) = im1re1im0re0;
			*(__m128*)(synthwork + i*2 + 4) = im3re3im2re2;
		}
	}

	// FFT を実行する
	synthwork[1] = 0.0; // synthwork[1] = nyquist freq. power (どっちみち使えないので0に)
	rdft_sse(FrameSize, -1, synthwork, FFTWorkIp, FFTWorkW); // Inverse Real DFT
}
Example #23
0
//---------------------------------------------------------------------------
void tRisaPhaseVocoderDSP::ProcessCore(int ch)
{
	unsigned int framesize_d2 = FrameSize / 2;
	float * analwork = AnalWork[ch];
	float * synthwork = SynthWork[ch];

	// FFT を実行する
	rdft(FrameSize, 1, analwork, FFTWorkIp, FFTWorkW); // Real DFT
	analwork[1] = 0.0; // analwork[1] = nyquist freq. power (どっちみち使えないので0に)

	if(FrequencyScale != 1.0)
	{
		// 各フィルタバンドごとに変換
		//-- 各フィルタバンドごとの音量と周波数を求める。
		//-- FFT を実行すると各フィルタバンドごとの値が出てくるが、
		//-- フィルタバンドというバンドパスフィルタの幅の中で
		//-- 周波数のピークが本当はどこにあるのかは、前回計算した
		//-- 位相との差をとってみないとわからない。
		for(unsigned int i = 0; i < framesize_d2; i ++)
		{
			// 直交座標系→極座標系
			float re = analwork[i*2  ];
			float im = analwork[i*2+1];

			float mag = sqrt(re*re + im*im); // mag = √(re^2+im^2)
			float ang = VFast_arctan2(im, re); // ang = atan(im/re)

			// 前回の位相との差をとる
			// --注意: ここで使用しているFFTパッケージは、
			// --      ソース先頭の参考資料などで示しているFFTと
			// --      出力される複素数の虚数部の符号が逆なので
			// --      (共役がでてくるので)注意が必要。ここでも符号を
			// --      逆の物として扱う。
			float tmp = LastAnalPhase[ch][i] - ang;
			LastAnalPhase[ch][i] = ang; // 今回の値を保存

			// over sampling の影響を考慮する
			// -- 通常、FrameSize で FFT の1周期であるところを、
			// -- 精度を補うため、OverSampling 倍の周期で演算をしている。
			// -- そのために生じる位相のずれを修正する。
			tmp -= i * OverSamplingRadian;

			// unwrapping をする
			// -- tmp が -M_PI ~ +M_PI の範囲に収まるようにする
			tmp = WrapPi_F1(tmp);

			// -M_PI~+M_PIを-1.0~+1.0の変位に変換
			tmp =  tmp * OverSamplingRadianRecp;

			// tmp をフィルタバンド中央からの周波数の変位に変換し、
			// それにフィルタバンドの中央周波数を加算する
			// -- i * FrequencyPerFilterBand はフィルタバンドの中央周波数を
			// -- 表し、tmp * FrequencyPerFilterBand は フィルタバンド中央から
			// -- の周波数の変位を表す。これらをあわせた物が、そのフィルタ
			// -- バンド内での「真」の周波数である。
			float freq = (i + tmp) *FrequencyPerFilterBand;

			// analwork に値を格納する
			analwork[i*2  ] = mag;
			analwork[i*2+1] = freq;
		}


		//------------------------------------------------
		// 変換
		//------------------------------------------------

		// 周波数軸方向のリサンプリングを行う
		float FrequencyScale_rcp = 1.0f / FrequencyScale;
		for(unsigned int i = 0; i < framesize_d2; i ++)
		{
			// i に対応するインデックスを得る
			float fi = i * FrequencyScale_rcp;

			// floor(x) と floor(x) + 1 の間でバイリニア補間を行う
			unsigned int index = static_cast<unsigned int>(fi); // floor
			float frac = fi - index;

			if(index + 1 < framesize_d2)
			{
				synthwork[i*2  ] =
					analwork[index*2  ] +
					frac * (analwork[index*2+2]-analwork[index*2  ]);
				synthwork[i*2+1] =
					FrequencyScale * (
					analwork[index*2+1] +
					frac * (analwork[index*2+3]-analwork[index*2+1]) );
			}
			else if(index < framesize_d2)
			{
				synthwork[i*2  ] = analwork[index*2  ];
				synthwork[i*2+1] = analwork[index*2+1] * FrequencyScale;
			}
			else
			{
				synthwork[i*2  ] = 0.0;
				synthwork[i*2+1] = 0.0;
			}
		}


		//------------------------------------------------
		// 合成
		//------------------------------------------------

		// 各フィルタバンドごとに変換
		// 基本的には解析の逆変換である
		for(unsigned int i = 0; i < framesize_d2; i ++)
		{
			float mag  = synthwork[i*2  ];
			float freq = synthwork[i*2+1];

			// 周波数から各フィルタバンドの中央周波数を減算し、
			// フィルタバンドの中央周波数からの-1.0~+1.0の変位
			// に変換する
			float tmp = freq * FrequencyPerFilterBandRecp - (float)i;

			// -1.0~+1.0の変位を-M_PI~+M_PIの位相に変換
			tmp =  tmp * OverSamplingRadian;

			// OverSampling による位相の補正
			tmp += i   * OverSamplingRadian;

			// TimeScale による位相の補正
			// TimeScale で出力が時間軸方向にのびれば(あるいは縮めば)、
			// 位相の差分もそれに伴ってのびる(縮む)
			tmp *= ExactTimeScale;

			// 前回の位相と加算する
			// ここでも虚数部の符号が逆になるので注意
			LastSynthPhase[ch][i] -= tmp;
			float ang = LastSynthPhase[ch][i];

			// 極座標系→直交座標系
			float c, s;
			VFast_sincos(ang, s, c);
			synthwork[i*2  ] = mag * c;
			synthwork[i*2+1] = mag * s;
		}
	}
	else
	{
		// 周波数軸方向にシフトがない場合

		// 各フィルタバンドごとに変換
		//-- 各フィルタバンドごとの音量と周波数を求める。
		//-- FFT を実行すると各フィルタバンドごとの値が出てくるが、
		//-- フィルタバンドというバンドパスフィルタの幅の中で
		//-- 周波数のピークが本当はどこにあるのかは、前回計算した
		//-- 位相との差をとってみないとわからない。
		for(unsigned int i = 0; i < framesize_d2; i ++)
		{
			// 直交座標系→極座標系
			float re = analwork[i*2  ];
			float im = analwork[i*2+1];

			float mag = sqrt(re*re + im*im); // mag = √(re^2+im^2)
			float ang = VFast_arctan2(im, re); // ang = atan(im/re)

			// 前回の位相との差をとる
			// --注意: ここで使用しているFFTパッケージは、
			// --      ソース先頭の参考資料などで示しているFFTと
			// --      出力される複素数の虚数部の符号が逆なので
			// --      (共役がでてくるので)注意が必要。ここでも符号を
			// --      逆の物として扱う。
			float tmp = LastAnalPhase[ch][i] - ang;
			LastAnalPhase[ch][i] = ang; // 今回の値を保存

			// phase shift
			float phase_shift = i * OverSamplingRadian;

			// over sampling の影響を考慮する
			// -- 通常、FrameSize で FFT の1周期であるところを、
			// -- 精度を補うため、OverSampling 倍の周期で演算をしている。
			// -- そのために生じる位相のずれを修正する。
			tmp -= phase_shift;

			// unwrapping をする
			// -- tmp が -M_PI ~ +M_PI の範囲に収まるようにする
			tmp = WrapPi_F1(tmp);

//--
			// OverSampling による位相の補正
			tmp += phase_shift;

			// TimeScale による位相の補正
			// TimeScale で出力が時間軸方向にのびれば(あるいは縮めば)、
			// 位相の差分もそれに伴ってのびる(縮む)
			tmp *= ExactTimeScale;

			// 前回の位相と加算する
			// ここでも虚数部の符号が逆になるので注意
			LastSynthPhase[ch][i] -= tmp;
			ang = LastSynthPhase[ch][i];

			// 極座標系→直交座標系
			float c, s;
			VFast_sincos(ang, s, c);
			synthwork[i*2  ] = mag * c;
			synthwork[i*2+1] = mag * s;
		}
	}

	// FFT を実行する
	synthwork[1] = 0.0; // synthwork[1] = nyquist freq. power (どっちみち使えないので0に)
	rdft(FrameSize, -1, SynthWork[ch], FFTWorkIp, FFTWorkW); // Inverse Real DFT
}
Example #24
0
t_int *bthresher_perform(t_int *w)
{
	
  float sample, outsamp ;
  int	i, j, on;
  t_bthresher *x = (t_bthresher *) (w[1]);
  float *in = (t_float *)(w[2]);
  float *inthresh = (t_float *)(w[3]);
  float *damping = (t_float *)(w[4]);
  float *out = (t_float *)(w[5]);
  t_int n = w[6];
	

  int *bitshuffle = x->bitshuffle;
  float *trigland = x->trigland;
  float mult = x->mult;	

  int in_count = x->in_count;
  int R = x->R;
  int N = x->N;
  int N2 = x->N2;
  int D = x->D;
  int Nw = x->Nw;
  float *Wanal = x->Wanal;
  float *Wsyn = x->Wsyn;
  float *damping_factor = x->damping_factor;
  float *move_threshold = x->move_threshold;
  float *input = x->input;
  float *output = x->output;
  float *buffer = x->buffer;
  float *channel = x->channel;
  float *composite_frame = x->composite_frame;
  int max_hold_frames = x->max_hold_frames;
  int *frames_left = x->frames_left;
  float thresh_scalar = x->thresh_scalar;
  float damp_scalar = x->damp_scalar;
  short inf_hold = x->inf_hold;
  
  if( x->mute ) {
    for( j = 0; j < D; j++) {
      *out++ = 0.0 ;
    }
  } else if ( x->bypass ) {
    for( j = 0; j < D; j++) {
      *out++ = *in++ * 0.5;
    }
  } else {
#if MSP
    if( x->thresh_connected ) {
      thresh_scalar = *inthresh++;
    }
    if( x->damping_connected ) {
      damp_scalar = *damping++;
    }
#endif

#if PD
      thresh_scalar = *inthresh++;
      damp_scalar = *damping++;
#endif	

    in_count += D;


    for ( j = 0 ; j < Nw - D ; j++ )
      input[j] = input[j+D];

    for ( j = Nw-D; j < Nw; j++ ) {
      input[j] = *in++;
    }

    fold( input, Wanal, Nw, buffer, N, in_count );
    rdft( N, 1, buffer, bitshuffle, trigland );
    convert( buffer, channel, N2, x->c_lastphase_in, x->c_fundamental, x->c_factor_in  );
	
    if( x->first_frame ){
      for ( i = 0; i < N+2; i++ ){
        composite_frame[i] = channel[i];
        x->frames_left[i] = max_hold_frames;
      }
      x->first_frame = 0;
    } else {
      if( thresh_scalar < .999 || thresh_scalar > 1.001 || damp_scalar < .999 || damp_scalar > 1.001 ) {
				for(i = 0, j = 0; i < N+2; i += 2, j++ ){
				  if( fabs( composite_frame[i] - channel[i] ) > move_threshold[j] * thresh_scalar|| frames_left[j] <= 0 ){
				    composite_frame[i] = channel[i];
				    composite_frame[i+1] = channel[i+1];
				    frames_left[j] = max_hold_frames;
				  } else {
				    if(!inf_hold){
				      --(frames_left[j]);
				    }
				    composite_frame[i] *= damping_factor[j] * damp_scalar;
				  }
				}

      } else {
				for( i = 0, j = 0; i < N+2; i += 2, j++ ){
				  if( fabs( composite_frame[i] - channel[i] ) > move_threshold[j] || frames_left[j] <= 0 ){
				    composite_frame[i] = channel[i];
				    composite_frame[i+1] = channel[i+1];
				    frames_left[j] = max_hold_frames;
				  } else {
				    if(!inf_hold){
				      --(frames_left[j]);
				    }
				    composite_frame[i] *= damping_factor[j];
				  }
				}
      }
    }

    unconvert(x->composite_frame, buffer, N2, x->c_lastphase_out, x->c_fundamental, x->c_factor_out);
    rdft(N, -1, buffer, bitshuffle, trigland);

    overlapadd(buffer, N, Wsyn, output, Nw, in_count);

    for ( j = 0; j < D; j++ )
      *out++ = output[j] * mult;

    for ( j = 0; j < Nw - D; j++ )
      output[j] = output[j+D];
			
    for ( j = Nw - D; j < Nw; j++ )
      output[j] = 0.;
  }
  x->in_count = in_count % Nw;
  x->thresh_scalar = thresh_scalar;
  x->damp_scalar = damp_scalar;
	
  return (w+7);
}		
Example #25
0
t_int *ether_perform(t_int *w)
{

  int		i,j,
			inCount,
			R,
			N,
			N2,
			D,
			Nw,
			invert = 1,
  			even, odd,
  	 		*bitshuffle;

  float		maxamp,	
  			threshMult = 1.,
			mult,
			a1, b1,
  			a2, b2,
  			*inputOne,
			*inputTwo,
			*bufferOne,
			*bufferTwo,
			*output,
			*Wanal,
			*Wsyn,
			*channelOne,
			*channelTwo,
			*trigland;

  
/* get our inlets and outlets */
	
  t_ether *x = (t_ether *) (w[1]);
  t_float *inOne = (t_float *)(w[2]);
  t_float *inTwo = (t_float *)(w[3]);
  t_float *vec_threshMult = (t_float *)(w[4]);
  t_float *out = (t_float *)(w[5]);
  t_int n = w[6];
	
  short *connected = x->connected;
  
/* dereference structure  */	

  inputOne = x->inputOne;
  inputTwo = x->inputTwo;
  bufferOne = x->bufferOne;
  bufferTwo = x->bufferTwo;
  inCount = x->inCount;
  R = x->R;
  N = x->N;
  N2 = x->N2;
  D = x->D;
  Nw = x->Nw;
  Wanal = x->Wanal;
  Wsyn = x->Wsyn;
  output = x->output;
  channelOne = x->channelOne;
  channelTwo = x->channelTwo;
  bitshuffle = x->bitshuffle;
  trigland = x->trigland;
  mult = x->mult;	
  invert = x->invert;
  
  if(connected[2]){
  	threshMult = *vec_threshMult;
  }
  else if ( x->threshMult != 0. ){
  	threshMult = x->threshMult;
  }
  else { 
	threshMult = 1.0;
  }
  
  if(x->mute){
	while(n--)
		*out++ = 0.0;
	return w+7;
  }

/* fill our retaining buffers */

  inCount += D;

  for ( j = 0 ; j < Nw - D ; j++ ) {
    inputOne[j] = inputOne[j+D];
    inputTwo[j] = inputTwo[j+D];
  }

  for ( j = Nw - D; j < Nw; j++ ) {
    inputOne[j] = *inOne++;
    inputTwo[j] = *inTwo++;
  }

/* apply hamming window and fold our window buffer into the fft buffer */ 

  fold( inputOne, Wanal, Nw, bufferOne, N, inCount );
  fold( inputTwo, Wanal, Nw, bufferTwo, N, inCount );


/* do an fft */ 

  rdft( N, 1, bufferOne, bitshuffle, trigland );
  rdft( N, 1, bufferTwo, bitshuffle, trigland );

/* use slow fft */


/* use redundant coding for speed, even though moving the invert variable
   comparison outside of the for loop will give us only a minimal performance
   increase (hypot and atan2 are the most intensive portions of this code).
   consider adding a table lookup for atan2 instead.
*/

  if (invert) {	
 
/* convert to polar coordinates from complex values */
 
    for ( i = 0; i <= N2; i++ ) {
      odd = ( even = i<<1 ) + 1;

      a1 = ( i == N2 ? *(bufferOne+1) : *(bufferOne+even) );
      b1 = ( i == 0 || i == N2 ? 0. : *(bufferOne+odd) );
    
      a2 = ( i == N2 ? *(bufferTwo+1) : *(bufferTwo+even) );
      b2 = ( i == 0 || i == N2 ? 0. : *(bufferTwo+odd) );

      *(channelOne+even) = hypot( a1, b1 );
      *(channelOne+odd) = -atan2( b1, a1 );
    
      *(channelTwo+even) = hypot( a2, b2 );
      *(channelTwo+odd) = -atan2( b2, a2 );

/* use simple threshold for inverse compositing */
    
      if ( *(channelOne+even) > *(channelTwo+even) * threshMult )
      	*(channelOne+even) = *(channelTwo+even);
    	
      if ( *(channelOne+odd) == 0. )
    	*(channelOne+odd) = *(channelTwo+odd);	 
    }
  }

  else {

/* convert to polar coordinates from complex values */
 
    for ( i = 0; i <= N2; i++ ) {
    
      odd = ( even = i<<1 ) + 1;

      a1 = ( i == N2 ? *(bufferOne+1) : *(bufferOne+even) );
      b1 = ( i == 0 || i == N2 ? 0. : *(bufferOne+odd) );
    
      a2 = ( i == N2 ? *(bufferTwo+1) : *(bufferTwo+even) );
      b2 = ( i == 0 || i == N2 ? 0. : *(bufferTwo+odd) );

      *(channelOne+even) = hypot( a1, b1 );
      *(channelOne+odd) = -atan2( b1, a1 );
    
      *(channelTwo+even) = hypot( a2, b2 );
      *(channelTwo+odd) = -atan2( b2, a2 );

/* use simple threshold for compositing */
    
      if ( *(channelOne+even) < *(channelTwo+even) * threshMult )
      	*(channelOne+even) = *(channelTwo+even);
    	
      if ( *(channelOne+odd) == 0. )
    	*(channelOne+odd) = *(channelTwo+odd);	 
    }  
  }

/* convert back to complex form, read for the inverse fft */

  for ( i = 0; i <= N2; i++ ) {

    odd = ( even = i<<1 ) + 1;

    *(bufferOne+even) = *(channelOne+even) * cos( *(channelOne+odd) );

    if ( i != N2 )
      *(bufferOne+odd) = -(*(channelOne+even)) * sin( *(channelOne+odd) );
  }


/* do an inverse fft */

  rdft( N, -1, bufferOne, bitshuffle, trigland );


/* dewindow our result */

  overlapadd( bufferOne, N, Wsyn, output, Nw, inCount);

/* set our output and adjust our retaining output buffer */

  for ( j = 0; j < D; j++ )
    *out++ = output[j] * mult;
	
  for ( j = 0; j < Nw - D; j++ )
    output[j] = output[j+D];
  
  for ( j = Nw - D; j < Nw; j++ )
    output[j] = 0.;
		

/* restore state variables */

  x->inCount = inCount % Nw;
  return (w+7);
}		
Example #26
0
int PSDCalculator::calculatePowerSpectrum(
  double *input, int inputLen, 
  double *output, int outputLen, 
  bool removeMean, bool interpolateHoles,
  bool average, int averageLen, 
  bool apodize, ApodizeFunction apodizeFxn, double gaussianSigma,
  PSDType outputType, double inputSamplingFreq) {

  if (outputLen != calculateOutputVectorLength(inputLen, average, averageLen)) {
    KstDebug::self()->log(QObject::tr("in PSDCalculator::calculatePowerSpectrum: received output array with wrong length."), KstDebug::Error);

    return -1;
  }

  if (outputLen != _prevOutputLen) {
    delete[] _a;
    delete[] _w;

    _awLen = outputLen*2;
    _prevOutputLen = outputLen;

    _a = new double[_awLen];
    _w = new double[_awLen];

    updateWindowFxn(apodizeFxn, gaussianSigma);
  }

  if ( (_prevApodizeFxn != apodizeFxn) || (_prevGaussianSigma != gaussianSigma) ) {
    updateWindowFxn(apodizeFxn, gaussianSigma);
  }

  int currentCopyLen, nsamples = 0;
  int i_samp, i_subset, ioffset;

  memset(output, 0, sizeof(double) * outputLen);

  bool done = false;
  for (i_subset = 0; !done; i_subset++) {
    //
    // overlapping average => i_subset*outputLen...
    //

    ioffset = i_subset * outputLen;

    //
    // only zero pad if we really have to.  
    //  It is better to adjust the last chunk's overlap...
    //

    if (ioffset + _awLen*5/4 < inputLen) {
      currentCopyLen = _awLen; // will copy a complete window.
    } else if (_awLen<inputLen) {  // count the last one from the end.
      ioffset = inputLen-_awLen - 1;
      currentCopyLen = _awLen; // will copy a complete window.
      done = true;
    } else {
      currentCopyLen = inputLen - ioffset; // will copy a partial window.
      memset(&_a[currentCopyLen], 0, sizeof(double)*(_awLen - currentCopyLen)); // zero the leftovers.
      done = true;
    }

    double mean = 0.0;

    if (removeMean) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        mean += input[i_samp + ioffset];
      }
      mean /= (double)currentCopyLen;
    }

    //
    // apply the PSD options (removeMean, apodize, etc.)
    // separate cases for speed- although this shouldn't really matter - 
    //  the rdft should be the most time consuming step by far for any large data set...
    //

    if (removeMean && apodize && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = (kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen) - mean)*_w[i_samp];
      }
    } else if (removeMean && apodize) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = (input[i_samp + ioffset] - mean)*_w[i_samp];
      }
    } else if (removeMean && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen) - mean;
      }
    } else if (apodize && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen)*_w[i_samp];
      }
    } else if (removeMean) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset] - mean;
      }
    } else if (apodize) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset]*_w[i_samp];
      }
    } else if (interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen);
      }
    } else {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset];
      }
    }

    nsamples += currentCopyLen;

    //
    // real discrete fourier transorm on _a.
    //

    rdft(_awLen, 1, _a); 

    output[0] += _a[0] * _a[0];
    output[outputLen-1] += _a[1] * _a[1];
    for (i_samp = 1; i_samp < outputLen - 1; i_samp++) {
      output[i_samp] += cabs2(_a[i_samp * 2], _a[i_samp * 2 + 1]);
    }
  }

  double frequencyStep = 2.0*(double)inputSamplingFreq/(double)nsamples;
  double norm = 2.0/(double)nsamples*2.0/(double)nsamples;

  switch (outputType) {
    default:
    case PSDAmplitudeSpectralDensity: // amplitude spectral density (default) [V/Hz^1/2]
      norm /= frequencyStep;
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] = sqrt(output[i_samp]*norm);
      }
      break;

    case PSDPowerSpectralDensity: // power spectral density [V^2/Hz]
      norm /= frequencyStep;
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] *= norm;
      }
      break;

    case PSDAmplitudeSpectrum: // amplitude spectrum [V]
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] = sqrt(output[i_samp]*norm);
      }
      break;

    case PSDPowerSpectrum: // power spectrum [V^2]
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] *= norm;
      }
      break;
  }

  return 0;
}
Example #27
0
t_int *pvcompand_perform(t_int *w)
{
  float sample, outsamp ;	
  int i,j;	
  float maxamp ;	
  float fmult;
  float cutoff;
  float avr, new_avr, rescale;

  t_pvcompand *x = (t_pvcompand *) (w[1]);
  t_float *in = (t_float *)(w[2]);
  t_float *in2 = (t_float *)(w[3]);
  t_float *out = (t_float *)(w[4]);
  int n = (int)(w[5]);

  int  inCount = x->inCount;
  float *Wanal = x->Wanal;
  float *Wsyn = x->Wsyn;
  float *input = x->input;
  float *Hwin = x->Hwin;
  float *buffer = x->buffer;
  float *channel = x->channel;
  float *output = x->output;
  	
  int D = x->D;
  int I = D;
  int R = x->R;
  int Nw = x->Nw;
  int N = x->N ;
  int N2 = x-> N2;
  int Nw2 = x->Nw2;
  int *bitshuffle = x->bitshuffle;
  float *trigland = x->trigland;
  float mult = x->mult;
  int count = x->count;
  float *atten = x->atten;
  float *curthresh = x->curthresh;
  float *thresh = x->thresh;
  float max_atten = x->max_atten;		

if( x->mute ){
	while( n-- ){
		*out++ = 0.0;
	}
	return (w+6); 
}
if( x->bypass ){
	while( n-- ){
		*out++ = *in++ * 0.5; // gain compensation
	}
	return (w+6); 
}

#if MSP
  if( x->connected[1] ){
	  max_atten = *in2++ ;
	  if(max_atten != x->last_max_atten) {
	    x->last_max_atten = x->max_atten = max_atten;
	    update_thresholds(x);
	  }
  } 
#endif

#if PD
  max_atten = *in2++ ;
  if(max_atten != x->last_max_atten) {
    x->last_max_atten = x->max_atten = max_atten;
    update_thresholds(x);
  }
#endif

  inCount += D;

  for ( j = 0 ; j < Nw - D ; j++ ){
    input[j] = input[j+D];
  }
  for ( j = Nw - D; j < Nw; j++ ) {
    input[j] = *in++;
  }

  fold( input, Wanal, Nw, buffer, N, inCount );	
  rdft( N, 1, buffer, bitshuffle, trigland );

  leanconvert(buffer, channel, N2);

  maxamp = 0.;
  avr = 0;
  for( i = 0; i < N; i+= 2 ){
    avr += channel[i];
    if( maxamp < channel[i] ){
      maxamp = channel[i] ;
    }
  }
   if(count <= 1){
	//	post("count too low!"); 
		count = 1;
	}
  for( i = 0; i < count; i++ ){
    curthresh[i] = thresh[i]*maxamp ;
  }
  cutoff = curthresh[count-1];
  new_avr = 0;
  for( i = 0; i < N; i += 2){
    if( channel[i] > cutoff ){
      j = count-1;
      while( channel[i] > curthresh[j] ){
				j--;
				if( j < 0 ){
				  j = 0;
				  break;
				}
      }
      channel[i] *= atten[j];
    }
    new_avr += channel[i] ;
  }

  leanunconvert( channel,buffer, N2);

  rdft( N, -1, buffer, bitshuffle, trigland );

  overlapadd( buffer, N, Wsyn, output, Nw, inCount);
  if( x->norml ) {
    if( new_avr <= 0 ){
      new_avr = .0001;
    }
    rescale =  avr / new_avr ;
    mult *= rescale ;

  } else {
    mult *= pvcompand_ampdb( max_atten * -.5); ;
  }

  for ( j = 0; j < D; j++ ){
    *out++ = output[j] * mult;

  }
  for ( j = 0; j < Nw - D; j++ )
    output[j] = output[j+D];
			
  for ( j = Nw - D; j < Nw; j++ )
    output[j] = 0.;

	

  /* restore state variables */
  x->inCount = inCount % Nw;
  return (w+6);
}	
Example #28
0
t_int *thresher_perform(t_int *w)
{
	float sample, outsamp ;
	int		    i,j;
	
	t_thresher *x = (t_thresher *) (w[1]);
	
	float *in = (t_float *)(w[2]);
	float *inthresh = (t_float *)(w[3]);
	float *damping = (t_float *)(w[4]);
	float *out = (t_float *)(w[5]);
	int n = (int)(w[6]);
	
	float	*input = x->input;
	float *output = x->output;
	float *buffer = x->buffer;
	float *Wanal = x->Wanal;
	float *Wsyn = x->Wsyn;
	float *channel = x->channel;
	float damping_factor = x->damping_factor;
	int max_hold_frames = x->max_hold_frames;
	int *frames_left = x->frames_left;
	float *composite_frame = x->composite_frame;
	float *c_lastphase_in = x->c_lastphase_in;
	float *c_lastphase_out = x->c_lastphase_out;
	float c_fundamental = x->c_fundamental;
	float c_factor_in = x->c_factor_in;
	float c_factor_out = x->c_factor_out;
	int *bitshuffle = x->bitshuffle;
	float *trigland = x->trigland;
	float mult = x->mult;	
	int in_count = x->in_count;
	int R = x->R;
	int N = x->N;
	int N2 = x->N2;
	int D = x->D;
	int Nw = x->Nw;
	float move_threshold = x->move_threshold;
	
	
	if( x->mute ) {
		for( j = 0; j < D; j++) {
			*out++ = 0.0 ;
		}
		return (w+7);
	} 
	
	if ( x->bypass ) {
		for( j = 0; j < D; j++) {
			*out++ = *in++ ;
		}
		return (w+7);
	} 
	
	
	
	
    if( x->thresh_connected ) {
		move_threshold = *inthresh ;
    }
    if( x->damping_connected ) {
		damping_factor = *damping ;
    }
	
	in_count += D;
	
	for ( j = 0 ; j < Nw - D ; j++ )
		input[j] = input[j+D];
	
	for ( j = Nw - D; j < Nw; j++ ) {
		input[j] = *in++;
	}
	
	fold( input, Wanal, Nw, buffer, N, in_count );
	
	rdft( N, 1, buffer, bitshuffle, trigland );
	
	convert( buffer, channel, N2, c_lastphase_in, c_fundamental, c_factor_in  );
	
	if( x->first_frame ){
		for ( i = 0; i < N+2; i++ ){
			composite_frame[i] = channel[i];
			frames_left[i] = max_hold_frames;
		}
		x->first_frame = 0;
	} else {
		for( i = 0; i < N+2; i += 2 ){
			if(fabs( composite_frame[i] - channel[i] ) > move_threshold ||
			   frames_left[i] <= 0 ){
				composite_frame[i] = channel[i];
				composite_frame[i+1] = channel[i+1];
				frames_left[i] = max_hold_frames;
			} else {
				--(frames_left[i]);
				composite_frame[i] *= damping_factor;
			}
		}
	}
	
	
    unconvert( composite_frame, buffer, N2, c_lastphase_out, c_fundamental, c_factor_out  );
    rdft( N, -1, buffer, bitshuffle, trigland );
	
    overlapadd( buffer, N, Wsyn, output, Nw, in_count );
	
    for ( j = 0; j < D; j++ )
		*out++ = output[j] * mult;
	
    for ( j = 0; j < Nw - D; j++ )
		output[j] = output[j+D];
	
    for ( j = Nw - D; j < Nw; j++ )
		output[j] = 0.;
	
    x->in_count = in_count;
    x->damping_factor = damping_factor;
	
    return (w+7);
}
Example #29
0
t_int *crossx_perform(t_int *w)
{
	int i, j;

  float a1, a2, b1, b2;
  int even, odd;
  int amp, freq;
  float gainer, threshie;
  float ingain = 0;
  float outgain, rescale;
  float mymult;

  t_crossx *x = (t_crossx *) (w[1]);
  t_float *in1 = (t_float *)(w[2]);
  t_float *in2 = (t_float *)(w[3]);
  t_float *in3 = (t_float *)(w[4]);
  t_float *out = (t_float *)(w[5]);
  t_int n = w[6];
	
  /* dereference struncture  */	
  float *input1 = x->input1;
  float *input2 = x->input2;
  float *buffer1 = x->buffer1;
  float *buffer2 = x->buffer2;
  int inCount = x->inCount;
  int R = x->R;
  int N = x->N;
  int N2 = x->N2;
  int D = x->D;
  int Nw = x->Nw;
  float *Wanal = x->Wanal;
  float *Wsyn = x->Wsyn;
  float *output = x->output;
  float *channel1 = x->channel1;
  float *channel2 = x->channel2;
  float *last_channel = x->last_channel;
  int *bitshuffle = x->bitshuffle;
  float *trigland = x->trigland;
  float mult = x->mult;
  float *c_lastphase_in1 = x->c_lastphase_in1;
  float *c_lastphase_in2 = x->c_lastphase_in2;
float *c_lastphase_out = x->c_lastphase_out;
float c_fundamental = x->c_fundamental;
	float c_factor_in = x->c_factor_in;
	float c_factor_out = x->c_factor_out;
	short autonorm = x->autonorm;

  if(x->mute){
    while(n--){
      *out++ = 0;
    }
    return w+7;
  }
  
  if( x->thresh_connected ){	
  	threshie = *in3++;
  } else {
  	threshie = x->threshie;
  }
  
  inCount += D;

  for ( j = 0 ; j < Nw - D ; j++ ){
    input1[j] = input1[j+D];
    input2[j] = input2[j+D];
  }
  for ( j = Nw - D; j < Nw; j++ ) {
    input1[j] = *in1++;
    input2[j] = *in2++;
  }

  fold( input1, Wanal, Nw, buffer1, N, inCount );		
  fold( input2, Wanal, Nw, buffer2, N, inCount );	
  rdft( N, 1, buffer1, bitshuffle, trigland );
  rdft( N, 1, buffer2, bitshuffle, trigland );

/* changing algorithm for window flexibility */
  if(autonorm){
    ingain = 0;
  	for(i = 0; i < N; i+=2){
  		ingain += hypot(buffer1[i], buffer1[i+1]);
  	}
  }

  for ( i = 0; i <= N2; i++ ) {
    odd = ( even = i<<1 ) + 1;

    a1 = ( i == N2 ? *(buffer1+1) : *(buffer1+even) );
    b1 = ( i == 0 || i == N2 ? 0. : *(buffer1+odd) );
    a2 = ( i == N2 ? *(buffer2+1) : *(buffer2+even) );
    b2 = ( i == 0 || i == N2 ? 0. : *(buffer2+odd) );
    gainer = hypot(a2, b2);
    if( gainer > threshie ) 
    	*(channel1+even) = hypot( a1, b1 ) * gainer;
    *(channel1+odd) = -atan2( b1, a1 );
    *(buffer1+even) = *(channel1+even) * cos( *(channel1+odd) );
    if ( i != N2 )
      *(buffer1+odd) = -(*(channel1+even)) * sin( *(channel1+odd) );

  }
  if(autonorm){
    outgain = 0;
  	for(i = 0; i < N; i+=2){
  		outgain += hypot(buffer1[i], buffer1[i+1]);
  	}
	if(ingain <= .0000001){
  		// post("gain emergency!");
  		rescale = 1.0;
  	} else {
  		rescale = ingain / outgain;
  	} 
  	// post("ingain %f outgain %f rescale %f",ingain, outgain, rescale);
  	mymult = mult * rescale;
  }  else {
  	mymult = mult;
  }

  rdft( N, -1, buffer1, bitshuffle, trigland );
  overlapadd( buffer1, N, Wsyn, output, Nw, inCount);

  for ( j = 0; j < D; j++ )
    *out++ = output[j] * mymult;

  for ( j = 0; j < Nw - D; j++ )
    output[j] = output[j+D];
			
  for ( j = Nw - D; j < Nw; j++ )
    output[j] = 0.;

	

  /* restore state variables */
  x->inCount = inCount % Nw;
  return (w+7);
}		
Example #30
0
int WBPMDetect1::PutSamples(short *pSamples, unsigned int nSampleNum)
{

	// create samples array

	unsigned int i;
	if(c_nChannel == 2)
	{
		// convert to mono
		for(i = 0; i < nSampleNum; i++)
			c_Samples[i] = ((BPM_DETECT1_REAL) pSamples[2 * i] +  (BPM_DETECT1_REAL) pSamples[2 * i + 1]) * c_pflWindow[i] / 2.0;

	}
	else
	{
		for(i = 0; i < nSampleNum; i++)
			c_Samples[i] = (BPM_DETECT1_REAL) pSamples[i] * c_pflWindow[i];
	}


	// make fft
	rdft(BPM_DETECT_FFT_POINTS1, 1, c_Samples, c_pnIp, c_pflw);

	BPM_DETECT1_REAL amp;
	BPM_DETECT1_REAL re = c_Samples[1] ;
	BPM_DETECT1_REAL im = 0;

	amp = sqrt(re * re + im * im) / c_sqrtFFTPoints;
	c_Amplitudes[BPM_DETECT_FFT_POINTS1 / 2 - 1] = amp * amp;


	for(i = 1; i < BPM_DETECT_FFT_POINTS1 / 2; i++)
	{
		re = c_Samples[i * 2] ;
		im = c_Samples[i * 2 + 1];
		amp = sqrt(re * re + im * im) / c_sqrtFFTPoints;
		c_Amplitudes[i - 1] = amp * amp;

	}

	unsigned int j;
	unsigned int nSubbandSize = BPM_DETECT_FFT_POINTS1 / ( 2 * BPM_NUMBER_OF_SUBBANDS);

	//for(i = 0; i < BPM_NUMBER_OF_SUBBANDS; i++)
	for(i = c_nLowLimitIndex; i < c_nHighLimitIndex; i++)
	{
		SUBBAND1 *subband = &c_pSubBand[i];

		if(subband->BPM)	// we have BPM, don't compute anymore
			continue;
	
		// === CREATE SUBBANDS =================================
		BPM_DETECT1_REAL InstantAmplitude = 0;

		for(j =  i * nSubbandSize; j < (i + 1) * nSubbandSize; j++)
			InstantAmplitude += c_Amplitudes[j];

		InstantAmplitude /= (BPM_DETECT1_REAL) nSubbandSize;

		// =====================================================

		// FILL BUFFER

		subband->Buffer[subband->BufferLoad] = InstantAmplitude;

		subband->BufferLoad++;
		if(subband->BufferLoad < c_nBufferSize)
			continue;

		unsigned int j;
		unsigned int bpm = 0;
		BPM_DETECT1_REAL max_correlation = 0;

		// calculate auto correlation of each BPM in range

		unsigned int k;

		for(j = BPM_DETECT_MIN_BPM - BPM_DETECT_MIN_MARGIN - 1; j <= BPM_DETECT_MAX_BPM + BPM_DETECT_MAX_MARGIN; j++)
		{
			BPM_DETECT1_REAL correlation = 0;
			for(k = 0; k < c_nWindowSize; k++)
				correlation += (subband->Buffer[k] * subband->Buffer[k + c_pnOffset[j]]);

			if(correlation >= max_correlation)
			{
				max_correlation = correlation;	
				bpm = j;
			}
		}

		// mark bpm in history
		if(bpm >= BPM_DETECT_MIN_BPM && bpm <= BPM_DETECT_MAX_BPM)
		{	
			
			unsigned int HistoryHit = subband->BPMHistoryHit[bpm] + subband->BPMHistoryHit[bpm - 1] + subband->BPMHistoryHit[bpm + 1];
			if(HistoryHit)
			{
				if(HistoryHit >= BPM_HISTORY_HIT)
				{
					
					unsigned int Avg = (bpm * subband->BPMHistoryHit[bpm]  + (bpm - 1) * subband->BPMHistoryHit[bpm - 1] + (bpm + 1) * subband->BPMHistoryHit[bpm + 1]) / HistoryHit;
					subband->BPM = Avg;
					c_nSubbandBPMDetected++;
				}
			}

			subband->BPMHistoryHit[bpm]++;


			unsigned int j;
			for(j = 0 ; j < c_nOverlapSuccessSize; j++)
				subband->Buffer[j] = subband->Buffer[j + c_nOverlapSuccessStart];

			subband->BufferLoad = c_nOverlapSuccessSize;
			
		}
		else
		{
			unsigned int j;
			for(j = 0 ; j < c_nOverlapFailSize; j++)
				subband->Buffer[j] = subband->Buffer[j + c_nOverlapFailStart];

			subband->BufferLoad = c_nOverlapFailSize;
		}
	}

	

	if(c_nSubbandBPMDetected == c_nBandSizeIndex)
		return 1;

	return 0;


}