📄 enc_acelp.c
字号:
psk = sq;
alpk = alp2;
pos = i1;
}
}
p1 -= 32;
if(pos >= 0)
{
ix = i0;
iy = pos;
}
}
/*
* Build the codeword, the filtered codeword and index of codevector.
*/
memset(code, 0, L_SUBFR * sizeof(Word16));
i0 = ix / 2; /* pos of pulse 1 (0..31) */
i1 = iy / 2; /* pos of pulse 2 (0..31) */
if(sign[ix] > 0.0)
{
code[ix] = 512;
p0 = h - ix;
}
else
{
code[ix] = -512;
i0 += 32;
p0 = h_inv - ix;
}
if(sign[iy] > 0.0)
{
code[iy] = 512;
p1 = h - iy;
}
else
{
code[iy] = -512;
i1 += 32;
p1 = h_inv - iy;
}
*index = (i0 << 6) + i1;
for(i = 0; i < L_SUBFR; i++)
{
y[i] = (*p0++) + (*p1++);
}
return;
}
/*
* E_ACELP_4t
*
* Parameters:
* dn I: corr. between target and h[].
* cn I: residual after Word32 term prediction
* H I: impulse response of weighted synthesis filter (Q12)
* code O: algebraic (fixed) codebook excitation (Q9)
* y O: filtered fixed codebook excitation (Q9)
* nbbits I: 20, 36, 44, 52, 64, 72 or 88 bits
* mode I: speech mode
* _index O: index
*
* Function:
* 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
* 4 tracks x 16 positions per track = 64 samples.
*
* 20 bits 5 + 5 + 5 + 5 --> 4 pulses in a frame of 64 samples.
* 36 bits 9 + 9 + 9 + 9 --> 8 pulses in a frame of 64 samples.
* 44 bits 13 + 9 + 13 + 9 --> 10 pulses in a frame of 64 samples.
* 52 bits 13 + 13 + 13 + 13 --> 12 pulses in a frame of 64 samples.
* 64 bits 2 + 2 + 2 + 2 + 14 + 14 + 14 + 14 -->
* 16 pulses in a frame of 64 samples.
* 72 bits 10 + 2 + 10 + 2 + 10 + 14 + 10 + 14 -->
* 18 pulses in a frame of 64 samples.
* 88 bits 11 + 11 + 11 + 11 + 11 + 11 + 11 + 11 -->
* 24 pulses in a frame of 64 samples.
*
* All pulses can have two (2) possible amplitudes: +1 or -1.
* Each pulse can sixteen (16) possible positions.
*
* Returns:
* void
*/
void E_ACELP_4t(Float32 dn[], Float32 cn[], Float32 H[], Word16 code[],
Float32 y[], Word32 nbbits, Word16 mode, Word32 _index[])
{
Float32 sign[L_SUBFR], vec[L_SUBFR];
Float32 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
Float32 rrixix[4][16];
Float32 rrixiy[4][256];
Float32 dn2[L_SUBFR];
Word32 ind[NPMAXPT*4];
Word32 codvec[NB_PULSE_MAX];
Word32 nbpos[10];
Word32 pos_max[4];
Word32 dn2_pos[8 * 4];
UWord8 ipos[NB_PULSE_MAX];
Word32 i, j, k, st, pos = 0, index, track, nb_pulse = 0, nbiter = 4;
Word32 L_index;
Float32 psk, ps, alpk, alp = 0.0F;
Float32 val;
Float32 s, cor;
Float32 *p0, *p1, *p2, *p3, *psign;
Float32 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf;
switch (nbbits)
{
case 20: /* 20 bits, 4 pulses, 4 tracks */
nbiter = 4; /* 4x16x16=1024 loop */
alp = 2.0;
nb_pulse = 4;
nbpos[0] = 4;
nbpos[1] = 8;
break;
#ifdef NEW_28bits
case 28: /* 28 bits, 6 pulses, 4 tracks */
nbiter = 4; /* 4x20x16=1280 loop */
alp = 1.5;
nb_pulse = 6;
nbpos[0] = 4;
nbpos[1] = 8;
nbpos[2] = 8;
break;
#endif
case 36: /* 36 bits, 8 pulses, 4 tracks */
nbiter = 4; /* 4x20x16=1280 loop */
alp = 1.0; /* coeff for sign setting */
nb_pulse = 8;
nbpos[0] = 4;
nbpos[1] = 8;
nbpos[2] = 8;
break;
case 44: /* 44 bits, 10 pulses, 4 tracks */
nbiter = 4; /* 4x26x16=1664 loop */
alp = 1.0;
nb_pulse = 10;
nbpos[0] = 4;
nbpos[1] = 6;
nbpos[2] = 8;
nbpos[3] = 8;
break;
case 52: /* 52 bits, 12 pulses, 4 tracks */
nbiter = 4; /* 4x26x16=1664 loop */
alp = 1.0;
nb_pulse = 12;
nbpos[0] = 4;
nbpos[1] = 6;
nbpos[2] = 8;
nbpos[3] = 8;
break;
case 64: /* 64 bits, 16 pulses, 4 tracks */
nbiter = 3; /* 3x36x16=1728 loop */
alp = 0.8F;
nb_pulse = 16;
nbpos[0] = 4;
nbpos[1] = 4;
nbpos[2] = 6;
nbpos[3] = 6;
nbpos[4] = 8;
nbpos[5] = 8;
break;
case 72: /* 72 bits, 18 pulses, 4 tracks */
nbiter = 3; /* 3x35x16=1680 loop */
alp = 0.75F;
nb_pulse = 18;
nbpos[0] = 2;
nbpos[1] = 3;
nbpos[2] = 4;
nbpos[3] = 5;
nbpos[4] = 6;
nbpos[5] = 7;
nbpos[6] = 8;
break;
case 88: /* 88 bits, 24 pulses, 4 tracks */
if (mode > MODE_23k)
{
nbiter = 1;
}
else
{
nbiter = 2; /* 2x53x16=1696 loop */
}
alp = 0.5;
nb_pulse = 24;
nbpos[0] = 2;
nbpos[1] = 2;
nbpos[2] = 3;
nbpos[3] = 4;
nbpos[4] = 5;
nbpos[5] = 6;
nbpos[6] = 7;
nbpos[7] = 8;
nbpos[8] = 8;
nbpos[9] = 8;
break;
}
/*
* Find sign for each pulse position.
*/
/* calculate energy for normalization of cn[] and dn[] */
val = (cn[0] * cn[0]) + 1.0F;
cor = (dn[0] * dn[0]) + 1.0F;
for (i = 1; i < L_SUBFR; i += 7)
{
val += (cn[i] * cn[i]);
cor += (dn[i] * dn[i]);
val += (cn[i + 1] * cn[i + 1]);
cor += (dn[i + 1] * dn[i + 1]);
val += (cn[i + 2] * cn[i + 2]);
cor += (dn[i + 2] * dn[i + 2]);
val += (cn[i + 3] * cn[i + 3]);
cor += (dn[i + 3] * dn[i + 3]);
val += (cn[i + 4] * cn[i + 4]);
cor += (dn[i + 4] * dn[i + 4]);
val += (cn[i + 5] * cn[i + 5]);
cor += (dn[i + 5] * dn[i + 5]);
val += (cn[i + 6] * cn[i + 6]);
cor += (dn[i + 6] * dn[i + 6]);
}
s = (Float32)sqrt(cor / val);
for (j = 0; j < L_SUBFR; j++)
{
cor = (s * cn[j]) + (alp * dn[j]);
if (cor >= 0.0F)
{
sign[j] = 1.0F;
vec[j] = -1.0F;
dn2[j] = cor; /* dn2[] = mix of dn[] and cn[] */
}
else
{
sign[j] = -1.0F;
vec[j] = 1.0F;
dn[j] = -dn[j]; /* modify dn[] according to the fixed sign */
dn2[j] = -cor; /* dn2[] = mix of dn[] and cn[] */
}
}
/*
* Select 8 position per track according to dn2[].
*/
for (i = 0; i < 4; i++)
{
for (k = 0; k < 8; k++)
{
ps = -1;
for (j = i; j < L_SUBFR; j += 4)
{
if (dn2[j] > ps)
{
ps = dn2[j];
pos = j;
}
}
dn2[pos] = (Float32)k - 8; /* dn2 < 0 when position is selected */
dn2_pos[i * 8 + k] = pos;
}
pos_max[i] = dn2_pos[i * 8];
}
/*
* Compute h_inv[i].
*/
memset(h_buf, 0, L_SUBFR * sizeof(Float32));
memset(h_buf + (2 * L_SUBFR), 0, L_SUBFR * sizeof(Float32));
h = h_buf + L_SUBFR;
h_inv = h_buf + (3 * L_SUBFR);
memcpy(h, H, L_SUBFR * sizeof(Float32));
h_inv[0] = -h[0];
h_inv[1] = -h[1];
h_inv[2] = -h[2];
h_inv[3] = -h[3];
for(i = 4; i < L_SUBFR; i += 6)
{
h_inv[i] = -h[i];
h_inv[i + 1] = -h[i + 1];
h_inv[i + 2] = -h[i + 2];
h_inv[i + 3] = -h[i + 3];
h_inv[i + 4] = -h[i + 4];
h_inv[i + 5] = -h[i + 5];
}
/*
* Compute rrixix[][] needed for the codebook search.
*/
/* storage order --> i3i3, i2i2, i1i1, i0i0 */
/* Init pointers to last position of rrixix[] */
p0 = &rrixix[0][16 - 1];
p1 = &rrixix[1][16 - 1];
p2 = &rrixix[2][16 - 1];
p3 = &rrixix[3][16 - 1];
ptr_h1 = h;
cor = 0.0F;
for(i = 0; i < 16; i++)
{
cor += (*ptr_h1) * (*ptr_h1);
ptr_h1++;
*p3-- = cor * 0.5F;
cor += (*ptr_h1) * (*ptr_h1);
ptr_h1++;
*p2-- = cor * 0.5F;
cor += (*ptr_h1) * (*ptr_h1);
ptr_h1++;
*p1-- = cor * 0.5F;
cor += (*ptr_h1) * (*ptr_h1);
ptr_h1++;
*p0-- = cor * 0.5F;
}
/*
* Compute rrixiy[][] needed for the codebook search.
*/
/* storage order --> i2i3, i1i2, i0i1, i3i0 */
pos = 256 - 1;
ptr_hf = h + 1;
for(k = 0; k < 16; k++)
{
p3 = &rrixiy[2][pos];
p2 = &rrixiy[1][pos];
p1 = &rrixiy[0][pos];
p0 = &rrixiy[3][pos - 16];
cor = 0.0F;
ptr_h1 = h;
ptr_h2 = ptr_hf;
for(i = k + 1; i < 16; i++)
{
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p3 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p2 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p1 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p0 = cor;
p3 -= (16 + 1);
p2 -= (16 + 1);
p1 -= (16 + 1);
p0 -= (16 + 1);
}
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p3 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p2 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p1 = cor;
pos -= 16;
ptr_hf += 4;
}
/* storage order --> i3i0, i2i3, i1i2, i0i1 */
pos = 256 - 1;
ptr_hf = h + 3;
for(k = 0; k < 16; k++)
{
p3 = &rrixiy[3][pos];
p2 = &rrixiy[2][pos - 1];
p1 = &rrixiy[1][pos - 1];
p0 = &rrixiy[0][pos - 1];
cor = 0.0F;
ptr_h1 = h;
ptr_h2 = ptr_hf;
for(i= k + 1; i < 16; i++ )
{
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p3 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p2 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p1 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p0 = cor;
p3 -= (16 + 1);
p2 -= (16 + 1);
p1 -= (16 + 1);
p0 -= (16 + 1);
}
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p3 = cor;
pos--;
ptr_hf += 4;
}
/*
* Modification of rrixiy[][] to take signs into account.
*/
p0 = &rrixiy[0][0];
for (k = 0; k < 4; k++)
{
for(i = k; i < L_SUBFR; i += 4)
{
psign = sign;
if (psign[i] < 0.0F)
{
psign = vec;
}
j = (k + 1) % 4;
p0[0] = p0[0] * psign[j];
p0[1] = p0[1] * psign[j + 4];
p0[2] = p0[2] * psign[j + 8];
p0[3] = p0[3] * psign[j + 12];
p0[4] = p0[4] * psign[j + 16];
p0[5] = p0[5] * psign[j + 20];
p0[6] = p0[6] * psign[j + 24];
p0[7] = p0[7] * psign[j + 28];
p0[8] = p0[8] * psign[j + 32];
p0[9] = p0[9] * psign[j + 36];
p0[10] = p0[10] * psign[j + 40];
p0[11] = p0[11] * psign[j + 44];
p0[12] = p0[12] * psign[j + 48];
p0[13] = p0[13] * psign[j + 52];
p0[14] = p0[14] * psign[j + 56];
p0[15] = p0[15] * psign[j + 60];
p0 += 16;
}
}
/*
* Deep first search:
* ------------------
* 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests
* 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
* 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
* +(8x16)+(8x16)) = 1248 tests
* 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
* +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
*/
psk = -1.0;
alpk = 1.0;
for (k = 0; k < nbiter; k++)
{
for (i = 0; i < nb_pulse - (nb_pulse % 3); i += 3)
{
ipos[i] = E_ROM_tipos[(k * 4) + i];
ipos[i + 1] = E_ROM_tipos[(k * 4) + i + 1];
ipos[i + 2] = E_ROM_tipos[(k * 4) + i + 2];
}
for (; i < nb_pulse; i ++)
{
ipos[i] = E_ROM_tipos[(k * 4) + i];
}
#ifdef NEW_28bits
if ((nbbits == 20) | (nbbits == 28))
#else
if (nbbits == 20)
#endif
{
pos = 0;
ps = 0.0F;
alp = 0.0F;
memset(vec, 0, L_SUBFR * sizeof(Float32));
#ifdef NEW_28bits
if (nbbits == 28)
{
ipos[4] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -