📄 cbsearch.c
字号:
*************************************************************************/Word16 code_2i40_9bits( Word16 subNr, /* i : subframe number */ Word16 x[], /* i : target vector */ Word16 h[], /* i : impulse response of weighted synthesis filter */ /* h[-L_subfr..-1] must be set to zero. */ Word16 T0, /* i : Pitch lag */ Word16 pitch_sharp, /* i : Last quantized pitch gain */ Word16 code[], /* o : Innovative codebook */ Word16 y[], /* o : filtered fixed codebook excitation */ Word16 * sign /* o : Signs of 2 pulses */){
Word16 codvec[NB_PULSE_2i40_9BITS];
Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE]; Word16 rr[L_CODE][L_CODE]; Word16 i, index, sharp; Word16 *px = x, *ph = h, *py = y,*pcode = code ;
sharp = pitch_sharp << 1; if (T0 < L_CODE) for (i = T0; i < L_CODE; i++) { ph[i] += (ph[i - T0]*sharp >> 15 );
}
cor_h_x2(ph, px, dn, 1, NB_TRACK, STEP);
set_sign(dn, dn_sign, dn2, 8); /* dn2[] not used in this codebook search */ cor_h(ph, dn_sign, rr);
search_2i40_9BITS(subNr, dn, rr, codvec);
index = build_code_2i40_9BITS(subNr, codvec, dn_sign, pcode, ph, py, sign);
/*-----------------------------------------------------------------* * Compute innovation vector gain. * * Include fixed-gain pitch contribution into code[]. * *-----------------------------------------------------------------*/ if (T0 < L_CODE ) for (i = T0; i < L_CODE; i++) { pcode[i] += pcode[i - T0]*sharp >> 15;
} return index;
}/******************************************************************************* PRIVATE PROGRAM CODE******************************************************************************//************************************************************************* * * FUNCTION search_2i40() * * PURPOSE: Search the best codevector; determine positions of the 2 pulses * in the 40-sample frame. * *************************************************************************/
static void search_2i40_9BITS(
Word16 subNr, /* i : subframe number */ Word16 dn[], /* i : correlation between target and h[] */ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ Word16 codvec[] /* o : algebraic codebook vector */){
Word16 i0, i1;
Word16 ix = 0; /* initialization only needed to keep gcc silent */
Word16 track1, ipos[NB_PULSE_2i40_9BITS];
Word16 psk, ps0, ps1, sq, sq1;
Word16 alpk, alp, alp_16;
Word32 alp0, alp1;
Word16 temp;
Word16*pdn = dn, *pcodvec = codvec;
const Word16 *pstartPos =startPos;
psk = -1;
alpk = 1;
pcodvec[0] = 0; pcodvec[1] = 1;
for (track1 = 0; track1 < 2; track1++)
{
/* fix starting position */
temp = subNr*2 +8*track1;
ipos[0] = pstartPos[temp];
ipos[1] = pstartPos[temp+1];
/*----------------------------------------------------------------*
* i0 loop: try 8 positions. *
*----------------------------------------------------------------*/
for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
{
ps0 = pdn[i0];
alp0 = (rr[i0][i0]<<14);
/*----------------------------------------------------------------*
* i1 loop: 8 positions. *
*----------------------------------------------------------------*/
sq = -1;
alp = 1;
ix = ipos[1];
/*-------------------------------------------------------------------*
* These index have low complexity address computation because *
* they are, in fact, pointers with fixed increment. For example, *
* "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" *
* and incremented by "STEP". *
*-------------------------------------------------------------------*/
for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
{
ps1 = ps0+pdn[i1];
alp1 = alp0+ ( rr[i1][i1]<<14); /* idx incr = STEP */
alp1 = alp1+ ( rr[i0][i1]<<15); /* idx incr = STEP */
sq1 = (ps1* ps1 >> 15 );
alp_16 = (alp1 + 0x00008000)>>16;
temp = alp*sq1 > sq*alp_16;
sq = temp ? sq1 : sq;
alp = temp ? alp_16 : alp;
ix = temp ? i1 : ix;
}
/*----------------------------------------------------------------*
* memorise codevector if this one is better than the last one. *
*----------------------------------------------------------------*/
temp = alpk* sq > psk* alp;
psk = temp ? sq : psk;
alpk = temp ? alp : alpk;
pcodvec[0] = temp ? i0 : pcodvec[0];
pcodvec[1] = temp ? ix : pcodvec[1];
}
}
return;}/************************************************************************* * * FUNCTION: build_code() * * PURPOSE: Builds the codeword, the filtered codeword and index of the * codevector, based on the signs and positions of 2 pulses. * *************************************************************************/static Word16 build_code_2i40_9BITS(
Word16 subNr, /* i : subframe number */ Word16 codvec[], /* i : position of pulses */ Word16 dn_sign[], /* i : sign of pulses */ Word16 cod[], /* o : innovative code vector */ Word16 h[], /* i : impulse response of weighted synthesis filter */ Word16 y[], /* o : filtered innovative code */ Word16 sign[] /* o : sign of 2 pulses */){
Word16 i, j, track, first, index, _sign[NB_PULSE_2i40_9BITS], indx, rsign;
Word16 *p0, *p1, *pt; static Word16 trackTable[4*5] = { 0, 1, 0, 1, -1, /* subframe 1; track to code; -1 do not code this position */ 0, -1, 1, 0, 1, /* subframe 2 */ 0, 1, 0, -1, 1, /* subframe 3 */ 0, 1, -1, 0, 1};/* subframe 4 */
Word16 *pcod = cod,*pdn_sign = dn_sign, *pcodvec = codvec,*ph = h, *py = y, *psign = sign;
pt = &trackTable[subNr + (subNr<<2)];
memset(pcod, 0, 80 );
indx = 0; rsign = 0;
i = pcodvec[0]; /* read pulse position */
j = pdn_sign[i]; /* read sign */
index = (i*6554 >>15 );
track = i - (Word16)(index*5); first = pt[track];
track = 0;
index = (first == 0) ? index : index+64 ;
pcod[i] = j > 0 ? 8191 : -8192;
_sign[0] = (Word16)(j > 0 ?32767 : -32768L);
rsign = j>0? rsign+(1<<track) : rsign;
indx += index;
i = pcodvec[1]; /* read pulse position */
j = pdn_sign[i]; /* read sign */
index = (i*6554 >>15 );
track = i - (Word16)(index*5); first = pt[track];
track = 1;
index = index<<3;
pcod[i] = j > 0 ? 8191 : -8192;
_sign[1] = (Word16)(j > 0 ?32767 : -32768L);
rsign = j>0? rsign+(1<<track) : rsign;
indx += index;
*psign = rsign;
p0 = ph - pcodvec[0];
p1 = ph - pcodvec[1];
py[0] = ((( p0[0]*_sign[0] + p1[0]*_sign[1])<<1) + 0x00008000)>>16;
py[1] = ((( p0[1]*_sign[0] + p1[1]*_sign[1])<<1) + 0x00008000)>>16;
py[2] = ((( p0[2]*_sign[0] + p1[2]*_sign[1])<<1) + 0x00008000)>>16;
py[3] = ((( p0[3]*_sign[0] + p1[3]*_sign[1])<<1) + 0x00008000)>>16;
py[4] = ((( p0[4]*_sign[0] + p1[4]*_sign[1])<<1) + 0x00008000)>>16;
py[5] = ((( p0[5]*_sign[0] + p1[5]*_sign[1])<<1) + 0x00008000)>>16;
py[6] = ((( p0[6]*_sign[0] + p1[6]*_sign[1])<<1) + 0x00008000)>>16;
py[7] = ((( p0[7]*_sign[0] + p1[7]*_sign[1])<<1) + 0x00008000)>>16;
py[8] = ((( p0[8]*_sign[0] + p1[8]*_sign[1])<<1) + 0x00008000)>>16;
py[9] = ((( p0[9]*_sign[0] + p1[9]*_sign[1])<<1) + 0x00008000)>>16;
py[10] = ((( p0[10]*_sign[0] + p1[10]*_sign[1])<<1) + 0x00008000)>>16;
py[11] = ((( p0[11]*_sign[0] + p1[11]*_sign[1])<<1) + 0x00008000)>>16;
py[12] = ((( p0[12]*_sign[0] + p1[12]*_sign[1])<<1) + 0x00008000)>>16;
py[13] = ((( p0[13]*_sign[0] + p1[13]*_sign[1])<<1) + 0x00008000)>>16;
py[14] = ((( p0[14]*_sign[0] + p1[14]*_sign[1])<<1) + 0x00008000)>>16;
py[15] = ((( p0[15]*_sign[0] + p1[15]*_sign[1])<<1) + 0x00008000)>>16;
py[16] = ((( p0[16]*_sign[0] + p1[16]*_sign[1])<<1) + 0x00008000)>>16;
py[17] = ((( p0[17]*_sign[0] + p1[17]*_sign[1])<<1) + 0x00008000)>>16;
py[18] = ((( p0[18]*_sign[0] + p1[18]*_sign[1])<<1) + 0x00008000)>>16;
py[19] = ((( p0[19]*_sign[0] + p1[19]*_sign[1])<<1) + 0x00008000)>>16;
py[20] = ((( p0[20]*_sign[0] + p1[20]*_sign[1])<<1) + 0x00008000)>>16;
py[21] = ((( p0[21]*_sign[0] + p1[21]*_sign[1])<<1) + 0x00008000)>>16;
py[22] = ((( p0[22]*_sign[0] + p1[22]*_sign[1])<<1) + 0x00008000)>>16;
py[23] = ((( p0[23]*_sign[0] + p1[23]*_sign[1])<<1) + 0x00008000)>>16;
py[24] = ((( p0[24]*_sign[0] + p1[24]*_sign[1])<<1) + 0x00008000)>>16;
py[25] = ((( p0[25]*_sign[0] + p1[25]*_sign[1])<<1) + 0x00008000)>>16;
py[26] = ((( p0[26]*_sign[0] + p1[26]*_sign[1])<<1) + 0x00008000)>>16;
py[27] = ((( p0[27]*_sign[0] + p1[27]*_sign[1])<<1) + 0x00008000)>>16;
py[28] = ((( p0[28]*_sign[0] + p1[28]*_sign[1])<<1) + 0x00008000)>>16;
py[29] = ((( p0[29]*_sign[0] + p1[29]*_sign[1])<<1) + 0x00008000)>>16;
py[30] = ((( p0[30]*_sign[0] + p1[30]*_sign[1])<<1) + 0x00008000)>>16;
py[31] = ((( p0[31]*_sign[0] + p1[31]*_sign[1])<<1) + 0x00008000)>>16;
py[32] = ((( p0[32]*_sign[0] + p1[32]*_sign[1])<<1) + 0x00008000)>>16;
py[33] = ((( p0[33]*_sign[0] + p1[33]*_sign[1])<<1) + 0x00008000)>>16;
py[34] = ((( p0[34]*_sign[0] + p1[34]*_sign[1])<<1) + 0x00008000)>>16;
py[35] = ((( p0[35]*_sign[0] + p1[35]*_sign[1])<<1) + 0x00008000)>>16;
py[36] = ((( p0[36]*_sign[0] + p1[36]*_sign[1])<<1) + 0x00008000)>>16;
py[37] = ((( p0[37]*_sign[0] + p1[37]*_sign[1])<<1) + 0x00008000)>>16;
py[38] = ((( p0[38]*_sign[0] + p1[38]*_sign[1])<<1) + 0x00008000)>>16;
py[39] = ((( p0[39]*_sign[0] + p1[39]*_sign[1])<<1) + 0x00008000)>>16;
return indx;
}
/********************************************************************************** DECLARATION OF PROTOTYPES*********************************************************************************/static void search_3i40_14BITS(
Word16 dn[], /* i : correlation between target and h[] */ Word16 dn2[], /* i : maximum of corr. in each track. */ Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ Word16 codvec[] /* o : algebraic codebook vector */);static Word16 build_code_3i40_14BITS(
Word16 codvec[], /* i : algebraic codebook vector */ Word16 dn_sign[], /* i : sign of dn[] */ Word16 cod[], /* o : algebraic (fixed) codebook excitation */ Word16 h[], /* i : impulse response of weighted synthesis filter */ Word16 y[], /* o : filtered fixed codebook excitation */ Word16 sign[] /* o : sign of 3 pulses */);/********************************************************************************** PUBLIC PROGRAM CODE*********************************************************************************//************************************************************************* * * FUNCTION: code_3i40_14bits() * * PURPOSE: Searches a 14 bit algebraic codebook containing 3 pulses * in a frame of 40 samples. * * DESCRIPTION: * The code length is 40, containing 3 nonzero pulses: i0...i2. * All pulses can have two possible amplitudes: +1 or -1. * Pulse i0 can have 8 possible positions, pulses i1 and i2 can have * 2x8=16 positions. * * i0 : 0, 5, 10, 15, 20, 25, 30, 35. * i1 : 1, 6, 11, 16, 21, 26, 31, 36. * 3, 8, 13, 18, 23, 28, 33, 38. * i2 : 2, 7, 12, 17, 22, 27, 32, 37. * 4, 9, 14, 19, 24, 29, 34, 39. * *************************************************************************/Word16 code_3i40_14bits( Word16 x[], /* i : target vector */ Word16 h[], /* i : impulse response of weighted synthesis filter */ /* h[-L_subfr..-1] must be set to zero. */ Word16 T0, /* i : Pitch lag */ Word16 pitch_sharp, /* i : Last quantized pitch gain */ Word16 code[], /* o : Innovative codebook */ Word16 y[], /* o : filtered fixed codebook excitation */ Word16 * sign /* o : Signs of 3 pulses */){
Word16 codvec[NB_PULSE_3i40_14BITS];
Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE]; Word16 rr[L_CODE][L_CODE]; Word16 i, index, sharp; sharp = pitch_sharp << 1; if ( T0 <L_CODE) { for (i = T0; i < L_CODE; i++) { h[i] += (h[i - T0]*sharp >> 15); } } //cor_h_x(h, x, dn, 1);
cor_h_x2(h, x, dn, 1, NB_TRACK, STEP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -