📄 ilbc_decoder.java
字号:
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;
}
}
}
/* previous frame lost, use recorded lag and periodicity */
else {
lag=this.prevLag;
max_per=this.per;
}
/* downscaling */
use_gain=1.0f;
if (this.consPLICount*this.ULP_inst.blockl>320)
use_gain=(float)0.9;
else if (this.consPLICount*this.ULP_inst.blockl>2*320)
use_gain=(float)0.7;
else if (this.consPLICount*this.ULP_inst.blockl>3*320)
use_gain=(float)0.5;
else if (this.consPLICount*this.ULP_inst.blockl>4*320)
use_gain=(float)0.0f;
/* mix noise and pitch repeatition */
ftmp=(float)(float)Math.sqrt(max_per);
if (ftmp>(float)0.7)
pitchfact=(float)1.0f;
else if (ftmp>(float)0.4)
pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);
else
pitchfact=0.0f;
/* avoid repetition of same pitch cycle */
use_lag=lag;
if (lag<80) {
use_lag=2*lag;
}
/* compute concealed residual */
energy = 0.0f;
for (i=0; i<this.ULP_inst.blockl; i++) {
/* noise component */
this.seed = (this.seed * 69069 + 1) & (0x80000000 - 1);
randlag = 50 + (int) (this.seed % 70);
pick = i - randlag;
if (pick < 0) {
randvec[i] = this.prevResidual[this.ULP_inst.blockl+pick];
} else {
randvec[i] = randvec[pick];
}
/* pitch repeatition component */
pick = i - use_lag;
if (pick < 0) {
PLCresidual[i] = this.prevResidual[this.ULP_inst.blockl+pick];
} else {
PLCresidual[i] = PLCresidual[pick];
}
/* mix random and periodicity component */
if (i<80)
PLCresidual[i] = use_gain*(pitchfact *
PLCresidual[i] +
((float)1.0f - pitchfact) * randvec[i]);
else if (i<160)
PLCresidual[i] = (float)0.95*use_gain*(pitchfact *
PLCresidual[i] +
((float)1.0f - pitchfact) * randvec[i]);
else
PLCresidual[i] = (float)0.9*use_gain*(pitchfact *
PLCresidual[i] +
((float)1.0f - pitchfact) * randvec[i]);
energy += PLCresidual[i] * PLCresidual[i];
}
/* less than 30 dB, use only noise */
if ((float)Math.sqrt(energy/(float)this.ULP_inst.blockl) < 30.0f) {
gain=0.0f;
for (i=0; i<this.ULP_inst.blockl; i++) {
PLCresidual[i] = randvec[i];
}
}
/* use old LPC */
// memcpy(PLClpc,this.prevLpc, (LPC_FILTERORDER+1)*sizeof(float));
System.arraycopy(this.prevLpc, 0, PLClpc, 0, ilbc_constants.LPC_FILTERORDER + 1);
}
/* no packet loss, copy input */
else {
// memcpy(PLCresidual, decresidual,this.ULP_inst.blockl*sizeof(float));
System.arraycopy(decresidual, 0, PLCresidual, 0, this.ULP_inst.blockl);
// memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
System.arraycopy(lpc, lpc_idx, PLClpc, 0, ilbc_constants.LPC_FILTERORDER + 1);
this.consPLICount = 0;
}
/* update state */
if (PLI != 0) {
this.prevLag = lag;
this.per=max_per;
}
this.prevPLI = PLI;
// memcpy(this.prevLpc, PLClpc, (LPC_FILTERORDER+1)*sizeof(float));
System.arraycopy(PLClpc, 0, this.prevLpc, 0, ilbc_constants.LPC_FILTERORDER + 1);
// memcpy(this.prevResidual, PLCresidual, this.ULP_inst.blockl*sizeof(float));
System.arraycopy(PLCresidual, 0, this.prevResidual, 0, this.ULP_inst.blockl);
}
// public int decode(short decoded_data[], short encoded_data[], int mode)
// {
// return this.ULP_inst.blockl;
// }
public short decode( /* (o) Number of decoded samples */
short decoded_data[], /* (o) Decoded signal block*/
short encoded_data[], /* (i) Encoded bytes */
short mode) /* (i) 0=PL, 1=Normal */
{
int k;
float decblock [] = new float[ilbc_constants.BLOCKL_MAX];
float dtmp;
// char en_data[] = new char [this.ULP_inst.no_of_bytes];
bitstream en_data = new bitstream(this.ULP_inst.no_of_bytes);
/* check if mode is valid */
if ( (mode < 0) || (mode > 1)) {
System.out.println("\nERROR - Wrong mode - 0, 1 allowed\n");
}
/* do actual decoding of block */
for (k = 0; k < encoded_data.length; k++) {
en_data.buffer[2*k+1] = (char) (encoded_data[k] & 0xff);
en_data.buffer[2*k] = (char) ((encoded_data[k] >> 8) & 0xff);
// System.out.println("on decode " + (en_data.buffer[2*k]+0) + " et " + (en_data.buffer[2*k+1]+0));
}
iLBC_decode(decblock, en_data, mode);
/* convert to short */
for (k = 0; k < this.ULP_inst.blockl; k++) {
dtmp=decblock[k];
// System.out.println("on a eu : " + dtmp);
if (dtmp < ilbc_constants.MIN_SAMPLE)
dtmp = ilbc_constants.MIN_SAMPLE;
else if (dtmp > ilbc_constants.MAX_SAMPLE)
dtmp = ilbc_constants.MAX_SAMPLE;
decoded_data[k] = (short) dtmp;
}
return ((short) this.ULP_inst.blockl);
}
/*----------------------------------------------------------------*
* frame residual decoder function (subrutine to iLBC_decode)
*---------------------------------------------------------------*/
public void Decode(
float decresidual[], /* (o) decoded residual frame */
int start, /* (i) location of start
state */
int idxForMax, /* (i) codebook index for the
maximum value */
int idxVec[], /* (i) codebook indexes for the
samples in the start
state */
float syntdenum[], /* (i) the decoded synthesis
filter coefficients */
int cb_index[], /* (i) the indexes for the
adaptive codebook */
int gain_index[], /* (i) the indexes for the
corresponding gains */
int extra_cb_index[], /* (i) the indexes for the
adaptive codebook part
of start state */
int extra_gain_index[], /* (i) the indexes for the
corresponding gains */
int state_first) /* (i) 1 if non adaptive part
of start state comes
first 0 if that part
comes last */
{
float [] reverseDecresidual = new float[ilbc_constants.BLOCKL_MAX];
float [] mem = new float[ilbc_constants.CB_MEML];
int k, meml_gotten, Nfor, Nback, i;
int diff, start_pos;
int subcount, subframe;
diff = ilbc_constants.STATE_LEN - this.ULP_inst.state_short_len;
if (state_first == 1) {
start_pos = (start-1) * ilbc_constants.SUBL;
} else {
start_pos = (start-1) * ilbc_constants.SUBL + diff;
}
/* decode scalar part of start state */
ilbc_common.StateConstructW(idxForMax, idxVec,
syntdenum, (start-1)*(ilbc_constants.LPC_FILTERORDER+1),
decresidual, start_pos, this.ULP_inst.state_short_len);
if (state_first != 0) { /* put adaptive part in the end */
/* setup memory */
for (int li = 0; li < (ilbc_constants.CB_MEML-this.ULP_inst.state_short_len); li++)
mem[li] = 0.0f;
// memset(mem, 0,
// (CB_MEML-this.ULP_inst.state_short_len)*sizeof(float));
System.arraycopy(decresidual, start_pos,
mem, ilbc_constants.CB_MEML - this.ULP_inst.state_short_len,
this.ULP_inst.state_short_len);
// memcpy(mem+CB_MEML-this.ULP_inst.state_short_len,
// decresidual+start_pos,
// this.ULP_inst.state_short_len*sizeof(float));
/* construct decoded vector */
ilbc_common.iCBConstruct(decresidual, start_pos+this.ULP_inst.state_short_len,
extra_cb_index, 0, extra_gain_index, 0,
mem, ilbc_constants.CB_MEML - ilbc_constants.stMemLTbl,
ilbc_constants.stMemLTbl, diff, ilbc_constants.CB_NSTAGES);
}
else {/* put adaptive part in the beginning */
/* create reversed vectors for prediction */
for (k=0; k<diff; k++) {
reverseDecresidual[k] = decresidual[(start+1)*ilbc_constants.SUBL - 1 -
(k+this.ULP_inst.state_short_len)];
}
/* setup memory */
meml_gotten = this.ULP_inst.state_short_len;
for (k=0; k<meml_gotten; k++){
mem[ilbc_constants.CB_MEML-1-k] = decresidual[start_pos + k];
}
for (int li = 0; li < ilbc_constants.CB_MEML - k; li++)
mem[li] = 0.0f;
// memset(mem, 0, (CB_MEML-k)*sizeof(float));
/* construct decoded vector */
ilbc_common.iCBConstruct(reverseDecresidual, 0, extra_cb_index, 0,
extra_gain_index, 0,
mem, ilbc_constants.CB_MEML - ilbc_constants.stMemLTbl,
ilbc_constants.stMemLTbl, diff, ilbc_constants.CB_NSTAGES);
/* get decoded residual from reversed vector */
for (k=0; k<diff; k++) {
decresidual[start_pos-1-k] = reverseDecresidual[k];
}
}
/* counter for predicted sub-frames */
subcount=0;
/* forward prediction of sub-frames */
Nfor = this.ULP_inst.nsub-start-1;
if ( Nfor > 0 ){
/* setup memory */
for (int li = 0; li < ilbc_constants.CB_MEML - ilbc_constants.STATE_LEN; li++)
mem[li] = 0.0f;
// memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float));
System.arraycopy(decresidual, (start - 1) * ilbc_constants.SUBL,
mem, ilbc_constants.CB_MEML - ilbc_constants.STATE_LEN,
ilbc_constants.STATE_LEN);
// memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL,
// STATE_LEN*sizeof(float));
/* loop over sub-frames to encode */
for (subframe=0; subframe<Nfor; subframe++) {
/* construct decoded vector */
ilbc_common.iCBConstruct(decresidual, (start+1+subframe)*ilbc_constants.SUBL,
cb_index, subcount*ilbc_constants.CB_NSTAGES,
gain_index, subcount*ilbc_constants.CB_NSTAGES,
mem, ilbc_constants.CB_MEML-ilbc_constants.memLfTbl[subcount],
ilbc_constants.memLfTbl[subcount], ilbc_constants.SUBL,
ilbc_constants.CB_NSTAGES);
/* update memory */
System.arraycopy(mem, ilbc_constants.SUBL,
mem, 0,
ilbc_constants.CB_MEML - ilbc_constants.SUBL);
// memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));
System.arraycopy(decresidual, (start + 1 + subframe) * ilbc_constants.SUBL,
mem, ilbc_constants.CB_MEML - ilbc_constants.SUBL,
ilbc_constants.SUBL);
// memcpy(mem+CB_MEML-SUBL,
// &decresidual[(start+1+subframe)*SUBL],
// SUBL*sizeof(float));
subcount++;
}
}
/* backward prediction of sub-frames */
Nback = start-1;
if ( Nback > 0 ) {
/* setup memory */
meml_gotten = ilbc_constants.SUBL*(this.ULP_inst.nsub+1-start);
if ( meml_gotten > ilbc_constants.CB_MEML ) {
meml_gotten = ilbc_constants.CB_MEML;
}
for (k=0; k<meml_gotten; k++) {
mem[ilbc_constants.CB_MEML-1-k] = decresidual[(start-1)*ilbc_constants.SUBL + k];
}
for (int li = 0; li < (ilbc_constants.CB_MEML - k); li++)
mem[li] = 0.0f;
// memset(mem, 0, (ilbc_constants.CB_MEML-k)*sizeof(float));
/* loop over subframes to decode */
for (subframe=0; subframe<Nback; subframe++) {
/* construct decoded vector */
ilbc_common.iCBConstruct(reverseDecresidual, subframe * ilbc_constants.SUBL,
cb_index, subcount * ilbc_constants.CB_NSTAGES,
gain_index, subcount * ilbc_constants.CB_NSTAGES,
mem, ilbc_constants.CB_MEML - ilbc_constants.memLfTbl[subcount],
ilbc_constants.memLfTbl[subcount], ilbc_constants.SUBL,
ilbc_constants.CB_NSTAGES);
/* update memory */
System.arraycopy(mem, ilbc_constants.SUBL,
mem, 0,
ilbc_constants.CB_MEML - ilbc_constants.SUBL);
// memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));
System.arraycopy(reverseDecresidual, subframe * ilbc_constants.SUBL,
mem, ilbc_constants.CB_MEML - ilbc_constants.SUBL,
ilbc_constants.SUBL);
// memcpy(mem+CB_MEML-SUBL,
// &reverseDecresidual[subframe*SUBL],
// SUBL*sizeof(float));
subcount++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -