package org.mobicents.media.server.impl.dsp.audio.g729; public class QuaLsp { /* static memory */ float freq_prev[][] = new float[LD8KConstants.MA_NP][LD8KConstants.M]; /* previous LSP vector */ float freq_prev_reset[] = new float[]{ /* previous LSP vector(init) */ (float)0.285599, (float)0.571199, (float)0.856798, (float)1.142397, (float)1.427997, (float)1.713596, (float)1.999195, (float)2.284795, (float)2.570394, (float)2.855993 }; /* PI*(float)(j+1)/(float)(M+1) */ public void qua_lsp( float lsp[], /* (i) : Unquantized LSP */ float lsp_q[], /* (o) : Quantized LSP */ int ana[] /* (o) : indexes */ ) { int i; float lsf[] = new float[LD8KConstants.M], lsf_q[] = new float[LD8KConstants.M]; /* domain 0.0<= lsf <PI */ /* Convert LSPs to LSFs */ for (i=0; i<LD8KConstants.M; i++ ) lsf[i] = (float)Math.acos(lsp[i]); lsp_qua_cs(lsf, lsf_q, ana ); /* Convert LSFs to LSPs */ for (i=0; i<LD8KConstants.M; i++ ) lsp_q[i] = (float)Math.cos(lsf_q[i]); return; } /*---------------------------------------------------------------------------- * lsp_encw_reset - set the previous LSP vector *---------------------------------------------------------------------------- */ void lsp_encw_reset( ) { int i; for(i=0; i<LD8KConstants.MA_NP; i++) Util.copy (freq_prev_reset, freq_prev[i], LD8KConstants.M ); return; } /*---------------------------------------------------------------------------- * lsp_qua_cs - lsp quantizer *---------------------------------------------------------------------------- */ public void lsp_qua_cs( float []flsp_in, /* input : Original LSP parameters */ float []lspq_out, /* output: Quantized LSP parameters */ int[] code /* output: codes of the selected LSP */ ) { float wegt[] = new float[LD8KConstants.M]; /* weight coef. */ get_wegt( flsp_in, wegt ); relspwed( flsp_in, wegt, lspq_out, TabLD8k.lspcb1, TabLD8k.lspcb2, TabLD8k.fg, freq_prev, TabLD8k.fg_sum, TabLD8k.fg_sum_inv, code); return; } /*---------------------------------------------------------------------------- * relspwed - *---------------------------------------------------------------------------- */ static void relspwed( float lsp[], /*input: unquantized LSP parameters */ float wegt[], /*input: weight coef. */ float lspq[], /*output:quantized LSP parameters */ float lspcb1[][], /*input: first stage LSP codebook */ float lspcb2[][], /*input: Second stage LSP codebook */ float fg[][][], /*input: MA prediction coef. */ float freq_prev[][], /*input: previous LSP vector */ float fg_sum[][], /*input: present MA prediction coef. */ float fg_sum_inv[][], /*input: inverse coef. */ int code_ana[] /*output:codes of the selected LSP */ ) { int mode, j; IntegerPointer index = new IntegerPointer(); IntegerPointer mode_index = new IntegerPointer(),cand_cur = new IntegerPointer(); int cand[] = new int[LD8KConstants.MODE]; int tindex1[] =new int[LD8KConstants.MODE], tindex2[] = new int[LD8KConstants.MODE]; float tdist[] = new float[LD8KConstants.MODE]; float rbuf[] = new float[LD8KConstants.M]; float buf[] = new float[LD8KConstants.M]; for(mode = 0; mode<LD8KConstants.MODE; mode++) { LspGetq.lsp_prev_extract(lsp, rbuf, fg[mode], freq_prev, fg_sum_inv[mode]); /*----- search the first stage lsp codebook -----*/ lsp_pre_select(rbuf, lspcb1, cand_cur); cand[mode]=cand_cur.value; /*----- search the second stage lsp codebook (lower 0-4) ----- */ lsp_select_1(rbuf, lspcb1[cand_cur.value], wegt, lspcb2, index); tindex1[mode] = index.value; for(j=0; j<LD8KConstants.NC; j++) buf[j]=lspcb1[cand_cur.value][j]+lspcb2[index.value][j]; LspGetq.lsp_expand_1(buf, LD8KConstants.GAP1); /* check */ /*----- search the second stage lsp codebook (Higher 5-9) ----- */ lsp_select_2(rbuf, lspcb1[cand_cur.value], wegt, lspcb2, index); tindex2[mode] = index.value; for(j=LD8KConstants.NC; j<LD8KConstants.M; j++) buf[j]=lspcb1[cand_cur.value][j]+lspcb2[index.value][j]; LspGetq.lsp_expand_2(buf, LD8KConstants.GAP1); /* check */ /* check */ LspGetq.lsp_expand_1_2(buf, LD8KConstants.GAP2); FloatPointer tmp = new FloatPointer(tdist[mode]); lsp_get_tdist(wegt, buf, tmp, rbuf, fg_sum[mode]); /* calculate the distortion */ tdist[mode] = tmp.value; } /* mode */ lsp_last_select(tdist, mode_index); /* select the codes */ /* pack codes for lsp parameters */ code_ana[0] = (mode_index.value<<LD8KConstants.NC0_B) | cand[mode_index.value]; code_ana[1] = (tindex1[mode_index.value]<<LD8KConstants.NC1_B) | tindex2[mode_index.value]; /* reconstruct quantized LSP parameter and check the stabilty */ LspGetq.lsp_get_quant(lspcb1, lspcb2, cand[mode_index.value], tindex1[mode_index.value], tindex2[mode_index.value], fg[mode_index.value], freq_prev, lspq, fg_sum[mode_index.value]); return; } /*---------------------------------------------------------------------------- * lsp_pre_select - select the code of first stage lsp codebook *---------------------------------------------------------------------------- */ static void lsp_pre_select( float rbuf[], /*input : target vetor */ float lspcb1[][], /*input : first stage lsp codebook */ IntegerPointer cand /*output: selected code */ ) { int i, j; float dmin, dist, temp; /* calculate the distortion */ cand.value = 0; dmin= LD8KConstants.FLT_MAX_G729; for(i=0; i<LD8KConstants.NC0; i++) { dist =(float)0.; for(j=0; j<LD8KConstants.M; j++){ temp = rbuf[j]-lspcb1[i][j]; dist += temp * temp; } if(dist<dmin) { dmin=dist; cand.value=i; } } return; } /*---------------------------------------------------------------------------- * lsp_pre_select_1 - select the code of second stage lsp codebook (lower 0-4) *---------------------------------------------------------------------------- */ static void lsp_select_1( float rbuf[], /*input : target vector */ float lspcb1[], /*input : first stage lsp codebook */ float wegt[], /*input : weight coef. */ float lspcb2[][], /*input : second stage lsp codebook*/ IntegerPointer index /*output: selected codebook index */ ) { int j, k1; float buf[] = new float[LD8KConstants.M]; float dist, dmin, tmp; for(j=0; j<LD8KConstants.NC; j++) buf[j]=rbuf[j]-lspcb1[j]; index.value = 0; dmin=LD8KConstants.FLT_MAX_G729; for(k1 = 0; k1<LD8KConstants.NC1; k1++) { /* calculate the distortion */ dist = (float)0.; for(j=0; j<LD8KConstants.NC; j++) { tmp = buf[j]-lspcb2[k1][j]; dist += wegt[j] * tmp * tmp; } if(dist<dmin) { dmin = dist; index.value = k1; } } return; } /*---------------------------------------------------------------------------- * lsp_pre_select_2 - select the code of second stage lsp codebook (higher 5-9) *---------------------------------------------------------------------------- */ static void lsp_select_2( float rbuf[], /*input : target vector */ float lspcb1[], /*input : first stage lsp codebook */ float wegt[], /*input : weighting coef. */ float lspcb2[][], /*input : second stage lsp codebook*/ IntegerPointer index /*output: selected codebook index */ ) { int j, k1; float buf[] = new float[LD8KConstants.M]; float dist, dmin, tmp; for(j=LD8KConstants.NC; j<LD8KConstants.M; j++) buf[j]=rbuf[j]-lspcb1[j]; index.value = 0; dmin= LD8KConstants.FLT_MAX_G729; for(k1 = 0; k1<LD8KConstants.NC1; k1++) { dist = (float)0.0; for(j=LD8KConstants.NC; j<LD8KConstants.M; j++) { tmp = buf[j] - lspcb2[k1][j]; dist += wegt[j] * tmp * tmp; } if(dist<dmin) { dmin = dist; index.value = k1; } } return; } /*---------------------------------------------------------------------------- * lsp_get_tdist - calculate the distortion *---------------------------------------------------------------------------- */ static void lsp_get_tdist( float wegt[], /*input : weight coef. */ float buf[], /*input : candidate LSP vector */ FloatPointer tdist, /*output: distortion */ float rbuf[], /*input : target vector */ float fg_sum[] /*input : present MA prediction coef. */ ) { int j; float tmp; tdist.value = (float)0.0; for(j=0; j<LD8KConstants.M; j++) { tmp = (buf[j] - rbuf[j]) * fg_sum[j]; tdist.value += wegt[j] * tmp * tmp; } return; } /*---------------------------------------------------------------------------- * lsp_last_select - select the mode *---------------------------------------------------------------------------- */ static void lsp_last_select( float tdist[], /*input : distortion */ IntegerPointer mode_index /*output: the selected mode */ ) { mode_index.value = 0; if( tdist[1] < tdist[0] ) mode_index.value = 1; return; } /*---------------------------------------------------------------------------- * get_wegt - compute lsp weights *---------------------------------------------------------------------------- */ static void get_wegt( float flsp[], /* input : M LSP parameters */ float wegt[] /* output: M weighting coefficients */ ) { int i; float tmp; tmp = flsp[1] - LD8KConstants.PI04 - (float)1.0; if (tmp > (float)0.0) wegt[0] = (float)1.0; else wegt[0] = tmp * tmp * (float)10. + (float)1.0; for ( i=1; i<LD8KConstants.M-1; i++ ) { tmp = flsp[i+1] - flsp[i-1] - (float)1.0; if (tmp > (float)0.0) wegt[i] = (float)1.0; else wegt[i] = tmp * tmp * (float)10. + (float)1.0; } tmp = LD8KConstants.PI92 - flsp[LD8KConstants.M-2] - (float)1.0; if (tmp > (float)0.0) wegt[LD8KConstants.M-1] = (float)1.0; else wegt[LD8KConstants.M-1] = tmp * tmp * (float)10. + (float)1.0; wegt[4] *= LD8KConstants.CONST12; wegt[5] *= LD8KConstants.CONST12; return; } }