📄 enc_acelp.c
字号:
if (((pos1 ^ pos2) & nb_pos) == 0)
{
index = E_ACELP_quant_2p_2N1(pos1, pos2, (N - 1));
index += (pos1 & nb_pos) << N;
index += E_ACELP_quant_1p_N1(pos3, N) << (2 * N);
}
else if (((pos1 ^ pos3) & nb_pos) == 0)
{
index = E_ACELP_quant_2p_2N1(pos1, pos3, (N - 1));
index += (pos1 & nb_pos) << N;
index += E_ACELP_quant_1p_N1(pos2, N) << (2 * N);
}
else
{
index = E_ACELP_quant_2p_2N1(pos2, pos3, (N - 1));
index += (pos2 & nb_pos) << N;
index += E_ACELP_quant_1p_N1(pos1, N) << (2 * N);
}
return(index);
}
/*
* E_ACELP_quant_4p_4N1
*
* Parameters:
* pos1 I: position of the pulse 1
* pos2 I: position of the pulse 2
* pos3 I: position of the pulse 3
* pos4 I: position of the pulse 4
* N I: number of bits for position
*
* Function:
* Quantization of 4 pulses with 4*N+1 bits
*
* Returns:
* (4*N)+1 bits
*/
static Word32 E_ACELP_quant_4p_4N1(Word32 pos1, Word32 pos2, Word32 pos3,
Word32 pos4, Word32 N)
{
Word32 nb_pos;
Word32 index;
nb_pos = (1 << (N - 1));
/*
* Quantization of 4 pulses with 4*N+1 bits:
*/
if (((pos1 ^ pos2) & nb_pos) == 0)
{
index = E_ACELP_quant_2p_2N1(pos1, pos2, (N - 1));
index += (pos1 & nb_pos) << N;
index += E_ACELP_quant_2p_2N1(pos3, pos4, N) << (2 * N);
}
else if (((pos1 ^ pos3) & nb_pos) == 0)
{
index = E_ACELP_quant_2p_2N1(pos1, pos3, (N - 1));
index += (pos1 & nb_pos) << N;
index += E_ACELP_quant_2p_2N1(pos2, pos4, N) << (2 * N);
}
else
{
index = E_ACELP_quant_2p_2N1(pos2, pos3, (N - 1));
index += (pos2 & nb_pos) << N;
index += E_ACELP_quant_2p_2N1(pos1, pos4, N) << (2 * N);
}
return(index);
}
/*
* E_ACELP_quant_4p_4N
*
* Parameters:
* pos I: position of the pulse 1..4
* N I: number of bits for position
*
* Function:
* Quantization of 4 pulses with 4*N bits
*
* Returns:
* 4*N bits
*/
static Word32 E_ACELP_quant_4p_4N(Word32 pos[], Word32 N)
{
Word32 i, j, k, nb_pos, n_1;
Word32 posA[4], posB[4];
Word32 index=0;
n_1 = N - 1;
nb_pos = (1 << n_1);
i = 0;
j = 0;
for (k = 0; k < 4; k++)
{
if ((pos[k] & nb_pos) == 0)
{
posA[i++] = pos[k];
}
else
{
posB[j++] = pos[k];
}
}
switch (i)
{
case 0:
index = 1 << ((4 * N) - 3);
index += E_ACELP_quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1);
break;
case 1:
index = E_ACELP_quant_1p_N1(posA[0], n_1) << (( 3 * n_1) + 1);
index += E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1);
break;
case 2:
index = E_ACELP_quant_2p_2N1(posA[0], posA[1], n_1) << (( 2 * n_1) + 1);
index += E_ACELP_quant_2p_2N1(posB[0], posB[1], n_1);
break;
case 3:
index = E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << N;
index += E_ACELP_quant_1p_N1(posB[0], n_1);
break;
case 4:
index = E_ACELP_quant_4p_4N1(posA[0], posA[1], posA[2], posA[3], n_1);
break;
}
index += (i & 3) << ((4 * N) - 2);
return(index);
}
/*
* E_ACELP_quant_5p_5N
*
* Parameters:
* pos I: position of the pulse 1..5
* N I: number of bits for position
*
* Function:
* Quantization of 5 pulses with 5*N bits
*
* Returns:
* 5*N bits
*/
static Word32 E_ACELP_quant_5p_5N(Word32 pos[], Word32 N)
{
Word32 i,j,k,nb_pos,n_1;
Word32 posA[5], posB[5];
Word32 index=0;
n_1 = N-1;
nb_pos = (1 << n_1);
i = 0;
j = 0;
for (k = 0; k < 5; k++)
{
if ((pos[k] & nb_pos) == 0)
{
posA[i++] = pos[k];
}
else
{
posB[j++] = pos[k];
}
}
switch (i)
{
case 0:
index = 1 << ((5 * N) - 1);
index +=
E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2 * N) + 1);
index += E_ACELP_quant_2p_2N1(posB[3], posB[4], N);
break;
case 1:
index = 1 << ((5 * N) - 1);
index +=
E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2 * N) + 1);
index += E_ACELP_quant_2p_2N1(posB[3], posA[0], N);
break;
case 2:
index = 1 << ((5 * N) - 1);
index +=
E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2 * N) + 1);
index += E_ACELP_quant_2p_2N1(posA[0], posA[1], N);
break;
case 3:
index =
E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2 * N) + 1);
index += E_ACELP_quant_2p_2N1(posB[0], posB[1], N);
break;
case 4:
index =
E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2 * N) + 1);
index += E_ACELP_quant_2p_2N1(posA[3], posB[0], N);
break;
case 5:
index =
E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2 * N) + 1);
index += E_ACELP_quant_2p_2N1(posA[3], posA[4], N);
break;
}
return(index);
}
/*
* E_ACELP_quant_6p_6N_2
*
* Parameters:
* pos I: position of the pulse 1..6
* N I: number of bits for position
*
* Function:
* Quantization of 6 pulses with 6*N-2 bits
*
* Returns:
* (6*N)-2 bits
*/
static Word32 E_ACELP_quant_6p_6N_2(Word32 pos[], Word32 N)
{
Word32 i, j, k, nb_pos, n_1;
Word32 posA[6], posB[6];
Word32 index=0;
n_1 = N - 1;
nb_pos = 1 << n_1;
i = 0;
j = 0;
for (k = 0; k < 6; k++)
{
if ((pos[k] & nb_pos) == 0)
{
posA[i++] = pos[k];
}
else
{
posB[j++] = pos[k];
}
}
switch (i)
{
case 0:
index = 1 << ((6 * N) - 5);
index += E_ACELP_quant_5p_5N(posB, n_1) << N;
index += E_ACELP_quant_1p_N1(posB[5], n_1);
break;
case 1:
index = 1 << ((6 * N) - 5);
index += E_ACELP_quant_5p_5N(posB, n_1) << N;
index += E_ACELP_quant_1p_N1(posA[0], n_1);
break;
case 2:
index = 1 << ((6 * N) - 5);
index += E_ACELP_quant_4p_4N(posB, n_1) << ((2 * n_1) + 1);
index += E_ACELP_quant_2p_2N1(posA[0], posA[1], n_1);
break;
case 3:
index = E_ACELP_quant_3p_3N1(posA[0], posA[1], posA[2], n_1)
<< ((3 * n_1) + 1);
index += E_ACELP_quant_3p_3N1(posB[0], posB[1], posB[2], n_1);
break;
case 4:
i = 2;
index = E_ACELP_quant_4p_4N(posA, n_1) << ((2 * n_1) + 1);
index += E_ACELP_quant_2p_2N1(posB[0], posB[1], n_1);
break;
case 5:
i = 1;
index = E_ACELP_quant_5p_5N(posA, n_1) << N;
index += E_ACELP_quant_1p_N1(posB[0], n_1);
break;
case 6:
i = 0;
index = E_ACELP_quant_5p_5N(posA, n_1) << N;
index += E_ACELP_quant_1p_N1(posA[5], n_1);
break;
}
index += (i & 3) << ((6 * N) - 4);
return(index);
}
/*
* E_ACELP_2t
*
* 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)
* index O: index (12): 5 + 1 + 5 + 1 = 11 bits.
*
* Function:
* 12 bits algebraic codebook.
* 2 tracks x 32 positions per track = 64 samples.
*
* 12 bits --> 2 pulses in a frame of 64 samples.
*
* All pulses can have two (2) possible amplitudes: +1 or -1.
* Each pulse can have 32 possible positions.
*
* Returns:
* void
*/
void E_ACELP_2t(Float32 dn[], Float32 cn[], Float32 H[],
Word16 code[], Float32 y[], Word32 *index)
{
Word32 i, j, k, i0, i1, ix, iy, pos = 0, pos2;
Float32 ps, psk, ps1, ps2, alpk, alp1, alp2, sq;
Float32 s, cor, alp, val;
Float32 *p0, *p1, *p2, *psign;
Float32 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf;
Float32 sign[L_SUBFR], vec[L_SUBFR], dn2[L_SUBFR];
Float32 h_buf[4 * L_SUBFR];
Float32 rrixix[2][32];
Float32 rrixiy[1024];
/*
* Find sign for each pulse position.
*/
alp = 2.0;
/* calculate energy for normalization of cn[] and dn[] */
val = 1.0;
cor = 1.0;
for(i = 0; i < L_SUBFR; i++)
{
val += cn[i] * cn[i];
}
for(i = 0; i < L_SUBFR; i++)
{
cor += dn[i] * dn[i];
}
s = (Float32)sqrt(cor / val);
for(i = 0; i < 2; i++)
{
for(j = i; j < L_SUBFR; j += 2)
{
val = dn[j];
cor = (s * cn[j]) + (alp * val);
if(cor >= 0.0)
{
sign[j] = 1.0;
vec[j] = -1.0;
}
else
{
sign[j] = -1.0;
vec[j] = 1.0;
val = -val;
cor = -cor;
}
dn[j] = val; /* modify dn[] according to the fixed sign */
dn2[j] = cor;
}
}
/*
* Select 16 position per track according to dn2[].
*/
for(i = 0; i < 2; i++)
{
for(k = 0; k < 16; k++)
{
ps = -1;
for(j = i; j < L_SUBFR; j += 2)
{
if(dn2[j] > ps)
{
ps = dn2[j];
pos = j;
}
}
dn2[pos] = (Float32)k - 16; /* dn2 < 0 when position is selected */
}
}
/*
* Compute h_inv[i].
*/
h = h_buf;
h_inv = h_buf + (2 * L_SUBFR);
for(i = 0; i < L_SUBFR; i++)
{
*h++ = 0.0F;
*h_inv++ = 0.0F;
}
for(i = 0; i < L_SUBFR; i++)
{
h[i] = H[i];
h_inv[i] = -h[i];
}
/*
* Compute rrixix[][] needed for the codebook search.
*/
/* Init pointers to last position of rrixix[] */
p0 = &rrixix[0][32 - 1];
p1 = &rrixix[1][32 - 1];
ptr_h1 = h;
cor = 0.0F;
for(i = 0; i < 32; i++)
{
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.
*/
pos = 1024 - 1;
pos2 = 1024 - 2;
ptr_hf = h + 1;
for(k = 0; k < 32; k++)
{
p1 = &rrixiy[pos];
p0 = &rrixiy[pos2];
cor = 0.0;
ptr_h1 = h;
ptr_h2 = ptr_hf;
for(i = k + 1; i < 32; i++)
{
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p1 = cor;
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p0 = cor;
p1 -= (32 + 1);
p0 -= (32 + 1);
}
cor += (*ptr_h1) * (*ptr_h2);
ptr_h1++;
ptr_h2++;
*p1 = cor;
pos -= 32;
pos2--;
ptr_hf += 2;
}
/*
* Modification of rrixiy[][] to take signs into account.
*/
p0 = rrixiy;
for(i = 0; i < L_SUBFR; i += 2)
{
psign = sign;
if(psign[i] < 0.0)
{
psign = vec;
}
for(j = 1; j < L_SUBFR; j += 2)
{
*p0 = *p0 * psign[j];
p0++;
}
}
/*
* search 2 pulses:
* ---------------
* 32 pos x 32 pos = 1024 tests (all combinations are tested)
*/
p0 = rrixix[0];
p1 = rrixix[1];
p2 = rrixiy;
psk = -1.0;
alpk = 1.0;
ix = 0;
iy = 1;
for(i0 = 0; i0 < L_SUBFR; i0 += 2)
{
ps1 = dn[i0];
alp1 = (*p0++);
pos = -1;
for(i1 = 1; i1 < L_SUBFR; i1 += 2)
{
ps2 = ps1 + dn[i1];
alp2 = alp1 + (*p1++) + (*p2++);
sq = ps2 * ps2;
s = (alpk * sq) - (psk * alp2);
if(s > 0.0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -