📄 ilbc_decoder.java
字号:
// memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } } /* future */ for (i=0; i<periodl; i++) { plocs2[i]=plocs[i]-period[i]; } for (q=hl+1; q<=2*hl; q++) { lagBlock[q] = NearestNeighbor(plocs2, blockStartPos[q-1]+ilbc_constants.ENH_BLOCKL_HALF, periodl); blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]]; if (blockStartPos[q]+ilbc_constants.ENH_BLOCKL+ilbc_constants.ENH_OVERHANG<idatal) { blockStartPos[q] = refiner(sseq,q*ilbc_constants.ENH_BLOCKL, idata, idatal, centerStartPos, blockStartPos[q], period[lagBlock[q]]); } else { psseq=q*ilbc_constants.ENH_BLOCKL;// psseq=sseq+q*ENH_BLOCKL; for (int li = 0; li < ilbc_constants.ENH_BLOCKL; li++) sseq[psseq+li] = 0.0f;// memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } } } /*----------------------------------------------------------------* * perform enhancement on idata+centerStartPos through * idata+centerStartPos+ENH_BLOCKL-1 *---------------------------------------------------------------*/ public void enhancer( float odata[], /* (o) smoothed block, dimension blockl */ int odata_idx, float idata[], /* (i) data buffer used for enhancing */ int idatal, /* (i) dimension idata */ int centerStartPos, /* (i) first sample current block within idata */ float alpha0, /* (i) max correction-energy-fraction (in [0,1]) */ float period[], /* (i) pitch period array */ float plocs[], /* (i) locations where period array values valid */ int periodl /* (i) dimension of period and plocs */ ){ float [] sseq = new float[(2*ilbc_constants.ENH_HL+1)*ilbc_constants.ENH_BLOCKL]; /* get said second sequence of segments */ getsseq(sseq,idata,idatal,centerStartPos,period, plocs,periodl,ilbc_constants.ENH_HL); /* compute the smoothed output from said second sequence */ smath(odata, odata_idx, sseq,ilbc_constants.ENH_HL,alpha0); } /*----------------------------------------------------------------* * cross correlation *---------------------------------------------------------------*/ public float xCorrCoef( float target[], /* (i) first array */ int t_idx, float regressor[], /* (i) second array */ int r_idx, int subl) /* (i) dimension arrays */ { int i; float ftmp1, ftmp2; ftmp1 = 0.0f; ftmp2 = 0.0f; for (i=0; i<subl; i++) { ftmp1 += target[t_idx + i] * regressor[r_idx + i]; ftmp2 += regressor[r_idx + i] * regressor[r_idx + i]; } if (ftmp1 > 0.0f) { return (float)(ftmp1*ftmp1/ftmp2); } else { return (float)0.0f; } } /*----------------------------------------------------------------* * interface for enhancer *---------------------------------------------------------------*/ int enhancerInterface( float out[], /* (o) enhanced signal */ float in[]) /* (i) unenhanced signal */ { // float *enh_buf, *enh_period; (definis en global pour la classe) int iblock, isample; int lag=0, ilag, i, ioffset; float cc, maxcc; float ftmp1, ftmp2; // float *inPtr, *enh_bufPtr1, *enh_bufPtr2; int inPtr, enh_bufPtr1, enh_bufPtr2; float [] plc_pred = new float[ilbc_constants.ENH_BLOCKL]; float [] lpState = new float[6]; float [] downsampled = new float[(ilbc_constants.ENH_NBLOCKS*ilbc_constants.ENH_BLOCKL+120)/2]; int inLen=ilbc_constants.ENH_NBLOCKS*ilbc_constants.ENH_BLOCKL+120; int start, plc_blockl, inlag; // enh_buf=iLBCdec_inst->enh_buf; // enh_period=iLBCdec_inst->enh_period; System.arraycopy(enh_buf, this.ULP_inst.blockl, enh_buf, 0, ilbc_constants.ENH_BUFL-this.ULP_inst.blockl);// memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl],// (ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float)); System.arraycopy(in, 0, enh_buf, ilbc_constants.ENH_BUFL-this.ULP_inst.blockl, this.ULP_inst.blockl);// memcpy(&enh_buf[ENH_BUFL-this.ULP_inst.blockl], in,// this.ULP_inst.blockl*sizeof(float)); if (this.ULP_inst.mode==30) plc_blockl=ilbc_constants.ENH_BLOCKL; else plc_blockl=40; /* when 20 ms frame, move processing one block */ ioffset=0; if (this.ULP_inst.mode==20) ioffset=1; i=3-ioffset; System.arraycopy(enh_period, i, enh_period, 0, ilbc_constants.ENH_NBLOCKS_TOT-i);// memmove(enh_period, &enh_period[i],// (ENH_NBLOCKS_TOT-i)*sizeof(float)); /* Set state information to the 6 samples right before the samples to be downsampled. */ System.arraycopy(enh_buf, (ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset)*ilbc_constants.ENH_BLOCKL-126, lpState, 0, 6);// memcpy(lpState,// enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126,// 6*sizeof(float)); /* Down sample a factor 2 to save computations */ DownSample(enh_buf, (ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset)*ilbc_constants.ENH_BLOCKL-120, ilbc_constants.lpFilt_coefsTbl, inLen-ioffset*ilbc_constants.ENH_BLOCKL, lpState, downsampled); /* Estimate the pitch in the down sampled domain. */ for (iblock = 0; iblock<ilbc_constants.ENH_NBLOCKS-ioffset; iblock++) { lag = 10; maxcc = xCorrCoef(downsampled, 60+iblock * ilbc_constants.ENH_BLOCKL_HALF, downsampled, 60+iblock * ilbc_constants.ENH_BLOCKL_HALF - lag, ilbc_constants.ENH_BLOCKL_HALF); for (ilag=11; ilag<60; ilag++) { cc = xCorrCoef(downsampled, 60+iblock* ilbc_constants.ENH_BLOCKL_HALF, downsampled, 60+iblock* ilbc_constants.ENH_BLOCKL_HALF - ilag, ilbc_constants.ENH_BLOCKL_HALF); if (cc > maxcc) { maxcc = cc; lag = ilag; } } /* Store the estimated lag in the non-downsampled domain */ enh_period[iblock+ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2; } /* PLC was performed on the previous packet */ if (this.prev_enh_pl==1) { inlag=(int)enh_period[ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset]; lag = inlag-1; maxcc = xCorrCoef(in, 0, in, lag, plc_blockl); for (ilag=inlag; ilag<=inlag+1; ilag++) { cc = xCorrCoef(in, 0, in, ilag, plc_blockl); if (cc > maxcc) { maxcc = cc; lag = ilag; } } enh_period[ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag; /* compute new concealed residual for the old lookahead, mix the forward PLC with a backward PLC from the new frame */ // inPtr=&in[lag-1]; inPtr = lag - 1; // enh_bufPtr1=&plc_pred[plc_blockl-1]; enh_bufPtr1 = plc_blockl - 1; if (lag>plc_blockl) { start=plc_blockl; } else { start=lag; } for (isample = start; isample>0; isample--) { // *enh_bufPtr1-- = *inPtr--; plc_pred[enh_bufPtr1] = in[inPtr]; enh_bufPtr1--; inPtr--; } // enh_bufPtr2=&enh_buf[ENH_BUFL-1-this.ULP_inst.blockl]; enh_bufPtr2 = ilbc_constants.ENH_BUFL - 1 - this.ULP_inst.blockl; for (isample = (plc_blockl-1-lag); isample>=0; isample--) { // *enh_bufPtr1-- = *enh_bufPtr2--; plc_pred[enh_bufPtr1] = enh_buf[enh_bufPtr2]; enh_bufPtr1--; enh_bufPtr2--; } /* limit energy change */ ftmp2=0.0f; ftmp1=0.0f; for (i=0;i<plc_blockl;i++) { ftmp2+=enh_buf[ilbc_constants.ENH_BUFL-1-this.ULP_inst.blockl-i]* enh_buf[ilbc_constants.ENH_BUFL-1-this.ULP_inst.blockl-i]; ftmp1+=plc_pred[i]*plc_pred[i]; } ftmp1=(float)(float)Math.sqrt(ftmp1/(float)plc_blockl); ftmp2=(float)(float)Math.sqrt(ftmp2/(float)plc_blockl); if (ftmp1>(float)2.0f*ftmp2 && ftmp1>0.0) { for (i=0;i<plc_blockl-10;i++) { plc_pred[i]*=(float)2.0f*ftmp2/ftmp1; } for (i=plc_blockl-10;i<plc_blockl;i++) { plc_pred[i]*=(float)(i-plc_blockl+10)* ((float)1.0f-(float)2.0*ftmp2/ftmp1)/(float)(10)+ (float)2.0f*ftmp2/ftmp1; } } enh_bufPtr1=ilbc_constants.ENH_BUFL-1-this.ULP_inst.blockl;// enh_bufPtr1=&enh_buf[ilbc_constants.ENH_BUFL-1-this.ULP_inst.blockl]; for (i=0; i<plc_blockl; i++) { ftmp1 = (float) (i+1) / (float) (plc_blockl+1); enh_buf[enh_bufPtr1] *= ftmp1;// *enh_bufPtr1 *= ftmp1; enh_buf[enh_bufPtr1] += ((float)1.0f-ftmp1)* plc_pred[plc_blockl-1-i];// *enh_bufPtr1 += ((float)1.0f-ftmp1)*// plc_pred[plc_blockl-1-i]; enh_bufPtr1--; } } if (this.ULP_inst.mode==20) { /* Enhancer with 40 samples delay */ for (iblock = 0; iblock<2; iblock++) { enhancer(out, iblock*ilbc_constants.ENH_BLOCKL, enh_buf, ilbc_constants.ENH_BUFL, (5+iblock)*ilbc_constants.ENH_BLOCKL+40, ilbc_constants.ENH_ALPHA0, enh_period, ilbc_constants.enh_plocsTbl, ilbc_constants.ENH_NBLOCKS_TOT); } } else if (this.ULP_inst.mode==30) { /* Enhancer with 80 samples delay */ for (iblock = 0; iblock<3; iblock++) { enhancer(out, iblock*ilbc_constants.ENH_BLOCKL, enh_buf, ilbc_constants.ENH_BUFL, (4+iblock)*ilbc_constants.ENH_BLOCKL, ilbc_constants.ENH_ALPHA0, enh_period, ilbc_constants.enh_plocsTbl, ilbc_constants.ENH_NBLOCKS_TOT); } } return (lag*2); } /*----------------------------------------------------------------* * Packet loss concealment routine. Conceals a residual signal * and LP parameters. If no packet loss, update state. *---------------------------------------------------------------*/ /*----------------------------------------------------------------* * Compute cross correlation and pitch gain for pitch prediction * of last subframe at given lag. *---------------------------------------------------------------*/ public void compCorr( float cc[], /* (o) cross correlation coefficient */ float gc[], /* (o) gain */ float pm[], float buffer[], /* (i) signal buffer */ int lag, /* (i) pitch lag */ int bLen, /* (i) length of buffer */ int sRange) /* (i) correlation search length */ { int i; float ftmp1, ftmp2, ftmp3; /* Guard against getting outside buffer */ if ((bLen - sRange - lag) < 0) { sRange = bLen - lag; } ftmp1 = 0.0f; ftmp2 = 0.0f; ftmp3 = 0.0f; for (i=0; i<sRange; i++) { ftmp1 += buffer[bLen-sRange+i] * buffer[bLen-sRange+i-lag]; ftmp2 += buffer[bLen-sRange+i-lag] * buffer[bLen-sRange+i-lag]; ftmp3 += buffer[bLen-sRange+i] * buffer[bLen-sRange+i]; } if (ftmp2 > 0.0f) { cc[0] = ftmp1*ftmp1/ftmp2; gc[0] = (float)(float)Math.abs(ftmp1 / ftmp2); pm[0] = (float)(float)Math.abs(ftmp1) / ((float)(float)Math.sqrt(ftmp2)*(float)Math.sqrt(ftmp3)); } else { cc[0] = 0.0f; gc[0] = 0.0f; pm[0] = 0.0f; } } public void doThePLC( float PLCresidual[], /* (o) concealed residual */ float PLClpc[], /* (o) concealed LP parameters */ int PLI, /* (i) packet loss indicator 0 - no PL, 1 = PL */ float decresidual[], /* (i) decoded residual */ float lpc[], /* (i) decoded LPC (only used for no PL) */ int lpc_idx, int inlag) /* (i) pitch lag */ { int lag = 20, randlag = 0; float gain = 0.0f, maxcc = 0.0f; float use_gain = 0.0f; float gain_comp = 0.0f, maxcc_comp = 0.0f, per = 0.0f, max_per = 0.0f; int i, pick, use_lag; float ftmp, randvec[], pitchfact, energy; float [] a_gain, a_comp, a_per; randvec = new float [ilbc_constants.BLOCKL_MAX]; a_gain = new float[1]; a_comp = new float[1]; a_per = new float[1]; /* Packet Loss */ if (PLI == 1) { this.consPLICount += 1; /* if previous frame not lost, determine pitch pred. gain */ if (this.prevPLI != 1) { /* Search around the previous lag to find the best pitch period */ lag=inlag-3; a_comp[0] = maxcc; a_gain[0] = gain; a_per[0] = max_per; compCorr(a_comp, a_gain, a_per, this.prevResidual, lag, this.ULP_inst.blockl, 60); maxcc = a_comp[0]; gain = a_gain[0]; max_per = a_per[0]; for (i=inlag-2;i<=inlag+3;i++) { a_comp[0] = maxcc_comp; a_gain[0] = gain_comp; a_per[0] = per; compCorr(a_comp, a_gain, a_per, this.prevResidual, i, this.ULP_inst.blockl, 60); maxcc_comp = a_comp[0]; gain_comp = a_gain[0]; per = a_per[0]; if (maxcc_comp>maxcc) { maxcc=maxcc_comp; gain=gain_comp; lag=i; max_per=per; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -