📄 ilbc_encoder.java
字号:
/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */package net.java.sip.communicator.impl.media.codec.audio.ilbc;/** * @author Jean Lorchat */class ilbc_encoder { /* encoding mode, either 20 or 30 ms */ int mode; /* analysis filter state */ float anaMem[];//LPC_FILTERORDER]; /* old lsf parameters for interpolation */ float lsfold[]; //LPC_FILTERORDER]; float lsfdeqold[]; //LPC_FILTERORDER]; /* signal buffer for LP analysis */ float lpc_buffer[]; //LPC_LOOKBACK + BLOCKL_MAX]; /* state of input HP filter */ float hpimem[]; //4]; ilbc_ulp ULP_inst = null; /* encoder methods start here */ /*----------------------------------------------------------------* * predictive noise shaping encoding of scaled start state * (subrutine for StateSearchW) *---------------------------------------------------------------*/ void AbsQuantW( float in[], /* (i) vector to encode */ int in_idx, float syntDenum[], /* (i) denominator of synthesis filter */ int syntDenum_idx, float weightDenum[], /* (i) denominator of weighting filter */ int weightDenum_idx, int out[], /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ ){ // float *syntOut; int syntOut; float [] syntOutBuf = new float[ilbc_constants.LPC_FILTERORDER + ilbc_constants.STATE_SHORT_LEN_30MS]; float toQ, xq; int n; int [] index = new int[1]; /* initialization of buffer for filtering */ for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) { syntOutBuf[li] = 0.0f; } // memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float)); /* initialization of pointer for filtering */ // syntOut = &syntOutBuf[LPC_FILTERORDER]; syntOut = ilbc_constants.LPC_FILTERORDER; /* synthesis and weighting filters on input */ if (state_first != 0) { ilbc_common.AllPoleFilter (in, in_idx, weightDenum, weightDenum_idx, ilbc_constants.SUBL, ilbc_constants.LPC_FILTERORDER); } else { ilbc_common.AllPoleFilter (in, in_idx, weightDenum, weightDenum_idx, this.ULP_inst.state_short_len - ilbc_constants.SUBL, ilbc_constants.LPC_FILTERORDER); } /* encoding loop */ for (n=0; n<len; n++) { /* time update of filter coefficients */ if ((state_first != 0)&&(n==ilbc_constants.SUBL)){ syntDenum_idx += (ilbc_constants.LPC_FILTERORDER+1); weightDenum_idx += (ilbc_constants.LPC_FILTERORDER+1); /* synthesis and weighting filters on input */ ilbc_common.AllPoleFilter (in, in_idx + n, weightDenum, weightDenum_idx, len-n, ilbc_constants.LPC_FILTERORDER); } else if ((state_first==0)&& (n==(this.ULP_inst.state_short_len-ilbc_constants.SUBL))) { syntDenum_idx += (ilbc_constants.LPC_FILTERORDER+1); weightDenum_idx += (ilbc_constants.LPC_FILTERORDER+1); /* synthesis and weighting filters on input */ ilbc_common.AllPoleFilter (in, in_idx + n, weightDenum, weightDenum_idx, len-n, ilbc_constants.LPC_FILTERORDER); } /* prediction of synthesized and weighted input */ syntOutBuf[syntOut + n] = 0.0f; ilbc_common.AllPoleFilter (syntOutBuf, syntOut + n, weightDenum, weightDenum_idx, 1, ilbc_constants.LPC_FILTERORDER); /* quantization */ toQ = in[in_idx+n] - syntOutBuf[syntOut+n]; xq = sort_sq(index, 0, toQ, ilbc_constants.state_sq3Tbl, 8); out[n]=index[0]; syntOutBuf[syntOut + n] = ilbc_constants.state_sq3Tbl[out[n]]; /* update of the prediction filter */ ilbc_common.AllPoleFilter(syntOutBuf, syntOut + n, weightDenum, weightDenum_idx, 1, ilbc_constants.LPC_FILTERORDER); } } /*----------------------------------------------------------------* * encoding of start state *---------------------------------------------------------------*/ void StateSearchW( float residual[],/* (i) target residual vector */ int residual_idx, float syntDenum[], /* (i) lpc synthesis filter */ int syntDenum_idx, float weightDenum[], /* (i) weighting filter denuminator */ int weightDenum_idx, int idxForMax[], /* (o) quantizer index for maximum amplitude */ int idxVec[], /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first) /* (i) position of start state in the 80 vec */ { float dtmp, maxVal; float [] tmpbuf = new float[ilbc_constants.LPC_FILTERORDER + 2 * ilbc_constants.STATE_SHORT_LEN_30MS]; // float *tmp, int tmp; float [] numerator = new float[1+ilbc_constants.LPC_FILTERORDER]; float [] foutbuf = new float[ilbc_constants.LPC_FILTERORDER + 2 * ilbc_constants.STATE_SHORT_LEN_30MS]; //, *fout; int fout; int k; float qmax, scal; /* initialization of buffers and filter coefficients */ for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) { tmpbuf[li] = 0.0f; foutbuf[li] = 0.0f; } // memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); // memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k < ilbc_constants.LPC_FILTERORDER; k++) { numerator[k]=syntDenum[syntDenum_idx+ilbc_constants.LPC_FILTERORDER-k]; } numerator[ilbc_constants.LPC_FILTERORDER]=syntDenum[syntDenum_idx]; // tmp = &tmpbuf[LPC_FILTERORDER]; tmp = ilbc_constants.LPC_FILTERORDER; // fout = &foutbuf[LPC_FILTERORDER]; fout = ilbc_constants.LPC_FILTERORDER; /* circular convolution with the all-pass filter */ System.arraycopy(residual, residual_idx, tmpbuf, tmp, len); // memcpy(tmp, residual, len*sizeof(float)); for (int li = 0; li < len; li++) tmpbuf[tmp+len+li] = 0.0f; // memset(tmp+len, 0, len*sizeof(float)); ilbc_common.ZeroPoleFilter(tmpbuf, tmp, numerator, syntDenum, syntDenum_idx, 2*len, ilbc_constants.LPC_FILTERORDER, foutbuf, fout); for (k=0; k<len; k++) { foutbuf[fout+k] += foutbuf[fout+k+len]; } /* identification of the maximum amplitude value */ maxVal = foutbuf[fout+0]; for (k=1; k<len; k++) { if (foutbuf[fout+k]*foutbuf[fout+k] > maxVal*maxVal){ maxVal = foutbuf[fout+k]; } } maxVal=(float)Math.abs(maxVal); /* encoding of the maximum amplitude value */ if (maxVal < 10.0f) { maxVal = 10.0f; } // log10 is since 1.5 //maxVal = (float)Math.log10(maxVal); maxVal = (float)(Math.log(maxVal)/Math.log(10)); dtmp = sort_sq(idxForMax, 0, maxVal, ilbc_constants.state_frgqTbl, 64); /* decoding of the maximum amplitude representation value, and corresponding scaling of start state */ maxVal = ilbc_constants.state_frgqTbl[idxForMax[0]]; qmax = (float)Math.pow(10,maxVal); scal = 4.5f / qmax; for (k=0; k<len; k++){ foutbuf[fout+k] *= scal; } /* predictive noise shaping encoding of scaled start state */ AbsQuantW(foutbuf, fout,syntDenum, syntDenum_idx, weightDenum, weightDenum_idx, idxVec, len, state_first); } /*----------------------------------------------------------------* * conversion from lpc coefficients to lsf coefficients *---------------------------------------------------------------*/ void a2lsf( float freq[],/* (o) lsf coefficients */ int freq_idx, float a[]) /* (i) lpc coefficients */ { float [] steps = {(float)0.00635f, (float)0.003175f, (float)0.0015875f, (float)0.00079375f}; float step; int step_idx; int lsp_index; float [] p = new float[ilbc_constants.LPC_HALFORDER]; float [] q = new float[ilbc_constants.LPC_HALFORDER]; float [] p_pre = new float[ilbc_constants.LPC_HALFORDER]; float [] q_pre = new float[ilbc_constants.LPC_HALFORDER]; int old_p = 0, old_q = 1; //float *old; float [] olds = new float[2]; int old; // float *pq_coef; float [] pq_coef; float omega, old_omega; int i; float hlp, hlp1, hlp2, hlp3, hlp4, hlp5; for (i=0; i < ilbc_constants.LPC_HALFORDER; i++) { p[i] = (float)-1.0f * (a[i + 1] + a[ilbc_constants.LPC_FILTERORDER - i]); q[i] = a[ilbc_constants.LPC_FILTERORDER - i] - a[i + 1]; } p_pre[0] = (float) -1.0f - p[0]; p_pre[1] = - p_pre[0] - p[1]; p_pre[2] = - p_pre[1] - p[2]; p_pre[3] = - p_pre[2] - p[3]; p_pre[4] = - p_pre[3] - p[4]; p_pre[4] = p_pre[4] / 2; q_pre[0] = (float) 1.0f - q[0]; q_pre[1] = q_pre[0] - q[1]; q_pre[2] = q_pre[1] - q[2]; q_pre[3] = q_pre[2] - q[3]; q_pre[4] = q_pre[3] - q[4]; q_pre[4] = q_pre[4] / 2; omega = 0.0f; old_omega = 0.0f; olds[old_p] = ilbc_constants.DOUBLE_MAX; olds[old_q] = ilbc_constants.DOUBLE_MAX; /* Here we loop through lsp_index to find all the LPC_FILTERORDER roots for omega. */ for (lsp_index = 0; lsp_index < ilbc_constants.LPC_FILTERORDER; lsp_index++) { /* Depending on lsp_index being even or odd, we alternatively solve the roots for the two LSP equations. */ if ((lsp_index & 0x1) == 0) { pq_coef = p_pre; old = old_p; } else { pq_coef = q_pre; old = old_q; } /* Start with low resolution grid */ for (step_idx = 0, step = steps[step_idx]; step_idx < ilbc_constants.LSF_NUMBER_OF_STEPS;){ /* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) + pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */ hlp = (float)Math.cos(omega * ilbc_constants.TWO_PI); hlp1 = 2.0f * hlp + pq_coef[0]; hlp2 = 2.0f * hlp * hlp1 - (float)1.0 + pq_coef[1]; hlp3 = 2.0f * hlp * hlp2 - hlp1 + pq_coef[2]; hlp4 = 2.0f * hlp * hlp3 - hlp2 + pq_coef[3]; hlp5 = hlp * hlp4 - hlp3 + pq_coef[4]; if (((hlp5 * (olds[old])) <= 0.0f) || (omega >= 0.5)){ if (step_idx == (ilbc_constants.LSF_NUMBER_OF_STEPS - 1)){ if ((float)Math.abs(hlp5) >= Math.abs(olds[old])) { //System.out.println("acces index " + freq_idx + lsp_index); freq[freq_idx+lsp_index] = omega - step; } else { //System.out.println("acces index " + freq_idx + lsp_index); freq[freq_idx+lsp_index] = omega; } if ((olds[old]) >= 0.0f){ olds[old] = -1.0f * ilbc_constants.DOUBLE_MAX; } else { olds[old] = ilbc_constants.DOUBLE_MAX; } omega = old_omega; step_idx = 0; step_idx = ilbc_constants.LSF_NUMBER_OF_STEPS; } else { if (step_idx == 0) { old_omega = omega; } step_idx++; omega -= steps[step_idx]; /* Go back one grid step */ step = steps[step_idx]; } } else { /* increment omega until they are of different sign, and we know there is at least one root between omega and old_omega */ olds[old] = hlp5; omega += step; } } } for (i = 0; i < ilbc_constants.LPC_FILTERORDER; i++) { //System.out.println("acces index " + freq_idx + i); freq[freq_idx+i] = freq[freq_idx+i] * ilbc_constants.TWO_PI; } } /*----------------------------------------------------------------* * lpc analysis (subrutine to LPCencode) *---------------------------------------------------------------*/ void SimpleAnalysis( float lsf[], /* (o) lsf coefficients */ float data[]) /* (i) new data vector */ { int k, is; float [] temp = new float[ilbc_constants.BLOCKL_MAX]; float [] lp = new float[ilbc_constants.LPC_FILTERORDER + 1]; float [] lp2 = new float[ilbc_constants.LPC_FILTERORDER + 1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -