void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel) { int i; for (i=0;i<bank->nb_banks;i++) mel[i] = 0; for (i=0;i<bank->len;i++) { int id; id = bank->bank_left[i]; mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]); id = bank->bank_right[i]; mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]); } /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */ #ifndef FIXED_POINT /*for (i=0;i<bank->nb_banks;i++) mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]); */ #endif }
FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type) { FilterBank *bank; spx_word32_t df; spx_word32_t max_mel, mel_interval; int i; int id1; int id2; df = DIV32(SHL32(sampling,15),MULT16_16(2,len)); max_mel = toBARK(EXTRACT16(sampling/2)); mel_interval = PDIV32(max_mel,banks-1); bank = (FilterBank*)speex_alloc(sizeof(FilterBank)); bank->nb_banks = banks; bank->len = len; bank->bank_left = (int*)speex_alloc(len*sizeof(int)); bank->bank_right = (int*)speex_alloc(len*sizeof(int)); bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t)); bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t)); /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */ #ifndef FIXED_POINT bank->scaling = (float*)speex_alloc(banks*sizeof(float)); #endif for (i=0;i<len;i++) { spx_word16_t curr_freq; spx_word32_t mel; spx_word16_t val; curr_freq = EXTRACT16(MULT16_32_P15(i,df)); mel = toBARK(curr_freq); if (mel > max_mel) break; #ifdef FIXED_POINT id1 = DIV32(mel,mel_interval); #else id1 = (int)(floor(mel/mel_interval)); #endif if (id1>banks-2) { id1 = banks-2; val = Q15_ONE; } else { val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15))); } id2 = id1+1; bank->bank_left[i] = id1; bank->filter_left[i] = SUB16(Q15_ONE,val); bank->bank_right[i] = id2; bank->filter_right[i] = val; } /* Think I can safely disable normalisation for fixed-point (and probably float as well) */ #ifndef FIXED_POINT for (i=0;i<bank->nb_banks;i++) bank->scaling[i] = 0; for (i=0;i<bank->len;i++) { int id = bank->bank_left[i]; bank->scaling[id] += bank->filter_left[i]; id = bank->bank_right[i]; bank->scaling[id] += bank->filter_right[i]; } for (i=0;i<bank->nb_banks;i++) bank->scaling[i] = Q15_ONE/(bank->scaling[i]); #endif return bank; }
void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[], word32_t reflectionCoefficients[], word32_t autoCorrelationCoefficients[], word32_t noLagAutocorrelationCoefficients[], int8_t *autoCorrelationCoefficientsScale, uint8_t autoCorrelationCoefficientsNumber) { int i,j; word16_t windowedSignal[L_LP_ANALYSIS_WINDOW]; word64_t acc64=0; /* acc on 64 bits */ int rightShiftToNormalise=0; word32_t residualEnergy; /* interally compute by autoCorrelation2LP and extracted for DTX only, useless here */ /*********************************************************************/ /* Compute the windowed signal according to spec 3.2.1 eq4 */ /*********************************************************************/ for (i=0; i<L_LP_ANALYSIS_WINDOW; i++) { windowedSignal[i] = MULT16_16_P15(signal[i], wlp[i]); /* signal in Q0, wlp in Q0.15, windowedSignal in Q0 */ } /*********************************************************************************/ /* Compute the autoCorrelation coefficients r[0..10] according to spec 3.2.1 eq5 */ /*********************************************************************************/ /* Compute autoCorrelationCoefficients[0] first as it is the highest number and normalise it on 32 bits then apply the same normalisation to the other coefficients */ /* autoCorrelationCoefficients are normalised on 32 bits and then considered as Q31 in range [-1,1[ */ /* autoCorrelationCoefficients[0] is computed on 64 bits as it is likely to overflow 32 bits */ for (i=0; i<L_LP_ANALYSIS_WINDOW; i++) { acc64 = MAC64(acc64, windowedSignal[i], windowedSignal[i]); } if (acc64==0) { acc64 = 1; /* spec 3.2.1: To avoid arithmetic problems for low-level input signals the value of r(0) has a lower boundary of r(0) = 1.0 */ } /* normalise the acc64 on 32 bits */ if (acc64>MAXINT32) { do { acc64 = SHR(acc64,1); rightShiftToNormalise++; } while (acc64>MAXINT32); autoCorrelationCoefficients[0] = acc64; } else { rightShiftToNormalise = -countLeadingZeros((word32_t)acc64); autoCorrelationCoefficients[0] = SHL((word32_t)acc64, -rightShiftToNormalise); } /* give current autoCorrelation coefficients scale to the output */ *autoCorrelationCoefficientsScale = -rightShiftToNormalise; /* compute autoCorrelationCoefficients 1 to requested number (10 - no VAD - or 12 if VAD is enabled */ if (rightShiftToNormalise>0) { /* acc64 was not fitting on 32 bits so compute the other sum on 64 bits too */ for (i=1; i<autoCorrelationCoefficientsNumber; i++) { /* compute the sum in the 64 bits acc*/ acc64=0; for (j=i; j<L_LP_ANALYSIS_WINDOW; j++) { acc64 = ADD64_32(acc64, MULT16_16(windowedSignal[j], windowedSignal[j-i])); } /* normalise it */ autoCorrelationCoefficients[i] = SHR(acc64 ,rightShiftToNormalise); } } else { /* acc64 was fitting on 32 bits, compute the other sum on 32 bits only as it is faster */ for (i=1; i<autoCorrelationCoefficientsNumber; i++) { /* compute the sum in the 64 bits acc*/ word32_t acc32=0; for (j=i; j<L_LP_ANALYSIS_WINDOW; j++) { acc32 = MAC16_16(acc32, windowedSignal[j], windowedSignal[j-i]); } /* normalise it */ autoCorrelationCoefficients[i] = SHL(acc32, -rightShiftToNormalise); } } /* save autocorrelation before applying lag window as they are requested like this for DTX */ for (i=0; i<autoCorrelationCoefficientsNumber; i++) { noLagAutocorrelationCoefficients[i] = autoCorrelationCoefficients[i]; } /* apply lag window on the autocorrelation coefficients spec 3.2.1 eq7 */ /* this check shall be useless but it makes some compiler happy */ if (autoCorrelationCoefficientsNumber>NB_LSP_COEFF+3) { autoCorrelationCoefficientsNumber = NB_LSP_COEFF+3; } for (i=1; i<autoCorrelationCoefficientsNumber; i++) { autoCorrelationCoefficients[i] = MULT16_32_P15(wlag[i], autoCorrelationCoefficients[i]); /* wlag in Q15 */ //autoCorrelationCoefficients[i] = MULT32_32_Q31(wlag[i], autoCorrelationCoefficients[i]); /* wlag in Q31 */ } /* convert to LP using Levinson-Durbin algo described in sepc 3.2.2 */ autoCorrelation2LP(autoCorrelationCoefficients, LPCoefficientsQ12, reflectionCoefficients, &residualEnergy); return; }