?? ilbc_decoder.java
字號:
for (q=hl-1; q>=0; q--) {
blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]];
lagBlock[q] = NearestNeighbor(plocs,
blockStartPos[q]+
ilbc_constants.ENH_BLOCKL_HALF-period[lagBlock[q+1]],
periodl);
if (blockStartPos[q]-ilbc_constants.ENH_OVERHANG>=0) {
blockStartPos[q] = refiner(sseq,q*ilbc_constants.ENH_BLOCKL, idata,
idatal, centerStartPos,
blockStartPos[q],
period[lagBlock[q+1]]);
} 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));
}
}
/* 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;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -