📄 c8_35pf.c
字号:
/* 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 + (Shortword) 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 = vec;
for (j = ((k + 1) % NB_TRACK); j < L_SUBFR; j += STEP)
{
*p0++ = mult(*p0, psign[j]);
}
}
}
/*-------------------------------------------------------------------*
* Deep first search: 4 iterations of 264 tests = 1056 tests. *
* *
* Stages of deep first search: *
* stage 1 : fix i0 and i1 --> try 6x11 = 66 positions *
* stage 2 : fix i2 and i3 --> try 6x11 = 66 positions. *
* stage 3 : fix i4 and i5 --> try 6x11 = 66 positions. *
* stage 4 : fix i6 and i7 --> try 6x11 = 66 positions. *
*-------------------------------------------------------------------*/
/* default value */
psk = -1;
alpk = 1;
for (i = 0; i < NB_PULSE; i++)
codvec[i] = i;
for (k = 0; k < NB_ITER; k++)
{
/* Change back to the search strategy used in the float point simulation */
alp = 0;
ps = 0;
search_ixiy(ipos[k], ipos[k + 1], &ps, &alp, &ix, &iy,
dn, cn, rrixix[ipos[k]], rrixix[ipos[k+1]], rrixiy);
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 and i7 */
for (j = 2; j < NB_PULSE; 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++));
}
/*--------------------------------------------------*
* 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 6x11 = 66 positions. *
*--------------------------------------------------*/
search_ixiy(ipos[k + j], ipos[k + j + 1], &ps, &alp, &ix, &iy,
dn, cn, 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 < NB_PULSE; i++)
codvec[i] = ip[i];
codvec[8] = k;
}
} /* end of for (k=0; k<NB_ITER; k++) */
/*-------------------------------------------------------------------*
* Build the codeword, the filtered codeword and index of codevector.*
*-------------------------------------------------------------------*/
for (i = 0; i < l_subfr; i++)
{
code[i] = 0;
}
for (i = 0; i < NB_TRACK; i++)
{
indx[i] = -1;
}
for (k = 0; k < NB_PULSE; k++)
{
i = codvec[k]; /* read pulse position */
j = sign[i]; /* read sign */
index = mult(i, Q15_1_5); /* index = pos/5 */
/* track = pos%5 */
track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));
if (j > 0)
{
if (i < l_subfr)
code[i] = add(code[i], 4096); /* codeword in Q12 format */
codvec[k] += (2 * L_SUBFR);
}
else
{
if (i < l_subfr)
code[i] = sub(code[i], 4096); /* codeword in Q12 format */
index = add(index, 16);
}
/*-------------------------------------------------------*
* Quantization of 2 pulses with 8 or 9 bits: *
* 1 bit for 2 pulses sign. (b8) *
* 7 bits for 2 pulses in same track (b7..b4) *
* 8 bits for 2 pulses in different track (b7..b4) *
*-------------------------------------------------------*/
if (indx[track] < 0)
{
indx[track] = index;
}
else
{
if (((index ^ indx[track]) & 16) == 0)
{
/* sign of 1st pulse == sign of 2th pulse */
if (sub(indx[track], index) <= 0)
{
indx[track] = shl((indx[track] & 16), 3)
+ shr(extract_l(L_mult((indx[track] & 15), NB_POS)), 1)
+ (index & 15);
}
else
{
indx[track] = shl((index & 16), 3)
+ shr(extract_l(L_mult((index & 15), NB_POS)), 1)
+ (indx[track] & 15);
}
}
else
{
/* sign of 1st pulse != sign of 2th pulse */
if (sub((indx[track] & 15), (index & 15)) <= 0)
{
indx[track] = shl((index & 16), 3)
+ shr(extract_l(L_mult((index & 15), NB_POS)), 1)
+ (indx[track] & 15);
}
else
{
indx[track] = shl((indx[track] & 16), 3)
+ shr(extract_l(L_mult((indx[track] & 15), NB_POS)), 1)
+ (index & 15);
}
}
}
}
if (codvec[8] == 0)
{
i = indx[3];
j = indx[4];
}
else if (codvec[8] == 1)
{
i = indx[4];
j = indx[0];
indx[0] = indx[1];
indx[1] = indx[2];
indx[2] = indx[3];
}
else if (codvec[8] == 2)
{
i = indx[0];
j = indx[1];
indx[0] = indx[2];
indx[1] = indx[3];
indx[2] = indx[4];
}
else if (codvec[8] == 3)
{
i = indx[1];
j = indx[2];
indx[1] = indx[4];
indx[2] = indx[0];
indx[0] = indx[3];
}
indx[3] = shl(codvec[8], 9)
+ shl((i & 16), 4)
+ shl((j & 16), 3)
+ shr(extract_l(L_mult((i & 15), NB_POS)), 1)
+ (j & 15);
for (i = 0; i < l_subfr; i++)
{
h[i] = H[i];
h_inv[i] = negate(h[i]);
}
p0 = h_inv - codvec[0];
p1 = h_inv - codvec[1];
p2 = h_inv - codvec[2];
p3 = h_inv - codvec[3];
p4 = h_inv - codvec[4];
p5 = h_inv - codvec[5];
p6 = h_inv - codvec[6];
p7 = h_inv - codvec[7];
for (i = 0; i < l_subfr; i++)
{
s = L_mult(*p0++, 8192); /* Q12 --> Q10 */
s = L_mac(s, *p1++, 8192);
s = L_mac(s, *p2++, 8192);
s = L_mac(s, *p3++, 8192);
s = L_mac(s, *p4++, 8192);
s = L_mac(s, *p5++, 8192);
s = L_mac(s, *p6++, 8192);
s = L_mac(s, *p7++, 8192);
y[i] = round32(s);
}
return;
}
/*-------------------------------------------------------------------*
* Function cor_h_vec() *
* ~~~~~~~~~~~~~~~~~~~~~ *
* Compute correlations of h[] with vec[] for the specified track. *
*-------------------------------------------------------------------*/
static void cor_h_vec(
Shortword h[], /* (i) scaled impulse response */
Shortword vec[], /* (i) vector to correlate with h[] */
Shortword track, /* (i) track to use */
Shortword sign[], /* (i) sign vector */
Shortword rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */
Shortword cor[] /* (o) result of correlation (NB_POS elements) */
)
{
Shortword i, j, pos;
Shortword *p0, *p1, *p2;
Longword 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++);
cor[i] = add(mult(round32(s), sign[pos]), *p0++);
}
return;
}
/*-------------------------------------------------------------------*
* Function search_ixiy() *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Find the best positions of 2 pulses in a subframe. *
*-------------------------------------------------------------------*/
static void search_ixiy(
Shortword track_x, /* (i) track of pulse 1 */
Shortword track_y, /* (i) track of pulse 2 */
Shortword * ps, /* (i/o) correlation of all fixed pulses */
Shortword * alp, /* (i/o) energy of all fixed pulses */
Shortword * ix, /* (o) position of pulse 1 */
Shortword * iy, /* (o) position of pulse 2 */
Shortword dn[], /* (i) corr. between target and h[] */
Shortword cn[], /* (i) corr. vector (search if cn[]>=0) */
Shortword cor_x[], /* (i) corr. of pulse 1 with fixed pulses */
Shortword cor_y[], /* (i) corr. of pulse 2 with fixed pulses */
Shortword rrixiy[][MSIZE] /* (i) corr. of pulse 1 with pulse 2 */
)
{
Shortword x, y, pos;
Shortword ps1, ps2, sq, sqk;
Shortword alp1, alp2, alpk;
Shortword *p0, *p1, *p2;
Longword s;
p0 = cor_x;
p1 = cor_y;
p2 = rrixiy[track_x];
/* default value */
sqk = -1;
alpk = 1;
*ix = track_x;
*iy = track_y;
for (x = track_x; x < L_SUBFR; x += STEP)
{
ps1 = add(*ps, dn[x]);
alp1 = add(*alp, *p0++);
if (cn[x] >= 0)
{
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;
}
}
else
{
p2 += NB_POS;
}
}
*ps = add(*ps, add(dn[*ix], dn[*iy]));
*alp = alpk;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -