void aks_to_M2( 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 */ ) { COMP Pw[FFT_DEC]; /* 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; r = TWO_PI/(FFT_DEC); /* Determine DFT of A(exp(jw)) --------------------------------------------*/ for(i=0; i<FFT_DEC; i++) { Pw[i].real = 0.0; Pw[i].imag = 0.0; } for(i=0; i<=order; i++) Pw[i].real = ak[i]; fft(&Pw[0].real,FFT_DEC,1); /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/ for(i=0; i<FFT_DEC/2; i++) Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); #ifdef DUMP if (dump) dump_Pw(Pw); #endif /* Determine magnitudes by linear interpolation of P(w) -------------------*/ signal = noise = 0.0; for(m=1; m<=model->L; m++) { am = floor((m - 0.5)*model->Wo/r + 0.5); bm = floor((m + 0.5)*model->Wo/r + 0.5); Em = 0.0; for(i=am; i<bm; i++) Em += Pw[i].real; Am = sqrt(Em); signal += pow(model->A[m],2.0); noise += pow(model->A[m] - Am,2.0); model->A[m] = Am; } *snr = 10.0*log10(signal/noise); }
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"); }