📄 enc_acelp.c
字号:
/*
*===================================================================
* 3GPP AMR Wideband Floating-point Speech Codec
*===================================================================
*/
#include <math.h>
#include <memory.h>
#include <float.h>
#include "typedef.h"
#include "enc_util.h"
#define NEW_28bits /* for amr_wbplus */
#define L_SUBFR 64
#define NB_PULSE_MAX 24
#define NPMAXPT ((NB_PULSE_MAX + 4 - 1) / 4)
#define NB_QUA_GAIN7B 128 /* Number of quantization level */
#define MODE_23k 7
extern const UWord8 E_ROM_tipos[];
extern const Float32 E_ROM_qua_gain6b[];
extern const Float32 E_ROM_qua_gain7b[];
/*
* E_ACELP_Gain2_Q_init
*
* Parameters:
* mem O: static memory
*
* Function:
* Initializes state memory
*
* Returns:
* void
*/
void E_ACELP_Gain2_Q_init(Word16 *mem)
{
Word16 i;
/* 2nd order quantizer energy predictor */
for (i = 0; i < 4; i++)
{
mem[i] = -14336; /* past_qua_en[i] */
}
return;
}
/*
* E_ACELP_xy1_corr
*
* Parameters:
* xn I: target signal
* y1 I: filtered adaptive codebook excitation
* g_coeff O: correlations <y1,y1> and -2<xn,y1>
*
* Function:
* Find the correlations between the target xn[] and the filtered adaptive
* codebook excitation y1[]. ( <y1,y1> and -2<xn,y1> )
* Subframe size = L_SUBFR
*
* Returns:
* pitch gain (0 ... 1.2F) (Q14)
*/
Float32 E_ACELP_xy1_corr(Float32 xn[], Float32 y1[], Float32 g_corr[])
{
Float32 gain;
Float32 t0, t1;
Word16 i;
t0 = xn[0] * y1[0];
t1 = y1[0] * y1[0];
for (i = 1; i < L_SUBFR; i += 7)
{
t0 += xn[i] * y1[i];
t1 += y1[i] * y1[i];
t0 += xn[i + 1] * y1[i + 1];
t1 += y1[i + 1] * y1[i + 1];
t0 += xn[i + 2] * y1[i + 2];
t1 += y1[i + 2] * y1[i + 2];
t0 += xn[i + 3] * y1[i + 3];
t1 += y1[i + 3] * y1[i + 3];
t0 += xn[i + 4] * y1[i + 4];
t1 += y1[i + 4] * y1[i + 4];
t0 += xn[i + 5] * y1[i + 5];
t1 += y1[i + 5] * y1[i + 5];
t0 += xn[i + 6] * y1[i + 6];
t1 += y1[i + 6] * y1[i + 6];
}
g_corr[0] = t1;
g_corr[1] = -2.0F * t0 + 0.01F;
/* find pitch gain and bound it by [0,1.2F] */
if (t1)
{
gain = t0 / t1;
}
else
{
gain = 1.0F;
}
if (gain < 0.0)
{
gain = 0.0;
}
else if (gain > 1.2F)
{
gain = 1.2F;
}
return gain;
}
/*
* E_ACELP_xy2_corr
*
* Parameters:
* xn I: target signal
* y1 I: filtered adaptive codebook excitation
* y2 I: filtered fixed codebook excitation
* g_corr O: correlations <y2,y2>, -2<xn,y2>, 2<y1,y2>
* L_subfr I: subframe size
*
* Function:
* Find the correlations between the target xn[], the filtered adaptive
* codebook exc. y1[], and the filtered fixed codebook innovation y2[].
* ( <y2,y2> , -2<xn,y2> and 2<y1,y2> )
* Subrame size = L_SUBFR
*
* Returns:
* pitch gain (0 ... 1.2F)
*/
void E_ACELP_xy2_corr(Float32 xn[], Float32 y1[], Float32 y2[],
Float32 g_corr[])
{
Float32 temp1, temp2, temp3;
Word32 i;
temp1 = 0.01F + y2[0] * y2[0];
temp2 = 0.01F + xn[0] * y2[0];
temp3 = 0.01F + y1[0] * y2[0];
temp1 += y2[1] * y2[1];
temp2 += xn[1] * y2[1];
temp3 += y1[1] * y2[1];
temp1 += y2[2] * y2[2];
temp2 += xn[2] * y2[2];
temp3 += y1[2] * y2[2];
temp1 += y2[3] * y2[3];
temp2 += xn[3] * y2[3];
temp3 += y1[3] * y2[3];
for (i = 4; i < L_SUBFR; i += 6)
{
temp1 += y2[i] * y2[i];
temp2 += xn[i] * y2[i];
temp3 += y1[i] * y2[i];
temp1 += y2[i + 1] * y2[i + 1];
temp2 += xn[i + 1] * y2[i + 1];
temp3 += y1[i + 1] * y2[i + 1];
temp1 += y2[i + 2] * y2[i + 2];
temp2 += xn[i + 2] * y2[i + 2];
temp3 += y1[i + 2] * y2[i + 2];
temp1 += y2[i + 3] * y2[i + 3];
temp2 += xn[i + 3] * y2[i + 3];
temp3 += y1[i + 3] * y2[i + 3];
temp1 += y2[i + 4] * y2[i + 4];
temp2 += xn[i + 4] * y2[i + 4];
temp3 += y1[i + 4] * y2[i + 4];
temp1 += y2[i + 5] * y2[i + 5];
temp2 += xn[i + 5] * y2[i + 5];
temp3 += y1[i + 5] * y2[i + 5];
}
g_corr[2] = temp1;
g_corr[3] = -2.0F * temp2;
g_corr[4] = 2.0F * temp3;
return;
}
/*
* E_ACELP_xh_corr
*
* Parameters:
* h I: impulse response (of weighted synthesis filter) (Q12)
* x I: target signal (Q0)
* y O: correlation between x[] and h[]
*
* Function:
* Compute the correlation between the target signal and the impulse
* response of the weighted synthesis filter.
*
* y[i]=sum(j=i,l-1) x[j]*h[j-i], i=0,l-1
*
* Vector size is L_SUBFR
*
* Returns:
* void
*/
void E_ACELP_xh_corr(Float32 *x, Float32 *y, Float32 *h)
{
Word16 i, j;
Float32 s;
for (i = 0; i < L_SUBFR; i++)
{
s = 0.0F;
for (j = i; j < L_SUBFR ; j++)
{
s += x[j] * h[j - i];
}
y[i] = s;
}
return;
}
/*
* E_ACELP_codebook_target_update
*
* Parameters:
* x I: old target (for pitch search) (Q0)
* x2 O: new target (for codebook search) (Q0)
* y I: filtered adaptive codebook vector (Q0)
* gain I: adaptive codebook gain (Q14)
*
* Function:
* Update the target vector for codebook search.
* Subframe size = L_SUBFR
* Returns:
* void
*/
void E_ACELP_codebook_target_update(Float32 *x, Float32 *x2, Float32 *y,
Float32 gain)
{
Word16 i;
for (i = 0; i < L_SUBFR; i ++)
{
x2[i] = x[i] - gain * y[i];
}
}
/*
* E_ACELP_h_vec_corr?
*
* Parameters:
* h I: scaled impulse response
* vec I: vector to correlate with h[]
* track I: track to use
* sign I: sign vector
* rrixix I: correlation of h[x] with h[x]
* cor O: result of correlation (16 elements)
*
* Function:
* Calculate the correlations of h[] with vec[] for the specified track
*
* Returns:
* void
*/
static void E_ACELP_h_vec_corr1(Float32 h[], Float32 vec[], UWord8 track,
Float32 sign[], Float32 (*rrixix)[16],
Float32 cor[], Word32 dn2_pos[],
Word32 nb_pulse)
{
Word16 i, j;
Word32 dn;
Word32 *dn2;
Float32 *p0;
Float32 s;
dn2 = &dn2_pos[track * 8];
p0 = rrixix[track];
for (i = 0; i < nb_pulse; i++)
{
dn = dn2[i];
s = 0.0F;
for (j = 0; j < (L_SUBFR - dn); j++)
{
s += h[j] * vec[dn + j];
}
cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];
}
return;
}
static void E_ACELP_h_vec_corr2(Float32 h[], Float32 vec[], UWord8 track,
Float32 sign[], Float32 (*rrixix)[16],
Float32 cor[])
{
Word32 i, j;
Float32 *p0;
Float32 s;
p0 = rrixix[track];
for (i = 0; i < 16; i++)
{
s = 0.0F;
for (j = 0; j < L_SUBFR - track; j++)
{
s += h[j] * vec[track + j];
}
cor[i] = s * sign[track] + p0[i];
track += 4;
}
return;
}
/*
* E_ACELP_2pulse_search
*
* Parameters:
* nb_pos_ix I: nb of pos for pulse 1 (1..8)
* track_x I: track of pulse 1
* track_y I: track of pulse 2
* ps I/O: correlation of all fixed pulses
* alp I/O: energy of all fixed pulses
* ix O: position of pulse 1
* iy O: position of pulse 2
* dn I: corr. between target and h[]
* dn2 I: vector of selected positions
* cor_x I: corr. of pulse 1 with fixed pulses
* cor_y I: corr. of pulse 2 with fixed pulses
* rrixiy I: corr. of pulse 1 with pulse 2
*
* Function:
* Find the best positions of 2 pulses in a subframe
*
* Returns:
* void
*/
static void E_ACELP_2pulse_search(Word32 nb_pos_ix, UWord8 track_x,
UWord8 track_y, Float32 *ps, Float32 *alp,
Word32 *ix, Word32 *iy, Float32 dn[],
Word32 *dn2, Float32 cor_x[],
Float32 cor_y[], Float32 (*rrixiy)[256])
{
Word32 x, x2, y, x_save = 0, y_save = 0, i, *pos_x;
Float32 ps0, alp0;
Float32 ps1, ps2, sq, sqk;
Float32 alp1, alp2, alpk;
Float32 *p1, *p2;
Float32 s;
/* eight dn2 max positions per track */
pos_x = &dn2[track_x << 3];
/* save these to limit memory searches */
ps0 = *ps;
alp0 = *alp;
sqk = -1.0F;
alpk = 1.0F;
/* loop track 1 */
for (i = 0; i < nb_pos_ix; i++)
{
x = pos_x[i];
x2 = x >> 2;
/* dn[x] has only nb_pos_ix positions saved */
ps1 = ps0 + dn[x];
alp1 = alp0 + cor_x[x2];
p1 = cor_y;
p2 = &rrixiy[track_x][x2 << 4];
for (y = track_y; y < L_SUBFR; y += 4)
{
ps2 = ps1 + dn[y];
alp2 = alp1 + (*p1++) + (*p2++);
sq = ps2 * ps2;
s = (alpk * sq) - (sqk * alp2);
if (s > 0.0F)
{
sqk = sq;
alpk = alp2;
y_save = y;
x_save = x;
}
}
}
*ps = ps0 + dn[x_save] + dn[y_save];
*alp = alpk;
*ix = x_save;
*iy = y_save;
return;
}
/*
* E_ACELP_quant_1p_N1
*
* Parameters:
* pos I: position of the pulse
* N I: number of bits for position
*
* Function:
* Quantization of 1 pulse with N+1 bits
*
* Returns:
* return N+1 bits
*/
static Word32 E_ACELP_quant_1p_N1(Word32 pos, Word32 N)
{
Word32 mask;
Word32 index;
mask = ((1<<N)-1);
/*
* Quantization of 1 pulse with N+1 bits:
*/
index = (pos & mask);
if ((pos & 16) != 0)
{
index += 1 << N;
}
return(index);
}
/*
* E_ACELP_quant_2p_2N1
*
* Parameters:
* pos1 I: position of the pulse 1
* pos2 I: position of the pulse 2
* N I: number of bits for position
*
* Function:
* Quantization of 2 pulses with 2*N+1 bits
*
* Returns:
* (2*N)+1 bits
*/
static Word32 E_ACELP_quant_2p_2N1(Word32 pos1, Word32 pos2, Word32 N)
{
Word32 mask;
Word32 index;
mask = ((1 << N) - 1);
/*
* Quantization of 2 pulses with 2*N+1 bits:
*/
if (((pos2 ^ pos1) & 16) == 0)
{
/* sign of 1st pulse == sign of 2th pulse */
if ((pos1 - pos2) <= 0)
{
index = ((pos1 & mask) << N) + (pos2 & mask);
}
else
{
index = ((pos2 & mask) << N) + (pos1 & mask);
}
if ((pos1 & 16) != 0)
{
index += 1 << (2 * N);
}
}
else
{
/* sign of 1st pulse != sign of 2th pulse */
if (((pos1 & mask) - (pos2 & mask)) <= 0)
{
index = ((pos2 & mask) << N) + (pos1 & mask);
if ((pos2 & 16) != 0)
{
index += 1 << (2 * N);
}
}
else
{
index = ((pos1 & mask) << N) + (pos2 & mask);
if ((pos1 & 16) != 0)
{
index += 1 << (2 * N);
}
}
}
return(index);
}
/*
* E_ACELP_quant_3p_3N1
*
* Parameters:
* pos1 I: position of the pulse 1
* pos2 I: position of the pulse 2
* pos3 I: position of the pulse 3
* N I: number of bits for position
*
* Function:
* Quantization of 3 pulses with 3*N+1 bits
*
* Returns:
* (3*N)+1 bits
*/
static Word32 E_ACELP_quant_3p_3N1(Word32 pos1, Word32 pos2, Word32 pos3,
Word32 N)
{
Word32 nb_pos;
Word32 index;
nb_pos = (1 << (N - 1));
/*
* Quantization of 3 pulses with 3*N+1 bits:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -