📄 acelp_e.c
字号:
h = h_buf;
h_inv = h_buf + (2*L_SUBFR);
for (i=0; i<L_SUBFR; i++) {
*h++ = 0;
*h_inv++ = 0;
}
/* Compute correlation between target x[] and H[] */
cor_h_x_e(H, x, dn);
/* find the sign of each pulse position */
set_sign(32767, cn, dn, sign, vec, pos_max, corr);
/* Compute correlations of h[] needed for the codebook search. */
cor_h_e(H, sign, vec, h, h_inv, rrixix, rrixiy);
/*-------------------------------------------------------------------*
* Search starting position for pulse i0 and i1. *
* In the deep first search, we start 4 times with different *
* position for i0 and i1. At all, we have 5 possible positions to *
* start (position 0 to 5). The following loop remove 1 position *
* to keep 4 positions for deep first search step. *
*-------------------------------------------------------------------*/
s = L_add(corr[4], corr[0]);
for (k=0; k<NB_TRACK-1; k++) corr[k] = L_add(corr[k], corr[k+1]);
corr[4] = s;
for (k=0; k<3; k++) {
s = corr[0];
track = 0;
for (i=1; i<NB_TRACK; i++) {
L_tmp = L_sub(corr[i], s);
if (L_tmp > 0) {
s = corr[i];
track = i;
}
}
corr[track] = -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 = -1;
alpk = 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 = add(dn[ix], dn[iy]);
i = mult(ix, Q15_1_5);
j = mult(iy, Q15_1_5);
alp = add(rrixix[ipos[k]][i], rrixix[ipos[k+1]][j]);
i = add(shl(i,3), j);
alp = add(alp, rrixiy[ipos[k]][i]);
ip[0] = ix;
ip[1] = iy;
for (i=0; i<L_SUBFR; i++) vec[i] = 0;
/* stage 2..5: fix pulse i2,i3,i4,i5,i6,i7,i8 and i9 */
for (j=2; j<10; j+=2) {
/*--------------------------------------------------*
* Store all impulse response of all fixed pulses *
* in vector vec[] for the "cor_h_vec()" function. *
*--------------------------------------------------*/
if (sign[ix] < 0) p0 = h_inv - ix;
else p0 = h - ix;
if (sign[iy] < 0) p1 = h_inv - iy;
else p1 = h - iy;
for (i=0; i<L_SUBFR; i++) {
vec[i] = add(vec[i], add(*p0, *p1));
p0++; p1++;
}
/*--------------------------------------------------*
* Calculate correlation of all possible positions *
* of the next 2 pulses with previous fixed pulses. *
* Each pulse can have 8 possible positions *
*--------------------------------------------------*/
cor_h_vec(h, vec, ipos[k+j], sign, rrixix, cor_x);
cor_h_vec(h, vec, ipos[k+j+1], sign, rrixix, cor_y);
/*--------------------------------------------------*
* Fix 2 pulses, try 8x8 = 64 positions. *
*--------------------------------------------------*/
search_ixiy(ipos[k+j], ipos[k+j+1], &ps, &alp, &ix, &iy,
dn, cor_x, cor_y, rrixiy);
ip[j] = ix;
ip[j+1] = iy;
}
/* memorise new codevector if it's better than the last one. */
ps = mult(ps,ps);
s = L_msu(L_mult(alpk,ps),psk,alp);
if (s > 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<NB_TRACK; i++) indx[i] = indx[i] & (Word16)127;
return;
}
/*-------------------------------------------------------------------*
* Function cor_h_x_e() *
* ~~~~~~~~~~~~~~~~~~~ *
* Compute correlation between target "x[]" and "h[]". *
*-------------------------------------------------------------------*/
static void cor_h_x_e(
Word16 h[], /* (i) Q12 : impulse response of weighted synthesis filter */
Word16 x[], /* (i) Q0 : correlation between target and h[] */
Word16 dn[] /* (o) Q0 : correlation between target and h[] */
)
{
Word16 i, j, k;
Word32 s, y32[L_SUBFR], max, tot, L_tmp;
/* first keep the result on 32 bits and find absolute maximum */
tot = 5;
for (k=0; k<NB_TRACK; k++) {
max = 0;
for (i=k; i<L_SUBFR; i+=STEP) {
s = 0;
for (j=i; j<L_SUBFR; j++) s = L_mac(s, x[j], h[j-i]);
y32[i] = s;
s = L_abs(s);
L_tmp = L_sub(s, max);
if (L_tmp > (Word32)0) max = s;
}
tot = L_add(tot, L_shr(max, 1)); /* tot += (2.0 x max) / 4.0 */
}
/* Find the number of right shifts to do on y32[] so that */
/* 2.0 x sumation of all max of dn[] in each track not saturate. */
j = sub(norm_l(tot), 2); /* multiply tot by 4 */
for (i=0; i<L_SUBFR; i++) {
dn[i] = round(L_shl(y32[i], j));
}
return;
}
/*-------------------------------------------------------------------*
* Function cor_h_vec() *
* ~~~~~~~~~~~~~~~~~~~~~ *
* Compute correlations of h[] with vec[] for the specified track. *
*-------------------------------------------------------------------*
*-------------------------------------------------------------------*/
static void cor_h_vec(
Word16 h[], /* (i) scaled impulse response */
Word16 vec[], /* (i) vector to correlate with h[] */
Word16 track, /* (i) track to use */
Word16 sign[], /* (i) sign vector */
Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
Word16 cor[] /* (o) result of correlation (NB_POS elements) */
)
{
Word16 i, j, pos;
Word16 *p0, *p1, *p2;
Word32 s;
p0 = rrixix[track];
pos = track;
for (i=0; i<NB_POS; i++, pos+=STEP) {
s = 0;
p1 = h;
p2 = &vec[pos];
for (j=pos; j<L_SUBFR; j++) {
s = L_mac(s, *p1, *p2);
p1++; p2++;
}
cor[i] = add(mult(round(s), sign[pos]), *p0++);
}
return;
}
/*-------------------------------------------------------------------*
* Function search_ixiy() *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Find the best positions of 2 pulses in a subframe. *
*-------------------------------------------------------------------*/
static void search_ixiy(
Word16 track_x, /* (i) track of pulse 1 */
Word16 track_y, /* (i) track of pulse 2 */
Word16 *ps, /* (i/o) correlation of all fixed pulses */
Word16 *alp, /* (i/o) energy of all fixed pulses */
Word16 *ix, /* (o) position of pulse 1 */
Word16 *iy, /* (o) position of pulse 2 */
Word16 dn[], /* (i) corr. between target and h[] */
Word16 cor_x[], /* (i) corr. of pulse 1 with fixed pulses */
Word16 cor_y[], /* (i) corr. of pulse 2 with fixed pulses */
Word16 rrixiy[][MSIZE] /* (i) corr. of pulse 1 with pulse 2 */
)
{
Word16 x, y, pos;
Word16 ps1, ps2, sq, sqk;
Word16 alp1, alp2, alpk;
Word16 *p0, *p1, *p2;
Word32 s;
p0 = cor_x;
p1 = cor_y;
p2 = rrixiy[track_x];
sqk = -1;
alpk = 1;
for (x=track_x; x<L_SUBFR; x+=STEP) {
ps1 = add(*ps, dn[x]);
alp1 = add(*alp, *p0++);
pos = -1;
for (y=track_y; y<L_SUBFR; y+=STEP) {
ps2 = add(ps1, dn[y]);
alp2 = add(alp1, add(*p1++, *p2++));
sq = mult(ps2, ps2);
s = L_msu(L_mult(alpk,sq),sqk,alp2);
if (s > 0) {
sqk = sq;
alpk = alp2;
pos = y;
}
}
p1 -= NB_POS;
if (pos >= 0) {
*ix = x;
*iy = pos;
}
}
*ps = add(*ps, add(dn[*ix], dn[*iy]));
*alp = alpk;
return;
}
/*-------------------------------------------------------------------*
* Function set_sign() *
* ~~~~~~~~~~~~~~~~~~~~ *
* Set the sign of each pulse position. *
*-------------------------------------------------------------------*/
static void set_sign(
Word16 fac_cn, /* (i) Q15: residual weight for sign determination */
Word16 cn[], /* (i) Q0 : residual after long term prediction */
Word16 dn[], /* (i) Q0 : correlation between target and h[] */
Word16 sign[], /* (o) Q15: sign vector (sign of each position) */
Word16 inv_sign[], /* (o) Q15: inverse of sign[] */
Word16 pos_max[], /* (o) : pos of max of correlation */
Word32 corr[] /* (o) : correlation of each track */
)
{
Word16 i, k, pos, k_cn, k_dn, val;
Word32 s, max;
/* calculate energy for normalization of cn[] and dn[] */
s = 0;
for (i=0; i<L_SUBFR; i++) s = L_mac(s, cn[i], cn[i]);
if (s < 512) s = 512;
s = Inv_sqrt(s);
k_cn = extract_h(L_shl(s, 5)); /* k_cn = 11..23170 */
k_cn = mult(k_cn, fac_cn);
s = 0;
for (i=0; i<L_SUBFR; i++) s = L_mac(s, dn[i], dn[i]);
if (s < 512) s = 512;
s = Inv_sqrt(s);
k_dn = extract_h(L_shl(s, 5)); /* k_dn = 11..23170 */
/* set sign according to en[] = k_cn*cn[] + k_dn*dn[] */
/* find position of maximum of correlation in each track */
for (k=0; k<NB_TRACK; k++) {
max = -1;
for (i=k; i<L_SUBFR; i+=STEP) {
val = dn[i];
s = L_mac(L_mult(k_cn, cn[i]), k_dn, val);
if (s >= 0) {
sign[i] = 32767L; /* sign = +1 (Q15) */
inv_sign[i] = -32768L;
}
else {
sign[i] = -32768L; /* sign = -1 (Q15) */
inv_sign[i] = 32767L;
val = negate(val);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -