?? acelp_ca.c
字號:
/*
ITU-T G.729A Speech Coder ANSI-C Source Code
Version 1.1 Last modified: September 1996
Copyright (c) 1996,
AT&T, France Telecom, NTT, Universite de Sherbrooke
All rights reserved.
*/
/*---------------------------------------------------------------------------*
* Function ACELP_Code_A() *
* ~~~~~~~~~~~~~~~~~~~~~~~~ *
* Find Algebraic codebook for G.729A *
*--------------------------------------------------------------------------*/
#include "typedef.h"
#include "intrindefs.h"
#include "ld8a.h"
/* Constants defined in ld8a.h */
/* L_SUBFR -> Lenght of subframe. */
/* NB_POS -> Number of positions for each pulse. */
/* STEP -> Step betweem position of the same pulse. */
/* MSIZE -> Size of vectors for cross-correlation between two pulses. */
/* local routines definition */
static void Cor_h(
Word16 *H, /* (i) Q12 :Impulse response of filters */
Word16 *rr /* (o) :Correlations of H[] */
);
static Word16 D4i40_17_fast(/*(o) : Index of pulses positions. */
Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */
Word16 *rr, /* (i) : Correlations of impulse response h[]. */
Word16 h[], /* (i) Q12: Impulse response of filters. */
Word16 cod[], /* (o) Q13: Selected algebraic codeword. */
Word16 y[], /* (o) Q12: Filtered algebraic codeword. */
Word16 *sign /* (o) : Signs of 4 pulses. */
);
/*-----------------------------------------------------------------*
* Main ACELP function. *
*-----------------------------------------------------------------*/
Word16 ACELP_Code_A( /* (o) :index of pulses positions */
Word16 x[], /* (i) :Target vector */
Word16 h[], /* (i) Q12 :Inpulse response of filters */
Word16 T0, /* (i) :Pitch lag */
Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */
Word16 code[], /* (o) Q13 :Innovative codebook */
Word16 y[], /* (o) Q12 :Filtered innovative codebook */
Word16 *sign /* (o) :Signs of 4 pulses */
)
{
Word16 i, index, sharp;
Word16 Dn[L_SUBFR];
Word16 rr[DIM_RR];
/*-----------------------------------------------------------------*
* Include fixed-gain pitch contribution into impulse resp. h[] *
* Find correlations of h[] needed for the codebook search. *
*-----------------------------------------------------------------*/
sharp = shl(pitch_sharp, 1); /* From Q14 to Q15 */
if (T0 < L_SUBFR)
for (i = T0; i < L_SUBFR; i++) /* h[i] += pitch_sharp*h[i-T0] */
h[i] = add(h[i], mult(h[i-T0], sharp));
Cor_h(h, rr);
/*-----------------------------------------------------------------*
* Compute correlation of target vector with impulse response. *
*-----------------------------------------------------------------*/
Cor_h_X(h, x, Dn);
/*-----------------------------------------------------------------*
* Find innovative codebook. *
*-----------------------------------------------------------------*/
index = D4i40_17_fast(Dn, rr, h, code, y, sign);
/*-----------------------------------------------------------------*
* Compute innovation vector gain. *
* Include fixed-gain pitch contribution into code[]. *
*-----------------------------------------------------------------*/
if(T0 < L_SUBFR)
for (i = T0; i < L_SUBFR; i++) /* code[i] += pitch_sharp*code[i-T0] */
code[i] = add(code[i], mult(code[i-T0], sharp));
return index;
}
/*--------------------------------------------------------------------------*
* Function Cor_h() *
* ~~~~~~~~~~~~~~~~~ *
* Compute correlations of h[] needed for the codebook search. *
*--------------------------------------------------------------------------*/
static void Cor_h(
Word16 *H, /* (i) Q12 :Impulse response of filters */
Word16 *rr /* (o) :Correlations of H[] */
)
{
Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4;
Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4;
Word16 *rri1i2, *rri1i3, *rri1i4;
Word16 *rri2i3, *rri2i4;
Word16 *p0, *p1, *p2, *p3, *p4;
Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2;
Word32 cor;
Word16 i, k, ldec, l_fin_sup, l_fin_inf;
Word16 h[L_SUBFR];
/* Scaling h[] for maximum precision */
cor = 0;
for(i=0; i<L_SUBFR; i++)
cor = L_mac(cor, H[i], H[i]);
if(sub(extract_h(cor),32000) > 0)
{
for(i=0; i<L_SUBFR; i++) {
h[i] = shr(H[i], 1);
}
}
else
{
k = norm_l(cor);
k = shr(k, 1);
for(i=0; i<L_SUBFR; i++) {
h[i] = shl(H[i], k);
}
}
/*------------------------------------------------------------*
* Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[] *
*------------------------------------------------------------*/
/* Init pointers */
rri0i0 = rr;
rri1i1 = rri0i0 + NB_POS;
rri2i2 = rri1i1 + NB_POS;
rri3i3 = rri2i2 + NB_POS;
rri4i4 = rri3i3 + NB_POS;
rri0i1 = rri4i4 + NB_POS;
rri0i2 = rri0i1 + MSIZE;
rri0i3 = rri0i2 + MSIZE;
rri0i4 = rri0i3 + MSIZE;
rri1i2 = rri0i4 + MSIZE;
rri1i3 = rri1i2 + MSIZE;
rri1i4 = rri1i3 + MSIZE;
rri2i3 = rri1i4 + MSIZE;
rri2i4 = rri2i3 + MSIZE;
p0 = rri0i0 + NB_POS-1; /* Init pointers to last position of rrixix[] */
p1 = rri1i1 + NB_POS-1;
p2 = rri2i2 + NB_POS-1;
p3 = rri3i3 + NB_POS-1;
p4 = rri4i4 + NB_POS-1;
ptr_h1 = h;
cor = 0;
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);
}
/*-----------------------------------------------------------------*
* Compute elements of: rri2i3[], rri1i2[], rri0i1[] and rri0i4[] *
*-----------------------------------------------------------------*/
l_fin_sup = MSIZE-1;
l_fin_inf = l_fin_sup-(Word16)1;
ldec = NB_POS+1;
ptr_hd = h;
ptr_hf = ptr_hd + 1;
for(k=0; k<NB_POS; k++) {
p3 = rri2i3 + l_fin_sup;
p2 = rri1i2 + l_fin_sup;
p1 = rri0i1 + l_fin_sup;
p0 = rri0i4 + l_fin_inf;
cor = 0;
ptr_h1 = ptr_hd;
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++;
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);
p3 -= ldec;
p2 -= ldec;
p1 -= ldec;
p0 -= ldec;
}
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
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);
l_fin_sup -= NB_POS;
l_fin_inf--;
ptr_hf += STEP;
}
/*---------------------------------------------------------------------*
* Compute elements of: rri2i4[], rri1i3[], rri0i2[], rri1i4[], rri0i3 *
*---------------------------------------------------------------------*/
ptr_hd = h;
ptr_hf = ptr_hd + 2;
l_fin_sup = MSIZE-1;
l_fin_inf = l_fin_sup-(Word16)1;
for(k=0; k<NB_POS; k++) {
p4 = rri2i4 + l_fin_sup;
p3 = rri1i3 + l_fin_sup;
p2 = rri0i2 + l_fin_sup;
p1 = rri1i4 + l_fin_inf;
p0 = rri0i3 + l_fin_inf;
cor = 0;
ptr_h1 = ptr_hd;
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 -= ldec;
p3 -= ldec;
p2 -= ldec;
p1 -= ldec;
p0 -= ldec;
}
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);
l_fin_sup -= NB_POS;
l_fin_inf--;
ptr_hf += STEP;
}
/*----------------------------------------------------------------------*
* Compute elements of: rri1i4[], rri0i3[], rri2i4[], rri1i3[], rri0i2 *
*----------------------------------------------------------------------*/
ptr_hd = h;
ptr_hf = ptr_hd + 3;
l_fin_sup = MSIZE-1;
l_fin_inf = l_fin_sup-(Word16)1;
for(k=0; k<NB_POS; k++) {
p4 = rri1i4 + l_fin_sup;
p3 = rri0i3 + l_fin_sup;
p2 = rri2i4 + l_fin_inf;
p1 = rri1i3 + l_fin_inf;
p0 = rri0i2 + l_fin_inf;
ptr_h1 = ptr_hd;
ptr_h2 = ptr_hf;
cor = 0;
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 -= ldec;
p3 -= ldec;
p2 -= ldec;
p1 -= ldec;
p0 -= ldec;
}
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);
l_fin_sup -= NB_POS;
l_fin_inf--;
ptr_hf += STEP;
}
/*----------------------------------------------------------------------*
* Compute elements of: rri0i4[], rri2i3[], rri1i2[], rri0i1[] *
*----------------------------------------------------------------------*/
ptr_hd = h;
ptr_hf = ptr_hd + 4;
l_fin_sup = MSIZE-1;
l_fin_inf = l_fin_sup-(Word16)1;
for(k=0; k<NB_POS; k++) {
p3 = rri0i4 + l_fin_sup;
p2 = rri2i3 + l_fin_inf;
p1 = rri1i2 + l_fin_inf;
p0 = rri0i1 + l_fin_inf;
ptr_h1 = ptr_hd;
ptr_h2 = ptr_hf;
cor = 0;
for(i=k+(Word16)1; i<NB_POS; i++ ) {
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++;
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);
p3 -= ldec;
p2 -= ldec;
p1 -= ldec;
p0 -= ldec;
}
cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
*p3 = extract_h(cor);
l_fin_sup -= NB_POS;
l_fin_inf--;
ptr_hf += STEP;
}
return;
}
/*------------------------------------------------------------------------*
* Function D4i40_17_fast() *
* ~~~~~~~~~ *
* Algebraic codebook for ITU 8kb/s. *
* -> 17 bits; 4 pulses in a frame of 40 samples *
* *
*------------------------------------------------------------------------*
* The code length is 40, containing 4 nonzero pulses i0, i1, i2, i3. *
* Each pulses can have 8 possible positions (positive or negative) *
* except i3 that have 16 possible positions. *
* *
* i0 (+-1) : 0, 5, 10, 15, 20, 25, 30, 35 *
* i1 (+-1) : 1, 6, 11, 16, 21, 26, 31, 36 *
* i2 (+-1) : 2, 7, 12, 17, 22, 27, 32, 37 *
* i3 (+-1) : 3, 8, 13, 18, 23, 28, 33, 38 *
* 4, 9, 14, 19, 24, 29, 34, 39 *
*------------------------------------------------------------------------*/
static Word16 D4i40_17_fast(/*(o) : Index of pulses positions. */
Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */
Word16 rr[], /* (i) : Correlations of impulse response h[]. */
Word16 h[], /* (i) Q12: Impulse response of filters. */
Word16 cod[], /* (o) Q13: Selected algebraic codeword. */
Word16 y[], /* (o) Q12: Filtered algebraic codeword. */
Word16 *sign /* (o) : Signs of 4 pulses. */
)
{
Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3;
Word16 i, j, ix, iy, track, trk, max;
Word16 prev_i0, i1_offset;
Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
Word16 alpk, alp, alp_16;
Word32 s, alp0, alp1, alp2;
Word16 *p0, *p1, *p2, *p3, *p4;
Word16 sign_dn[L_SUBFR], sign_dn_inv[L_SUBFR], *psign;
Word16 tmp_vect[NB_POS];
Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4;
Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4;
Word16 *rri1i2, *rri1i3, *rri1i4;
Word16 *rri2i3, *rri2i4;
Word16 *ptr_rri0i3_i4;
Word16 *ptr_rri1i3_i4;
Word16 *ptr_rri2i3_i4;
Word16 *ptr_rri3i3_i4;
/* Init pointers */
rri0i0 = rr;
rri1i1 = rri0i0 + NB_POS;
rri2i2 = rri1i1 + NB_POS;
rri3i3 = rri2i2 + NB_POS;
rri4i4 = rri3i3 + NB_POS;
rri0i1 = rri4i4 + NB_POS;
rri0i2 = rri0i1 + MSIZE;
rri0i3 = rri0i2 + MSIZE;
rri0i4 = rri0i3 + MSIZE;
rri1i2 = rri0i4 + MSIZE;
rri1i3 = rri1i2 + MSIZE;
rri1i4 = rri1i3 + MSIZE;
rri2i3 = rri1i4 + MSIZE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -