www.pudn.com > AVS_M_ver10.rar > cod_lf_b.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2007 Audio Video Coding Standard, Part ¢ú * * This software module was developed by AVS Audio sub-group * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include #include #include #include "../include/amr_plus.h" #include "../../c-code/include/open_pitch.h" #ifdef PW_UPDATE static void try_tcx( int k, int mode, /* 1=TCX20, 2=TCX40 3=TCX80 */ float *snr, float A[], float wsp[], int mod[], short coding_mod[], float isp[], float isp_q[], float AqLF[], float speech[], float mem_w0[], float mem_xnq[], float mem_wsyn[], float old_exc[], float mem_syn[], float wovlp[], int ovlp_size[], float past_isfq[], int pit_adj, int nbits, int nprm_tcx, int prm[], float mem_formant[NB_DIV+1][M], float mem_tilt[NB_DIV+1][TILT_ORDER], float mem_formant_zir[NB_DIV+1][M], float mem_tilt_zir[NB_DIV+1][TILT_ORDER], float mem_formant_wsyn[NB_DIV+1][M], float mem_tilt_wsyn[NB_DIV+1][TILT_ORDER]); #endif #ifndef PW_UPDATE static void try_tcx( int k, int mode, /* 1=TCX20, 2=TCX40 3=TCX80 */ float *snr, float A[], float wsp[], int mod[], short coding_mod[], float isp[], float isp_q[], float AqLF[], float speech[], float mem_w0[], float mem_xnq[], float mem_wsyn[], float old_exc[], float mem_syn[], float wovlp[], int ovlp_size[], float past_isfq[], int pit_adj, int nbits, int nprm_tcx, int prm[]); #endif void coder_lf_b(int codec_mode, /* (i) : AMR-WB+ mode (see cnst.h) */ float speech[], /* (i) : speech vector [-M..L_FRAME_PLUS+L_NEXT] */ float synth[], /* (o) : synthesis vector [-M..L_FRAME_PLUS] */ int mod[], /* (o) : mode for each 20ms frame (mode[4] */ float AqLF[], /* (o) : quantized coefficients (AdLF[16]) */ float window[], /* (i) : window for LPC analysis */ int param[], /* (o) : parameters (NB_DIV*NPRM_DIV) */ float ol_gain[], /* (o) : open-loop LTP gain */ int ave_T_out[], /* (o) : average LTP lag */ float ave_p_out[], /* (o) : average LTP gain */ short coding_mod[],/* (i) : selected mode for each 20ms */ int pit_adj, /* (i) : indicate pitch adjustment */ Coder_State_Plus *st /* i/o : coder memory state */ ) { /* LPC coefficients */ float r[M+1]; /* Autocorrelations of windowed speech */ float A[(NB_SUBFR+1)*(M+1)]; float Ap[M+1]; float ispnew[M]; /* LSPs at 4nd subframe */ float isfnew[M]; float isp[(NB_DIV+1)*M]; float isp_q[(NB_DIV+1)*M]; float past_isfq[3*M]; /* past isf quantizer */ float mem_w0[NB_DIV+1], mem_wsyn[NB_DIV+1]; float mem_xnq[NB_DIV+1]; int ovlp_size[NB_DIV+1]; float *wsp; float mem_syn[(NB_DIV+1)*M]; float wovlp[(NB_DIV+1)*128]; /* Scalars */ int i, j, k, i2, i1, nbits, *prm; float snr, snr1, snr2; float ener, cor_max, t0; /* OPEN_PITCH_SEARCH */ #ifdef AVS_OPEN_PITCH float R1, R2, R0; #endif /* END_OPEN_PITCH_SEARCH */ float *p, *p1; float norm_corr[4], norm_corr2[4]; int T_op[NB_DIV], T_op2[NB_DIV]; int T_out[4]; /* integer pitch-lag */ float p_out[4]; float LTPGain[2]; int PIT_MIN; /* Minimum pitch lag with resolution 1/4 */ int PIT_MAX; /* Maximum pitch lag */ #ifdef PW_UPDATE float mem_formant[NB_DIV+1][M]; float mem_tilt[NB_DIV+1][TILT_ORDER]; float mem_formant_zir[NB_DIV+1][M]; float mem_tilt_zir[NB_DIV+1][TILT_ORDER]; float mem_formant_wsyn[NB_DIV+1][M]; float mem_tilt_wsyn[NB_DIV+1][TILT_ORDER]; #endif if(pit_adj ==0) { PIT_MIN = PIT_MIN_12k8; PIT_MAX = PIT_MAX_12k8; } else { i = (((pit_adj*PIT_MIN_12k8)+(FSCALE_DENOM/2))/FSCALE_DENOM)-PIT_MIN_12k8; PIT_MIN = PIT_MIN_12k8 + i; PIT_MAX = PIT_MAX_12k8 + (6*i); } /* number of bits per frame (80 ms) */ nbits = NBITS_CORE[codec_mode]; /* remove bits for mode */ nbits -= NBITS_MODE; /*---------------------------------------------------------------* * Perform LP analysis four times (every 20 ms) * * - autocorrelation + lag windowing * * - Levinson-Durbin algorithm to find a[] * * - convert a[] to isp[] * * - interpol isp[] * *---------------------------------------------------------------*/ /* read old isp for LPC interpolation */ mvr2r(st->ispold, isp, M); for (i = 0; i < NB_DIV; i++) { if (pit_adj<=FSCALE_DENOM) { /* Autocorrelations of signal at 12.8kHz */ E_UTIL_autocorrPlus(&speech[(i*L_DIV)+L_SUBFR], r, M, L_WINDOW, window); } else { /* Autocorrelations of signal at 12.8kHz */ E_UTIL_autocorrPlus(&speech[(i*L_DIV)+(L_SUBFR/2)], r, M, L_WINDOW_HIGH_RATE, window); } /* Lag windowing */ lag_wind(r, M); /* Levinson Durbin */ E_LPC_lev_dur(Ap, r, M); /* From A(z) to ISP */ E_LPC_a_isp_conversion(Ap, ispnew, st->ispold, M); for (j = 0; j < M; j++) { st->stClass->ApBuf[i*M+j] = Ap[j]; } mvr2r(ispnew, &isp[(i+1)*M], M); /* A(z) interpolation every 20 ms (used for weighted speech) */ int_lpc_np1(st->ispold, ispnew, &A[i*4*(M+1)], 4, M); /* update ispold[] for the next LPC analysis */ mvr2r(ispnew, st->ispold, M); } mvr2r(synth-M, mem_syn, M); wsp = synth; /* wsp[] use synth[] as tmp buffer */ { float old_d_wsp[(PIT_MAX_MAX/OPL_DECIM)+L_DIV]; /* Weighted speech vector */ float *d_wsp; d_wsp = old_d_wsp + PIT_MAX_MAX/OPL_DECIM; mvr2r(st->old_d_wsp, old_d_wsp, PIT_MAX_MAX/OPL_DECIM); /* Calculate open-loop LTP parameters */ for (i = 0; i < NB_DIV; i++) { /* weighted speech for SNR */ #ifdef PW_UPDATE find_wsp_mono(&A[i*(NB_SUBFR/4)*(M+1)],&speech[i*L_DIV],&wsp[i*L_DIV],st->mem_formant_wsp,st->mem_tilt_wsp,L_DIV); #endif #ifndef PW_UPDATE find_wsp(&A[i*(NB_SUBFR/4)*(M+1)], &speech[i*L_DIV], &wsp[i*L_DIV], &(st->mem_wsp), L_DIV); #endif mvr2r(&wsp[i*L_DIV], d_wsp, L_DIV); E_GAIN_lp_decim2(d_wsp, L_DIV, st->mem_lp_decim2); /* OPEN_PITCH_SEARCH */ #ifdef AVS_OPEN_PITCH T_op[i] = (int)find_pitch(d_wsp,(PIT_MIN/OPL_DECIM)+2,PIT_MAX/OPL_DECIM,(2*L_SUBFR)/OPL_DECIM); /* calculate open pitch gain */ R0 = R1 = R2 = 0.0F; for (j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) { R1 += d_wsp[j] * d_wsp[j]; R2 += d_wsp[j-T_op[i]] * d_wsp[j-T_op[i]]; R0 += d_wsp[j] * d_wsp[j-T_op[i]]; } LTPGain[1] = st->ol_gain = (Float32)(R0 / (sqrt(R1 * R2) + 1e-5)); #endif /* END_OPEN_PITCH_SEARCH */ #ifndef AVS_OPEN_PITCH /* Find open loop pitch lag for first 1/2 frame */ T_op[i] = E_GAIN_open_loop_search(d_wsp, (PIT_MIN/OPL_DECIM)+1, PIT_MAX/OPL_DECIM, (2*L_SUBFR)/OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_ol_ltp_mem, st->hp_old_wsp, (unsigned char)st->ol_wght_flg); LTPGain[1] = st->ol_gain; if (st->ol_gain > 0.6) { st->old_T0_med = E_GAIN_olag_median(T_op[i], st->old_ol_lag); st->ada_w = 1.0; } else { st->ada_w = st->ada_w * 0.9f; } if (st->ada_w < 0.8) { st->ol_wght_flg = 0; } else { st->ol_wght_flg = 1; } #endif /* compute max */ cor_max = 0.0f; p = &d_wsp[0]; p1 = d_wsp - T_op[i]; for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) { cor_max += *p++ * *p1++; } /* compute energy */ t0 = 0.01f; p = d_wsp - T_op[i]; for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++, p++) { t0 += *p * *p; } t0 = (float)(1.0 / sqrt(t0)); /* 1/sqrt(energy) */ norm_corr[i] = cor_max * t0; /* max/sqrt(energy) */ /* normalized corr (0..1) */ ener = 0.01f; for (j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) { ener += d_wsp[j]*d_wsp[j]; } ener = (float)(1.0 / sqrt(ener)); /* 1/sqrt(energy) */ norm_corr[i] *= ener; /* OPEN_PITCH_SEARCH */ #ifdef AVS_OPEN_PITCH T_op2[i] = (int)find_pitch(d_wsp+(2*L_SUBFR)/OPL_DECIM,(PIT_MIN/OPL_DECIM)+2,PIT_MAX/OPL_DECIM,(2*L_SUBFR)/OPL_DECIM); for (j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) { R1 += d_wsp[j+(2*L_SUBFR)/OPL_DECIM] * d_wsp[j+(2*L_SUBFR)/OPL_DECIM]; R2 += d_wsp[(2*L_SUBFR)/OPL_DECIM+j-T_op[i]] * d_wsp[(2*L_SUBFR)/OPL_DECIM+j-T_op[i]]; R0 += d_wsp[(2*L_SUBFR)/OPL_DECIM+j] * d_wsp[(2*L_SUBFR)/OPL_DECIM+j-T_op[i]]; } LTPGain[0] = st->ol_gain = (Float32)(R0 / (sqrt(R1 * R2) + 1e-5)); #endif /* END_OPEN_PITCH_SEARCH */ #ifndef AVS_OPEN_PITCH /* Find open loop pitch lag for second 1/2 frame */ T_op2[i] = E_GAIN_open_loop_search(d_wsp + ((2*L_SUBFR)/OPL_DECIM), (PIT_MIN/OPL_DECIM)+1, PIT_MAX/OPL_DECIM, (2*L_SUBFR)/OPL_DECIM, st->old_T0_med, &st->ol_gain, st->hp_ol_ltp_mem,st->hp_old_wsp, (unsigned char)st->ol_wght_flg); LTPGain[0] = st->ol_gain; if (st->ol_gain > 0.6) { st->old_T0_med = E_GAIN_olag_median(T_op2[i], st->old_ol_lag); st->ada_w = 1.0; } else { st->ada_w = st->ada_w * 0.9f; } if( st->ada_w < 0.8) { st->ol_wght_flg = 0; } else { st->ol_wght_flg = 1; } #endif /* compute max */ cor_max = 0.0f; p = d_wsp + (2*L_SUBFR)/OPL_DECIM; p1 = d_wsp + ((2*L_SUBFR)/OPL_DECIM) - T_op2[i]; for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) { cor_max += *p++ * *p1++; } /* compute energy */ t0 = 0.01f; p = d_wsp + ((2*L_SUBFR)/OPL_DECIM) - T_op2[i]; for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++, p++) { t0 += *p * *p; } t0 = (float)(1.0 / sqrt(t0)); /* 1/sqrt(energy) */ norm_corr2[i] = cor_max * t0; /* max/sqrt(energy) */ /* normalized corr (0..1) */ ener = 0.01f; for (j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) { ener += d_wsp[((2*L_SUBFR)/OPL_DECIM)+j]*d_wsp[((2*L_SUBFR)/OPL_DECIM)+j]; } ener = (float)(1.0 / sqrt(ener)); /* 1/sqrt(energy) */ norm_corr2[i] *= ener; ol_gain[i] = st->ol_gain; mvr2r(&old_d_wsp[L_DIV/OPL_DECIM], old_d_wsp, PIT_MAX_MAX/OPL_DECIM); st->stClass->LTPGain[(2*i+2)] = LTPGain[1]; st->stClass->LTPGain[(2*i+2)+1] = LTPGain[0]; st->stClass->LTPLag[(2*i)+2] = T_op[i]; st->stClass->LTPLag[(2*i+2)+1] = T_op2[i]; st->stClass->NormCorr[(2*i+2)] = norm_corr[i]; st->stClass->NormCorr[(2*i+2)+1] = norm_corr2[i]; } mvr2r(old_d_wsp, st->old_d_wsp, PIT_MAX_MAX/OPL_DECIM); /* d_wsp already shifted */ } /*---------------------------------------------------------------* * Call ACELP and TCX codec * *---------------------------------------------------------------*/ ovlp_size[0] = st->old_ovlp_size; /*Classification refinement */ classifyExcitationRef(st->stClass, isp, coding_mod); if (st->SwitchFlagPlusToWB && coding_mod[0] != 0) { coding_mod[0] = 0; st->stClass->NbOfAcelps++; st->SwitchFlagPlusToWB = 0; } ovlp_size[1] = st->old_ovlp_size; ovlp_size[2] = st->old_ovlp_size; ovlp_size[3] = st->old_ovlp_size; ovlp_size[4] = st->old_ovlp_size; mem_w0[0] = st->old_mem_w0; mem_xnq[0] = st->old_mem_xnq; mem_wsyn[0] = st->old_mem_wsyn; mvr2r(st->old_wovlp, wovlp, 128); mvr2r(st->past_isfq, &past_isfq[0], M); mvr2r(st->ispold_q, isp_q, M); snr2 = 0.0; #ifdef PW_UPDATE mvr2r(st->mem_formant,mem_formant[0],M); mvr2r(st->mem_tilt,mem_tilt[0],TILT_ORDER); mvr2r(st->mem_formant_zir,mem_formant_zir[0],M); mvr2r(st->mem_tilt_zir,mem_tilt_zir[0],TILT_ORDER); mvr2r(st->mem_formant_wsyn,mem_formant_wsyn[0],M); mvr2r(st->mem_tilt_wsyn,mem_tilt_wsyn[0],TILT_ORDER); #endif for (i1=0; i1<2; i1++) { mvr2r(&past_isfq[i1*M], &past_isfq[(i1+1)*M], M); snr1 = 0.0; for (i2=0; i2<2; i2++) { k = (i1*2) + i2; if (coding_mod[k] == 0 || (coding_mod[k] == 1 && st->stClass->NbOfAcelps != 0) || (st->stClass->NoMtcx[i1] != 0 && st->stClass->NbOfAcelps == 0) ) { /* set pointer to parameters */ prm = param + (k*NPRM_DIV); /*---------------------------------------------------------------* * Quantize ISF parameters (46 bits) every 20 ms * *---------------------------------------------------------------*/ /* Convert isps to frequency domain 0..6400 */ E_LPC_isp_isf_conversion(&isp[(k+1)*M], isfnew, M); /* quantize 1st and 2nd LPC with 46 bits */ /* ISF quantization */ qpisf_2s_46b_new(isfnew, isfnew, &past_isfq[(i1+1)*M], prm, 4); prm += NPRM_LPC; /* Convert isfs to the cosine domain */ isf2isp(isfnew, &isp_q[(k+1)*M], M); /* interpol quantized lpc */ int_lpc_np1(&isp_q[k*M], &isp_q[(k+1)*M], &AqLF[k*4*(M+1)], 4, M); /*---------------------------------------------------------------* * Call ACELP 4 subfr x 5ms = 20 ms frame * *---------------------------------------------------------------*/ if (coding_mod[k] == 0) { #ifdef PW_UPDATE mvr2r(mem_formant[k],mem_formant[k+1],M); mvr2r(mem_tilt[k],mem_tilt[k+1],TILT_ORDER); mvr2r(mem_formant_zir[k],mem_formant_zir[k+1],M); mvr2r(mem_tilt_zir[k],mem_tilt_zir[k+1],TILT_ORDER); #endif mem_w0[k+1] = mem_w0[k]; mem_xnq[k+1] = mem_xnq[k]; ovlp_size[k+1] = 0; { float old_exc[PIT_MAX_MAX+L_INTERPOL+L_DIV+1]; /* Excitation vector */ float old_syn[M+L_DIV]; float buf[L_DIV]; mvr2r(st->old_exc, old_exc, PIT_MAX_MAX+L_INTERPOL); mvr2r(&mem_syn[k*M], old_syn, M); #ifdef PW_UPDATE coder_acelp(&A[k*(NB_SUBFR/4)*(M+1)], &AqLF[k*(NB_SUBFR/4)*(M+1)], &speech[k*L_DIV], &mem_w0[k+1], &mem_xnq[k+1], old_syn+M, old_exc+PIT_MAX_MAX+L_INTERPOL, &wovlp[(k+1)*128], L_DIV, codec_mode, norm_corr[k], norm_corr2[k], T_op[k], T_op2[k], T_out, p_out, st->mem_gain_code, pit_adj, prm, mem_formant[k+1], mem_tilt[k+1], mem_formant_zir[k+1], mem_tilt_zir[k+1]); #endif #ifndef PW_UPDATE coder_acelp(&A[k*(NB_SUBFR/4)*(M+1)], &AqLF[k*(NB_SUBFR/4)*(M+1)], &speech[k*L_DIV], &mem_w0[k+1], &mem_xnq[k+1], old_syn+M, old_exc+PIT_MAX_MAX+L_INTERPOL, &wovlp[(k+1)*128], L_DIV, codec_mode, norm_corr[k], norm_corr2[k], T_op[k], T_op2[k], T_out, p_out, st->mem_gain_code, pit_adj, prm); #endif mvr2r(&old_exc[L_DIV], st->old_exc, PIT_MAX_MAX+L_INTERPOL); mvr2r(old_syn+L_DIV, &mem_syn[(k+1)*M], M); /* average integer pitch-lag for high band coding */ ave_T_out[k] = (int)((T_op[k]+T_op2[k])); ave_p_out[k] = (p_out[0]+p_out[1]+p_out[2]+p_out[3])/4.0f; mem_wsyn[k+1] = mem_wsyn[k]; #ifdef PW_UPDATE mvr2r(mem_formant_wsyn[k],mem_formant_wsyn[k+1],M); mvr2r(mem_tilt_wsyn[k],mem_tilt_wsyn[k+1],TILT_ORDER); find_wsp_mono(&A[k*(NB_SUBFR/4)*(M+1)], old_syn+M, buf,mem_formant_wsyn[k+1],mem_tilt_wsyn[k+1],L_DIV); #endif #ifndef PW_UPDATE find_wsp(&A[k*(NB_SUBFR/4)*(M+1)], old_syn+M, buf, &mem_wsyn[k+1], L_DIV); #endif } mod[k] = 0; coding_mod[k] = 0; } /* end ACELP */ /*--------------------------------------------------* * Call 20MS TCX coder and find segmental SNR * *--------------------------------------------------*/ if (coding_mod[k] != 0 ) { snr = -10000.0f; #ifdef PW_UPDATE try_tcx(k, 1, &snr, A, wsp, mod, coding_mod, isp, isp_q, AqLF, speech, mem_w0, mem_xnq, mem_wsyn, st->old_exc, mem_syn, wovlp, ovlp_size, past_isfq, pit_adj, ((nbits/4)-NBITS_LPC), NPRM_TCX20, prm, mem_formant,mem_tilt,mem_formant_zir, mem_tilt_zir,mem_formant_wsyn,mem_tilt_wsyn); #endif #ifndef PW_UPDATE try_tcx(k, 1, &snr, A, wsp, mod, coding_mod, isp, isp_q, AqLF, speech, mem_w0, mem_xnq, mem_wsyn, st->old_exc, mem_syn, wovlp, ovlp_size, past_isfq, pit_adj, ((nbits/4)-NBITS_LPC), NPRM_TCX20, prm); #endif snr1 += 0.5f*snr; } /* end of TCX_20MS */ } /* end of i2 */ } /* end of coding mode ACELP or TCX_20MS */ if (coding_mod[i1*2] != 0 && coding_mod[i1*2+1] != 0) { if (st->stClass->NbOfAcelps == 0) { snr1 = -10000.0; /* TCX20 off*/ } k = (i1*2); /* set pointer to parameters */ prm = param + (k*NPRM_DIV); #ifdef PW_UPDATE try_tcx(k, 2, &snr1, A, wsp, mod, coding_mod, isp, isp_q, AqLF, speech, mem_w0, mem_xnq, mem_wsyn, st->old_exc, mem_syn, wovlp, ovlp_size, past_isfq, pit_adj, ((nbits/2)-NBITS_LPC), NPRM_LPC+NPRM_TCX40, prm, mem_formant,mem_tilt,mem_formant_zir, mem_tilt_zir,mem_formant_wsyn,mem_tilt_wsyn); #endif #ifndef PW_UPDATE try_tcx(k, 2, &snr1, A, wsp, mod, coding_mod, isp, isp_q, AqLF, speech, mem_w0, mem_xnq, mem_wsyn, st->old_exc, mem_syn, wovlp, ovlp_size, past_isfq, pit_adj, ((nbits/2)-NBITS_LPC), NPRM_LPC+NPRM_TCX40, prm); #endif snr2 += 0.5f*snr1; } /* end of coding mode TCX_40MS */ } /* end of i1 */ if (coding_mod[0] != 0 && coding_mod[1] != 0 && coding_mod[2] != 0 && coding_mod[3] != 0 && st->stClass->NoMtcx[0] == 0 && st->stClass->NoMtcx[1] == 0) { k = 0; /* set pointer to parameters */ prm = param + (k*NPRM_DIV); #ifdef PW_UPDATE try_tcx(k, 3, &snr2, A, wsp, mod, coding_mod, isp, isp_q, AqLF, speech, mem_w0, mem_xnq, mem_wsyn, st->old_exc, mem_syn, wovlp, ovlp_size, past_isfq, pit_adj, (nbits-NBITS_LPC), NPRM_LPC+NPRM_TCX80, prm, mem_formant,mem_tilt,mem_formant_zir, mem_tilt_zir,mem_formant_wsyn,mem_tilt_wsyn); #endif #ifndef PW_UPDATE try_tcx(k, 3, &snr2, A, wsp, mod, coding_mod, isp, isp_q, AqLF, speech, mem_w0, mem_xnq, mem_wsyn, st->old_exc, mem_syn, wovlp, ovlp_size, past_isfq, pit_adj, (nbits-NBITS_LPC), NPRM_LPC+NPRM_TCX80, prm); #endif } /* end of coding mode 3 */ /*Mode buffer update & reset MTcx counter*/ for(i=0;i<4;i++){ st->stClass->prevModes[i] = coding_mod[i]; } if (st->stClass->NoMtcx[0] != 0) { st->stClass->NoMtcx[0] = 0; } if (st->stClass->NoMtcx[1] != 0) { st->stClass->NoMtcx[1] = 0; } /*--------------------------------------------------* * Update filter memory. * *--------------------------------------------------*/ #ifdef PW_UPDATE mvr2r(mem_formant[NB_DIV],st->mem_formant,M); mvr2r(mem_tilt[NB_DIV],st->mem_tilt,TILT_ORDER); mvr2r(mem_formant_zir[NB_DIV],st->mem_formant_zir,M); mvr2r(mem_tilt_zir[NB_DIV],st->mem_tilt_zir,TILT_ORDER); mvr2r(mem_formant_wsyn[NB_DIV],st->mem_formant_wsyn,M); mvr2r(mem_tilt_wsyn[NB_DIV],st->mem_tilt_wsyn,TILT_ORDER); #endif st->old_ovlp_size = ovlp_size[NB_DIV]; st->old_mem_w0 = mem_w0[NB_DIV]; st->old_mem_xnq = mem_xnq[NB_DIV]; st->old_mem_wsyn = mem_wsyn[NB_DIV]; mvr2r(&wovlp[NB_DIV*128], st->old_wovlp, 128); mvr2r(&past_isfq[2*M], st->past_isfq, M); mvr2r(&isp_q[NB_DIV*M], st->ispold_q, M); mvr2r(&mem_syn[NB_DIV*M], synth+L_FRAME_PLUS-M, M); /*--------------------------------------------------* * Update exc for next frame. * *--------------------------------------------------*/ return; } #ifdef PW_UPDATE static void try_tcx( int k, int mode, /* 1=TCX20, 2=TCX40 3=TCX80 */ float *snr, float A[], float wsp[], int mod[], short coding_mod[], float isp[], float isp_q[], float AqLF[], float speech[], float mem_w0[], float mem_xnq[], float mem_wsyn[], float old_exc[], float mem_syn[], float wovlp[], int ovlp_size[], float past_isfq[], int pit_adj, int nbits, int nprm_tcx, int prm[], float mem_formant[NB_DIV+1][M], float mem_tilt[NB_DIV+1][TILT_ORDER], float mem_formant_zir[NB_DIV+1][M], float mem_tilt_zir[NB_DIV+1][TILT_ORDER], float mem_formant_wsyn[NB_DIV+1][M], float mem_tilt_wsyn[NB_DIV+1][TILT_ORDER] ) { float Aq[(NB_SUBFR+1)*(M+1)], *p_Aq; int prm_tcx_buf[NPRM_LPC+NPRM_TCX80], *prm_tcx; float synth_tcx[M+L_TCX]; float exc_tcx[L_TCX]; float mem_w0_tcx, mem_xnq_tcx, mem_wsyn_tcx; float wovlp_tcx[128]; float past_isfq_tcx[M]; float ispnew_q[M]; /* LSPs at 4nd subframe */ float isfnew[M]; /* Scalars */ int i, ndiv; float tmp; int PIT_MAX; //Perceptual Weighting float mem_formant_tcx[M]; float mem_tilt_tcx[TILT_ORDER]; float mem_formant_exc_tcx[M]; float mem_tilt_exc_tcx[TILT_ORDER]; float mem_formant_wsyn_tcx[M]; float mem_tilt_wsyn_tcx[TILT_ORDER]; if(pit_adj ==0) { PIT_MAX = PIT_MAX_12k8; } else { i = (((pit_adj*PIT_MIN_12k8)+(FSCALE_DENOM/2))/FSCALE_DENOM)-PIT_MIN_12k8; PIT_MAX = PIT_MAX_12k8 + (6*i); } prm_tcx = prm_tcx_buf; ndiv = mode; if (ndiv == 3) { ndiv++; /* 4 divisions in mode 3 (TCX80) */ } if (mode > 1) { /*---------------------------------------------------------------* * Quantize ISF parameters (46 bits) every 40/80 ms * *---------------------------------------------------------------*/ /* Convert isps to frequency domain 0..6400 */ E_LPC_isp_isf_conversion(&isp[(k+ndiv)*M], isfnew, M); mvr2r(&past_isfq[(k/2)*M], past_isfq_tcx, M); /* quantize 1st and 2nd LPC with 46 bits */ /* ISF quantization */ qpisf_2s_46b_new(isfnew, isfnew, past_isfq_tcx, prm_tcx, 4); prm_tcx += NPRM_LPC; /* Convert isfs to the cosine domain */ isf2isp(isfnew, ispnew_q, M); /* interpol quantized lpc */ int_lpc_np1(&isp_q[k*M], ispnew_q, Aq, ndiv*4, M); p_Aq = Aq; } else { p_Aq = &AqLF[k*4*(M+1)]; } /*--------------------------------------------------------* * Call 20/40/80MS TCX coder and find segmental SNR * *--------------------------------------------------------*/ //Perceptual Weighting mvr2r(mem_formant[k],mem_formant_tcx,M); mvr2r(mem_tilt[k],mem_tilt_tcx,TILT_ORDER); mvr2r(mem_formant_zir[k],mem_formant_exc_tcx,M); mvr2r(mem_tilt_zir[k],mem_tilt_exc_tcx,TILT_ORDER); mvr2r(&mem_syn[k*M], synth_tcx, M); mem_w0_tcx = mem_w0[k]; mem_xnq_tcx = mem_xnq[k]; mvr2r(&wovlp[k*128], wovlp_tcx, 128); #ifdef NEW_TVC coder_tcx(p_Aq, &speech[k*L_DIV], &mem_w0_tcx, &mem_xnq_tcx, &synth_tcx[M], exc_tcx, wovlp_tcx, ovlp_size[k], ndiv*L_DIV, nbits, k, prm_tcx, mem_formant_tcx, mem_tilt_tcx, mem_formant_exc_tcx, mem_tilt_exc_tcx); #else coder_tcx(p_Aq, &speech[k*L_DIV], &mem_w0_tcx, &mem_xnq_tcx, &synth_tcx[M], exc_tcx, wovlp_tcx, ovlp_size[k], ndiv*L_DIV, nbits, prm_tcx, mem_formant_tcx, mem_tilt_tcx, mem_formant_exc_tcx, mem_tilt_exc_tcx); #endif mem_wsyn_tcx = mem_wsyn[k]; //Perceputal Weighting mvr2r(mem_formant_wsyn[k],mem_formant_wsyn_tcx,M); mvr2r(mem_tilt_wsyn[k],mem_tilt_wsyn_tcx,TILT_ORDER); { float buf[L_FRAME_PLUS]; //Perceptual Weighting find_wsp_mono(&A[k*4*(M+1)], &synth_tcx[M], buf,mem_formant_wsyn_tcx,mem_tilt_wsyn_tcx,ndiv*L_DIV); tmp = segsnr(&wsp[k*L_DIV], buf, (short)(ndiv*L_DIV), (short)L_SUBFR); } /*--------------------------------------------------------* * Save tcx parameters if tcx segmental SNR is better * *--------------------------------------------------------*/ if (tmp > *snr) { *snr = tmp; for (i=0; i 1) { mvr2r(ispnew_q, &isp_q[(k+ndiv)*M], M); mvr2r(past_isfq_tcx, &past_isfq[((k+ndiv)/2)*M], M); /* lpc coefficient needed for HF extension */ mvr2r(Aq, &AqLF[k*4*(M+1)], ((ndiv*4)+1)*(M+1)); } if (ndiv == 1) { mvr2r(&old_exc[L_DIV], old_exc, (PIT_MAX_MAX + L_INTERPOL)- L_DIV ); mvr2r(exc_tcx, old_exc+PIT_MAX_MAX+L_INTERPOL - L_DIV , L_DIV); } else { mvr2r(exc_tcx+(ndiv*L_DIV)-(PIT_MAX_MAX+L_INTERPOL), old_exc, PIT_MAX_MAX+L_INTERPOL); } mvr2r(wovlp_tcx, &wovlp[(k+ndiv)*128], 128); mvr2r(&synth_tcx[ndiv*L_DIV], &mem_syn[(k+ndiv)*M], M); mvi2i(prm_tcx_buf, prm, nprm_tcx); } return; } #endif #ifndef PW_UPDATE static void try_tcx( int k, int mode, /* 1=TCX20, 2=TCX40 3=TCX80 */ float *snr, float A[], float wsp[], int mod[], short coding_mod[], float isp[], float isp_q[], float AqLF[], float speech[], float mem_w0[], float mem_xnq[], float mem_wsyn[], float old_exc[], float mem_syn[], float wovlp[], int ovlp_size[], float past_isfq[], int pit_adj, int nbits, int nprm_tcx, int prm[]) { float Aq[(NB_SUBFR+1)*(M+1)], *p_Aq; int prm_tcx_buf[NPRM_LPC+NPRM_TCX80], *prm_tcx; float synth_tcx[M+L_TCX]; float exc_tcx[L_TCX]; float mem_w0_tcx, mem_xnq_tcx, mem_wsyn_tcx; float wovlp_tcx[128]; float past_isfq_tcx[M]; float ispnew_q[M]; /* LSPs at 4nd subframe */ float isfnew[M]; /* Scalars */ int i, ndiv; float tmp; int PIT_MAX; if(pit_adj ==0) { PIT_MAX = PIT_MAX_12k8; } else { i = (((pit_adj*PIT_MIN_12k8)+(FSCALE_DENOM/2))/FSCALE_DENOM)-PIT_MIN_12k8; PIT_MAX = PIT_MAX_12k8 + (6*i); } prm_tcx = prm_tcx_buf; ndiv = mode; if (ndiv == 3) { ndiv++; /* 4 divisions in mode 3 (TCX80) */ } if (mode > 1) { /*---------------------------------------------------------------* * Quantize ISF parameters (46 bits) every 40/80 ms * *---------------------------------------------------------------*/ /* Convert isps to frequency domain 0..6400 */ E_LPC_isp_isf_conversion(&isp[(k+ndiv)*M], isfnew, M); mvr2r(&past_isfq[(k/2)*M], past_isfq_tcx, M); /* quantize 1st and 2nd LPC with 46 bits */ /* ISF quantization */ qpisf_2s_46b_new(isfnew, isfnew, past_isfq_tcx, prm_tcx, 4); prm_tcx += NPRM_LPC; /* Convert isfs to the cosine domain */ isf2isp(isfnew, ispnew_q, M); /* interpol quantized lpc */ int_lpc_np1(&isp_q[k*M], ispnew_q, Aq, ndiv*4, M); p_Aq = Aq; } else { p_Aq = &AqLF[k*4*(M+1)]; } /*--------------------------------------------------------* * Call 20/40/80MS TCX coder and find segmental SNR * *--------------------------------------------------------*/ mvr2r(&mem_syn[k*M], synth_tcx, M); mem_w0_tcx = mem_w0[k]; mem_xnq_tcx = mem_xnq[k]; mvr2r(&wovlp[k*128], wovlp_tcx, 128); #ifdef NEW_TVC coder_tcx(p_Aq, &speech[k*L_DIV], &mem_w0_tcx, &mem_xnq_tcx, &synth_tcx[M], exc_tcx, wovlp_tcx, ovlp_size[k], ndiv*L_DIV, nbits, k, prm_tcx); #else coder_tcx(p_Aq, &speech[k*L_DIV], &mem_w0_tcx, &mem_xnq_tcx, &synth_tcx[M], exc_tcx, wovlp_tcx, ovlp_size[k], ndiv*L_DIV, nbits, prm_tcx); #endif mem_wsyn_tcx = mem_wsyn[k]; { float buf[L_FRAME_PLUS]; find_wsp(&A[k*4*(M+1)], &synth_tcx[M], buf, &mem_wsyn_tcx, ndiv*L_DIV); tmp = segsnr(&wsp[k*L_DIV], buf, (short)(ndiv*L_DIV), (short)L_SUBFR); } /*--------------------------------------------------------* * Save tcx parameters if tcx segmental SNR is better * *--------------------------------------------------------*/ if (tmp > *snr) { *snr = tmp; for (i=0; i 1) { mvr2r(ispnew_q, &isp_q[(k+ndiv)*M], M); mvr2r(past_isfq_tcx, &past_isfq[((k+ndiv)/2)*M], M); /* lpc coefficient needed for HF extension */ mvr2r(Aq, &AqLF[k*4*(M+1)], ((ndiv*4)+1)*(M+1)); } if (ndiv == 1) { mvr2r(&old_exc[L_DIV], old_exc, (PIT_MAX_MAX + L_INTERPOL)- L_DIV ); mvr2r(exc_tcx, old_exc+PIT_MAX_MAX+L_INTERPOL - L_DIV , L_DIV); } else { mvr2r(exc_tcx+(ndiv*L_DIV)-(PIT_MAX_MAX+L_INTERPOL), old_exc, PIT_MAX_MAX+L_INTERPOL); } mvr2r(wovlp_tcx, &wovlp[(k+ndiv)*128], 128); mvr2r(&synth_tcx[ndiv*L_DIV], &mem_syn[(k+ndiv)*M], M); mvi2i(prm_tcx_buf, prm, nprm_tcx); } return; } #endif