www.pudn.com > p_voice.rar > 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
#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 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 (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 (E*Csq_best) ) {
E_best = E;
Csq_best = Csq;
m0_bestIndex=pulse0;
m1_bestIndex=pulse1;
}
}
ptr1++;
}
/* m0 -> i1 m1 -> i1 (sub 0 vs sub 3) */
m0 = 1;
ptr1 = rri1i1;
ptr3 = rri0i2;
for (pulse0=0; pulse0 (E*Csq_best) ) {
E_best = E;
Csq_best = Csq;
m0_bestIndex=pulse0;
m1_bestIndex=pulse1;
}
}
ptr1++;
}
/* m0 -> i3 m1 -> i0 (sub 1 vs sub 0) */
m1 = 0;
ptr1 = rri0i0;
ptr3 = rri0i3;
for (pulse1=0; pulse1<24; pulse1+=3, m1+=STEP) {
m0 = 3;
ptr2 = rri3i3;
C0 = dn[m1];
for (pulse0=1; 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 -> i3 m1 -> i2 (sub 1 vs sub 1) */
m1 = 2;
ptr1 = rri2i2;
ptr3 = rri2i3;
for (pulse1=1; pulse1<24; pulse1+=3, m1+=STEP) {
m0 = 3;
ptr2 = rri3i3;
C0 = dn[m1];
for (pulse0=1; 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 -> i3 m1 -> i4 (sub 1 vs sub 2) rri0i4 contains rri3i4 */
m0 = 3;
ptr1 = rri3i3;
ptr3 = rri0i4;
for (pulse0=1; pulse0 (E*Csq_best) ) {
E_best = E;
Csq_best = Csq;
m0_bestIndex=pulse0;
m1_bestIndex=pulse1;
}
}
ptr1++;
}
/* m0 -> i3 m1 -> i1 (sub 1 vs sub 3) */
m1 = 1;
ptr1 = rri1i1;
ptr3 = rri1i3;
for (pulse1=24; pulse1<32; pulse1++, m1+=STEP) {
m0 = 3;
ptr2 = rri3i3;
C0 = dn[m1];
for (pulse0=1; 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_bestPos = trackTable0[m0_bestIndex];
m1_bestPos = trackTable1[m1_bestIndex];
posIndex[0] = grayEncode[m0_bestIndex];
posIndex[1] = grayEncode[m1_bestIndex];
signIndex[0] = ( p_sign[m0_bestPos] > 0);
signIndex[1] = ( p_sign[m1_bestPos] > 0);
/* build innovation vector */
for (i = 0; i < L_SUBFR; i++) code[i] = (F)0.0;
code[m0_bestPos] = (FLOAT)p_sign[m0_bestPos];
code[m1_bestPos] += (FLOAT)p_sign[m1_bestPos];
*sign = signIndex[0] + 2*signIndex[1];
index = posIndex[0] + 16*posIndex[1];
/* compute filtered cbInnovation */
for (i = 0; i < L_SUBFR; i++) y[i] = (F)0.0;
if(signIndex[0] == 1) {
for(i=m0_bestPos, j=0; i= (F)0.0)
{
p_sign[i] = (F)1.0;
}
else {
p_sign[i] = (F)-1.0;
dn[i] = -dn[i];
}
}
/*-------------------------------------------------------------------*
* - Compute the search threshold after three pulses *
*-------------------------------------------------------------------*/
average = dn[0] + dn[1] + dn[2];
max0 = dn[0];
max1 = dn[1];
max2 = dn[2];
for (i = 5; i < L_SUBFR; i+=STEP)
{
average += dn[i] + dn[i+1]+ dn[i+2];
if (dn[i] > max0) max0 = dn[i];
if (dn[i+1] > max1) max1 = dn[i+1];
if (dn[i+2] > max2) max2 = dn[i+2];
}
max0 += max1+max2;
average *= (F)0.125; /* 1/8 */
thres = average + (max0-average)*THRESHFCB;
/*-------------------------------------------------------------------*
* Modification of rrixiy to take into account signs. *
*-------------------------------------------------------------------*/
ptr_ri0i1 = rri0i1;
ptr_ri0i2 = rri0i2;
ptr_ri0i3 = rri0i3;
ptr_ri0i4 = rri0i4;
for(i0=0; i0 thres)
{
ptr_ri3i3 = rri3i3; /* Init. pointers that depend on 4th loop */
for (i3 = 3; i3 < L_SUBFR; i3 += STEP)
{
ps3 = ps2 + dn[i3];
alp3 = alp2 + *ptr_ri3i3++ + (F)2.0*(*ptr_ri1i3++ + *ptr_ri0i3++ + *ptr_ri2i3++);
ps3c = ps3*ps3;
if( (ps3c*alpha) > (psc * alp3) )
{
psc = ps3c;
alpha = alp3;
ip0 = i0;
ip1 = i1;
ip2 = i2;
ip3 = i3;
}
} /* end of for i3 = */
ptr_ri0i3 -= NB_POS;
ptr_ri1i3 -= NB_POS;
ptr_ri4i4 = rri4i4; /* Init. pointers that depend on 4th loop */
for (i3 = 4; i3 < L_SUBFR; i3 += STEP)
{
ps3 = ps2 + dn[i3];
alp3 = alp2 + *ptr_ri4i4++ + (F)2.0*(*ptr_ri1i4++ + *ptr_ri0i4++ + *ptr_ri2i4++);
ps3c = ps3*ps3;
if( (ps3c*alpha) > (psc * alp3) )
{
psc = ps3c;
alpha = alp3;
ip0 = i0;
ip1 = i1;
ip2 = i2;
ip3 = i3;
}
} /* end of for i3 = */
ptr_ri0i4 -= NB_POS;
ptr_ri1i4 -= NB_POS;
time --;
if(time <= 0 ) goto end_search; /* Maximum time finish */
} /* end of if >thres */
else {
ptr_ri2i3 += NB_POS;
ptr_ri2i4 += NB_POS;
}
} /* end of for i2 = */
ptr_ri0i2 -= NB_POS;
ptr_ri1i3 += NB_POS;
ptr_ri1i4 += NB_POS;
} /* end of for i1 = */
ptr_ri0i2 += NB_POS;
ptr_ri0i3 += NB_POS;
ptr_ri0i4 += NB_POS;
} /* end of for i0 = */
end_search:
extra = time;
/* Find the codeword corresponding to the selected positions */
for(i=0; i (F)0.0) {
for(i=ip0, j=0; i (F)0.0) {
for(i=ip1, j=0; i (F)0.0) {
for(i=ip2, j=0; i (F)0.0) {
for(i=ip3, j=0; i (F)0.0) i+=1;
if(p_sign[ip1] > (F)0.0) i+=2;
if(p_sign[ip2] > (F)0.0) i+=4;
if(p_sign[ip3] > (F)0.0) i+=8;
*signs = i;
ip0 = ip0 / 5;
ip1 = ip1 / 5;
ip2 = ip2 / 5;
j = (ip3 % 5) - 3;
ip3 = ( (ip3 / 5) << 1 ) + j;
i = (ip0) + (ip1<<3) + (ip2<<6) + (ip3<<9);
return i;
}
/*-------------------------------------------------------------------*
* Function ACELP_12i40_44bits() *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* Algebraic codebook; 44 bits: 12 pulses in a frame of 40 samples. *
*-------------------------------------------------------------------*
* The code length is 40, containing 12 nonzero pulses: i0...i11. *
* 12 pulses can have two (2) possible amplitudes: +1 or -1. *
* 10 pulses can have eight (8) possible positions: *
* i2,i7 : 0, 5, 10, 15, 20, 25, 30, 35. --> t0 *
* i3,i8 : 1, 6, 11, 16, 21, 26, 31, 36. --> t1 *
* i4,i9 : 2, 7, 12, 17, 22, 27, 32, 37. --> t2 *
* i5,i10 : 3, 8, 13, 18, 23, 28, 33, 38. --> t3 *
* i6,i11 : 4, 9, 14, 19, 24, 29, 34, 39. --> t4 *
* *
* The 2 other pulses can be on the following track: *
* t0-t1,t1-t2,t2-t3,t3-t4,t4-t0. *
*-------------------------------------------------------------------*/
void ACELP_12i40_44bits(
FLOAT x[], /* (i) : target vector */
FLOAT cn[], /* (i) : residual after long term prediction */
FLOAT h1[], /* (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 5 words: 13,10,7,7,7 = 44 bits */
)
{
int i, j, k, ix, iy, itrk[3], track, pos, index;
int idx[NB_TRACK];
FLOAT psk, ps, alpk, alp;
FLOAT s, corr[NB_TRACK];
FLOAT *p0, *p1, *h_inv, *h;
FLOAT dn[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
int ip[12], codvec[12], pos_max[NB_TRACK];
FLOAT cor_x[NB_POS], cor_y[NB_POS];
FLOAT h_buf[4*L_SUBFR];
FLOAT rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
FLOAT L_tmp;
h = h_buf;
h_inv = h_buf + (2*L_SUBFR);
for (i=0; i (FLOAT)0.) {
s = corr[i];
track = i;
}
}
corr[track] = (FLOAT)-1.;
itrk[k] = track;
}
/*-------------------------------------------------------------------*
* Deep first search: 3 iterations of 320 tests = 960 tests. *
* *
* Stages of deep first search: *
* stage 1 : fix i0 and i1 --> 2 positions is fixed previously. *
* stage 2 : fix i2 and i3 --> try 8x8 = 64 positions. *
* stage 3 : fix i4 and i5 --> try 8x8 = 64 positions. *
* stage 4 : fix i6 and i7 --> try 8x8 = 64 positions. *
* stage 5 : fix i8 and i9 --> try 8x8 = 64 positions. *
* stage 6 : fix i10 and i11 --> try 8x8 = 64 positions. *
*-------------------------------------------------------------------*/
/* stage 0: fix pulse i0 and i1 according to max of correlation */
psk = (FLOAT)-1.;
alpk = (FLOAT)1.;
for (pos=0; pos<3; pos++) {
k = itrk[pos]; /* starting position index */
/* stage 1: fix pulse i0 and i1 according to max of correlation */
ix = pos_max[ipos[k]];
iy = pos_max[ipos[k+1]];
ps = dn[ix] + dn[iy];
i = ix/5;
j = iy/5;
alp = rrixix[ipos[k]][i] + rrixix[ipos[k+1]][j];
i = (i<<3) + j;
alp += rrixiy[ipos[k]][i];
ip[0] = ix;
ip[1] = iy;
for (i=0; i (FLOAT)0.) {
psk = ps;
alpk = alp;
for (i=0; i<12; i++) codvec[i] = ip[i];
}
} /* end of for (pos=0; pos<3; pos++) */
/*-------------------------------------------------------------------*
* index of 12 pulses = 44 bits on 5 words *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* indx[0] =13 bits --> 3(track) + *
* 3(pos#11) + 3(pos#6) + 1(sign#1) + 3(pos#1) *
* indx[1] =10 bits --> 3(pos#12) + 3(pos#7) + 1(sign#2) + 3(pos#2) *
* indx[2] = 7 bits --> 3(pos#8) + 1(sign#3) + 3(pos#3) *
* indx[3] = 7 bits --> 3(pos#9) + 1(sign#4) + 3(pos#4) *
* indx[4] = 7 bits --> 3(pos#10)+ 1(sign#5) + 3(pos#5) *
*-------------------------------------------------------------------*/
build_code(codvec+2, sign, 10, h, code, y, idx);
track = 0; /* to avoid visual warning */
for (k=0; k<2; k++) {
pos = codvec[k];
index = pos/5; /* index = pos/5 */
track = pos%5;
if (sign[pos] > (FLOAT)0.) {
code[pos] += (FLOAT)1.;
for (i=pos, j=0; i>4) & (int)15;
iy = idx[track] & (int)15;
index = pack3(ix, iy, index);
if (k == 0) index += track<<10;
indx[k] = index;
}
for (k=2; k= NB_TRACK) track = 0;
indx[k] = (idx[track] & (int)127);
}
return;
}
/*-------------------------------------------------------------------*
* Function ACELP_10i40_35bits() *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* Algebraic codebook; 35 bits: 10 pulses in a frame of 40 samples. *
*-------------------------------------------------------------------*
* The code length is 40, containing 10 nonzero pulses: i0...i9. *
* All pulses can have two (2) possible amplitudes: +1 or -1. *
* Each pulse can have eight (8) possible positions: *
* *
* i0,i5 : 0, 5, 10, 15, 20, 25, 30, 35. *
* i1,i6 : 1, 6, 11, 16, 21, 26, 31, 36. *
* i2,i7 : 2, 7, 12, 17, 22, 27, 32, 37. *
* i3,i8 : 3, 8, 13, 18, 23, 28, 33, 38. *
* i4,i9 : 4, 9, 14, 19, 24, 29, 34, 39. *
*-------------------------------------------------------------------*/
void ACELP_10i40_35bits(
FLOAT x[], /* (i) : target vector */
FLOAT cn[], /* (i) : residual after long term prediction */
FLOAT h1[], /* (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 5 words: 7,7,7,7,7 = 35 bits */
)
{
int i, j, k, ix, iy, pos, track;
FLOAT psk, ps, alpk, alp;
int itrk[3];
FLOAT s, corr[NB_TRACK], L_tmp;
FLOAT *p0, *p1, *h_inv, *h;
/* these vectors are not static */
FLOAT dn[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
int ip[10], codvec[10], pos_max[NB_TRACK];
FLOAT cor_x[NB_POS], cor_y[NB_POS];
FLOAT h_buf[4*L_SUBFR];
FLOAT rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
h = h_buf;
h_inv = h_buf + (2*L_SUBFR);
for (i=0; i (FLOAT)0.) {
s = corr[i];
track = i;
}
}
corr[track] = (FLOAT)-1.;
itrk[k] = track;
}
/*-------------------------------------------------------------------*
* Deep first search: 4 iterations of 256 tests = 1024 tests. *
* *
* Stages of deep first search: *
* stage 1 : fix i0 and i1 --> 2 positions is fixed previously. *
* stage 2 : fix i2 and i3 --> try 8x8 = 64 positions. *
* stage 3 : fix i4 and i5 --> try 8x8 = 64 positions. *
* stage 4 : fix i6 and i7 --> try 8x8 = 64 positions. *
* stage 5 : fix i8 and i9 --> try 8x8 = 64 positions. *
*-------------------------------------------------------------------*/
psk = (FLOAT)-1.;
alpk = (FLOAT)1.;
for (pos=0; pos<3; pos++) {
k = itrk[pos]; /* starting position index */
/* stage 1: fix pulse i0 and i1 according to max of correlation */
ix = pos_max[ipos[k]];
iy = pos_max[ipos[k+1]];
ps = dn[ix] + dn[iy];
i = ix/5;
j = iy/5;
alp = rrixix[ipos[k]][i] + rrixix[ipos[k+1]][j];
i = (i<<3) + j;
alp += rrixiy[ipos[k]][i];
ip[0] = ix;
ip[1] = iy;
for (i=0; i (FLOAT)0.) {
psk = ps;
alpk = alp;
for (i=0; i<10; i++) codvec[i] = ip[i];
}
} /* end of for (pos=0; pos<3; pos++) */
/*-------------------------------------------------------------------*
* index of 10 pulses = 35 bits on 5 words *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* indx[0] = 7 bits --> 3(pos#6) + 1(sign#1) + 3(pos#1) *
* indx[1] = 7 bits --> 3(pos#7) + 1(sign#2) + 3(pos#2) *
* indx[2] = 7 bits --> 3(pos#8) + 1(sign#3) + 3(pos#3) *
* indx[3] = 7 bits --> 3(pos#9) + 1(sign#4) + 3(pos#4) *
* indx[4] = 7 bits --> 3(pos#10)+ 1(sign#5) + 3(pos#5) *
*-------------------------------------------------------------------*/
build_code(codvec, sign, 10, h, code, y, indx);
for (i=0; i (FLOAT)0.) {
sqk = sq;
alpk = alp2;
pos = j;
}
}
p1 -= NB_POS;
if (pos >= 0) {
*ix = i;
*iy = pos;
}
}
*ps += dn[*ix] + dn[*iy];
*alp = alpk;
return;
}
/*-------------------------------------------------------------------*
* Function set_sign() *
* ~~~~~~~~~~~~~~~~~~~~ *
* Set the sign of each pulse position. *
*-------------------------------------------------------------------*/
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 */
)
{
int i, k, pos;
FLOAT k_cn, k_dn, val;
FLOAT s, max;
/* calculate energy for normalization of cn[] and dn[] */
s = (FLOAT)0.;
for (i=0; i= (FLOAT)0.) {
sign[i] = (FLOAT)1.;
inv_sign[i] = (FLOAT)-1.;
}
else {
sign[i] = (FLOAT)-1.;
inv_sign[i] = (FLOAT)1.;
val = -val;
}
dn[i] = val; /* modify dn[] according to the fixed sign */
s = (FLOAT)fabs(s);
if (s > max) {
max = s;
pos = i;
}
}
pos_max[k] = pos;
corr[k] = max;
}
return;
}
/*-------------------------------------------------------------------*
* Function cor_h_e() *
* ~~~~~~~~~~~~~~~~~ *
* Compute correlations of h[] needed for the codebook search. *
*-------------------------------------------------------------------*/
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. */
)
{
int i, j, k, pos;
FLOAT *ptr_h1, *ptr_h2, *ptr_hf, *psign;
FLOAT *p0, *p1, *p2, *p3, *p4;
FLOAT cor;
for(i=0; i i4i4, i3i3, i2i2, i1i1, i0i0 */
/* Init pointers to last position of rrixix[] */
p0 = &rrixix[0][NB_POS-1];
p1 = &rrixix[1][NB_POS-1];
p2 = &rrixix[2][NB_POS-1];
p3 = &rrixix[3][NB_POS-1];
p4 = &rrixix[4][NB_POS-1];
ptr_h1 = h;
cor = (FLOAT)0.;
for(i=0; i i3i4, i2i3, i1i2, i0i1, i4i0 */
pos = MSIZE-1;
ptr_hf = h + 1;
for(k=0; k i4i0, i3i4, i2i3, i1i2, i0i1 */
pos = MSIZE-1;
ptr_hf = h + 4;
for(k=0; k 0) {
code[i] += (FLOAT)1.;
for (i=codvec[k], j=0; i (index2 & 7)) {
tmp = index1;
index1 = index2;
index2 = tmp;
}
if ((index1 & 7) > (index3 & 7)) {
tmp = index1;
index1 = index3;
index3 = tmp;
}
if ((index2 & 7) > (index3 & 7)) {
tmp = index2;
index2 = index3;
index3 = tmp;
}
k = (int)(index1>> 1) & (int)4;
k += (int)(index2>> 2) & (int)2;
k += (int)(index3>>3) & (int)1;
index = 0; /* to avoid visual warning */
switch (k) {
case 0:
case 7:
index = (int)(index1 & (int)7) << (int)7;
index += (int)(index2 & (int)7) << (int)4;
index += index3;
break;
case 1:
case 6:
index = (int)(index3 & (int)7) << (int)7;
index += (int)(index1 & (int)7) << (int)4;
index += index2;
break;
case 2:
case 5:
index = (int)(index2 & (int)7) << (int)7;
index += (int)(index1 & (int)7) << (int)4;
index += index3;
break;
case 3:
case 4:
index = (int)(index2 & (int)7) << (int)7;
index += (int)(index3 & (int)7)<< (int)4;
index += index1;
break;
}
return (index);
}