📄 acelp_e.c
字号:
dn[i] = val; /* modify dn[] according to the fixed sign */
s = L_abs(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(
Word16 H[], /* (i) Q12 :Impulse response of filters */
Word16 sign[], /* (i) Q15: sign vector */
Word16 inv_sign[], /* (i) Q15: inverse of sign[] */
Word16 h[], /* (o) : scaled h[] */
Word16 h_inv[], /* (o) : inverse of scaled h[] */
Word16 rrixix[][NB_POS], /* (o) energy of h[]. */
Word16 rrixiy[][MSIZE] /* (o) correlation between 2 pulses. */
)
{
Word16 i, j, k, pos;
Word16 *ptr_h1, *ptr_h2, *ptr_hf, *psign;
Word16 *p0, *p1, *p2, *p3, *p4;
Word32 cor;
/*------------------------------------------------------------*
* normalize h[] for maximum precision on correlation. *
*------------------------------------------------------------*/
cor = 0;
for(i=0; i<L_SUBFR; i++) cor = L_mac(cor, H[i], H[i]);
/* scale h[] with shift operation */
k = norm_l(cor);
k = shr(k, 1);
for(i=0; i<L_SUBFR; i++) h[i] = shl(H[i], k);
cor = L_shl(cor, add(k, k));
/*------------------------------------------------------------*
* Scaling h[] with a factor (0.5 < fac < 0.25) *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* extract_h(cor) = 8192 .. 32768 --> scale to 4096 (1/8 Q15) *
* *
* 4096 (1/8) = fac^2 * extract_h(cor) *
* fac = sqrt(4096/extract_h(cor)) *
* *
* fac = 1/sqrt(cor/4096) * 256 = 0.125 to 0.5 *
*------------------------------------------------------------*/
cor = L_shr(cor, 12);
k = extract_h(L_shl(Inv_sqrt(cor), 8));
for(i=0; i<L_SUBFR; i++) {
h[i] = mult(h[i], k);
h_inv[i] = negate(h[i]);
}
/*------------------------------------------------------------*
* Compute rrixix[][] needed for the codebook search. *
* This algorithm compute impulse response energy of all *
* positions (8) in each track (5). Total = 5x8 = 40. *
*------------------------------------------------------------*/
/* storage order --> 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 = 0x00010000L; /* 1.0 (for rounding) */
for(i=0; i<NB_POS; i++) {
cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
*p4-- = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
*p3-- = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
*p2-- = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
*p1-- = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
*p0-- = extract_h(cor);
}
/* Divide all elements of rrixix[][] by 2. */
p0 = &rrixix[0][0];
for(i=0; i<L_SUBFR; i++) *p0++ = shr(*p0, 1);
/*------------------------------------------------------------*
* Compute rrixiy[][] needed for the codebook search. *
* This algorithm compute correlation between 2 pulses *
* (2 impulses responses) in 5 possible adjacents tracks. *
* (track 0-1, 1-2, 2-3, 3-4 and 4-0). Total = 5x8x8 = 320. *
*------------------------------------------------------------*/
/* storage order --> i3i4, i2i3, i1i2, i0i1, i4i0 */
pos = MSIZE-1;
ptr_hf = h + 1;
for(k=0; k<NB_POS; k++) {
p4 = &rrixiy[3][pos];
p3 = &rrixiy[2][pos];
p2 = &rrixiy[1][pos];
p1 = &rrixiy[0][pos];
p0 = &rrixiy[4][pos-NB_POS];
cor = 0x00008000L; /* 0.5 (for rounding) */
ptr_h1 = h;
ptr_h2 = ptr_hf;
for(i=k+(Word16)1; i<NB_POS; i++ ) {
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p4 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p3 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p2 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p1 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p0 = extract_h(cor);
p4 -= (NB_POS+1);
p3 -= (NB_POS+1);
p2 -= (NB_POS+1);
p1 -= (NB_POS+1);
p0 -= (NB_POS+1);
}
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p4 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p3 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p2 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p1 = extract_h(cor);
pos -= NB_POS;
ptr_hf += STEP;
}
/* storage order --> i4i0, i3i4, i2i3, i1i2, i0i1 */
pos = MSIZE-1;
ptr_hf = h + 4;
for(k=0; k<NB_POS; k++) {
p4 = &rrixiy[4][pos];
p3 = &rrixiy[3][pos-1];
p2 = &rrixiy[2][pos-1];
p1 = &rrixiy[1][pos-1];
p0 = &rrixiy[0][pos-1];
cor = 0x00008000L; /* 0.5 (for rounding) */
ptr_h1 = h;
ptr_h2 = ptr_hf;
for(i=k+(Word16)1; i<NB_POS; i++ ) {
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p4 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p3 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p2 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p1 = extract_h(cor);
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p0 = extract_h(cor);
p4 -= (NB_POS+1);
p3 -= (NB_POS+1);
p2 -= (NB_POS+1);
p1 -= (NB_POS+1);
p0 -= (NB_POS+1);
}
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p4 = extract_h(cor);
pos--;
ptr_hf += STEP;
}
/*------------------------------------------------------------*
* Modification of rrixiy[][] to take signs into account. *
*------------------------------------------------------------*/
p0 = &rrixiy[0][0];
for (k=0; k<NB_TRACK; k++) {
for(i=k; i<L_SUBFR; i+=STEP) {
psign = sign;
if (psign[i] < 0) psign = inv_sign;
for(j=(Word16)((k+(Word16)1)%NB_TRACK); j<(Word16)L_SUBFR; j+=(Word16)STEP) {
*p0 = mult(*p0, psign[j]); p0++;
}
}
}
return;
}
/*-------------------------------------------------------------------*
* Function build_code() *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* Build the codeword, the filtered codeword and index of codevector.*
*-------------------------------------------------------------------*/
static void build_code(
Word16 codvec[], /* (i) : positions of each pulse */
Word16 sign[], /* (i) Q15: sign vector */
Word16 nb_of_pulse, /* (i) : number of pulses */
Word16 H[], /* (i) Q12: impulse response of weighted synthesis filter */
Word16 code[], /* (o) Q12: algebraic (fixed) codebook excitation */
Word16 y[], /* (o) Q11: filtered fixed codebook excitation */
Word16 indx[] /* (o) : index of pulses (5 words, 1 per track). */
)
{
Word16 i, j, k, index, track;
for (i=0; i<L_SUBFR; i++) H[i] = shr(H[i], 1); /* Q12 to Q11 */
for (i=0; i<L_SUBFR; i++) {
code[i] = 0;
y[i] = 0;
}
for (i=0; i<NB_TRACK; i++) indx[i] = -1;
for (k=0; k<nb_of_pulse; k++) {
i = codvec[k]; /* read pulse position */
index = mult(i, Q15_1_5); /* index = pos/5 */
/* track = pos%5 */
track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));
/* codeword & filtered codeword */
if (sign[i] > 0) {
code[i] = add(code[i], 4096); /* Q12 */
for (i=codvec[k], j=0; i<L_SUBFR; i++, j++) y[i] = add(y[i], H[j]);
}
else {
code[i] = sub(code[i], 4096); /* Q12 */
index = add(index, 8);
for (i=codvec[k], j=0; i<L_SUBFR; i++, j++) y[i] = sub(y[i], H[j]);
}
/* quantize position & sign */
if (indx[track] < 0) {
indx[track] = index;
}
else {
if (((index ^ indx[track]) & 8) == 0) {
/* sign of 1st pulse == sign of 2th pulse */
if (sub(indx[track],index) <= 0) {
indx[track] = add(shl(indx[track], (Word16)4), index) | (Word16)256;
}
else {
indx[track] = add(shl(index, (Word16)4), indx[track]) | (Word16)256;
}
}
else {
/* sign of 1st pulse != sign of 2th pulse */
if (sub((Word16)(indx[track] & (Word16)7),(Word16)(index & (Word16)7)) <= 0) {
indx[track] = add(shl(index, (Word16)4), indx[track]) | (Word16)256;
}
else {
indx[track] = add(shl(indx[track], (Word16)4), index) | (Word16)256;
}
}
}
}
return;
}
/*-------------------------------------------------------------------*
* Function pack3() *
* ~~~~~~~~~~~~~~~~~ *
* build index of 3 pulses. (pack 3x4 bits into 10 bits). *
*-------------------------------------------------------------------*/
static Word16 pack3(Word16 index1, Word16 index2, Word16 index3)
{
Word16 k, index, tmp;
if ((index1 & 7) > (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 = add(add((Word16)(shr(index1, 1) & (Word16)4),(Word16)(shr(index2, 2) & (Word16)2)), (Word16)(shr(index3, 3) & (Word16)1));
switch (k) {
case 0:
case 7:
index = add(add(shl((Word16)(index1 & (Word16)7), (Word16)7), shl((Word16)(index2 & (Word16)7), (Word16)4)), index3);
break;
case 1:
case 6:
index = add(add(shl((Word16)(index3 & (Word16)7), (Word16)7), shl((Word16)(index1 & (Word16)7), (Word16)4)), index2);
break;
case 2:
case 5:
index = add(add(shl((Word16)(index2 & (Word16)7), (Word16)7), shl((Word16)(index1 & (Word16)7), (Word16)4)), index3);
break;
case 3:
case 4:
index = add(add(shl((Word16)(index2 & (Word16)7), (Word16)7), shl((Word16)(index3 & (Word16)7), (Word16)4)), index1);
break;
}
return (index);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -