📄 acelp_cp.c
字号:
/*
ITU-T G.729 Annex C+ - Reference C code for floating point
implementation of G.729 Annex C+
(integration of Annexes B, D and E)
Version 2.1 of October 1999
*/
/*
File : ACELP_CP.C
*/
/*****************************************************************************/
/* fixed codebook encoding routines for 11.8, 8 and 6.4 kbit/s */
/*****************************************************************************/
#include <math.h>
#include "typedef.h"
#include "ld8k.h"
#include "ld8cp.h"
#include "tabld8cp.h"
/* prototypes of local functions */
static void cor_h_cp(
FLOAT *H, /* (i) :Impulse response of filters */
FLOAT *rr, /* (o) :Correlations of H[] */
int rate
);
static int d4i40_17( /* (o) : Index of pulses positions. */
FLOAT Dn[], /* (i) : Correlations between h[] and Xn[]. */
FLOAT rr[], /* (i) : Correlations of impulse response h[]. */
FLOAT h[], /* (i) : Impulse response of filters. */
FLOAT cod[], /* (o) : Selected algebraic codeword. */
FLOAT y[], /* (o) : Filtered algebraic codeword. */
int *sign, /* (o) : Signs of 4 pulses. */
int i_subfr /* (i) : subframe flag */
);
static void cor_h_vec(
FLOAT h[], /* (i) scaled impulse response */
FLOAT vec[], /* (i) vector to correlate with h[] */
int track, /* (i) track to use */
FLOAT sign[], /* (i) sign vector */
FLOAT rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
FLOAT cor[] /* (o) result of correlation (NB_POS elements) */
);
static void search_ixiy(
int track_x, /* (i) track of pulse 1 */
int track_y, /* (i) track of pulse 2 */
FLOAT *ps, /* (i/o) correlation of all fixed pulses */
FLOAT *alp, /* (i/o) energy of all fixed pulses */
int *ix, /* (o) position of pulse 1 */
int *iy, /* (o) position of pulse 2 */
FLOAT dn[], /* (i) corr. between target and h[] */
FLOAT cor_x[], /* (i) corr. of pulse 1 with fixed pulses */
FLOAT cor_y[], /* (i) corr. of pulse 2 with fixed pulses */
FLOAT rrixiy[][MSIZE] /* (i) corr. of pulse 1 with pulse 2 */
);
static void set_sign(
FLOAT cn[], /* (i) : residual after long term prediction */
FLOAT dn[], /* (i) : correlation between target and h[] */
FLOAT sign[], /* (o) : sign vector (sign of each position) */
FLOAT inv_sign[], /* (o) : inverse of sign[] */
int pos_max[], /* (o) : pos of max of correlation */
FLOAT corr[] /* (o) : correlation of each track */
);
static void cor_h_e(
FLOAT sign[], /* (i) : sign vector */
FLOAT inv_sign[], /* (i) : inverse of sign[] */
FLOAT h[], /* (o) : scaled h[] */
FLOAT h_inv[], /* (o) : inverse of scaled h[] */
FLOAT rrixix[][NB_POS], /* (o) energy of h[]. */
FLOAT rrixiy[][MSIZE] /* (o) correlation between 2 pulses. */
);
static void build_code(
int codvec[], /* (i) : positions of each pulse */
FLOAT sign[], /* (i) : sign vector */
int nb_of_pulse, /* (i) : number of pulses */
FLOAT h[], /* (i) : impulse response of weighted synthesis filter */
FLOAT code[], /* (o) : algebraic (fixed) codebook excitation */
FLOAT y[], /* (o) : filtered fixed codebook excitation */
int indx[] /* (o) : index of pulses (5 words, 1 per track). */
);
static int pack3(int index1, int index2, int index3);
int ACELP_codebook( /* (o) :index of pulses positions */
FLOAT x[], /* (i) :Target vector */
FLOAT h[], /* (i) :Impulse response of filters */
int t0, /* (i) :Pitch lag */
FLOAT pitch_sharp, /* (i) :Last quantized pitch gain */
int i_subfr, /* (i) :Indicator of 1st subframe, */
FLOAT code[], /* (o) :Innovative codebook */
FLOAT y[], /* (o) :Filtered innovative codebook */
int *sign /* (o) :Signs of 4 pulses */
)
{
int i, index;
FLOAT dn[L_SUBFR];
FLOAT rr[DIM_RR];
/*----------------------------------------------------------------*
* Include fixed-gain pitch contribution into impulse resp. h[] *
* Find correlations of h[] needed for the codebook search. *
*-----------------------------------------------------------------*/
if(t0 < L_SUBFR) {
for (i = t0; i < L_SUBFR; i++)
h[i] += pitch_sharp * h[i-t0];
}
cor_h_cp(h, rr, G729);
/*----------------------------------------------------------------*
* Compute correlation of target vector with impulse response. *
*-----------------------------------------------------------------*/
cor_h_x(h, x, dn); /* backward filtered target vector dn */
/*----------------------------------------------------------------*
* Find innovative codebook. *
*-----------------------------------------------------------------*/
index = d4i40_17(dn, rr, h, code, y, sign, i_subfr);
/*------------------------------------------------------*
* - Add the fixed-gain pitch contribution to code[]. *
*-------------------------------------------------------*/
if(t0 < L_SUBFR) {
for (i = t0; i < L_SUBFR; i++)
code[i] += pitch_sharp * code[i-t0];
}
return index;
}
int ACELP_codebook64( /* (o) :Index of pulses positions */
FLOAT x[], /* (i) :Target vector */
FLOAT h[], /* (i) :Impulse response of filters */
int t0, /* (i) :Pitch lag */
FLOAT pitch_sharp, /* (i) :Last quantized pitch gain */
FLOAT code[], /* (o) :Innovative codebook */
FLOAT y[], /* (o) :Filtered innovative codebook */
int *sign /* (o) :Signs of 4 pulses */
)
{
int i, j;
int posIndex[NB_PULSES_6K]; /* position index of last constructed vector */
int signIndex[NB_PULSES_6K]; /* sign index of last constructed vector */
/* (1=positive, 0=negative) */
FLOAT dn[L_SUBFR];
FLOAT Csq_best;
FLOAT E_best;
FLOAT C;
FLOAT Csq;
FLOAT E;
int m0_bestIndex;
int m1_bestIndex;
int m0_bestPos;
int m1_bestPos;
int index;
int m0, m1, pulse0, pulse1;
FLOAT *ptr1, *ptr2, *ptr3;
FLOAT C0;
FLOAT rr[DIM_RR];
int p_sign[L_SUBFR];
int i0, i1, i2, i3;
FLOAT *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4;
FLOAT *rri0i1, *rri0i2, *rri0i3, *rri0i4;
FLOAT *rri1i2, *rri1i3, *rri1i4;
FLOAT *rri2i3, *rri2i4;
FLOAT *ptr_ri0i1, *ptr_ri0i2, *ptr_ri0i3, *ptr_ri0i4;
FLOAT *ptr_ri1i2, *ptr_ri1i3, *ptr_ri1i4;
FLOAT *ptr_ri2i3, *ptr_ri2i4;
/*----------------------------------------------------------------*
* Include fixed-gain pitch contribution into impulse resp. h[] *
* Find correlations of h[] needed for the codebook search. *
*-----------------------------------------------------------------*/
if(t0 < L_SUBFR) {
for (i = t0; i < L_SUBFR; i++)
h[i] += pitch_sharp * h[i-t0];
}
cor_h_x(h, x, dn); /* backward filtered target vector dn */
cor_h_cp(h, rr, G729D);
/* approximate sign by using ltpResidual and target */
for ( i = 0; i < L_SUBFR; i++) {
if (dn[i] >= 0) {
p_sign[i] = 1;
}
else {
p_sign[i] = -1;
dn[i] = -dn[i]; /* absolute value vector */
}
}
/* Init pointers */
rri0i0 = rr;
rri1i1 = rri0i0 + NB_POS;
rri2i2 = rri1i1 + NB_POS;
rri3i3 = rri2i2 + NB_POS;
rri4i4 = rri3i3 + NB_POS;
rri0i1 = rri4i4 + NB_POS;
rri0i2 = rri0i1 + MSIZE;
rri0i3 = rri0i2 + MSIZE;
rri0i4 = rri0i3 + MSIZE;
rri1i2 = rri0i4 + MSIZE;
rri1i3 = rri1i2 + MSIZE;
rri1i4 = rri1i3 + MSIZE;
rri2i3 = rri1i4 + MSIZE;
rri2i4 = rri2i3 + MSIZE;
/*-------------------------------------------------------------------*
* Modification of rrixiy to take into account signs. *
*-------------------------------------------------------------------*/
ptr_ri0i1 = rri0i1;
ptr_ri0i2 = rri0i2;
ptr_ri0i3 = rri0i3;
ptr_ri0i4 = rri0i4;
for(i0=0; i0<L_SUBFR; i0+=STEP)
{
for(i1=1; i1<L_SUBFR; i1+=STEP) {
*ptr_ri0i1 *= (p_sign[i0] * p_sign[i1]);
ptr_ri0i1++;
*ptr_ri0i3 *= (p_sign[i0] * p_sign[i1+2]);
ptr_ri0i3++;
}
}
ptr_ri1i2 = rri1i2;
ptr_ri1i3 = rri1i3;
ptr_ri1i4 = rri1i4;
for(i1=1; i1<L_SUBFR; i1+=STEP)
{
for(i2=2; i2<L_SUBFR; i2+=STEP)
{
*ptr_ri1i2 *= (p_sign[i1] * p_sign[i2]);
ptr_ri1i2++;
*ptr_ri1i3 *= (p_sign[i1] * p_sign[i2+1]);
ptr_ri1i3++;
*ptr_ri1i4 *= (p_sign[i1] * p_sign[i2+2]);
ptr_ri1i4++;
}
}
ptr_ri2i3 = rri2i3;
ptr_ri2i4 = rri2i4;
ptr_ri0i4=rri0i4;
for(i2=2; i2<L_SUBFR; i2+=STEP)
{
for(i3=3; i3<L_SUBFR; i3+=STEP)
{
*ptr_ri2i3 *= (p_sign[i2] * p_sign[i3]);
ptr_ri2i3++;
*ptr_ri2i4 *= (p_sign[i2] * p_sign[i3+1]);
ptr_ri2i4++;
*ptr_ri0i4 *= (p_sign[i2+1] * p_sign[i3+1]); /* signs for i3 vs i4 */
ptr_ri0i4++;
}
}
/* signs for new i1 corr i1 */
ptr_ri0i2=rri0i2;
for(i2=1; i2<L_SUBFR; i2+=STEP)
{
for(i3=1; i3<L_SUBFR; i3+=STEP)
{
*ptr_ri0i2 *= (p_sign[i2] * p_sign[i3]);
ptr_ri0i2++;
}
}
/* start of actual search */
Csq_best=(F)0.0;
E_best=(F)1.0e38;
m0_bestIndex=trackTable0[0];
m1_bestIndex=trackTable1[0];
/* m0 -> i1 m1 -> i0 (sub 0 vs sub 0) */
m1 = 0;
ptr1 = rri0i0;
ptr3 = rri0i1;
for (pulse1=0; pulse1<24; pulse1+=3, m1+=STEP) {
m0 = 1;
ptr2 = rri1i1;
C0 = dn[m1];
for (pulse0=0; pulse0<16; pulse0+=2, m0+=STEP) {
C = C0;
E = *ptr1;
C += dn[m0];
Csq = C*C;
E += *ptr2++;
E += (F)2.0 * *ptr3++;
if ( (Csq*E_best) > (E*Csq_best) ) {
E_best = E;
Csq_best = Csq;
m0_bestIndex=pulse0;
m1_bestIndex=pulse1;
}
}
ptr1++;
}
/* m0 -> i1 m1 -> i2 (sub 0 vs sub 1) */
m0 = 1;
ptr1 = rri1i1;
ptr3 = rri1i2;
for (pulse0=0; pulse0<posSearched[0]; pulse0+=2, m0+=STEP) {
m1 = 2;
ptr2 = rri2i2;
C0 = dn[m0];
for (pulse1=1; pulse1<24; pulse1+=3, m1+=STEP) {
C = C0;
E = *ptr1;
C += dn[m1];
Csq = C*C;
E += *ptr2++;
E += (F)2.0 * *ptr3++;
if ( (Csq*E_best) > (E*Csq_best) ) {
E_best = E;
Csq_best = Csq;
m0_bestIndex=pulse0;
m1_bestIndex=pulse1;
}
}
ptr1++;
}
/* m0 -> i1 m1 -> i4 (sub 0 vs sub 2) */
m0 = 1;
ptr1 = rri1i1;
ptr3 = rri1i4;
for (pulse0=0; pulse0<posSearched[0]; pulse0+=2, m0+=STEP) {
m1 = 4;
ptr2 = rri4i4;
C0 = dn[m0];
for (pulse1=2; pulse1<24; pulse1+=3, m1+=STEP) {
C = C0;
E = *ptr1;
C += dn[m1];
Csq = C*C;
E += *ptr2++;
E += (F)2.0 * *ptr3++;
if ( (Csq*E_best) > (E*Csq_best) ) {
E_best = E;
Csq_best = Csq;
m0_bestIndex=pulse0;
m1_bestIndex=pulse1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -