📄 ilbc_encoder.java
字号:
}
/* from anaFilter.c, perform LP analysis filtering */
private void anaFilter(float In[], int in_idx, float a[], int a_idx, int len, float Out[], int out_idx, float mem[])
{
int i, j;
int po, pi, pm, pa;
po = out_idx;
/* Filter first part using memory from past */
for (i = 0; i < ilbc_constants.LPC_FILTERORDER; i++) {
pi = in_idx + i;
pm = ilbc_constants.LPC_FILTERORDER - 1;
pa = a_idx;
Out[po] = 0.0f;
for (j=0; j<=i; j++) {
Out[po] += a[pa] * In[pi];
pa++;
pi--;
}
for (j=i+1; j < ilbc_constants.LPC_FILTERORDER+1; j++) {
Out[po] += a[pa] * mem[pm];
pa++;
pm--;
}
po++;
}
/* Filter last part where the state is entirely
in the input vector */
for (i = ilbc_constants.LPC_FILTERORDER; i<len; i++) {
pi = in_idx + i;
pa = a_idx;
Out[po] = 0.0f;
for (j = 0; j < ilbc_constants.LPC_FILTERORDER+1; j++) {
Out[po] += a[pa] * In[pi];
pa++;
pi--;
}
po++;
}
/* Update state vector */
System.arraycopy(In, in_idx + len - ilbc_constants.LPC_FILTERORDER, mem, 0, ilbc_constants.LPC_FILTERORDER);
}
/*----------------------------------------------------------------*
* Construct an additional codebook vector by filtering the
* initial codebook buffer. This vector is then used to expand
* the codebook with an additional section.
*---------------------------------------------------------------*/
private void filteredCBvecs(float cbvectors[], float mem[], int mem_idx, int lMem)
{
int i, j, k;
int pp, pp1;
float tempbuff2[];
int pos;
tempbuff2 = new float [ilbc_constants.CB_MEML+ilbc_constants.CB_FILTERLEN];
for (i = 0; i < ilbc_constants.CB_HALFFILTERLEN; i++)
tempbuff2[i] = 0.0f;
System.arraycopy(mem, mem_idx, tempbuff2, ilbc_constants.CB_HALFFILTERLEN - 1, lMem);
for (i = lMem + ilbc_constants.CB_HALFFILTERLEN - 1; i < lMem + ilbc_constants.CB_FILTERLEN; i++)
tempbuff2[i] = 0.0f;
/* Create codebook vector for higher section by filtering */
/* do filtering */
pos=0;
for (i = 0; i < lMem; i++)
cbvectors[i] = 0;
for (k = 0; k < lMem; k++) {
// pp=&tempbuff2[k];
pp = k;
// pp1=&cbfiltersTbl[CB_FILTERLEN-1];
pp1 = ilbc_constants.CB_FILTERLEN - 1;
for (j = 0;j < ilbc_constants.CB_FILTERLEN;j++) {
cbvectors[pos] += tempbuff2[pp] * ilbc_constants.cbfiltersTbl[pp1];
pp++;
pp1--;
}
pos++;
}
}
/*----------------------------------------------------------------*
* Search the augmented part of the codebook to find the best
* measure.
*----------------------------------------------------------------*/
private void searchAugmentedCB(
int low, /* (i) Start index for the search */
int high, /* (i) End index for the search */
int stage, /* (i) Current stage */
int startIndex, /* (i) Codebook index for the first
aug vector */
float target[], /* (i) Target vector for encoding */
float buffer[], /* (i) Pointer to the end of the buffer for
augmented codebook construction */
int buffer_idx,
float max_measure[], /* (i/o) Currently maximum measure */
int best_index[],/* (o) Currently the best index */
float gain[], /* (o) Currently the best gain */
float energy[], /* (o) Energy of augmented codebook
vectors */
float invenergy[]/* (o) Inv energy of augmented codebook
vectors */
)
{
int icount, ilow, j, tmpIndex;
int pp, ppo, ppi, ppe;
float crossDot, alfa;
float weighted, measure, nrjRecursive;
float ftmp;
/* Compute the energy for the first (low-5)
noninterpolated samples */
// for (pp = 0; pp < buffer.length; pp++)
// System.out.println("buffer[" + (pp - buffer_idx) + "] = " + buffer[pp]);
nrjRecursive = (float) 0.0f;
// pp = buffer - low + 1;
pp = 1 - low + buffer_idx;
for (j=0; j<(low-5); j++) {
nrjRecursive += ( buffer[pp] * buffer[pp] );
pp++;
}
ppe = buffer_idx - low;
// System.out.println("energie recursive " + nrjRecursive);
for (icount=low; icount<=high; icount++) {
/* Index of the codebook vector used for retrieving
energy values */
tmpIndex = startIndex+icount-20;
ilow = icount-4;
/* Update the energy recursively to save complexity */
nrjRecursive = nrjRecursive + buffer[ppe] * buffer[ppe];
ppe--;
energy[tmpIndex] = nrjRecursive;
/* Compute cross dot product for the first (low-5)
samples */
crossDot = (float) 0.0f;
pp = buffer_idx - icount;
for (j = 0; j < ilow; j++) {
crossDot += target[j]*buffer[pp];
pp++;
}
/* interpolation */
alfa = (float) 0.2;
ppo = buffer_idx - 4;
ppi = buffer_idx - icount - 4;
for (j=ilow; j<icount; j++) {
weighted = ((float)1.0f-alfa)*(buffer[ppo])+alfa*(buffer[ppi]);
ppo++;
ppi++;
energy[tmpIndex] += weighted*weighted;
crossDot += target[j]*weighted;
alfa += (float)0.2;
}
/* Compute energy and cross dot product for the
remaining samples */
pp = buffer_idx - icount;
for (j=icount; j < ilbc_constants.SUBL; j++) {
energy[tmpIndex] += buffer[pp] * buffer[pp];
crossDot += target[j]*buffer[pp];
pp++;
}
if (energy[tmpIndex]>0.0f) {
invenergy[tmpIndex]=(float)1.0f/(energy[tmpIndex] + ilbc_constants.EPS);
} else {
invenergy[tmpIndex] = (float) 0.0f;
}
if (stage==0) {
measure = (float)-10000000.0f;
if (crossDot > 0.0f) {
measure = crossDot*crossDot*invenergy[tmpIndex];
}
}
else {
measure = crossDot*crossDot*invenergy[tmpIndex];
}
/* check if measure is better */
ftmp = crossDot*invenergy[tmpIndex];
// System.out.println("on compare " + measure + " et " + max_measure[0]);
// System.out.println("ainsi que " + Math.abs(ftmp) + " et " + ilbc_constants.CB_MAXGAIN);
if ((measure>max_measure[0]) && ((float)Math.abs(ftmp) < ilbc_constants.CB_MAXGAIN)) {
// System.out.println("new best index at " + tmpIndex + ", where icount = " + icount);
best_index[0] = tmpIndex;
max_measure[0] = measure;
gain[0] = ftmp;
}
}
}
/*----------------------------------------------------------------*
* Recreate a specific codebook vector from the augmented part.
*
*----------------------------------------------------------------*/
private void createAugmentedVec(int index, float buffer[], int buffer_idx, float cbVec[])
{
int ilow, j;
int pp, ppo, ppi;
float alfa, alfa1, weighted;
ilow = index - 5;
/* copy the first noninterpolated part */
pp = buffer_idx - index;
System.arraycopy(buffer, pp, cbVec, 0, index);
// memcpy(cbVec,pp,sizeof(float)*index);
/* interpolation */
alfa1 = (float)0.2;
alfa = 0.0f;
// ppo = buffer-5;
ppo = buffer_idx - 5;
// ppi = buffer-index-5;
ppi = buffer_idx - index - 5;
for (j=ilow; j<index; j++) {
// weighted = ((float)1.0f-alfa)*(*ppo)+alfa*(*ppi);
weighted = (1.0f - alfa) * buffer[ppo] + alfa * buffer[ppi];
ppo++;
ppi++;
cbVec[j] = weighted;
alfa += alfa1;
}
/* copy the second noninterpolated part */
// pp = buffer - index;
pp = buffer_idx - index;
// memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));
System.arraycopy(buffer, pp, cbVec, index, ilbc_constants.SUBL - index);
}
public ilbc_encoder(int init_mode) throws Error
{
mode = init_mode;
if ( (mode == 30) || (mode == 20) )
{
ULP_inst = new ilbc_ulp(mode);
}
else
{
throw(new Error("invalid mode"));
}
anaMem = new float[ilbc_constants.LPC_FILTERORDER];
lsfold = new float[ilbc_constants.LPC_FILTERORDER];
lsfdeqold = new float[ilbc_constants.LPC_FILTERORDER];
lpc_buffer = new float[ilbc_constants.LPC_LOOKBACK + ilbc_constants.BLOCKL_MAX];
hpimem = new float[4];
for (int li = 0; li < anaMem.length; li++)
anaMem[li] = 0.0f;
System.arraycopy(ilbc_constants.lsfmeanTbl, 0, this.lsfdeqold, 0,
ilbc_constants.LPC_FILTERORDER);
// for (int li = 0; li < lsfold.length; li++)
// lsfold[li] = 0.0f;
System.arraycopy(ilbc_constants.lsfmeanTbl, 0, this.lsfold, 0,
ilbc_constants.LPC_FILTERORDER);
// for (int li = 0; li < lsfdeqold.length; li++)
// lsfdeqold[li] = 0.0f;
for (int li = 0; li < lpc_buffer.length; li++)
lpc_buffer[li] = 0.0f;
for (int li = 0; li < hpimem.length; li++)
hpimem[li] = 0.0f;
// memset((*iLBCenc_inst).anaMem, 0,
// LPC_FILTERORDER*sizeof(float));
// memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl,
// LPC_FILTERORDER*sizeof(float));
// memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl,
// LPC_FILTERORDER*sizeof(float));
// memset((*iLBCenc_inst).lpc_buffer, 0,
// (LPC_LOOKBACK+BLOCKL_MAX)*sizeof(float));
// memset((*iLBCenc_inst).hpimem, 0, 4*sizeof(float));
// return (iLBCenc_inst->no_of_bytes);
}
// public int encode(short encoded_data[], short data[])
// {
// for (int i = 0; i < encoded_data.length; i ++) {
// data[i%data.length] = encoded_data[i];
// }
// if (mode == 20)
// return ilbc_constants.BLOCKL_20MS;
// else
// return ilbc_constants.BLOCKL_30MS;
// }
public short encode(short encoded_data[], short data[])
{
float block[] = new float [this.ULP_inst.blockl];
bitstream en_data = new bitstream(this.ULP_inst.no_of_bytes * 2);
// char en_data[] = new char [this.ULP_inst.no_of_bytes];
int k;
/* convert signal to float */
for (k=0; k<this.ULP_inst.blockl; k++)
block[k] = (float) data[k];
// for (int li = 0; li < block.length; li++)
// System.out.println("block " + li + " : " + block[li]);
/* do the actual encoding */
iLBC_encode(en_data, block);
for (k=0; k < encoded_data.length; k++)
encoded_data[k] = (short) (((en_data.buffer[2*k] << 8) & 0xff00) | ( ((short) en_data.buffer[2*k+1]) & 0x00ff));
return ((short) this.ULP_inst.no_of_bytes);
}
public void iLBC_encode(
bitstream bytes, /* (o) encoded data bits iLBC */
float block[]) /* (o) speech vector to encode */
{
int start;
int [] idxForMax = new int[1];
int n, k, meml_gotten, Nfor, Nback, i, pos;
// unsigned char *pbytes;
int pbytes;
int diff, start_pos, state_first;
float en1, en2;
int index, ulp;
// int [] firstpart = new int[1];
int firstpart;
int subcount, subframe;
float [] data = new float[ilbc_constants.BLOCKL_MAX];
float [] residual = new float[ilbc_constants.BLOCKL_MAX];
float [] reverseResidual = new float[ilbc_constants.BLOCKL_MAX];
int [] idxVec = new int[ilbc_constants.STATE_LEN];
float [] reverseDecresidual = new
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -