📄 ilbc_encoder.java
字号:
/*
* 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_encoder {
/* encoding mode, either 20 or 30 ms */
int mode;
/* analysis filter state */
float anaMem[];//LPC_FILTERORDER];
/* old lsf parameters for interpolation */
float lsfold[]; //LPC_FILTERORDER];
float lsfdeqold[]; //LPC_FILTERORDER];
/* signal buffer for LP analysis */
float lpc_buffer[]; //LPC_LOOKBACK + BLOCKL_MAX];
/* state of input HP filter */
float hpimem[]; //4];
ilbc_ulp ULP_inst = null;
/* encoder methods start here */
/*----------------------------------------------------------------*
* predictive noise shaping encoding of scaled start state
* (subrutine for StateSearchW)
*---------------------------------------------------------------*/
void AbsQuantW(
float in[], /* (i) vector to encode */
int in_idx,
float syntDenum[], /* (i) denominator of synthesis filter */
int syntDenum_idx,
float weightDenum[], /* (i) denominator of weighting filter */
int weightDenum_idx,
int out[], /* (o) vector of quantizer indexes */
int len, /* (i) length of vector to encode and
vector of quantizer indexes */
int state_first /* (i) position of start state in the
80 vec */
){
// float *syntOut;
int syntOut;
float [] syntOutBuf = new float[ilbc_constants.LPC_FILTERORDER +
ilbc_constants.STATE_SHORT_LEN_30MS];
float toQ, xq;
int n;
int [] index = new int[1];
/* initialization of buffer for filtering */
for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) {
syntOutBuf[li] = 0.0f;
}
// memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
/* initialization of pointer for filtering */
// syntOut = &syntOutBuf[LPC_FILTERORDER];
syntOut = ilbc_constants.LPC_FILTERORDER;
/* synthesis and weighting filters on input */
if (state_first != 0) {
ilbc_common.AllPoleFilter (in, in_idx, weightDenum, weightDenum_idx,
ilbc_constants.SUBL, ilbc_constants.LPC_FILTERORDER);
} else {
ilbc_common.AllPoleFilter (in, in_idx, weightDenum, weightDenum_idx,
this.ULP_inst.state_short_len - ilbc_constants.SUBL,
ilbc_constants.LPC_FILTERORDER);
}
/* encoding loop */
for (n=0; n<len; n++) {
/* time update of filter coefficients */
if ((state_first != 0)&&(n==ilbc_constants.SUBL)){
syntDenum_idx += (ilbc_constants.LPC_FILTERORDER+1);
weightDenum_idx += (ilbc_constants.LPC_FILTERORDER+1);
/* synthesis and weighting filters on input */
ilbc_common.AllPoleFilter (in, in_idx + n, weightDenum, weightDenum_idx,
len-n, ilbc_constants.LPC_FILTERORDER);
} else if ((state_first==0)&&
(n==(this.ULP_inst.state_short_len-ilbc_constants.SUBL))) {
syntDenum_idx += (ilbc_constants.LPC_FILTERORDER+1);
weightDenum_idx += (ilbc_constants.LPC_FILTERORDER+1);
/* synthesis and weighting filters on input */
ilbc_common.AllPoleFilter (in, in_idx + n, weightDenum, weightDenum_idx, len-n,
ilbc_constants.LPC_FILTERORDER);
}
/* prediction of synthesized and weighted input */
syntOutBuf[syntOut + n] = 0.0f;
ilbc_common.AllPoleFilter (syntOutBuf, syntOut + n, weightDenum, weightDenum_idx,
1, ilbc_constants.LPC_FILTERORDER);
/* quantization */
toQ = in[in_idx+n] - syntOutBuf[syntOut+n];
xq = sort_sq(index, 0, toQ, ilbc_constants.state_sq3Tbl, 8);
out[n]=index[0];
syntOutBuf[syntOut + n] = ilbc_constants.state_sq3Tbl[out[n]];
/* update of the prediction filter */
ilbc_common.AllPoleFilter(syntOutBuf, syntOut + n, weightDenum, weightDenum_idx,
1, ilbc_constants.LPC_FILTERORDER);
}
}
/*----------------------------------------------------------------*
* encoding of start state
*---------------------------------------------------------------*/
void StateSearchW(
float residual[],/* (i) target residual vector */
int residual_idx,
float syntDenum[], /* (i) lpc synthesis filter */
int syntDenum_idx,
float weightDenum[], /* (i) weighting filter denuminator */
int weightDenum_idx,
int idxForMax[], /* (o) quantizer index for maximum
amplitude */
int idxVec[], /* (o) vector of quantization indexes */
int len, /* (i) length of all vectors */
int state_first) /* (i) position of start state in the
80 vec */
{
float dtmp, maxVal;
float [] tmpbuf = new float[ilbc_constants.LPC_FILTERORDER +
2 * ilbc_constants.STATE_SHORT_LEN_30MS];
// float *tmp,
int tmp;
float [] numerator = new float[1+ilbc_constants.LPC_FILTERORDER];
float [] foutbuf = new float[ilbc_constants.LPC_FILTERORDER +
2 * ilbc_constants.STATE_SHORT_LEN_30MS];
//, *fout;
int fout;
int k;
float qmax, scal;
/* initialization of buffers and filter coefficients */
for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) {
tmpbuf[li] = 0.0f;
foutbuf[li] = 0.0f;
}
// memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
// memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
for (k=0; k < ilbc_constants.LPC_FILTERORDER; k++) {
numerator[k]=syntDenum[syntDenum_idx+ilbc_constants.LPC_FILTERORDER-k];
}
numerator[ilbc_constants.LPC_FILTERORDER]=syntDenum[syntDenum_idx];
// tmp = &tmpbuf[LPC_FILTERORDER];
tmp = ilbc_constants.LPC_FILTERORDER;
// fout = &foutbuf[LPC_FILTERORDER];
fout = ilbc_constants.LPC_FILTERORDER;
/* circular convolution with the all-pass filter */
System.arraycopy(residual, residual_idx, tmpbuf, tmp, len);
// memcpy(tmp, residual, len*sizeof(float));
for (int li = 0; li < len; li++)
tmpbuf[tmp+len+li] = 0.0f;
// memset(tmp+len, 0, len*sizeof(float));
ilbc_common.ZeroPoleFilter(tmpbuf, tmp, numerator,
syntDenum, syntDenum_idx, 2*len,
ilbc_constants.LPC_FILTERORDER, foutbuf, fout);
for (k=0; k<len; k++) {
foutbuf[fout+k] += foutbuf[fout+k+len];
}
/* identification of the maximum amplitude value */
maxVal = foutbuf[fout+0];
for (k=1; k<len; k++) {
if (foutbuf[fout+k]*foutbuf[fout+k] > maxVal*maxVal){
maxVal = foutbuf[fout+k];
}
}
maxVal=(float)Math.abs(maxVal);
/* encoding of the maximum amplitude value */
if (maxVal < 10.0f) {
maxVal = 10.0f;
}
// log10 is since 1.5
//maxVal = (float)Math.log10(maxVal);
maxVal = (float)(Math.log(maxVal)/Math.log(10));
dtmp = sort_sq(idxForMax, 0, maxVal, ilbc_constants.state_frgqTbl, 64);
/* decoding of the maximum amplitude representation value,
and corresponding scaling of start state */
maxVal = ilbc_constants.state_frgqTbl[idxForMax[0]];
qmax = (float)Math.pow(10,maxVal);
scal = 4.5f / qmax;
for (k=0; k<len; k++){
foutbuf[fout+k] *= scal;
}
/* predictive noise shaping encoding of scaled start state */
AbsQuantW(foutbuf, fout,syntDenum, syntDenum_idx,
weightDenum, weightDenum_idx, idxVec, len, state_first);
}
/*----------------------------------------------------------------*
* conversion from lpc coefficients to lsf coefficients
*---------------------------------------------------------------*/
void a2lsf(
float freq[],/* (o) lsf coefficients */
int freq_idx,
float a[]) /* (i) lpc coefficients */
{
float [] steps = {(float)0.00635f, (float)0.003175f, (float)0.0015875f,
(float)0.00079375f};
float step;
int step_idx;
int lsp_index;
float [] p = new float[ilbc_constants.LPC_HALFORDER];
float [] q = new float[ilbc_constants.LPC_HALFORDER];
float [] p_pre = new float[ilbc_constants.LPC_HALFORDER];
float [] q_pre = new float[ilbc_constants.LPC_HALFORDER];
int old_p = 0, old_q = 1;
//float *old;
float [] olds = new float[2];
int old;
// float *pq_coef;
float [] pq_coef;
float omega, old_omega;
int i;
float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;
for (i=0; i < ilbc_constants.LPC_HALFORDER; i++) {
p[i] = (float)-1.0f * (a[i + 1] + a[ilbc_constants.LPC_FILTERORDER - i]);
q[i] = a[ilbc_constants.LPC_FILTERORDER - i] - a[i + 1];
}
p_pre[0] = (float) -1.0f - p[0];
p_pre[1] = - p_pre[0] - p[1];
p_pre[2] = - p_pre[1] - p[2];
p_pre[3] = - p_pre[2] - p[3];
p_pre[4] = - p_pre[3] - p[4];
p_pre[4] = p_pre[4] / 2;
q_pre[0] = (float) 1.0f - q[0];
q_pre[1] = q_pre[0] - q[1];
q_pre[2] = q_pre[1] - q[2];
q_pre[3] = q_pre[2] - q[3];
q_pre[4] = q_pre[3] - q[4];
q_pre[4] = q_pre[4] / 2;
omega = 0.0f;
old_omega = 0.0f;
olds[old_p] = ilbc_constants.DOUBLE_MAX;
olds[old_q] = ilbc_constants.DOUBLE_MAX;
/* Here we loop through lsp_index to find all the
LPC_FILTERORDER roots for omega. */
for (lsp_index = 0; lsp_index < ilbc_constants.LPC_FILTERORDER; lsp_index++) {
/* Depending on lsp_index being even or odd, we
alternatively solve the roots for the two LSP equations. */
if ((lsp_index & 0x1) == 0) {
pq_coef = p_pre;
old = old_p;
} else {
pq_coef = q_pre;
old = old_q;
}
/* Start with low resolution grid */
for (step_idx = 0, step = steps[step_idx];
step_idx < ilbc_constants.LSF_NUMBER_OF_STEPS;){
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +
pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
hlp = (float)Math.cos(omega * ilbc_constants.TWO_PI);
hlp1 = 2.0f * hlp + pq_coef[0];
hlp2 = 2.0f * hlp * hlp1 - (float)1.0 + pq_coef[1];
hlp3 = 2.0f * hlp * hlp2 - hlp1 + pq_coef[2];
hlp4 = 2.0f * hlp * hlp3 - hlp2 + pq_coef[3];
hlp5 = hlp * hlp4 - hlp3 + pq_coef[4];
if (((hlp5 * (olds[old])) <= 0.0f) || (omega >= 0.5)){
if (step_idx == (ilbc_constants.LSF_NUMBER_OF_STEPS - 1)){
if ((float)Math.abs(hlp5) >= Math.abs(olds[old])) {
//System.out.println("acces index " + freq_idx + lsp_index);
freq[freq_idx+lsp_index] = omega - step;
} else {
//System.out.println("acces index " + freq_idx + lsp_index);
freq[freq_idx+lsp_index] = omega;
}
if ((olds[old]) >= 0.0f){
olds[old] = -1.0f * ilbc_constants.DOUBLE_MAX;
} else {
olds[old] = ilbc_constants.DOUBLE_MAX;
}
omega = old_omega;
step_idx = 0;
step_idx = ilbc_constants.LSF_NUMBER_OF_STEPS;
} else {
if (step_idx == 0) {
old_omega = omega;
}
step_idx++;
omega -= steps[step_idx];
/* Go back one grid step */
step = steps[step_idx];
}
} else {
/* increment omega until they are of different sign,
and we know there is at least one root between omega
and old_omega */
olds[old] = hlp5;
omega += step;
}
}
}
for (i = 0; i < ilbc_constants.LPC_FILTERORDER; i++) {
//System.out.println("acces index " + freq_idx + i);
freq[freq_idx+i] = freq[freq_idx+i] * ilbc_constants.TWO_PI;
}
}
/*----------------------------------------------------------------*
* lpc analysis (subrutine to LPCencode)
*---------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -