Exemple #1
0
/**
 * Run the actual transform based on the parameters set up in the
 * constructor.
 */
void Tracter::Fourier::Transform()
{
    assert(mFourierData);
    FourierData& m = *mFourierData;

    switch (m.Type)
    {
    case DCT2:
    {
        /* Duplicate */
        float* idata = (float*)m.IData;
        for (int i=0; i<m.Order; i++)
        {
            /* [1 2 3] -> [1 2 3 3 2 1] */
            idata[i+m.Order] = idata[m.Order-1-i];
        }

        /* Transform and rotate */
        kiss_fftr((kiss_fftr_cfg)m.Config, (const float*)m.IData, m.TmpData);
        float* odata = (float*)m.OData;
        for (int i=0; i<m.Order; i++)
        {
            float theta = 2.0f*M_PI*(-0.5f)*i/(2.0f*m.Order);
            odata[i] = ( m.TmpData[i].r * cos(theta) -
                         m.TmpData[i].i * sin(theta) );
        }
        break;
    }

    case REAL_TO_COMPLEX:
        kiss_fftr(
            (kiss_fftr_cfg)m.Config,
            (const float*)m.IData, (kiss_fft_cpx*)m.OData
        );
        break;

    case COMPLEX_TO_REAL:
        kiss_fftri(
            (kiss_fftr_cfg)m.Config,
            (const kiss_fft_cpx*)m.IData, (float*)m.OData
        );
        break;

    case COMPLEX_TO_COMPLEX:
        kiss_fft(
            (kiss_fft_cfg)m.Config,
            (const kiss_fft_cpx*)m.IData, (kiss_fft_cpx*)m.OData
        );
        break;

    default:
        assert(0);
    }
}
Exemple #2
0
void fft_do(const fft_cfg cfg, const COMP *in, COMP *out) {
#ifdef KISS_FFT
    kiss_fft(cfg, in, out);
#elif defined(LIBAVCODEC_FFT)
    memcpy(out, in, cfg->size);
    av_fft_permute(cfg->context, (FFTComplex *)out);
    av_fft_calc(cfg->context, (FFTComplex *)out);
#else
#error FFT engine was not defined
#endif
}
Exemple #3
0
void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
{
    int nfft = 0;

    kiss_fft_cpx    fin[1 << MAXLOGM];
    kiss_fft_cpx    fout[1 << MAXLOGM];

    if ( logm > MAXLOGM )
	{
		fprintf(stderr, "fft size too big\n");
		exit(1);
	}

    nfft = logm_to_nfft[logm];

    if ( fft_tables->cfg[logm][1] == NULL )
    {
        if ( nfft )
        {
            fft_tables->cfg[logm][1] = kiss_fft_alloc( nfft, 1, NULL, NULL );
        }
        else
        {
	    	fprintf(stderr, "bad logm = %d\n", logm);
            exit( 1 );
        }
    }
    
    if ( fft_tables->cfg[logm][1] )
    {
        unsigned int i;
        double fac = 1.0 / (double)nfft;
        
        for ( i = 0; i < nfft; i++ )
        {
            fin[i].r = xr[i];    
            fin[i].i = xi[i];
        }
        
        kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][1], fin, fout );

        for ( i = 0; i < nfft; i++ )
        {
            xr[i]   = fout[i].r * fac;
            xi[i]   = fout[i].i * fac;
        }
    }
    else
    {
        fprintf( stderr, "bad config for logm = %d\n", logm);
        exit( 1 );
    }
}
Exemple #4
0
void
fft_filt_c::work_complex() {
 for (uint32_t i=0;i<fft_len;i++) {
  input_buf_c[i].i = (i<l) ? fft_len * (*in)[2*i]   : 0;
  input_buf_c[i].r = (i<l) ? fft_len * (*in)[2*i+1] : 0;
 };

 kiss_fft(fft_fcfg_c, input_buf_c, fdom_buf);

 // now we convolve with the filter. 
 // the filter buffer is a fraction of i16's, the fdom buffer is i32's
 if (1) {
  for (uint32_t i=0;i<fft_len;i++) {
   int64_t i_i = fdom_buf[i].i; 
   int64_t i_r = fdom_buf[i].r;
   int64_t f_i = filt_buf[i].i;
   int64_t f_r = filt_buf[i].r; 
   int64_t p_r = (i_r * f_r - i_i * f_i);
   int64_t p_i = (i_r * f_i + i_i * f_r);
   fdom_conv_buf[i].i = p_i >> 15;
   fdom_conv_buf[i].r = p_r >> 15;
  }
 }

 kiss_fft(fft_icfg_c,fdom_conv_buf,output_buf_c);

 uint32_t extra = fft_len - l;
 for (uint32_t i=0; i<l; i++) {
  float vi = output_buf_c[i].i;
  float vr = output_buf_c[i].r;
  vi += (i<extra) ? last_output_buf_c[i].i : 0;
  vr += (i<extra) ? last_output_buf_c[i].r : 0;
  (*out)[2*i]     = vi;
  (*out)[2*i+1]   = vr;
 }

 for (uint32_t i=0;i<extra;i++) {
  last_output_buf_c[i] = output_buf_c[i+l];
 }
};
Exemple #5
0
void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], 
		   COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin)
{
    int   i,j,k;
    int   mpilot;
    COMP  s[MPILOTFFT];
    float mag, imax;
    int   ix;
    float r;

    /* LPF cutoff 200Hz, so we can handle max +/- 200 Hz freq offset */

    for(i=0; i<NPILOTLPF-nin; i++)
	pilot_lpf[i] = pilot_lpf[nin+i];
    for(i=NPILOTLPF-nin, j=0; i<NPILOTLPF; i++,j++) {
	pilot_lpf[i].real = 0.0; pilot_lpf[i].imag = 0.0;
	for(k=0; k<NPILOTCOEFF; k++)
	    pilot_lpf[i] = cadd(pilot_lpf[i], fcmult(pilot_coeff[k], pilot_baseband[j+k]));
    }

    /* decimate to improve DFT resolution, window and DFT */

    mpilot = FS/(2*200);  /* calc decimation rate given new sample rate is twice LPF freq */
    for(i=0; i<MPILOTFFT; i++) {
	s[i].real = 0.0; s[i].imag = 0.0;
    }
    for(i=0,j=0; i<NPILOTLPF; i+=mpilot,j++) {
	s[j] = fcmult(hanning[i], pilot_lpf[i]); 
    }

    kiss_fft(fft_pilot_cfg, (kiss_fft_cpx *)s, (kiss_fft_cpx *)S);

    /* peak pick and convert to Hz */

    imax = 0.0;
    ix = 0;
    for(i=0; i<MPILOTFFT; i++) {
	mag = S[i].real*S[i].real + S[i].imag*S[i].imag;
	if (mag > imax) {
	    imax = mag;
	    ix = i;
	}
    }
    r = 2.0*200.0/MPILOTFFT;     /* maps FFT bin to frequency in Hz */
  
    if (ix >= MPILOTFFT/2)
	*foff = (ix - MPILOTFFT)*r;
    else
	*foff = (ix)*r;
    *max = imax;

}
void *ConstQ::sparseKernelThread(void *arg)
{
  ConstQ *This = (ConstQ*) arg;

  unsigned int _fftLength = This->fftLength;
  int _constQBins = This->constQBins;
  int _Q = This->Q;
  double _minFreq = This->minFreq;
  double _maxFreq = This->maxFreq;
  int _fs = This->fs;
  float _thresh = This->thresh;
  int _bpo = This->bpo;

  kiss_fft_cpx tempKernel[_fftLength];
  memset(tempKernel, 0, _fftLength * sizeof(kiss_fft_cpx));

  kiss_fft_cpx specKernel[_fftLength];

  for (int k=_constQBins; k > 0; k--){
    This->progress = 1.0/_constQBins *(_constQBins - k);

    double centerFreq = (_minFreq * pow(2,(float(k-1)/_bpo)));
    int length = ceil(_Q * _fs / centerFreq);
    for(int n=0; n<length; n++){
      kiss_fft_cpx cpx = This->e(2*pi*_Q*n/length);
      double hwin = This->hamming(n, length) / length;
      tempKernel[n].r = (kiss_fft_scalar) hwin * cpx.r;
      tempKernel[n].i = (kiss_fft_scalar) hwin * cpx.i;
    }

    kiss_fft(This->fft, tempKernel, specKernel);

    int upperBound = This->sparkernel[k-1].e;
    int lowerBound = This->sparkernel[k-1].s;

    // cut under the threshold, Conjugate and scaling
    for(int i=lowerBound; i<upperBound; i++){
      if (This->mag(specKernel[i]) > _thresh){
	This->sparkernel[k-1].cpx[i-lowerBound].r = specKernel[i].r / _fftLength;
	This->sparkernel[k-1].cpx[i-lowerBound].i = - specKernel[i].i / _fftLength; // Conjugate
      } else {
	This->sparkernel[k-1].cpx[i-lowerBound].r = 0;
	This->sparkernel[k-1].cpx[i-lowerBound].i = 0;
      }
    }

  }

  This->progress = 1.0;
}
Exemple #7
0
DP_FN_POSTAMBLE

/* Some optimization work needs to be done. This function 
// can work directly from the input and output buffers for the 
// object, but there are two downsides. 1) we'd still need
// another buffer to do smoothing and 2) the output order of the 
// fft is not convenient for visualization. It has 0 Hz at index 0
// rather than centered int the list. The (-1)^i flipping below
// fixes that, but requires another buffer.
*/
DP_FN_PREAMBLE(cfft,work) {
  uint32_t i;
  if (s->need_buffers && !s->buffs_allocd) {
   dp_cfft_prerun(b);
  }

  if (s->need_buffers) {
   for (i=0;i<b->runlength;i++) {
    /* making sure to get r and i parts in the right sequence
     * and also applying -i^i transform to make result in order
     * linear from -sr/2 to sr/2.
     */
    s->ibuff[i].r = b->in_v->v[2*i]    * ((i%2) ? -1 : 1);
    s->ibuff[i].i = b->in_v->v[2*i+1]  * ((i%2) ? -1 : 1);
   } 
  } else {
   s->ibuff = (kiss_fft_cpx *)(void *)b->in_v->v;
   s->obuff = (kiss_fft_cpx *)(void *)b->out_v->v;
  }

  kiss_fft(s->cfg,s->ibuff, s->obuff);

  if (s->need_buffers) {
   for (i=0;i<b->runlength;i++) {
    int32_t av_r, av_i;
    av_r = (255 - s->averaging) * s->obuff[i].r + s->averaging * b->out_v->v[2*i];
    av_i = (255 - s->averaging) * s->obuff[i].i + s->averaging * b->out_v->v[2*i+1];
    b->out_v->v[2*i]   = av_r >> 8;
    b->out_v->v[2*i+1] = av_i >> 8;
    /* printf("i,%d,fft,%d,%d,in,%d,%d\n",i,av_r>>8,av_i>>8,b->in_v->v[2*i],b->in_v->v[2*i+1]);  */
   }
  }
  /* printf("\n\n\n\n");  */
}
Exemple #8
0
void test1d(int nfft,int isinverse)
{
    size_t buflen = sizeof(kiss_fft_cpx)*nfft;

    kiss_fft_cpx  * in = (kiss_fft_cpx*)malloc(buflen);
    kiss_fft_cpx  * out= (kiss_fft_cpx*)malloc(buflen);
    kiss_fft_cfg  cfg = kiss_fft_alloc(nfft,0,0);
    int k;

    for (k=0;k<nfft;++k) {
        in[k].r = (rand() % 32767) - 16384;
        in[k].i = (rand() % 32767) - 16384;
    }

#ifdef DOUBLE_PRECISION
    for (k=0;k<nfft;++k) {
       in[k].r *= 32768;
       in[k].i *= 32768;
    }
#endif
    
    if (isinverse)
    {
       for (k=0;k<nfft;++k) {
          in[k].r /= nfft;
          in[k].i /= nfft;
       }
    }
    
    /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
       
    if (isinverse)
       kiss_ifft(cfg,in,out);
    else
       kiss_fft(cfg,in,out);

    /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/

    check(in,out,nfft,isinverse);

    free(in);
    free(out);
    free(cfg);
}
static
void fft_file(FILE * fin, FILE * fout, int nfft, int isinverse)
{
    kiss_fft_cfg st;
    kiss_fft_cpx * buf;
    kiss_fft_cpx * bufout;

    buf = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * nfft);
    bufout = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * nfft);
    st = kiss_fft_alloc(nfft , isinverse , 0, 0);

    while (fread(buf , sizeof(kiss_fft_cpx) * nfft , 1, fin) > 0) {
        kiss_fft(st , buf , bufout);
        fwrite(bufout , sizeof(kiss_fft_cpx) , nfft , fout);
    }
    free(st);
    free(buf);
    free(bufout);
}
Exemple #10
0
FFT_RESULT PerformFFT(kiss_fft_cpx* in, kiss_fft_cpx* out, int samplesRead)
{
    kiss_fft_cfg cfg;

    if (samplesRead > 0)
    {
        /* printf("Samples Read: %i \n", samplesRead);  */
        if ((cfg = kiss_fft_alloc(samplesRead, 0/*is_inverse_fft*/, NULL, NULL)) != NULL)
        {
            kiss_fft(cfg, in, out);
            free(cfg);
        }
        else
        {
            printf("Cannot set up kissFFT.\n");
            exit(EXIT_FAILURE);
        }
    }

    FFT_RESULT result;
    result.bins = out;
    result.samples = samplesRead;
    return result;
}
Exemple #11
0
void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], 
					       COMP rx_fdm[], int nin) 
{
    int   i,j;
    COMP  fft_in[2*FDMDV_NSPEC];
    COMP  fft_out[2*FDMDV_NSPEC];
    float full_scale_dB;

    /* update buffer of input samples */

    for(i=0; i<2*FDMDV_NSPEC-nin; i++)
	f->fft_buf[i] = f->fft_buf[i+nin];
    for(j=0; j<nin; j++,i++)
	f->fft_buf[i] = rx_fdm[j].real;
    assert(i == 2*FDMDV_NSPEC);

    /* window and FFT */

    for(i=0; i<2*FDMDV_NSPEC; i++) {
	fft_in[i].real = f->fft_buf[i] * (0.5 - 0.5*cos((float)i*2.0*PI/(2*FDMDV_NSPEC)));
	fft_in[i].imag = 0.0;
    }

    kiss_fft(f->fft_cfg, (kiss_fft_cpx *)fft_in, (kiss_fft_cpx *)fft_out);

    /* FFT scales up a signal of level 1 FDMDV_NSPEC */

    full_scale_dB = 20*log10(FDMDV_NSPEC);

    /* scale and convert to dB */

    for(i=0; i<FDMDV_NSPEC; i++) {
	mag_spec_dB[i]  = 10.0*log10(fft_out[i].real*fft_out[i].real + fft_out[i].imag*fft_out[i].imag + 1E-12);
	mag_spec_dB[i] -= full_scale_dB;
    }
}
Exemple #12
0
void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak[],
                     int order, int dump, float beta, float gamma, int bass_boost)
{
    int   i;
    COMP  x[FFT_ENC];   /* input to FFTs                */
    COMP  Aw[FFT_ENC];  /* LPC analysis filter spectrum */
    COMP  Ww[FFT_ENC];  /* weighting spectrum           */
    float Rw[FFT_ENC];  /* R = WA                       */
    float e_before, e_after, gain;
    float Pfw[FFT_ENC]; /* Post filter mag spectrum     */
    float max_Rw, min_Rw;
    float coeff;
    TIMER_VAR(tstart, tfft1, taw, tfft2, tww, tr);

    TIMER_SAMPLE(tstart);

    /* Determine LPC inverse filter spectrum 1/A(exp(jw)) -----------*/

    /* we actually want the synthesis filter A(exp(jw)) but the
       inverse (analysis) filter is easier to find as it's FIR, we
       just use the inverse of 1/A to get the synthesis filter
       A(exp(jw)) */

    for(i=0; i<FFT_ENC; i++) {
	x[i].real = 0.0;
	x[i].imag = 0.0;
    }

    for(i=0; i<=order; i++)
	x[i].real = ak[i];
    kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)x, (kiss_fft_cpx *)Aw);

    TIMER_SAMPLE_AND_LOG(tfft1, tstart, "        fft1");

    for(i=0; i<FFT_ENC/2; i++) {
	Aw[i].real = 1.0/(Aw[i].real*Aw[i].real + Aw[i].imag*Aw[i].imag);
    }

    TIMER_SAMPLE_AND_LOG(taw, tfft1, "        Aw");

    /* Determine weighting filter spectrum W(exp(jw)) ---------------*/

    for(i=0; i<FFT_ENC; i++) {
	x[i].real = 0.0;
	x[i].imag = 0.0;
    }

    x[0].real = ak[0];
    coeff = gamma;
    for(i=1; i<=order; i++) {
	x[i].real = ak[i] * coeff;
        coeff *= gamma;
    }
    kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)x, (kiss_fft_cpx *)Ww);

    TIMER_SAMPLE_AND_LOG(tfft2, taw, "        fft2");

    for(i=0; i<FFT_ENC/2; i++) {
	Ww[i].real = Ww[i].real*Ww[i].real + Ww[i].imag*Ww[i].imag;
    }

    TIMER_SAMPLE_AND_LOG(tww, tfft2, "        Ww");

    /* Determined combined filter R = WA ---------------------------*/

    max_Rw = 0.0; min_Rw = 1E32;
    for(i=0; i<FFT_ENC/2; i++) {
	Rw[i] = sqrtf(Ww[i].real * Aw[i].real);
	if (Rw[i] > max_Rw)
	    max_Rw = Rw[i];
	if (Rw[i] < min_Rw)
	    min_Rw = Rw[i];

    }

    TIMER_SAMPLE_AND_LOG(tr, tww, "        R");

    #ifdef DUMP
    if (dump)
      dump_Rw(Rw);
    #endif

    /* create post filter mag spectrum and apply ------------------*/

    /* measure energy before post filtering */

    e_before = 1E-4;
    for(i=0; i<FFT_ENC/2; i++)
	e_before += Pw[i].real;

    /* apply post filter and measure energy  */

    #ifdef DUMP
    if (dump)
	dump_Pwb(Pw);
    #endif

    e_after = 1E-4;
    for(i=0; i<FFT_ENC/2; i++) {
	Pfw[i] = powf(Rw[i], beta);
	Pw[i].real *= Pfw[i] * Pfw[i];
	e_after += Pw[i].real;
    }
    gain = e_before/e_after;

    /* apply gain factor to normalise energy */

    for(i=0; i<FFT_ENC/2; i++) {
	Pw[i].real *= gain;
    }

    if (bass_boost) {
        /* add 3dB to first 1 kHz to account for LP effect of PF */

        for(i=0; i<FFT_ENC/8; i++) {
            Pw[i].real *= 1.4*1.4;
        }
    }

    TIMER_SAMPLE_AND_LOG2(tr, "        filt");
}
Exemple #13
0
/*------------------------------------------------------------*/
void ompfft2(bool inv          /* inverse/forward flag */, 
	     kiss_fft_cpx **pp /* [1...n2][1...n1] */,
	     int ompith,
	     fft2d fft) 
/*< Apply 2-D FFT >*/
{
    int i1,i2;
    
    if (inv) {

	/* IFT 1 */
	for (i2=0; i2 < fft->n2; i2++) {
#ifdef _OPENMP
#pragma omp critical
#endif
	    kiss_fft(fft->invs1[ompith],pp[i2],pp[i2]);
	}

	/* IFT 2 */
	for (i1=0; i1 < fft->n1; i1++) {
#ifdef _OPENMP
#pragma omp critical
#endif
	    kiss_fft_stride(fft->invs2[ompith],pp[0]+i1,
			    fft->ctrace[ompith],fft->n1);
	    for (i2=0; i2<fft->n2; i2++) {
		pp[i2][i1] = fft->ctrace[ompith][i2];
	    }
	}

	/* scaling */
	for     (i2=0; i2<fft->n2; i2++) {
	    for (i1=0; i1<fft->n1; i1++) {
		pp[i2][i1] = sf_crmul(pp[i2][i1],fft->fftscale);
	    }
	}

    } else {

	/* scaling */
	for     (i2=0; i2<fft->n2; i2++) {
	    for (i1=0; i1<fft->n1; i1++) {
		pp[i2][i1] = sf_crmul(pp[i2][i1],fft->fftscale);
	    }
	}
	
	/* FFT 2 */
	for (i1=0; i1 < fft->n1; i1++) {
#ifdef _OPENMP
#pragma omp critical
#endif
	    kiss_fft_stride(fft->forw2[ompith],pp[0]+i1,
			    fft->ctrace[ompith],fft->n1);
	    for (i2=0; i2<fft->n2; i2++) {
		pp[i2][i1] = fft->ctrace[ompith][i2];
	    }
	}

	/* FFT 1 */
	for (i2=0; i2 < fft->n2; i2++) {
#ifdef _OPENMP
#pragma omp critical
#endif
	    kiss_fft(fft->forw1[ompith],pp[i2],pp[i2]);
	}
    }
}
Exemple #14
0
void kfc_ifft(int nfft, const kiss_fft_cpx * fin,kiss_fft_cpx * fout)
{
    kiss_fft( find_cached_fft(nfft,1),fin,fout );
}
Exemple #15
0
KissFFTTest::KissFFTTest()
{
	CtrlLayout(*this, "Window title");
	
#if _DIRECT_KISSFFT_MEANS

	kiss_fft_cpx sin[N];
	kiss_fft_cpx sout[N];
	
	for(int i=0; i<N; i++)
	{
		sin[i].r = (kiss_fft_scalar)0;
		sin[i].i = (kiss_fft_scalar)0;
	}
		sin[0].r = (kiss_fft_scalar)1;


	kiss_fft_cfg st = kiss_fft_alloc(N,0,0,0);
	kiss_fft(st,sin,sout);
	kiss_fft_free(st);

	print_buffs(sin, sout, N);

	RLOG("");

	st = kiss_fft_alloc(N,1,0,0);
	kiss_fft(st,sout,sin);
	kiss_fft_free(st);

	//apply scale
	double sc = 1./N;
	for(int i = 0; i < N; i++)
	{
		sin[i].r *= sc, sin[i].i *= sc;
	}
	print_buffs(sout, sin, N);

#else

	//USING UPP STRUCTURES

#ifdef CD
	Vector<Complex> vt, vf;
#else
	Vector<kiss_fft_cpx> vt, vf;
#endif

	vt.SetCount(N); //in
	vf.SetCount(N); //out

#ifdef CD
	vt[0] = Complex(1.);
#else
	for(int i=0; i<N; i++)
	{ vt[i].r = (kiss_fft_scalar)0, vt[i].i = (kiss_fft_scalar)0; }
	vt[0].r = (kiss_fft_scalar)1;
#endif

	RLOG("fw fft");
	{
		KissFFT fft(N);
		fft(vf, vt);
	}
#ifdef CD
	DUMPC(vt);
	DUMPC(vf);
#else
	print_buffs((const kiss_fft_cpx*)vt, (const kiss_fft_cpx*)vf, N);
#endif
	
	RLOG("bw fft");
	{
		KissFFT fft(N,true);
		fft(vt, vf);
	}
	double sc = 1./N;
#ifdef CD
	for(int i = 0; i < vt.GetCount(); i++)
		vt[i] *= sc;
	DUMPC(vf);
	DUMPC(vt);
#else
	for(int i = 0; i < vt.GetCount(); i++)
	{ vt[i].r *= sc, vt[i].i *= sc; }
	print_buffs((const kiss_fft_cpx*)vf, (const kiss_fft_cpx*)vt, N);
#endif

#endif
}
Exemple #16
0
/* generic complex 1d-transform. */
int tcl_cfft_1d(ClientData nodata, Tcl_Interp *interp,
                int objc, Tcl_Obj *const objv[]) 
{
    Tcl_Obj *result, **tdata;
    
    const char *name;
    kiss_fft_cpx *input;
    kiss_fft_cpx *output;
    kiss_fft_cfg work;
    
    int dir, ndat, k;

    /* thread safety */
    Tcl_MutexLock(&myFftMutex);

    /* set defaults: */
    dir   = FFT_FORWARD;
    ndat  = -1;
    
    /* Parse arguments:
     *
     * usage: cfftf_1d <data>
     *    or: cfftb_1d <data>
     * 
     * cfftf_1d   : is the 1d complex forward transform.
     * cfftb_1d   : is the 1d complex backward transform.
     * <data>     : list containing data to be transformed. this can either a real 
     *              or a list with two reals interpreted as complex.
     */

    name = Tcl_GetString(objv[0]);
    if (strcmp(name,"cfftf_1d") == 0) {
        dir = FFT_FORWARD;
    } else if (strcmp(name,"cfftb_1d") == 0) {
        dir = FFT_BACKWARD;
    } else {
        Tcl_AppendResult(interp, name, ": unknown fft command.", NULL);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "<data>");
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    
    /* get handle on data  and check */
    Tcl_IncrRefCount(objv[1]);
    if (Tcl_ListObjGetElements(interp, objv[1], &ndat, &tdata) != TCL_OK) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if (ndat < 0) { /* this should not happen, but... */
        Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if ((ndat == 0) || (ndat == 1)) { /* no effect for zero or one element */
        Tcl_DecrRefCount(objv[1]);
        Tcl_SetObjResult(interp, objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_OK;
    }
    
    check_thread_count(interp,"fftcmds");

    /* get dynamic storage for passing data to the lowlevel code. */
    input  = (void *)Tcl_Alloc(ndat*sizeof(kiss_fft_cpx));
    output = (void *)Tcl_Alloc(ndat*sizeof(kiss_fft_cpx));
    work   = kiss_fft_alloc(ndat, dir, NULL, NULL);
    
    /* parse/copy data list */
    for (k=0; k<ndat; ++k) {
        if (read_list_cpx(interp, tdata[k], input + k) != TCL_OK) {
            Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
            Tcl_DecrRefCount(objv[1]);
            Tcl_MutexUnlock(&myFftMutex);
            return TCL_ERROR;
        }
    }
    Tcl_DecrRefCount(objv[1]);
    
    /* finally run the transform */
    kiss_fft(work, input, output);

    /* prepare results */
    result = Tcl_NewListObj(0, NULL);
    for (k=0; k<ndat; ++k) {
        make_list_cpx(interp, result, output + k);
    }
    Tcl_SetObjResult(interp, result);

    /* free intermediate storage */
    Tcl_Free((char *)input);
    Tcl_Free((char *)output);
    kiss_fft_free(work);
    kiss_fft_cleanup();
    
    Tcl_MutexUnlock(&myFftMutex);
    return TCL_OK;
}
Exemple #17
0
void make_analysis_window(kiss_fft_cfg fft_fwd_cfg, float w[], COMP W[])
{
  float m;
  COMP  wshift[FFT_ENC];
  COMP  temp;
  int   i,j;

  /* 
     Generate Hamming window centered on M-sample pitch analysis window
  
  0            M/2           M-1
  |-------------|-------------|
        |-------|-------|
            NW samples

     All our analysis/synthsis is centred on the M/2 sample.               
  */

  m = 0.0;
  for(i=0; i<M/2-NW/2; i++)
    w[i] = 0.0;
  for(i=M/2-NW/2,j=0; i<M/2+NW/2; i++,j++) {
    w[i] = 0.5 - 0.5*cos(TWO_PI*j/(NW-1));
    m += w[i]*w[i];
  }
  for(i=M/2+NW/2; i<M; i++)
    w[i] = 0.0;
 
  /* Normalise - makes freq domain amplitude estimation straight
     forward */

  m = 1.0/sqrt(m*FFT_ENC);
  for(i=0; i<M; i++) {
    w[i] *= m;
  }

  /* 
     Generate DFT of analysis window, used for later processing.  Note
     we modulo FFT_ENC shift the time domain window w[], this makes the
     imaginary part of the DFT W[] equal to zero as the shifted w[] is
     even about the n=0 time axis if NW is odd.  Having the imag part
     of the DFT W[] makes computation easier.

     0                      FFT_ENC-1
     |-------------------------|

      ----\               /----
           \             / 
            \           /          <- shifted version of window w[n]
             \         /
              \       /
               -------

     |---------|     |---------|      
       NW/2              NW/2
  */

  for(i=0; i<FFT_ENC; i++) {
    wshift[i].real = 0.0;
    wshift[i].imag = 0.0;
  }
  for(i=0; i<NW/2; i++)
    wshift[i].real = w[i+M/2];
  for(i=FFT_ENC-NW/2,j=M/2-NW/2; i<FFT_ENC; i++,j++)
   wshift[i].real = w[j];

  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)wshift, (kiss_fft_cpx *)W);

  /* 
      Re-arrange W[] to be symmetrical about FFT_ENC/2.  Makes later 
      analysis convenient.

   Before:


     0                 FFT_ENC-1
     |----------|---------|
     __                   _       
       \                 /          
        \_______________/      

   After:

     0                 FFT_ENC-1
     |----------|---------|
               ___                        
              /   \                
     ________/     \_______     

  */
       
      
  for(i=0; i<FFT_ENC/2; i++) {
    temp.real = W[i].real;
    temp.imag = W[i].imag;
    W[i].real = W[i+FFT_ENC/2].real;
    W[i].imag = W[i+FFT_ENC/2].imag;
    W[i+FFT_ENC/2].real = temp.real;
    W[i+FFT_ENC/2].imag = temp.imag;
  }

}
Exemple #18
0
	__declspec(dllexport) void KISS_FFT(kiss_fft_cfg cfg, const kiss_fft_cpx* fin, kiss_fft_cpx* fout)
	{
		kiss_fft(cfg, fin, fout);
	}
int main(int argc, char ** argv)
{
    int k;
    int nfft[32];
    int ndims = 1;
    int isinverse = 0;
    int numffts = 1000, i;
    kiss_fft_cpx * buf;
    kiss_fft_cpx * bufout;
    int real = 0;

    nfft[0] = 1024;// default

    while (1) {
        int c = getopt(argc, argv, "n:ix:r");
        if (c == -1)
            break;
        switch (c) {
        case 'r':
            real = 1;
            break;
        case 'n':
            ndims = getdims(nfft, optarg);
            if (nfft[0] != kiss_fft_next_fast_size(nfft[0])) {
                int ng = kiss_fft_next_fast_size(nfft[0]);
                fprintf(stderr, "warning: %d might be a better choice for speed than %d\n", ng, nfft[0]);
            }
            break;
        case 'x':
            numffts = atoi(optarg);
            break;
        case 'i':
            isinverse = 1;
            break;
        }
    }
    int nbytes = sizeof(kiss_fft_cpx);
    for (k = 0; k < ndims; ++k)
        nbytes *= nfft[k];

#ifdef USE_SIMD
    numffts /= 4;
    fprintf(stderr, "since SIMD implementation does 4 ffts at a time, numffts is being reduced to %d\n", numffts);
#endif

    buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes);
    bufout = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes);
    memset(buf, 0, nbytes);

    pstats_init();

    if (ndims == 1) {
        if (real) {
            kiss_fftr_cfg st = kiss_fftr_alloc(nfft[0] , isinverse , 0, 0);
            if (isinverse)
                for (i = 0; i < numffts; ++i)
                    kiss_fftri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout);
            else
                for (i = 0; i < numffts; ++i)
                    kiss_fftr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout);
            free(st);
        } else {
            kiss_fft_cfg st = kiss_fft_alloc(nfft[0] , isinverse , 0, 0);
            for (i = 0; i < numffts; ++i)
                kiss_fft(st , buf, bufout);
            free(st);
        }
    } else {
        if (real) {
            kiss_fftndr_cfg st = kiss_fftndr_alloc(nfft, ndims , isinverse , 0, 0);
            if (isinverse)
                for (i = 0; i < numffts; ++i)
                    kiss_fftndri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout);
            else
                for (i = 0; i < numffts; ++i)
                    kiss_fftndr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout);
            free(st);
        } else {
            kiss_fftnd_cfg st = kiss_fftnd_alloc(nfft, ndims, isinverse , 0, 0);
            for (i = 0; i < numffts; ++i)
                kiss_fftnd(st , buf, bufout);
            free(st);
        }
    }

    free(buf); free(bufout);

    fprintf(stderr, "KISS\tnfft=");
    for (k = 0; k < ndims; ++k)
        fprintf(stderr, "%d,", nfft[k]);
    fprintf(stderr, "\tnumffts=%d\n" , numffts);
    pstats_report();

    kiss_fft_cleanup();

    return 0;
}
Exemple #20
0
void generateSyntheticData(int row, int hosts, double ** m, std::string prefix, std::string topofile, double demand_jump_factor, double demand_locality_factor, int merge_len)
{
    char filedir[200];
    sprintf(filedir,"%s%s", prefix.c_str(),"patterns");
    printf("dir=%s!\n", filedir);
	FILE * fPattern = fopen(filedir,"r");
	assert(fPattern != NULL && "Unable to open petterns file");
	int nWeeks;
	int frlt=fscanf(fPattern, "%i", &nWeeks);
	assert(frlt >= 0);
	double ** totflow = new double *[nWeeks];
	for (int curWeek = 0; curWeek < nWeeks;curWeek++)
	{
		totflow[curWeek] = new double[2016];
		for (int i = 0; i < 2016; i++)
			frlt=fscanf(fPattern, "%lf", &totflow[curWeek][i]);
	}

	const int nfft = 2016;
	kiss_fft_cfg cfg = kiss_fft_alloc(nfft, false, 0, 0);
	kiss_fft_cfg cfg2 = kiss_fft_alloc(nfft,true, 0, 0);
	kiss_fft_cpx cx_in[nfft], cx_out[nfft];


	for (int curWeek = 0; curWeek < nWeeks; curWeek++)
	{
		for (int i = 0; i < nfft; i++)
		{
			cx_in[i].r = totflow[curWeek][i];
			cx_in[i].i = 0;
		}
		kiss_fft(cfg, cx_in, cx_out);
		for (int i = 0; i < nfft; i++)
		{
			cx_out[i].r /= nfft;
			cx_out[i].i /= nfft;
		}
		int position[nfft];
		for (int i = 0; i < nfft; i++)
			position[i] = i;

		for (int i = 0; i < nfft - 1; i++)
			for (int j = i + 1; j < nfft; j++)
			{
				double n1 = cxnorm(cx_out[position[i]]);
				double n2 = cxnorm(cx_out[position[j]]);
				if (n1 < n2)
				{
					int tmp;
					tmp = position[i];
					position[i] = position[j];
					position[j] = tmp;
				}
			}
		for (int i = 6; i < nfft; i++)
		{
			double a = uniform_rand(0, 3);
			cx_out[position[i]].r *= a;
			cx_out[position[i]].i *= a;
		}
		kiss_fft(cfg2, cx_out, cx_in);
		for (int i = 0; i < nfft; i++)
			totflow[curWeek][i] = cx_in[i].r;
	}


    /*
	FILE * fFFTout = fopen("fftout", "w");
	for (int curWeek = 0; curWeek < nWeeks; curWeek++)
	{
		for (int i = 0; i < 2016; i++)
			fprintf(fFFTout, "%.2lf  ", totflow[curWeek][i]);
		fprintf(fFFTout, "\n");
	}
	fclose(fFFTout);
    */

	int nMean;
    char filedir2[200];
    sprintf(filedir2,"%s%s", prefix.c_str(),"pareto");
    printf("dir=%s!\n", filedir2);
	FILE * fpareto = fopen(filedir2, "r");
	frlt=fscanf(fpareto, "%i", &nMean);

	double * saveMean = new double[nMean];
	for (int i = 0; i < nMean; i++)
		frlt=fscanf(fpareto, "%lf", &saveMean[i]);

	//m[col][row];
	double ** Tin = new double*[hosts];
	double ** Tout = new double*[hosts];



	for (int i = 0; i < hosts; i++)
	{
		Tin[i] = new double[row];
		Tout[i] = new double[row];
		generateW(Tin[i], saveMean[getRandNum(nMean)], row,demand_jump_factor);
		generateW(Tout[i], saveMean[getRandNum(nMean)], row,demand_jump_factor);
	}
		/*
	for (int i = 0; i < hosts; i++)
	{
		printf("No%i ----------%lf        ", i, Tin[i][0]);
		for (int j = 0; j < 100;j++)
			printf("%.2lf -- ", Tin[i][j]);
		double avg = 0;
		for (int j = 0; j < row; j++)
			avg += Tin[i][j] / row;
		printf("avg == %.2lf\n\n", avg);
	}
			*/
	double tot_in, tot_out;
	for (int i = 0; i < row; i++)
	{
        tot_in = 0;
        tot_out = 0;
		for (int j = 0; j < hosts;j++)
		{
			tot_in += Tin[j][i];
			tot_out += Tout[j][i];
		}
        if (tot_in==0)
            tot_in=1;
		for (int j = 0; j < hosts; j++)
		{
			Tin[j][i] /= tot_in;
			Tout[j][i] /= tot_out;
		}
	}
	/*
	for (int i = 0; i < 5; i++)
	{
		printf("No%i ---------- \n\n\n", i);
		for (int j = 0; j < 100;j++)
			printf("%.6lf -- ", Tin[i][j]);
	}*/
	double maxDist = 0;
	double ** graph=NULL;
	if (topofile.length() > 1)
	{
		FILE* topof=fopen(topofile.c_str(), "r");
		assert(topof != NULL);
		int topo_n, topo_m;
        int tmp_rlt;
		tmp_rlt=fscanf(topof, "%i%i", &topo_n, &topo_m);
        if (tmp_rlt<0)
          printf("error! in fscanf\n");
		graph = new double *[topo_n];
		for (int i = 0; i < topo_n; i++)
			graph[i] = new double[topo_n];
		for (int i = 0; i < topo_n; i++)
			for (int j = 0; j < topo_n; j++)
				if (i != j)
					graph[i][j] = 214748368;
				else
					graph[i][j] = 0;
		for (int i = 0; i < topo_m; i++)
		{
			int va, vb;
			double edge_len;
			double tmp_rlt=fscanf(topof, "%i%i%lf", &va, &vb, &edge_len);
            if (tmp_rlt<0)
              printf("error! in fscanf\n");
			graph[va][vb] = edge_len;
			graph[vb][va] = edge_len;
		}
		for (int k = 0; k < topo_n; k++)
			for (int i = 0; i < topo_n; i++)
				if (k != i)
					for (int j = 0; j < topo_n; j++)
						if ((k != j) && (i != j))
							if (graph[i][j]>graph[i][k] + graph[k][j])
								graph[i][j] = graph[i][k] + graph[k][j];
		for (int i = 0; i < topo_n; i++)
			for (int j = 0; j < topo_n; j++)
				if (maxDist<graph[i][j])
					maxDist = graph[i][j];
		fclose(topof);
	}

    int next=0;
	int pickedTotPattern=0;
	for (int i = 0; i < row; i++)
	{
        double s_merge=0;
        for (int j=0;j<merge_len;j++)
        {
            s_merge+= totflow[pickedTotPattern][next];
            next++;
            if (next>=2016)
            {
                next=0;
                pickedTotPattern=0;
            }
        }
        s_merge/=merge_len;
		for (int j = 0; j < hosts; j++)
			for (int k = 0; k < hosts; k++){
				if (maxDist == 0)
					m[j*hosts + k][i] = s_merge * Tin[j][i] * Tout[k][i];
				else
					m[j*hosts + k][i] = s_merge * Tin[j][i] * Tout[k][i]* exp(-demand_locality_factor*  graph[j][k]/maxDist/2);
                if (isnan(m[j*hosts+k][i]))
                    printf("%lf %lf %lf", s_merge, Tin[j][i], Tout[k][i]);
                if (m[j*hosts+k][i]==0)
                    m[j*hosts+k][i]=1000;
            }
	}
	fclose(fPattern);
	fclose(fpareto);
	for (int i = 0; i < nWeeks; i++)
		delete[] totflow[i];
	delete[] totflow;
	delete[] saveMean;
	delete[] Tin;
	delete[] Tout;
}
Exemple #21
0
void freqfilt4pi_lop (bool adj, bool add, int nx, int ny, float* x, float* y) 
/*< linear filtering operator >*/
{
    int iw, ik;
    kiss_fft_cpx temp;
    int verb; // just outputting values to check when I get zeroes

    sf_adjnull(adj,add,nx,ny,x,y);

    for (ik=0; ik < m2; ik++) {
	for (iw=0; iw < m1; iw++) {
	    trace[iw] = adj? y[ik*m1+iw]: x[ik*m1+iw];
	
		/*if(trace[iw] == 0.0){
		
			sf_warning("trace[%d] = %f",iw,trace[iw]);
			
		}*/
	
	}
	for (iw=m1; iw < nfft; iw++) {
	    trace[iw]=0.;
	}

	kiss_fftr (tfor,trace,ctrace);
	for (iw=0; iw < nw; iw++) {
	    fft[ik][iw] = ik%2? sf_cneg(ctrace[iw]): ctrace[iw];
	}
    }

    for (iw=0; iw < nw; iw++) {
	kiss_fft_stride(xfor,fft[0]+iw,ctrace2,nw);

	for (ik=0; ik < m2; ik++) {
	
		//double creal( double complex z );
	
	    //transform to kiss fft cpx
	    //creal are double complex functions - what should we
	    //do when double complex is not supported???  	
		if (adj){
			temp.r = creal(shape[iw][ik]);
			temp.i = (-1.0)*cimag(shape[iw][ik]);
		} else {
			temp.r = creal(shape[iw][ik]);
			temp.i = cimag(shape[iw][ik]);
	    }
	    
	    ctrace2[ik] = sf_cmul(ctrace2[ik],temp);
	
	}

	kiss_fft(xinv,ctrace2,ctrace2);

	for (ik=0; ik < m2; ik++) {
	    fft[ik][iw] = ik%2? sf_cneg(ctrace2[ik]): ctrace2[ik];
	}
    }

    for (ik=0; ik < m2; ik++) {
	kiss_fftri (tinv,fft[ik],trace);

	for (iw=0; iw < m1; iw++) {	  
	    if (adj) {
		x[ik*m1+iw] += trace[iw];
	    } else {
		y[ik*m1+iw] += trace[iw];
	    }
	}
    }
}
Exemple #22
0
/*------------------------------------------------------------*/
void ompfft3(bool inv          /* inverse/forward flag */, 
	     kiss_fft_cpx ***pp /* [n1][n2][n3] */,
	     int ompith,
	     fft3d fft) 
/*< Apply 3-D FFT >*/
{
    int i1,i2,i3;
    
    if (inv) {

	/* IFT 1 */
	for (i3=0; i3 < fft->n3; i3++) {
	    for (i2=0; i2 < fft->n2; i2++) {
#ifdef _OPENMP
#pragma omp critical
#endif
		kiss_fft(fft->invs1[ompith],pp[i3][i2],pp[i3][i2]);
	    }
	}

	/* IFT 2 */
	for (i3=0; i3 < fft->n3; i3++) {
	    for (i1=0; i1 < fft->n1; i1++) {
#ifdef _OPENMP
#pragma omp critical
#endif
		kiss_fft_stride(fft->invs2[ompith],pp[i3][0]+i1,
				fft->ctrace2[ompith],fft->n1);
		for (i2=0; i2<fft->n2; i2++) {
		    pp[i3][i2][i1] = fft->ctrace2[ompith][i2];
		}
	    }
	}
	
	/* IFT 3 */
	for (i2=0; i2 < fft->n2; i2++) {
	    for (i1=0; i1 < fft->n1; i1++) {
#ifdef _OPENMP
#pragma omp critical
#endif
		kiss_fft_stride(fft->invs3[ompith],pp[0][i2]+i1,
				fft->ctrace3[ompith],fft->n1);
		for (i3=0; i3 < fft->n3; i3++) {
		    pp[i3][i2][i1] = fft->ctrace3[ompith][i3];
		}
	    }
	}

	/* scaling */
	for (i3=0; i3 < fft->n3; i3++) {
	    for (i2=0; i2 < fft->n2; i2++) {
		for (i1=0; i1 < fft->n1; i1++) {
		    pp[i3][i2][i1] = sf_crmul(pp[i3][i2][i1],fft->fftscale);
		}
	    }
	}


    } else {
 
	/* scaling */
	for (i3=0; i3 < fft->n3; i3++) {
	    for (i2=0; i2 < fft->n2; i2++) {
		for (i1=0; i1 < fft->n1; i1++) {
		    pp[i3][i2][i1] = sf_crmul(pp[i3][i2][i1],fft->fftscale);
		}
	    }
	}
	
	/* FFT 3 */
	for (i2=0; i2 < fft->n2; i2++) {
	    for (i1=0; i1 < fft->n1; i1++) {
#ifdef _OPENMP
#pragma omp critical
#endif
		kiss_fft_stride(fft->forw3[ompith],pp[0][i2]+i1,fft->ctrace3[ompith],fft->n1);
		for (i3=0; i3 < fft->n3; i3++) {
		    pp[i3][i2][i1] = fft->ctrace3[ompith][i3];
		}
	    }
	}

	/* FFT 2 */
	for (i3=0; i3 < fft->n3; i3++) {
	    for (i1=0; i1 < fft->n1; i1++) {
#ifdef _OPENMP
#pragma omp critical
#endif
		kiss_fft_stride(fft->forw2[ompith],pp[i3][0]+i1,
				fft->ctrace2[ompith],fft->n1);
		for (i2=0; i2 < fft->n2; i2++) {
		    pp[i3][i2][i1] = fft->ctrace2[ompith][i2];
		}
	    }
	}

	/* FFT 1 */
	for (i3=0; i3 < fft->n3; i3++) {
	    for (i2=0; i2 < fft->n2; i2++) {
#ifdef _OPENMP
#pragma omp critical
#endif
		kiss_fft(fft->forw1[ompith],pp[i3][i2],pp[i3][i2]);
	    }
	}

    }
}
Exemple #23
0
float nlp(
  void *nlp_state, 
  float  Sn[],			/* input speech vector */
  int    n,			/* frames shift (no. new samples in Sn[]) */
  int    pmin,                  /* minimum pitch value */
  int    pmax,			/* maximum pitch value */
  float *pitch,			/* estimated pitch period in samples */
  COMP   Sw[],                  /* Freq domain version of Sn[] */
  COMP   W[],                   /* Freq domain window */
  float *prev_Wo
)
{
    NLP   *nlp;
    float  notch;		    /* current notch filter output    */
    COMP   fw[PE_FFT_SIZE];	    /* DFT of squared signal (input)  */
    COMP   Fw[PE_FFT_SIZE];	    /* DFT of squared signal (output) */
    float  gmax;
    int    gmax_bin;
    int    m, i,j;
    float  best_f0;
    TIMER_VAR(start, tnotch, filter, peakpick, window, fft, magsq, shiftmem);
    
    assert(nlp_state != NULL);
    nlp = (NLP*)nlp_state;
    m = nlp->m;

    TIMER_SAMPLE(start);

    /* Square, notch filter at DC, and LP filter vector */

    for(i=m-n; i<m; i++) 	    /* square latest speech samples */
	nlp->sq[i] = Sn[i]*Sn[i];

    for(i=m-n; i<m; i++) {	/* notch filter at DC */
	notch = nlp->sq[i] - nlp->mem_x;
	notch += COEFF*nlp->mem_y;
	nlp->mem_x = nlp->sq[i];
	nlp->mem_y = notch;
	nlp->sq[i] = notch + 1.0;  /* With 0 input vectors to codec,
				      kiss_fft() would take a long
				      time to execute when running in
				      real time.  Problem was traced
				      to kiss_fft function call in
				      this function. Adding this small
				      constant fixed problem.  Not
				      exactly sure why. */
    }

    TIMER_SAMPLE_AND_LOG(tnotch, start, "      square and notch");

    for(i=m-n; i<m; i++) {	/* FIR filter vector */

	for(j=0; j<NLP_NTAP-1; j++)
	    nlp->mem_fir[j] = nlp->mem_fir[j+1];
	nlp->mem_fir[NLP_NTAP-1] = nlp->sq[i];

	nlp->sq[i] = 0.0;
	for(j=0; j<NLP_NTAP; j++)
	    nlp->sq[i] += nlp->mem_fir[j]*nlp_fir[j];
    }

    TIMER_SAMPLE_AND_LOG(filter, tnotch, "      filter");
 
    /* Decimate and DFT */

    for(i=0; i<PE_FFT_SIZE; i++) {
	fw[i].real = 0.0;
	fw[i].imag = 0.0;
    }
    for(i=0; i<m/DEC; i++) {
	fw[i].real = nlp->sq[i*DEC]*nlp->w[i];
    }
    TIMER_SAMPLE_AND_LOG(window, filter, "      window");
    #ifdef DUMP
    dump_dec(Fw);
    #endif

    kiss_fft(nlp->fft_cfg, (kiss_fft_cpx *)fw, (kiss_fft_cpx *)Fw);
    TIMER_SAMPLE_AND_LOG(fft, window, "      fft");

    for(i=0; i<PE_FFT_SIZE; i++)
	Fw[i].real = Fw[i].real*Fw[i].real + Fw[i].imag*Fw[i].imag;

    TIMER_SAMPLE_AND_LOG(magsq, fft, "      mag sq");
    #ifdef DUMP
    dump_sq(nlp->sq);
    dump_Fw(Fw);
    #endif

    /* find global peak */

    gmax = 0.0;
    gmax_bin = PE_FFT_SIZE*DEC/pmax;
    for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) {
	if (Fw[i].real > gmax) {
	    gmax = Fw[i].real;
	    gmax_bin = i;
	}
    }
    
    TIMER_SAMPLE_AND_LOG(peakpick, magsq, "      peak pick");

    //#define POST_PROCESS_MBE
    #ifdef POST_PROCESS_MBE
    best_f0 = post_process_mbe(Fw, pmin, pmax, gmax, Sw, W, prev_Wo);
    #else
    best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_Wo);
    #endif

    TIMER_SAMPLE_AND_LOG(shiftmem, peakpick,  "      post process");

    /* Shift samples in buffer to make room for new samples */

    for(i=0; i<m-n; i++)
	nlp->sq[i] = nlp->sq[i+n];

    /* return pitch and F0 estimate */

    *pitch = (float)SAMPLE_RATE/best_f0;

    TIMER_SAMPLE_AND_LOG2(shiftmem,  "      shift mem");

    TIMER_SAMPLE_AND_LOG2(start,  "      nlp int");

    return(best_f0);  
}
int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut)
{
    PDEBUG("OfdmGenerator::process(dataIn: %p, dataOut: %p)\n",
            dataIn, dataOut);

    dataOut->setLength(myNbSymbols * mySpacing * sizeof(complexf));

    FFT_TYPE* in = reinterpret_cast<FFT_TYPE*>(dataIn->getData());
    FFT_TYPE* out = reinterpret_cast<FFT_TYPE*>(dataOut->getData());

    size_t sizeIn = dataIn->getLength() / sizeof(complexf);
    size_t sizeOut = dataOut->getLength() / sizeof(complexf);

    if (sizeIn != myNbSymbols * myNbCarriers) {
        PDEBUG("Nb symbols: %zu\n", myNbSymbols);
        PDEBUG("Nb carriers: %zu\n", myNbCarriers);
        PDEBUG("Spacing: %zu\n", mySpacing);
        PDEBUG("\n%zu != %zu\n", sizeIn, myNbSymbols * myNbCarriers);
        throw std::runtime_error(
                "OfdmGenerator::process input size not valid!");
    }
    if (sizeOut != myNbSymbols * mySpacing) {
        PDEBUG("Nb symbols: %zu\n", myNbSymbols);
        PDEBUG("Nb carriers: %zu\n", myNbCarriers);
        PDEBUG("Spacing: %zu\n", mySpacing);
        PDEBUG("\n%zu != %zu\n", sizeIn, myNbSymbols * mySpacing);
        throw std::runtime_error(
                "OfdmGenerator::process output size not valid!");
    }

#if USE_FFTW
    // No SIMD/no-SIMD distinction, it's too early to optimize anything
    for (size_t i = 0; i < myNbSymbols; ++i) {
        myFftIn[0][0] = 0;
        myFftIn[0][1] = 0;

        bzero(&myFftIn[myZeroDst], myZeroSize * sizeof(FFT_TYPE));
        memcpy(&myFftIn[myPosDst], &in[myPosSrc],
                myPosSize * sizeof(FFT_TYPE));
        memcpy(&myFftIn[myNegDst], &in[myNegSrc],
                myNegSize * sizeof(FFT_TYPE));

        fftwf_execute(myFftPlan);

        memcpy(out, myFftOut, mySpacing * sizeof(FFT_TYPE));

        in += myNbCarriers;
        out += mySpacing;
    }
#else
#  ifdef USE_SIMD
    for (size_t i = 0, j = 0; i < sizeIn; ) {
        // Pack 4 fft operations
        typedef struct {
            float r[4];
            float i[4];
        } fft_data;
        assert(sizeof(FFT_TYPE) == sizeof(fft_data));
        complexf *cplxIn = (complexf*)in;
        complexf *cplxOut = (complexf*)out;
        fft_data *dataBuffer = (fft_data*)myFftBuffer;

        FFT_REAL(myFftBuffer[0]) = _mm_setzero_ps();
        FFT_IMAG(myFftBuffer[0]) = _mm_setzero_ps();
        for (size_t k = 0; k < myZeroSize; ++k) {
            FFT_REAL(myFftBuffer[myZeroDst + k]) = _mm_setzero_ps();
            FFT_IMAG(myFftBuffer[myZeroDst + k]) = _mm_setzero_ps();
        }
        for (int k = 0; k < 4; ++k) {
            if (i < sizeIn) {
                for (size_t l = 0; l < myPosSize; ++l) {
                    dataBuffer[myPosDst + l].r[k] = cplxIn[i + myPosSrc + l].real();
                    dataBuffer[myPosDst + l].i[k] = cplxIn[i + myPosSrc + l].imag();
                }
                for (size_t l = 0; l < myNegSize; ++l) {
                    dataBuffer[myNegDst + l].r[k] = cplxIn[i + myNegSrc + l].real();
                    dataBuffer[myNegDst + l].i[k] = cplxIn[i + myNegSrc + l].imag();
                }
                i += myNbCarriers;
            }
            else {
                for (size_t l = 0; l < myNbCarriers; ++l) {
                    dataBuffer[l].r[k] = 0.0f;
                    dataBuffer[l].i[k] = 0.0f;
                }
            }
        }

        kiss_fft(myFftPlan, myFftBuffer, myFftBuffer);

        for (int k = 0; k < 4; ++k) {
            if (j < sizeOut) {
                for (size_t l = 0; l < mySpacing; ++l) {
                    cplxOut[j + l] = complexf(dataBuffer[l].r[k], dataBuffer[l].i[k]);
                }
                j += mySpacing;
            }
        }
    }
#  else
    for (size_t i = 0; i < myNbSymbols; ++i) {
        FFT_REAL(myFftBuffer[0]) = 0;
        FFT_IMAG(myFftBuffer[0]) = 0;
        bzero(&myFftBuffer[myZeroDst], myZeroSize * sizeof(FFT_TYPE));
        memcpy(&myFftBuffer[myPosDst], &in[myPosSrc],
                myPosSize * sizeof(FFT_TYPE));
        memcpy(&myFftBuffer[myNegDst], &in[myNegSrc],
                myNegSize * sizeof(FFT_TYPE));

        kiss_fft(myFftPlan, myFftBuffer, out);

        in += myNbCarriers;
        out += mySpacing;

    }
#  endif
#endif

    return sizeOut;
}
void fft_1d_only(FFT_DATA *data, int nsize, int flag, struct fft_plan_3d *plan)
{
  int i,total,length,offset,num;
  FFT_SCALAR norm, *data_ptr;

  // system specific constants

#ifdef FFT_SCSL
  int isys = 0;
  FFT_PREC scalef = 1.0;
#endif
#ifdef FFT_DEC
  char c = 'C';
  char f = 'F';
  char b = 'B';
  int one = 1;
#endif
#ifdef FFT_T3E
  int isys = 0;
  double scalef = 1.0;
#endif

  // total = size of data needed in each dim
  // length = length of 1d FFT in each dim
  // total/length = # of 1d FFTs in each dim
  // if total > nsize, limit # of 1d FFTs to available size of data

  int total1 = plan->total1;
  int length1 = plan->length1;
  int total2 = plan->total2;
  int length2 = plan->length2;
  int total3 = plan->total3;
  int length3 = plan->length3;

// fftw3 and Dfti in MKL encode the number of transforms
// into the plan, so we cannot operate on a smaller data set.
#if defined(FFT_MKL) || defined(FFT_FFTW3)
  if ((total1 > nsize) || (total2 > nsize) || (total3 > nsize))
    return;
#endif
  if (total1 > nsize) total1 = (nsize/length1) * length1;
  if (total2 > nsize) total2 = (nsize/length2) * length2;
  if (total3 > nsize) total3 = (nsize/length3) * length3;

  // perform 1d FFTs in each of 3 dimensions
  // data is just an array of 0.0

#ifdef FFT_SGI
  for (offset = 0; offset < total1; offset += length1)
    FFT_1D(flag,length1,&data[offset],1,plan->coeff1);
  for (offset = 0; offset < total2; offset += length2)
    FFT_1D(flag,length2,&data[offset],1,plan->coeff2);
  for (offset = 0; offset < total3; offset += length3)
    FFT_1D(flag,length3,&data[offset],1,plan->coeff3);
#elif defined(FFT_SCSL)
  for (offset = 0; offset < total1; offset += length1)
    FFT_1D(flag,length1,scalef,&data[offset],&data[offset],plan->coeff1,
           plan->work1,&isys);
  for (offset = 0; offset < total2; offset += length2)
    FFT_1D(flag,length2,scalef,&data[offset],&data[offset],plan->coeff2,
           plan->work2,&isys);
  for (offset = 0; offset < total3; offset += length3)
    FFT_1D(flag,length3,scalef,&data[offset],&data[offset],plan->coeff3,
           plan->work3,&isys);
#elif defined(FFT_ACML)
  int info=0;
  num=total1/length1;
  FFT_1D(&flag,&num,&length1,data,plan->coeff1,&info);
  num=total2/length2;
  FFT_1D(&flag,&num,&length2,data,plan->coeff2,&info);
  num=total3/length3;
  FFT_1D(&flag,&num,&length3,data,plan->coeff3,&info);
#elif defined(FFT_INTEL)
  for (offset = 0; offset < total1; offset += length1)
    FFT_1D(&data[offset],&length1,&flag,plan->coeff1);
  for (offset = 0; offset < total2; offset += length2)
    FFT_1D(&data[offset],&length2,&flag,plan->coeff2);
  for (offset = 0; offset < total3; offset += length3)
    FFT_1D(&data[offset],&length3,&flag,plan->coeff3);
#elif defined(FFT_MKL)
  if (flag == -1) {
    DftiComputeForward(plan->handle_fast,data);
    DftiComputeForward(plan->handle_mid,data);
    DftiComputeForward(plan->handle_slow,data);
  } else {
    DftiComputeBackward(plan->handle_fast,data);
    DftiComputeBackward(plan->handle_mid,data);
    DftiComputeBackward(plan->handle_slow,data);
  }
#elif defined(FFT_DEC)
  if (flag == -1) {
    for (offset = 0; offset < total1; offset += length1)
      FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length1,&one);
    for (offset = 0; offset < total2; offset += length2)
      FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length2,&one);
    for (offset = 0; offset < total3; offset += length3)
      FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length3,&one);
  } else {
    for (offset = 0; offset < total1; offset += length1)
      FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length1,&one);
    for (offset = 0; offset < total2; offset += length2)
      FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length2,&one);
    for (offset = 0; offset < total3; offset += length3)
      FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length3,&one);
  }
#elif defined(FFT_T3E)
  for (offset = 0; offset < total1; offset += length1)
    FFT_1D(&flag,&length1,&scalef,&data[offset],&data[offset],plan->coeff1,
           plan->work1,&isys);
  for (offset = 0; offset < total2; offset += length2)
    FFT_1D(&flag,&length2,&scalef,&data[offset],&data[offset],plan->coeff2,
           plan->work2,&isys);
  for (offset = 0; offset < total3; offset += length3)
    FFT_1D(&flag,&length3,&scalef,&data[offset],&data[offset],plan->coeff3,
           plan->work3,&isys);
#elif defined(FFT_FFTW2)
  if (flag == -1) {
    fftw(plan->plan_fast_forward,total1/length1,data,1,0,NULL,0,0);
    fftw(plan->plan_mid_forward,total2/length2,data,1,0,NULL,0,0);
    fftw(plan->plan_slow_forward,total3/length3,data,1,0,NULL,0,0);
  } else {
    fftw(plan->plan_fast_backward,total1/length1,data,1,0,NULL,0,0);
    fftw(plan->plan_mid_backward,total2/length2,data,1,0,NULL,0,0);
    fftw(plan->plan_slow_backward,total3/length3,data,1,0,NULL,0,0);
  }
#elif defined(FFT_FFTW3)
  FFTW_API(plan) theplan;
  if (flag == -1)
    theplan=plan->plan_fast_forward;
  else
    theplan=plan->plan_fast_backward;
  FFTW_API(execute_dft)(theplan,data,data);
  if (flag == -1)
    theplan=plan->plan_mid_forward;
  else
    theplan=plan->plan_mid_backward;
  FFTW_API(execute_dft)(theplan,data,data);
  if (flag == -1)
    theplan=plan->plan_slow_forward;
  else
    theplan=plan->plan_slow_backward;
  FFTW_API(execute_dft)(theplan,data,data);
#else
  if (flag == -1) {
    for (offset = 0; offset < total1; offset += length1)
      kiss_fft(plan->cfg_fast_forward,&data[offset],&data[offset]);
    for (offset = 0; offset < total2; offset += length2)
      kiss_fft(plan->cfg_mid_forward,&data[offset],&data[offset]);
    for (offset = 0; offset < total3; offset += length3)
      kiss_fft(plan->cfg_slow_forward,&data[offset],&data[offset]);
  } else {
    for (offset = 0; offset < total1; offset += length1)
      kiss_fft(plan->cfg_fast_backward,&data[offset],&data[offset]);
    for (offset = 0; offset < total2; offset += length2)
      kiss_fft(plan->cfg_mid_backward,&data[offset],&data[offset]);
    for (offset = 0; offset < total3; offset += length3)
      kiss_fft(plan->cfg_slow_backward,&data[offset],&data[offset]);
  }
#endif

  // scaling if required
  // limit num to size of data

#ifndef FFT_T3E
  if (flag == 1 && plan->scaled) {
    norm = plan->norm;
    num = MIN(plan->normnum,nsize);
    data_ptr = (FFT_SCALAR *)data;
    for (i = 0; i < num; i++) {
#if defined(FFT_FFTW3)
      *(data_ptr++) *= norm;
      *(data_ptr++) *= norm;
#elif defined(FFT_MKL)
      data[i] *= norm;
#else
      data[i].re *= norm;
      data[i].im *= norm;
#endif
    }
  }
#endif

#ifdef FFT_T3E
  if (flag == 1 && plan->scaled) {
    norm = plan->norm;
    num = MIN(plan->normnum,nsize);
    for (i = 0; i < num; i++) data[i] *= (norm,norm);
  }
#endif
}
Exemple #26
0
int main(int argc, char *argv[])
{
    //************************************************************
    // Initialisation
    //************************************************************
	std::cout << "INIT" << std::endl;
	srand((int)time(NULL));

    if (argc < 3)
    {
        std::cerr << "not enough parameters" << std::endl << "usage : ./NeuralNetwork sample_sound.wav sound_to_process.wav  [output_sound.wav]" << std::endl;
        return EXIT_FAILURE;
    }

    // Charge les fichiers audio
	WAV _inputWav, _sampleWav;
	
    if (_inputWav.Read(argv[2]) || _sampleWav.Read(argv[1]))
	{
        std::cerr << "unable to read file" << std::endl;
		return EXIT_FAILURE;
	}

    if (_inputWav.getChannels() != 1 || _sampleWav.getChannels() != 1)
    {
        std::cerr << "stereo sounds are not supported" << std::endl;
        return EXIT_FAILURE;
    }

    if (_inputWav.getBit() != 16 || _sampleWav.getBit() != 16)
    {
        std::cerr << "sounds must be 16 bits" << std::endl;
        return EXIT_FAILURE;
    }

    if (_inputWav.getSampleCount() < BUFFER_SIZE || _sampleWav.getSampleCount() < BUFFER_SIZE)
    {
        std::cerr << "sounds are too smalls" << std::endl;
        return EXIT_FAILURE;
    }



    // init buffers
    std::vector<kiss_fft_cpx> _fftIn(BUFFER_SIZE);
    for (int i = 0; i < BUFFER_SIZE; i++)
    {
        _fftIn[i].r = ((short*) _sampleWav.getData())[i] / 32767.f;
        _fftIn[i].i = 0.f;
    }

    // lance FFT
    kiss_fft_cfg _fftCfg = kiss_fft_alloc(BUFFER_SIZE, 0, 0, 0);
    std::vector<kiss_fft_cpx> _fftOut(BUFFER_SIZE);
    kiss_fft(_fftCfg, _fftIn.data(), _fftOut.data());
    normalizeFFT(_fftOut);

    // Reseaux de neruones
    std::vector<NeuralNetwork*> _pool (POOL_SIZE);
    for (unsigned int i = 0; i < _pool.size(); i++)
    {
        NeuralNetwork* _network = new NeuralNetwork();
        _pool[i] = _network;
    }


    Generator _generator;
    std::vector<float> _generatorParam(GENERATOR_COUNT, 0.f);
    std::vector<kiss_fft_cpx> _outGenerator(BUFFER_SIZE);
    std::vector<kiss_fft_cpx> _fftGenerator(BUFFER_SIZE);


    //************************************************************
    // Algorithme génétique pour trouver un bon réseau de neurone 
    //************************************************************
    for (int _generation = 0; _generation < GENERATION_COUNT; _generation++)
	{
        std::cout << "generation : " << _generation << std::endl;

        for (unsigned int i = 0; i < _pool.size(); i++)
        {
            // test avec le reseau de neurone
            _pool[i]->run(_fftOut, _generatorParam);

            // genere le son
            _generator.run(_generatorParam, _outGenerator, (float) _sampleWav.getSampleRate());

            // FFT du signal généré
            kiss_fft(_fftCfg, _outGenerator.data(), _fftGenerator.data());
            normalizeFFT(_fftGenerator);

            // calcul la distance entre les deux FFTs
            float _distance = 0.f;
            for (unsigned int j = 0; j < BUFFER_SIZE/2; j++)
            {
                _distance += fabs(_fftGenerator[j].r - _fftOut[j].r);
            }

            // plus le score est petit, mieux c'est
            _pool[i]->mScore = _distance;
        }

        // Trie la pool dans l'ordre croissant de score
        std::sort(_pool.begin(), _pool.end(), &NeuralNetwork::sortFct);

        std::cout << "best network : " << _pool[0]->mScore << std::endl;

        // croisement genetique entre les meilleurs réseaux de neurones
        int _selection = (int)_pool.size() / 3;
        for (int i = 0; i < _selection; i++)
        {
            NeuralNetwork* _nn = new NeuralNetwork(_pool[i], _pool[random(0, _selection)]);

            // detruit les reseaux les plus mauvais et les remplace par des enfants
            delete _pool[_pool.size() - 1 - i];
            _pool[_pool.size() - 1 - i] = _nn;
        }
	}


    //************************************************************
    // Ecriture du son final
    //************************************************************

    // test avec le meilleur reseau de neurone
    std::sort(_pool.begin(), _pool.end(), &NeuralNetwork::sortFct);

    // genere le son
    std::vector<short> _outputData(_inputWav.getSampleCount());
    std::vector<float> _previousGeneratorParam(GENERATOR_COUNT, 0.f);

    // le son est traité par morceau
    for (unsigned int i = 0; i < _inputWav.getSampleCount() - BUFFER_SIZE; i += BUFFER_SIZE)
    {
        for (unsigned int j = 0; j < BUFFER_SIZE; j++)
        {
            _fftIn[j].r = ((short*) _inputWav.getData())[i + j] / 32767.f;
            _fftIn[j].i = 0.f;
        }

        // fft
        kiss_fft(_fftCfg, _fftIn.data(), _fftOut.data());
        normalizeFFT(_fftOut);

        // réseau de neurone
        _pool[0]->run(_fftOut, _generatorParam);

        // générateurs
        _generator.run(_previousGeneratorParam, _generatorParam, _outGenerator, (float) _inputWav.getSampleRate(), i);
        _previousGeneratorParam = _generatorParam;

        // convertit en entier 16 bits
        for (unsigned int j = 0; j < BUFFER_SIZE; j++)
        {
            _outputData[i + j] = (short) (32767.f * _outGenerator[j].r);
        }
    }

    // écrit le son en sortie
    _inputWav.setSampleCount(_outputData.size());
    _inputWav.setData(_outputData.data(), _outputData.size() * sizeof(short));
    std::string _outFile = "out.wav";
    if (argc >= 4)
    {
        _outFile = argv[3];
    }
    std::cout << "write " << _outFile << std::endl;
    _inputWav.Write(_outFile.c_str());

	return EXIT_SUCCESS;
}
Exemple #27
0
void aks_to_M2(
  kiss_fft_cfg  fft_fwd_cfg,
  float         ak[],	     /* LPC's */
  int           order,
  MODEL        *model,	     /* sinusoidal model parameters for this frame */
  float         E,	     /* energy term */
  float        *snr,	     /* signal to noise ratio for this frame in dB */
  int           dump,        /* true to dump sample to dump file */
  int           sim_pf,      /* true to simulate a post filter */
  int           pf,          /* true to LPC post filter */
  int           bass_boost,  /* enable LPC filter 0-1khz 3dB boost */
  float         beta,
  float         gamma        /* LPC post filter parameters */
)
{
  COMP pw[FFT_ENC];	/* input to FFT for power spectrum */
  COMP Pw[FFT_ENC];	/* output power spectrum */
  int i,m;		/* loop variables */
  int am,bm;		/* limits of current band */
  float r;		/* no. rads/bin */
  float Em;		/* energy in band */
  float Am;		/* spectral amplitude sample */
  float signal, noise;
  TIMER_VAR(tstart, tfft, tpw, tpf);

  TIMER_SAMPLE(tstart);

  r = TWO_PI/(FFT_ENC);

  /* Determine DFT of A(exp(jw)) --------------------------------------------*/

  for(i=0; i<FFT_ENC; i++) {
    pw[i].real = 0.0;
    pw[i].imag = 0.0;
  }

  for(i=0; i<=order; i++)
    pw[i].real = ak[i];
  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)pw, (kiss_fft_cpx *)Pw);

  TIMER_SAMPLE_AND_LOG(tfft, tstart, "      fft");

  /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/

  for(i=0; i<FFT_ENC/2; i++)
    Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag);

  TIMER_SAMPLE_AND_LOG(tpw, tfft, "      Pw");

  if (pf)
      lpc_post_filter(fft_fwd_cfg, model, Pw, ak, order, dump, beta, gamma, bass_boost);

  TIMER_SAMPLE_AND_LOG(tpf, tpw, "      LPC post filter");

  #ifdef DUMP
  if (dump)
      dump_Pw(Pw);
  #endif

  /* Determine magnitudes from P(w) ----------------------------------------*/

  /* when used just by decoder {A} might be all zeroes so init signal
     and noise to prevent log(0) errors */

  signal = 1E-30; noise = 1E-32;

  for(m=1; m<=model->L; m++) {
      am = (int)((m - 0.5)*model->Wo/r + 0.5);
      bm = (int)((m + 0.5)*model->Wo/r + 0.5);
      Em = 0.0;

      for(i=am; i<bm; i++)
          Em += Pw[i].real;
      Am = sqrtf(Em);

      signal += model->A[m]*model->A[m];
      noise  += (model->A[m] - Am)*(model->A[m] - Am);

      /* This code significantly improves perf of LPC model, in
         particular when combined with phase0.  The LPC spectrum tends
         to track just under the peaks of the spectral envelope, and
         just above nulls.  This algorithm does the reverse to
         compensate - raising the amplitudes of spectral peaks, while
         attenuating the null.  This enhances the formants, and
         supresses the energy between formants. */

      if (sim_pf) {
          if (Am > model->A[m])
              Am *= 0.7;
          if (Am < model->A[m])
              Am *= 1.4;
      }

      model->A[m] = Am;
  }
  *snr = 10.0*log10f(signal/noise);

  TIMER_SAMPLE_AND_LOG2(tpf, "      rec");
}
Exemple #28
0
void synthesise(
  kiss_fft_cfg fft_inv_cfg, 
  float  Sn_[],		/* time domain synthesised signal              */
  MODEL *model,		/* ptr to model parameters for this frame      */
  float  Pn[],		/* time domain Parzen window                   */
  int    shift          /* flag used to handle transition frames       */
)
{
    int   i,l,j,b;	/* loop variables */
    COMP  Sw_[FFT_DEC];	/* DFT of synthesised signal */
    COMP  sw_[FFT_DEC];	/* synthesised signal */

    if (shift) {
	/* Update memories */

	for(i=0; i<N-1; i++) {
	    Sn_[i] = Sn_[i+N];
	}
	Sn_[N-1] = 0.0;
    }

    for(i=0; i<FFT_DEC; i++) {
	Sw_[i].real = 0.0;
	Sw_[i].imag = 0.0;
    }

    /*
      Nov 2010 - found that synthesis using time domain cos() functions
      gives better results for synthesis frames greater than 10ms.  Inverse
      FFT synthesis using a 512 pt FFT works well for 10ms window.  I think
      (but am not sure) that the problem is related to the quantisation of
      the harmonic frequencies to the FFT bin size, e.g. there is a 
      8000/512 Hz step between FFT bins.  For some reason this makes
      the speech from longer frame > 10ms sound poor.  The effect can also
      be seen when synthesising test signals like single sine waves, some
      sort of amplitude modulation at the frame rate.

      Another possibility is using a larger FFT size (1024 or 2048).
    */

#define FFT_SYNTHESIS
#ifdef FFT_SYNTHESIS
    /* Now set up frequency domain synthesised speech */
    for(l=1; l<=model->L; l++) {
    //for(l=model->L/2; l<=model->L; l++) {
    //for(l=1; l<=model->L/4; l++) {
	b = floor(l*model->Wo*FFT_DEC/TWO_PI + 0.5);
	if (b > ((FFT_DEC/2)-1)) {
		b = (FFT_DEC/2)-1;
	}
	Sw_[b].real = model->A[l]*cos(model->phi[l]);
	Sw_[b].imag = model->A[l]*sin(model->phi[l]);
	Sw_[FFT_DEC-b].real = Sw_[b].real;
	Sw_[FFT_DEC-b].imag = -Sw_[b].imag;
    }

    /* Perform inverse DFT */

    kiss_fft(fft_inv_cfg, (kiss_fft_cpx *)Sw_, (kiss_fft_cpx *)sw_);
#else
    /*
       Direct time domain synthesis using the cos() function.  Works
       well at 10ms and 20ms frames rates.  Note synthesis window is
       still used to handle overlap-add between adjacent frames.  This
       could be simplified as we don't need to synthesise where Pn[]
       is zero.
    */
    for(l=1; l<=model->L; l++) {
	for(i=0,j=-N+1; i<N-1; i++,j++) {
	    Sw_[FFT_DEC-N+1+i].real += 2.0*model->A[l]*cos(j*model->Wo*l + model->phi[l]);
	}
 	for(i=N-1,j=0; i<2*N; i++,j++)
	    Sw_[j].real += 2.0*model->A[l]*cos(j*model->Wo*l + model->phi[l]);
    }	
#endif

    /* Overlap add to previous samples */

    for(i=0; i<N-1; i++) {
	Sn_[i] += sw_[FFT_DEC-N+1+i].real*Pn[i];
    }

    if (shift)
	for(i=N-1,j=0; i<2*N; i++,j++)
	    Sn_[i] = sw_[j].real*Pn[i];
    else
	for(i=N-1,j=0; i<2*N; i++,j++)
	    Sn_[i] += sw_[j].real*Pn[i];
}
Exemple #29
0
int main(int argc, char *argv[])
{
    FILE *fout = NULL;	/* output speech file                    */
    FILE *fin;		/* input speech file                     */
    short buf[N];	/* input/output buffer                   */
    float buf_float[N];
    float Sn[M];	/* float input speech samples            */
    float Sn_pre[N];	/* pre-emphasised input speech samples   */
    COMP  Sw[FFT_ENC];	/* DFT of Sn[]                           */
    kiss_fft_cfg  fft_fwd_cfg;
    kiss_fft_cfg  fft_inv_cfg;
    float w[M];	        /* time domain hamming window            */
    COMP  W[FFT_ENC];	/* DFT of w[]                            */
    MODEL model;
    float Pn[2*N];	/* trapezoidal synthesis window          */
    float Sn_[2*N];	/* synthesised speech */
    int   i,m;		/* loop variable                         */
    int   frames;
    float prev_Wo, prev__Wo, prev_uq_Wo;
    float pitch;
    char  out_file[MAX_STR];
    char  ampexp_arg[MAX_STR];
    char  phaseexp_arg[MAX_STR];
    float snr;
    float sum_snr;
    int orderi;
    int lpc_model = 0, order = LPC_ORD;
    int lsp = 0, lspd = 0, lspvq = 0;
    int lspres = 0;
    int lspjvm = 0, lspjnd = 0, lspmel = 0;
    #ifdef __EXPERIMENTAL__
    int lspanssi = 0, 
    #endif
    int prede = 0;
    float pre_mem = 0.0, de_mem = 0.0;
    float ak[order];
    COMP  Sw_[FFT_ENC];
    COMP  Ew[FFT_ENC]; 
 
    int phase0 = 0;
    float ex_phase[MAX_AMP+1];

    int   postfilt;

    int   hand_voicing = 0, phaseexp = 0, ampexp = 0, hi = 0, simlpcpf = 0;
    int   lpcpf = 0;
    FILE *fvoicing = 0;

    MODEL prev_model;
    int dec;
    int decimate = 1;
    float lsps[order];
    float e, prev_e;
    int   lsp_indexes[order];
    float lsps_[order];
    float Woe_[2];

    float lsps_dec[4][LPC_ORD], e_dec[4], weight, weight_inc, ak_dec[4][LPC_ORD];
    MODEL model_dec[4], prev_model_dec;
    float prev_lsps_dec[order], prev_e_dec;

    void *nlp_states;
    float hpf_states[2];
    int   scalar_quant_Wo_e = 0;
    int   vector_quant_Wo_e = 0;
    int   dump_pitch_e = 0;
    FILE *fjvm = NULL;
    #ifdef DUMP
    int   dump;
    #endif
    struct PEXP *pexp = NULL;
    struct AEXP *aexp = NULL;
    float gain = 1.0;
    int   bpf_en = 0;
    float bpf_buf[BPF_N+N];

    char* opt_string = "ho:";
    struct option long_options[] = {
        { "lpc", required_argument, &lpc_model, 1 },
        { "lspjnd", no_argument, &lspjnd, 1 },
        { "lspmel", no_argument, &lspmel, 1 },
        { "lsp", no_argument, &lsp, 1 },
        { "lspd", no_argument, &lspd, 1 },
        { "lspvq", no_argument, &lspvq, 1 },
        { "lspres", no_argument, &lspres, 1 },
        { "lspjvm", no_argument, &lspjvm, 1 },
        #ifdef __EXPERIMENTAL__
        { "lspanssi", no_argument, &lspanssi, 1 },
        #endif
        { "phase0", no_argument, &phase0, 1 },
        { "phaseexp", required_argument, &phaseexp, 1 },
        { "ampexp", required_argument, &ampexp, 1 },
        { "postfilter", no_argument, &postfilt, 1 },
        { "hand_voicing", required_argument, &hand_voicing, 1 },
        { "dec", required_argument, &dec, 1 },
        { "hi", no_argument, &hi, 1 },
        { "simlpcpf", no_argument, &simlpcpf, 1 },
        { "lpcpf", no_argument, &lpcpf, 1 },
        { "prede", no_argument, &prede, 1 },
        { "dump_pitch_e", required_argument, &dump_pitch_e, 1 },
        { "sq_pitch_e", no_argument, &scalar_quant_Wo_e, 1 },
        { "vq_pitch_e", no_argument, &vector_quant_Wo_e, 1 },
        { "rate", required_argument, NULL, 0 },
        { "gain", required_argument, NULL, 0 },
        { "bpf", no_argument, &bpf_en, 1 },
        #ifdef DUMP
        { "dump", required_argument, &dump, 1 },
        #endif
        { "help", no_argument, NULL, 'h' },
        { NULL, no_argument, NULL, 0 }
    };
    int num_opts=sizeof(long_options)/sizeof(struct option);
    COMP Aw[FFT_ENC];

    for(i=0; i<M; i++) {
	Sn[i] = 1.0;
	Sn_pre[i] = 1.0;
    }
    for(i=0; i<2*N; i++)
	Sn_[i] = 0;

    prev_uq_Wo = prev_Wo = prev__Wo = TWO_PI/P_MAX;

    prev_model.Wo = TWO_PI/P_MIN;
    prev_model.L = floor(PI/prev_model.Wo);
    for(i=1; i<=prev_model.L; i++) {
	prev_model.A[i] = 0.0;
	prev_model.phi[i] = 0.0;
    }
    for(i=1; i<=MAX_AMP; i++) {
	//ex_phase[i] = (PI/3)*(float)rand()/RAND_MAX;
	ex_phase[i] = 0.0;
    }
    e = prev_e = 1;
    hpf_states[0] = hpf_states[1] = 0.0;

    nlp_states = nlp_create(M);

    if (argc < 2) {
        print_help(long_options, num_opts, argv);
    }

    /*----------------------------------------------------------------*\

                     Interpret Command Line Arguments

    \*----------------------------------------------------------------*/

    while(1) {
        int option_index = 0;
        int opt = getopt_long(argc, argv, opt_string, 
                    long_options, &option_index);
        if (opt == -1)
            break;
        switch (opt) {
         case 0:
            if(strcmp(long_options[option_index].name, "lpc") == 0) {
                orderi = atoi(optarg);
                if((orderi < 4) || (orderi > order)) {
                    fprintf(stderr, "Error in LPC order (4 to %d): %s\n", order, optarg);
                    exit(1);
                }
                order = orderi;
            #ifdef DUMP
            } else if(strcmp(long_options[option_index].name, "dump") == 0) {
                if (dump) 
	            dump_on(optarg);
            #endif
            } else if(strcmp(long_options[option_index].name, "lsp") == 0
                  || strcmp(long_options[option_index].name, "lspd") == 0
                  || strcmp(long_options[option_index].name, "lspvq") == 0) {
	        assert(order == LPC_ORD);
            } else if(strcmp(long_options[option_index].name, "dec") == 0) {
               
                decimate = atoi(optarg);
	        if ((decimate != 2) && (decimate != 4)) {
	            fprintf(stderr, "Error in --dec, must be 2 or 4\n");
	            exit(1);
	        }

                if (!phase0) {
                    printf("needs --phase0 to resample phase when using --dec\n");
                    exit(1);
                }
                if (!lpc_model) {
                    printf("needs --lpc [order] to resample amplitudes when using --dec\n");
                    exit(1);
                }
 
            } else if(strcmp(long_options[option_index].name, "hand_voicing") == 0) {
	        if ((fvoicing = fopen(optarg,"rt")) == NULL) {
	            fprintf(stderr, "Error opening voicing file: %s: %s.\n",
		        optarg, strerror(errno));
                    exit(1);
                }
	    } else if(strcmp(long_options[option_index].name, "dump_pitch_e") == 0) {
	        if ((fjvm = fopen(optarg,"wt")) == NULL) {
	            fprintf(stderr, "Error opening pitch & energy dump file: %s: %s.\n",
		        optarg, strerror(errno));
                    exit(1);
                }
	    } else if(strcmp(long_options[option_index].name, "phaseexp") == 0) {
		strcpy(phaseexp_arg, optarg);
	    } else if(strcmp(long_options[option_index].name, "ampexp") == 0) {
		strcpy(ampexp_arg, optarg);
	    } else if(strcmp(long_options[option_index].name, "gain") == 0) {
		gain = atof(optarg);
	    } else if(strcmp(long_options[option_index].name, "rate") == 0) {
                if(strcmp(optarg,"3200") == 0) {
	            lpc_model = 1;
		    scalar_quant_Wo_e = 1;
	            lspd = 1;
	            phase0 = 1;
	            postfilt = 1;
	            decimate = 1;
		    lpcpf = 1;
               } else if(strcmp(optarg,"2400") == 0) {
	            lpc_model = 1;
		    vector_quant_Wo_e = 1;
	            lsp = 1;
	            phase0 = 1;
	            postfilt = 1;
	            decimate = 2;
		    lpcpf = 1;
               } else if(strcmp(optarg,"1400") == 0) {
	            lpc_model = 1;
		    vector_quant_Wo_e = 1;
	            lsp = 1;
	            phase0 = 1;
	            postfilt = 1;
	            decimate = 4;
 		    lpcpf = 1;
               } else if(strcmp(optarg,"1300") == 0) {
	            lpc_model = 1;
		    scalar_quant_Wo_e = 1;
	            lsp = 1;
	            phase0 = 1;
	            postfilt = 1;
	            decimate = 4;
 		    lpcpf = 1;
               } else if(strcmp(optarg,"1200") == 0) {
	            lpc_model = 1;
		    scalar_quant_Wo_e = 1;
	            lspjvm = 1;
	            phase0 = 1;
	            postfilt = 1;
	            decimate = 4;
 		    lpcpf = 1;
                } else {
                    fprintf(stderr, "Error: invalid output rate (3200|2400|1400|1200) %s\n", optarg);
                    exit(1);
                }
            }
            break;

         case 'h':
            print_help(long_options, num_opts, argv);
            break;

         case 'o':
	     if (strcmp(optarg, "-") == 0) fout = stdout;
	     else if ((fout = fopen(optarg,"wb")) == NULL) {
	        fprintf(stderr, "Error opening output speech file: %s: %s.\n",
		    optarg, strerror(errno));
	        exit(1);
	     }
	     strcpy(out_file,optarg);
	     break;

         default:
            /* This will never be reached */
            break;
        }
    }

    /* Input file */

    if (strcmp(argv[optind], "-")  == 0) fin = stdin;
    else if ((fin = fopen(argv[optind],"rb")) == NULL) {
	fprintf(stderr, "Error opening input speech file: %s: %s.\n",
		argv[optind], strerror(errno));
	exit(1);
    }

    ex_phase[0] = 0;
    Woe_[0] = Woe_[1] = 1.0;

    /*
      printf("lspd: %d lspdt: %d lspdt_mode: %d  phase0: %d postfilt: %d "
	   "decimate: %d dt: %d\n",lspd,lspdt,lspdt_mode,phase0,postfilt,
	   decimate,dt);
    */

    /* Initialise ------------------------------------------------------------*/

    fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places   */
    fft_inv_cfg = kiss_fft_alloc(FFT_DEC, 1, NULL, NULL); /* inverse FFT, used just for synth */
    make_analysis_window(fft_fwd_cfg, w, W);
    make_synthesis_window(Pn);
    quantise_init();
    if (phaseexp)
	pexp = phase_experiment_create();
    if (ampexp)
	aexp = amp_experiment_create();

    if (bpf_en) {
        for(i=0; i<BPF_N; i++)
            bpf_buf[i] = 0.0;
    }

    for(i=0; i<LPC_ORD; i++) {
        prev_lsps_dec[i] = i*PI/(LPC_ORD+1);
    }
    prev_e_dec = 1;
    for(m=1; m<=MAX_AMP; m++)
	prev_model_dec.A[m] = 0.0;
    prev_model_dec.Wo = TWO_PI/P_MAX;
    prev_model_dec.L = PI/prev_model_dec.Wo;
    prev_model_dec.voiced = 0;

    /*----------------------------------------------------------------* \

                            Main Loop

    \*----------------------------------------------------------------*/

    frames = 0;
    sum_snr = 0;
    while(fread(buf,sizeof(short),N,fin)) {
	frames++;

	for(i=0; i<N; i++)
	    buf_float[i] = buf[i];

	/* optionally filter input speech */
	
        if (prede) {
           pre_emp(Sn_pre, buf_float, &pre_mem, N);
           for(i=0; i<N; i++)
                buf_float[i] = Sn_pre[i];
        }
         
        if (bpf_en) {
            for(i=0; i<BPF_N; i++)
                bpf_buf[i] =  bpf_buf[N+i];
            for(i=0; i<N; i++)
                bpf_buf[BPF_N+i] = buf_float[i];
            inverse_filter(&bpf_buf[BPF_N], bpf, N, buf_float, BPF_N);
       }

        /* shift buffer of input samples, and insert new samples */

	for(i=0; i<M-N; i++) {
	    Sn[i] = Sn[i+N];
	}
	for(i=0; i<N; i++)
	    Sn[i+M-N] = buf_float[i];

	/*------------------------------------------------------------*\

                      Estimate Sinusoidal Model Parameters

	\*------------------------------------------------------------*/

	nlp(nlp_states,Sn,N,P_MIN,P_MAX,&pitch,Sw,W,&prev_uq_Wo);
	model.Wo = TWO_PI/pitch;

	dft_speech(fft_fwd_cfg, Sw, Sn, w);
	two_stage_pitch_refinement(&model, Sw);
	estimate_amplitudes(&model, Sw, W, 1);
 
        #ifdef DUMP 
	dump_Sn(Sn); dump_Sw(Sw); dump_model(&model);
        #endif

	if (ampexp)
	    amp_experiment(aexp, &model, ampexp_arg);

	if (phaseexp) {
            #ifdef DUMP
	    dump_phase(&model.phi[0], model.L);
            #endif
	    phase_experiment(pexp, &model, phaseexp_arg);
            #ifdef DUMP
	    dump_phase_(&model.phi[0], model.L);
            #endif
	}
	
	if (hi) {
	    int m;
	    for(m=1; m<model.L/2; m++)
		model.A[m] = 0.0;
	    for(m=3*model.L/4; m<=model.L; m++)
		model.A[m] = 0.0;
	}

	/*------------------------------------------------------------*\

                            Zero-phase modelling

	\*------------------------------------------------------------*/

	if (phase0) {
	    float Wn[M];		        /* windowed speech samples */
	    float Rk[order+1];                  /* autocorrelation coeffs  */
            COMP a[FFT_ENC];	                

            #ifdef DUMP
	    dump_phase(&model.phi[0], model.L);
            #endif

	    /* find aks here, these are overwritten if LPC modelling is enabled */

            for(i=0; i<M; i++)
                Wn[i] = Sn[i]*w[i];
	    autocorrelate(Wn,Rk,M,order);
	    levinson_durbin(Rk,ak,order);

	    /* determine voicing */

	    snr = est_voicing_mbe(&model, Sw, W, Sw_, Ew);

	    if (dump_pitch_e)
		fprintf(fjvm, "%f %f %d ", model.Wo, snr, model.voiced);

	    //printf("snr %3.2f v: %d Wo: %f prev_Wo: %f\n", snr, model.voiced,
	    //	   model.Wo, prev_uq_Wo);
            #ifdef DUMP
	    dump_Sw_(Sw_);
	    dump_Ew(Ew);
	    dump_snr(snr);
            #endif

	    /* just to make sure we are not cheating - kill all phases */

	    for(i=0; i<=MAX_AMP; i++)
	    	model.phi[i] = 0;
	
            /* Determine DFT of A(exp(jw)), which is needed for phase0 model when
               LPC is not used, e.g. indecimate=1 (10ms) frames with no LPC */

            for(i=0; i<FFT_ENC; i++) {
                a[i].real = 0.0;
                a[i].imag = 0.0; 
            }

            for(i=0; i<=order; i++)
                a[i].real = ak[i];
            kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)a, (kiss_fft_cpx *)Aw);

	    if (hand_voicing) {
		fscanf(fvoicing,"%d\n",&model.voiced);
	    }
	}

	/*------------------------------------------------------------*\

	        LPC model amplitudes and LSP quantisation 

	\*------------------------------------------------------------*/

	if (lpc_model) {
	    
            e = speech_to_uq_lsps(lsps, ak, Sn, w, order);
            for(i=0; i<LPC_ORD; i++)
                lsps_[i] = lsps[i];

            #ifdef DUMP
	    dump_ak(ak, order);
            dump_E(e);
            #endif
	
	    /* tracking down -ve energy values with BW expansion */
	    /*
	    if (e < 0.0) {
		int i;
		FILE*f=fopen("x.txt","wt");
		for(i=0; i<M; i++)
		    fprintf(f,"%f\n", Sn[i]);
		fclose(f);
		printf("e = %f frames = %d\n", e, frames);
		for(i=0; i<order; i++)
		    printf("%f ", ak[i]);
		exit(0);
	    }
	    */

	    if (dump_pitch_e)
		fprintf(fjvm, "%f\n", e);

            #ifdef DUMP
            dump_lsp(lsps);
            #endif

	    /* various LSP quantisation schemes */

	    if (lsp) {
		encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
		decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
		bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
		lsp_to_lpc(lsps_, ak, LPC_ORD);
	    }

	    if (lspd) {
		encode_lspds_scalar(lsp_indexes, lsps, LPC_ORD);
		decode_lspds_scalar(lsps_, lsp_indexes, LPC_ORD);
		lsp_to_lpc(lsps_, ak, LPC_ORD);
	    }

#ifdef __EXPERIMENTAL__
	    if (lspvq) {
		lspvq_quantise(lsps, lsps_, LPC_ORD);
		bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
		lsp_to_lpc(lsps_, ak, LPC_ORD);
	    }
#endif

	    if (lspjvm) {
		/* Jean-Marc's multi-stage, split VQ */
		lspjvm_quantise(lsps, lsps_, LPC_ORD);
		{ 
		    float lsps_bw[LPC_ORD];
		    memcpy(lsps_bw, lsps_, sizeof(float)*LPC_ORD);
		    bw_expand_lsps(lsps_bw, LPC_ORD, 50.0, 100.0);			    
		    lsp_to_lpc(lsps_bw, ak, LPC_ORD);
		}
	    }

#ifdef __EXPERIMENTAL__
	    if (lspanssi) {
		/*  multi-stage VQ from Anssi Ramo OH3GDD */

		lspanssi_quantise(lsps, lsps_, LPC_ORD, 5);
		bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);			    
		lsp_to_lpc(lsps_, ak, LPC_ORD);
	    }
#endif

	    /* experimenting with non-linear LSP spacing to see if
	       it's just noticable */

	    if (lspjnd) {
		for(i=0; i<LPC_ORD; i++)
		    lsps_[i] = lsps[i];
		locate_lsps_jnd_steps(lsps_, LPC_ORD);
		lsp_to_lpc(lsps_, ak, LPC_ORD);
	    }

	    /* Another experiment with non-linear LSP spacing, this
	       time using a scaled version of mel frequency axis
	       warping.  The scaling is such that the integer output
	       can be directly sent over the channel.
	    */

	    if (lspmel) {
		float f, f_;
		float mel[LPC_ORD];
		int   mel_indexes[LPC_ORD];

		for(i=0; i<order; i++) {
		    f = (4000.0/PI)*lsps[i];
		    mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5);
		}

		for(i=1; i<order; i++) {
		    if (mel[i] == mel[i-1])
			mel[i]++;
		}

 		encode_mels_scalar(mel_indexes, mel, 6);
		decode_mels_scalar(mel, mel_indexes, 6);
                
                #ifdef DUMP
                dump_mel(mel, order);
                #endif

		for(i=0; i<LPC_ORD; i++) {
		    f_ = 700.0*( pow(10.0, (float)mel[i]/2595.0) - 1.0);
		    lsps_[i] = f_*(PI/4000.0);
		}
 
		lsp_to_lpc(lsps_, ak, order);
	    }
	
	    if (scalar_quant_Wo_e) {

		e = decode_energy(encode_energy(e, E_BITS), E_BITS);
                model.Wo = decode_Wo(encode_Wo(model.Wo, WO_BITS), WO_BITS);
		model.L  = PI/model.Wo; /* if we quantise Wo re-compute L */
	    }

	    if (vector_quant_Wo_e) {

		/* JVM's experimental joint Wo & LPC energy quantiser */

		quantise_WoE(&model, &e, Woe_);
	    }
            
	}

	/*------------------------------------------------------------*\

          Synthesise and optional decimation to 20 or 40ms frame rate

	\*------------------------------------------------------------*/

        /* 
           if decimate == 2, we interpolate frame n from frame n-1 and n+1
           if decimate == 4, we interpolate frames n, n+1, n+2, from frames n-1 and n+3

           This is meant to give identical results to the implementations of various modes
           in codec2.c
        */

        /* delay line to keep frame by frame voicing decisions */

        for(i=0; i<decimate-1; i++)
            model_dec[i] = model_dec[i+1];
        model_dec[decimate-1] = model;

        if ((frames % decimate) == 0) {
            for(i=0; i<order; i++)
                lsps_dec[decimate-1][i] = lsps_[i];
            e_dec[decimate-1] = e;
            model_dec[decimate-1] = model;

            /* interpolate the model parameters */

            weight_inc = 1.0/decimate;
            for(i=0, weight=weight_inc; i<decimate-1; i++, weight += weight_inc) {
                //model_dec[i].voiced = model_dec[decimate-1].voiced;
                interpolate_lsp_ver2(&lsps_dec[i][0], prev_lsps_dec, &lsps_dec[decimate-1][0], weight, order);
                interp_Wo2(&model_dec[i], &prev_model_dec, &model_dec[decimate-1], weight);
                e_dec[i] = interp_energy2(prev_e_dec, e_dec[decimate-1],weight);
            }

            /* then recover spectral amplitudes and synthesise */    

            for(i=0; i<decimate; i++) {
                if (lpc_model) {
                    lsp_to_lpc(&lsps_dec[i][0], &ak_dec[i][0], order);                
                    aks_to_M2(fft_fwd_cfg, &ak_dec[i][0], order, &model_dec[i], e_dec[i], 
                              &snr, 0, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
                    apply_lpc_correction(&model_dec[i]);
                    #ifdef DUMP
                    dump_lsp_(&lsps_dec[i][0]);
                    dump_ak_(&ak_dec[i][0], order);
                    sum_snr += snr;
                    dump_quantised_model(&model_dec[i]);
                    #endif
                }

                if (phase0)
                    phase_synth_zero_order(fft_fwd_cfg, &model_dec[i], ex_phase, Aw);	
                synth_one_frame(fft_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain);
                if (fout != NULL) fwrite(buf,sizeof(short),N,fout);
            }
                    /*
            for(i=0; i<decimate; i++) {
                    printf("%d Wo: %f L: %d v: %d\n", frames, model_dec[i].Wo, model_dec[i].L, model_dec[i].voiced);
            }
            if (frames == 4*50)
                exit(0);
                    */
            /* update memories for next frame ----------------------------*/

            prev_model_dec = model_dec[decimate-1];
            prev_e_dec = e_dec[decimate-1];
            for(i=0; i<LPC_ORD; i++)
                prev_lsps_dec[i] = lsps_dec[decimate-1][i];        
       }

    }

    /*----------------------------------------------------------------*\

                            End Main Loop

    \*----------------------------------------------------------------*/

    fclose(fin);

    if (fout != NULL)
	fclose(fout);

    if (lpc_model)
    	printf("SNR av = %5.2f dB\n", sum_snr/frames);

    if (phaseexp)
	phase_experiment_destroy(pexp);
    if (ampexp)
	amp_experiment_destroy(aexp);
    #ifdef DUMP
    if (dump)
	dump_off();
    #endif

    if (hand_voicing)
	fclose(fvoicing);

    nlp_destroy(nlp_states);

    return 0;
}
void fft_3d(FFT_DATA *in, FFT_DATA *out, int flag, struct fft_plan_3d *plan)
{
  int i,total,length,offset,num;
  FFT_SCALAR norm, *out_ptr;
  FFT_DATA *data,*copy;

  // system specific constants

#if defined(FFT_SCSL)
  int isys = 0;
  FFT_PREC scalef = 1.0;
#elif defined(FFT_DEC)
  char c = 'C';
  char f = 'F';
  char b = 'B';
  int one = 1;
#elif defined(FFT_T3E)
  int isys = 0;
  double scalef = 1.0;
#elif defined(FFT_ACML)
  int info;
#elif defined(FFT_FFTW3)
  FFTW_API(plan) theplan;
#else
  // nothing to do for other FFTs.
#endif

  // pre-remap to prepare for 1st FFTs if needed
  // copy = loc for remap result

  if (plan->pre_plan) {
    if (plan->pre_target == 0) copy = out;
    else copy = plan->copy;
    remap_3d((FFT_SCALAR *) in, (FFT_SCALAR *) copy, (FFT_SCALAR *) plan->scratch,
             plan->pre_plan);
    data = copy;
  }
  else
    data = in;

  // 1d FFTs along fast axis

  total = plan->total1;
  length = plan->length1;

#if defined(FFT_SGI)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(flag,length,&data[offset],1,plan->coeff1);
#elif defined(FFT_SCSL)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(flag,length,scalef,&data[offset],&data[offset],plan->coeff1,
           plan->work1,&isys);
#elif defined(FFT_ACML)
  num=total/length;
  FFT_1D(&flag,&num,&length,data,plan->coeff1,&info);
#elif defined(FFT_INTEL)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(&data[offset],&length,&flag,plan->coeff1);
#elif defined(FFT_MKL)
  if (flag == -1)
    DftiComputeForward(plan->handle_fast,data);
  else
    DftiComputeBackward(plan->handle_fast,data);
#elif defined(FFT_DEC)
  if (flag == -1)
    for (offset = 0; offset < total; offset += length)
      FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length,&one);
  else
    for (offset = 0; offset < total; offset += length)
      FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length,&one);
#elif defined(FFT_T3E)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(&flag,&length,&scalef,&data[offset],&data[offset],plan->coeff1,
           plan->work1,&isys);
#elif defined(FFT_FFTW2)
  if (flag == -1)
    fftw(plan->plan_fast_forward,total/length,data,1,length,NULL,0,0);
  else
    fftw(plan->plan_fast_backward,total/length,data,1,length,NULL,0,0);
#elif defined(FFT_FFTW3)
  if (flag == -1)
    theplan=plan->plan_fast_forward;
  else
    theplan=plan->plan_fast_backward;
  FFTW_API(execute_dft)(theplan,data,data);
#else
  if (flag == -1)
    for (offset = 0; offset < total; offset += length)
      kiss_fft(plan->cfg_fast_forward,&data[offset],&data[offset]);
  else
    for (offset = 0; offset < total; offset += length)
      kiss_fft(plan->cfg_fast_backward,&data[offset],&data[offset]);
#endif

  // 1st mid-remap to prepare for 2nd FFTs
  // copy = loc for remap result

  if (plan->mid1_target == 0) copy = out;
  else copy = plan->copy;
  remap_3d((FFT_SCALAR *) data, (FFT_SCALAR *) copy, (FFT_SCALAR *) plan->scratch,
           plan->mid1_plan);
  data = copy;

  // 1d FFTs along mid axis

  total = plan->total2;
  length = plan->length2;

#if defined(FFT_SGI)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(flag,length,&data[offset],1,plan->coeff2);
#elif defined(FFT_SCSL)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(flag,length,scalef,&data[offset],&data[offset],plan->coeff2,
           plan->work2,&isys);
#elif defined(FFT_ACML)
  num=total/length;
  FFT_1D(&flag,&num,&length,data,plan->coeff2,&info);
#elif defined(FFT_INTEL)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(&data[offset],&length,&flag,plan->coeff2);
#elif defined(FFT_MKL)
  if (flag == -1)
    DftiComputeForward(plan->handle_mid,data);
  else
    DftiComputeBackward(plan->handle_mid,data);
#elif defined(FFT_DEC)
  if (flag == -1)
    for (offset = 0; offset < total; offset += length)
      FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length,&one);
  else
    for (offset = 0; offset < total; offset += length)
      FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length,&one);
#elif defined(FFT_T3E)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(&flag,&length,&scalef,&data[offset],&data[offset],plan->coeff2,
           plan->work2,&isys);
#elif defined(FFT_FFTW2)
  if (flag == -1)
    fftw(plan->plan_mid_forward,total/length,data,1,length,NULL,0,0);
  else
    fftw(plan->plan_mid_backward,total/length,data,1,length,NULL,0,0);
#elif defined(FFT_FFTW3)
  if (flag == -1)
    theplan=plan->plan_mid_forward;
  else
    theplan=plan->plan_mid_backward;
  FFTW_API(execute_dft)(theplan,data,data);
#else
  if (flag == -1)
    for (offset = 0; offset < total; offset += length)
      kiss_fft(plan->cfg_mid_forward,&data[offset],&data[offset]);
  else
    for (offset = 0; offset < total; offset += length)
      kiss_fft(plan->cfg_mid_backward,&data[offset],&data[offset]);
#endif

  // 2nd mid-remap to prepare for 3rd FFTs
  // copy = loc for remap result

  if (plan->mid2_target == 0) copy = out;
  else copy = plan->copy;
  remap_3d((FFT_SCALAR *) data, (FFT_SCALAR *) copy, (FFT_SCALAR *) plan->scratch,
           plan->mid2_plan);
  data = copy;

  // 1d FFTs along slow axis

  total = plan->total3;
  length = plan->length3;

#if defined(FFT_SGI)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(flag,length,&data[offset],1,plan->coeff3);
#elif defined(FFT_SCSL)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(flag,length,scalef,&data[offset],&data[offset],plan->coeff3,
           plan->work3,&isys);
#elif defined(FFT_ACML)
  num=total/length;
  FFT_1D(&flag,&num,&length,data,plan->coeff3,&info);
#elif defined(FFT_INTEL)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(&data[offset],&length,&flag,plan->coeff3);
#elif defined(FFT_MKL)
  if (flag == -1)
    DftiComputeForward(plan->handle_slow,data);
  else
    DftiComputeBackward(plan->handle_slow,data);
#elif defined(FFT_DEC)
  if (flag == -1)
    for (offset = 0; offset < total; offset += length)
      FFT_1D(&c,&c,&f,&data[offset],&data[offset],&length,&one);
  else
    for (offset = 0; offset < total; offset += length)
      FFT_1D(&c,&c,&b,&data[offset],&data[offset],&length,&one);
#elif defined(FFT_T3E)
  for (offset = 0; offset < total; offset += length)
    FFT_1D(&flag,&length,&scalef,&data[offset],&data[offset],plan->coeff3,
           plan->work3,&isys);
#elif defined(FFT_FFTW2)
  if (flag == -1)
    fftw(plan->plan_slow_forward,total/length,data,1,length,NULL,0,0);
  else
    fftw(plan->plan_slow_backward,total/length,data,1,length,NULL,0,0);
#elif defined(FFT_FFTW3)
  if (flag == -1)
    theplan=plan->plan_slow_forward;
  else
    theplan=plan->plan_slow_backward;
  FFTW_API(execute_dft)(theplan,data,data);
#else
  if (flag == -1)
    for (offset = 0; offset < total; offset += length)
      kiss_fft(plan->cfg_slow_forward,&data[offset],&data[offset]);
  else
    for (offset = 0; offset < total; offset += length)
      kiss_fft(plan->cfg_slow_backward,&data[offset],&data[offset]);
#endif

  // post-remap to put data in output format if needed
  // destination is always out

  if (plan->post_plan)
    remap_3d((FFT_SCALAR *) data, (FFT_SCALAR *) out, (FFT_SCALAR *) plan->scratch,
             plan->post_plan);

  // scaling if required
#if !defined(FFT_T3E) && !defined(FFT_ACML)
  if (flag == 1 && plan->scaled) {
    norm = plan->norm;
    num = plan->normnum;
    out_ptr = (FFT_SCALAR *)out;
    for (i = 0; i < num; i++) {
#if defined(FFT_FFTW3)
      *(out_ptr++) *= norm;
      *(out_ptr++) *= norm;
#elif defined(FFT_MKL)
      out[i] *= norm;
#else
      out[i].re *= norm;
      out[i].im *= norm;
#endif
    }
  }
#endif

#ifdef FFT_T3E
  if (flag == 1 && plan->scaled) {
    norm = plan->norm;
    num = plan->normnum;
    for (i = 0; i < num; i++) out[i] *= (norm,norm);
  }
#endif

#ifdef FFT_ACML
  norm = plan->norm;
  num = plan->normnum;
  for (i = 0; i < num; i++) {
    out[i].re *= norm;
    out[i].im *= norm;
  }
#endif

}