?? ilbc_decoder.java
字號(hào):
/*
* 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;
import java.lang.*;
/**
* @author Jean Lorchat
*/
class ilbc_decoder {
int consPLICount;
int prevPLI;
int prevLag;
int last_lag;
int prev_enh_pl;
float per;
float prevResidual[];
long seed;
float prevLpc[];
ilbc_ulp ULP_inst = null;
float syntMem[];
float lsfdeqold[];
float old_syntdenum[];
float hpomem[];
int use_enhancer;
float enh_buf[];
float enh_period[];
// La plupart des variables globales sont dans ilbc_constants.etc...
void syntFilter(
float Out[], /* (i/o) Signal to be filtered */
int Out_idx,
float a[], /* (i) LP parameters */
int a_idx,
int len, /* (i) Length of signal */
float mem[]) /* (i/o) Filter state */
{
int i, j;
// float *po, *pi, *pa, *pm;
int po, pi, pa, pm;
// System.out.println("out size : " + Out.length);
// System.out.println("out idx : " + Out_idx);
// System.out.println("a size : " + a.length);
// System.out.println("a idx : " + a_idx);
// System.out.println("len : " + len);
// System.out.println("mem size : " + mem.length);
po = Out_idx;
/* Filter first part using memory from past */
for (i=0; i<ilbc_constants.LPC_FILTERORDER; i++) {
// pi=&Out[i-1];
// pa=&a[1];
// pm=&mem[LPC_FILTERORDER-1];
pi = Out_idx + i - 1;
pa = a_idx + 1;
pm = ilbc_constants.LPC_FILTERORDER - 1;
for (j=1; j<=i; j++) {
// *po-=(*pa++)*(*pi--);
// System.out.println("1 Soustraction (" + i + "," + j + ") a " + Out[po] + " de " + a[pa] + " * " + Out[pi]);
// System.out.println("index " + (po - Out_idx) + " <> " + (pi - Out_idx));
Out[po] -= a[pa] * Out[pi];
// System.out.println("Pour un resultat de " + Out[po]);
pa++;
pi--;
}
for (j=i+1; j < ilbc_constants.LPC_FILTERORDER+1; j++) {
// *po-=(*pa++)*(*pm--);
// System.out.println("2 Soustraction a " + Out[po] + " de " + a[pa] + " * " + mem[pm]);
Out[po] -= a[pa] * mem[pm];
// System.out.println("Pour un resultat de " + Out[po]);
pa++;
pm--;
}
po++;
}
/* Filter last part where the state is entirely in
the output vector */
for (i = ilbc_constants.LPC_FILTERORDER; i < len; i++) {
// pi=&Out[i-1];
pi = Out_idx + i - 1;
// pa=&a[1];
pa = a_idx + 1;
for (j=1; j < ilbc_constants.LPC_FILTERORDER+1; j++) {
// *po-=(*pa++)*(*pi--);
// System.out.println("3 Soustraction a " + Out[po] + " de " + a[pa] + " * " + Out[pi]);
Out[po] -= a[pa] * Out[pi];
// System.out.println("Pour un resultat de " + Out[po]);
pa++;
pi--;
}
po++;
}
/* Update state vector */
System.arraycopy(Out, Out_idx + len - ilbc_constants.LPC_FILTERORDER,
mem, 0, ilbc_constants.LPC_FILTERORDER);
// memcpy(mem, &Out[len-LPC_FILTERORDER],
// LPC_FILTERORDER*sizeof(float));
}
/*---------------------------------------------------------------*
* interpolation of lsf coefficients for the decoder
*--------------------------------------------------------------*/
public void LSFinterpolate2a_dec(
float a[], /* (o) lpc coefficients for a sub-frame */
float lsf1[], /* (i) first lsf coefficient vector */
float lsf2[], /* (i) second lsf coefficient vector */
int lsf2_idx,
float coef, /* (i) interpolation weight */
int length /* (i) length of lsf vectors */
){
float [] lsftmp = new float[ilbc_constants.LPC_FILTERORDER];
ilbc_common.interpolate(lsftmp, lsf1, lsf2, lsf2_idx, coef, length);
ilbc_common.lsf2a(a, lsftmp);
}
/*---------------------------------------------------------------*
* obtain dequantized lsf coefficients from quantization index
*--------------------------------------------------------------*/
void SimplelsfDEQ(
float lsfdeq[], /* (o) dequantized lsf coefficients */
int index[], /* (i) quantization index */
int lpc_n /* (i) number of LPCs */
){
int i, j, pos, cb_pos;
/* decode first LSF */
pos = 0;
cb_pos = 0;
for (i = 0; i < ilbc_constants.LSF_NSPLIT; i++) {
for (j = 0; j < ilbc_constants.dim_lsfCbTbl[i]; j++) {
lsfdeq[pos + j] = ilbc_constants.lsfCbTbl[cb_pos + (int)
((long)(index[i])*ilbc_constants.dim_lsfCbTbl[i] + j)];
}
pos += ilbc_constants.dim_lsfCbTbl[i];
cb_pos += ilbc_constants.size_lsfCbTbl[i]*ilbc_constants.dim_lsfCbTbl[i];
}
if (lpc_n>1) {
/* decode last LSF */
pos = 0;
cb_pos = 0;
for (i = 0; i < ilbc_constants.LSF_NSPLIT; i++) {
for (j = 0; j < ilbc_constants.dim_lsfCbTbl[i]; j++) {
lsfdeq[ilbc_constants.LPC_FILTERORDER + pos + j] =
ilbc_constants.lsfCbTbl[cb_pos + (int)
((long)(index[ilbc_constants.LSF_NSPLIT + i])*
ilbc_constants.dim_lsfCbTbl[i]) + j];
}
pos += ilbc_constants.dim_lsfCbTbl[i];
cb_pos += ilbc_constants.size_lsfCbTbl[i]*ilbc_constants.dim_lsfCbTbl[i];
}
}
}
/*----------------------------------------------------------------*
* obtain synthesis and weighting filters form lsf coefficients
*---------------------------------------------------------------*/
void DecoderInterpolateLSF(
float syntdenum[], /* (o) synthesis filter coefficients */
float weightdenum[], /* (o) weighting denumerator
coefficients */
float lsfdeq[], /* (i) dequantized lsf coefficients */
int length) /* (i) length of lsf coefficient vector */
{
int i, pos, lp_length;
float [] lp = new float[ilbc_constants.LPC_FILTERORDER + 1];
int lsfdeq2;
lsfdeq2 = length;
// lsfdeq2 = lsfdeq + length;
lp_length = length + 1;
if (this.ULP_inst.mode==30) {
/* sub-frame 1: Interpolation between old and first */
LSFinterpolate2a_dec(lp, this.lsfdeqold, lsfdeq, 0,
ilbc_constants.lsf_weightTbl_30ms[0], length);
System.arraycopy(lp, 0, syntdenum, 0, lp_length);
// memcpy(syntdenum,lp,lp_length*sizeof(float));
ilbc_common.bwexpand(weightdenum, 0, lp, ilbc_constants.LPC_CHIRP_WEIGHTDENUM, lp_length);
/* sub-frames 2 to 6: interpolation between first
and last LSF */
pos = lp_length;
for (i = 1; i < 6; i++) {
LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq, lsfdeq2,
ilbc_constants.lsf_weightTbl_30ms[i], length);
System.arraycopy(lp, 0, syntdenum, pos, lp_length);
// memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
ilbc_common.bwexpand(weightdenum, pos, lp,
ilbc_constants.LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
}
else {
pos = 0;
for (i = 0; i < this.ULP_inst.nsub; i++) {
LSFinterpolate2a_dec(lp, this.lsfdeqold,
lsfdeq, 0, ilbc_constants.lsf_weightTbl_20ms[i], length);
System.arraycopy(lp, 0, syntdenum, pos, lp_length);
// memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
ilbc_common.bwexpand(weightdenum, pos, lp, ilbc_constants.LPC_CHIRP_WEIGHTDENUM,
lp_length);
pos += lp_length;
}
}
/* update memory */
if (this.ULP_inst.mode==30) {
System.arraycopy(lsfdeq, lsfdeq2, this.lsfdeqold, 0, length);
// memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, length*sizeof(float));
} else {
System.arraycopy(lsfdeq, 0, this.lsfdeqold, 0, length);
// memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, length*sizeof(float));
}
}
public void index_conv_dec(int index[]) /* (i/o) Codebook indexes */
{
int k;
for (k=1; k<ilbc_constants.CB_NSTAGES; k++) {
if ((index[k]>=44)&&(index[k]<108)) {
index[k]+=64;
} else if ((index[k]>=108)&&(index[k]<128)) {
index[k]+=128;
} else {
/* ERROR */
}
}
}
public void hpOutput(
float In[], /* (i) vector to filter */
int len,/* (i) length of vector to filter */
float Out[], /* (o) the resulting filtered vector */
float mem[]) /* (i/o) the filter state */
{
int i;
// float *pi, *po;
int pi, po;
/* all-zero section*/
// pi = &In[0];
// po = &Out[0];
pi = 0;
po = 0;
for (i=0; i<len; i++) {
Out[po] = ilbc_constants.hpo_zero_coefsTbl[0] * (In[pi]);
Out[po] += ilbc_constants.hpo_zero_coefsTbl[1] * mem[0];
Out[po] += ilbc_constants.hpo_zero_coefsTbl[2] * mem[1];
mem[1] = mem[0];
mem[0] = In[pi];
po++;
pi++;
}
/* all-pole section*/
// po = &Out[0];
po = 0;
for (i=0; i<len; i++) {
Out[po] -= ilbc_constants.hpo_pole_coefsTbl[1] * mem[2];
Out[po] -= ilbc_constants.hpo_pole_coefsTbl[2] * mem[3];
mem[3] = mem[2];
mem[2] = Out[po];
po++;
}
}
/*----------------------------------------------------------------*
* downsample (LP filter and decimation)
*---------------------------------------------------------------*/
void DownSample (
float In[], /* (i) input samples */
int in_idx,
float Coef[], /* (i) filter coefficients */
int lengthIn, /* (i) number of input samples */
float state[], /* (i) filter state */
float Out[]) /* (o) downsampled output */
{
float o;
// float *Out_ptr = Out;
int out_ptr = 0;
//float *Coef_ptr, *In_ptr;
int coef_ptr = 0;
int in_ptr = in_idx;
//float *state_ptr;
int state_ptr = 0;
int i, j, stop;
/* LP filter and decimate at the same time */
for (i = ilbc_constants.DELAY_DS; i < lengthIn; i += ilbc_constants.FACTOR_DS)
{
coef_ptr = 0;
in_ptr = in_idx + i;
state_ptr = ilbc_constants.FILTERORDER_DS - 2;
o = (float)0.0f;
// stop = (i < ilbc_constants.FILTERORDER_DS) ? i + 1 : ilbc_constants.FILTERORDER_DS;
if (i < ilbc_constants.FILTERORDER_DS) {
stop = i + 1;
}
else {
stop = ilbc_constants.FILTERORDER_DS;
}
for (j = 0; j < stop; j++)
{
o += Coef[coef_ptr] * In[in_ptr];
coef_ptr++;
in_ptr--;
}
for (j = i + 1; j < ilbc_constants.FILTERORDER_DS; j++)
{
o += Coef[coef_ptr] * state[state_ptr];
coef_ptr++;
state_ptr--;
}
Out[out_ptr] = o;
out_ptr++;
// *Out_ptr++ = o;
}
/* Get the last part (use zeros as input for the future) */
for (i=(lengthIn+ilbc_constants.FACTOR_DS); i<(lengthIn+ilbc_constants.DELAY_DS);
i+=ilbc_constants.FACTOR_DS) {
o=(float)0.0f;
if (i<lengthIn) {
coef_ptr = 0;
in_ptr = in_idx + i;
for (j=0; j<ilbc_constants.FILTERORDER_DS; j++) {
o += Coef[coef_ptr] * Out[out_ptr];
coef_ptr++;
out_ptr--;
// o += *Coef_ptr++ * (*Out_ptr--);
}
} else {
coef_ptr = i-lengthIn;
in_ptr = in_idx + lengthIn - 1;
for (j=0; j<ilbc_constants.FILTERORDER_DS-(i-lengthIn); j++) {
o += Coef[coef_ptr] * In[in_ptr];
coef_ptr++;
in_ptr--;
}
}
Out[out_ptr] = o;
out_ptr++;
}
}
/*----------------------------------------------------------------*
* Find index in array such that the array element with said
* index is the element of said array closest to "value"
* according to the squared-error criterion
*---------------------------------------------------------------*/
public int NearestNeighbor(
// int index[], /* (o) index of array element closest
// to value */
float array[], /* (i) data array */
float value,/* (i) value */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -