- initial import

This commit is contained in:
2018-06-05 11:05:37 +03:00
commit e1a4931375
4673 changed files with 1383093 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
project (g729)
# Rely on C++ 11
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (G729_SOURCES
g729_acelp_ca.cpp
g729_basic_op.cpp
g729_cod_ld8a.cpp
g729_cor_func.cpp
g729_de_acelp.cpp
g729_dec_gain.cpp
g729_dec_lag3.cpp
g729_dec_ld8a.cpp
g729_dspfunc.cpp
g729_filter.cpp
g729_gainpred.cpp
g729_lpc_729.cpp
g729_lpcfunc.cpp
g729_lspdec.cpp
g729_lspgetq.cpp
g729_oper_32b.cpp
g729_pitch_a.cpp
g729_postfilt.cpp
g729_post_pro.cpp
g729_p_parity.cpp
g729_pred_lt3.cpp
g729_pre_proc.cpp
g729_gain.cpp
g729_lsp.cpp
g729_tab_ld8a.cpp
g729_taming.cpp
g729_util.cpp
)
add_library(g729_codec ${G729_SOURCES})

991
src/libs/libg729/acelp_ca.c Normal file
View File

@@ -0,0 +1,991 @@
/*
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 "basic_op.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 */
void Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */
Word16 * rr /* (o) :Correlations of H[] */
);
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. *
*--------------------------------------------------------------------------*/
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 *
*------------------------------------------------------------------------*/
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;
rri2i4 = rri2i3 + MSIZE;
/*-----------------------------------------------------------------------*
* Chose the sign of the impulse. *
*-----------------------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++) {
if (dn[i] >= 0) {
sign_dn[i] = MAX_16;
sign_dn_inv[i] = MIN_16;
}
else {
sign_dn[i] = MIN_16;
sign_dn_inv[i] = MAX_16;
dn[i] = negate (dn[i]);
}
}
/*-------------------------------------------------------------------*
* Modification of rrixiy[] to take signs into account. *
*-------------------------------------------------------------------*/
p0 = rri0i1;
p1 = rri0i2;
p2 = rri0i3;
p3 = rri0i4;
for (i0 = 0; i0 < L_SUBFR; i0 += STEP) {
psign = sign_dn;
if (psign[i0] < 0)
psign = sign_dn_inv;
for (i1 = 1; i1 < L_SUBFR; i1 += STEP) {
*p0 = mult (*p0, psign[i1]); p0++;
*p1 = mult (*p1, psign[i1 + 1]); p1++;
*p2 = mult (*p2, psign[i1 + 2]); p2++;
*p3 = mult (*p3, psign[i1 + 3]); p3++;
}
}
p0 = rri1i2;
p1 = rri1i3;
p2 = rri1i4;
for (i1 = 1; i1 < L_SUBFR; i1 += STEP) {
psign = sign_dn;
if (psign[i1] < 0)
psign = sign_dn_inv;
for (i2 = 2; i2 < L_SUBFR; i2 += STEP) {
*p0 = mult (*p0, psign[i2]); p0++;
*p1 = mult (*p1, psign[i2 + 1]); p1++;
*p2 = mult (*p2, psign[i2 + 2]); p2++;
}
}
p0 = rri2i3;
p1 = rri2i4;
for (i2 = 2; i2 < L_SUBFR; i2 += STEP) {
psign = sign_dn;
if (psign[i2] < 0)
psign = sign_dn_inv;
for (i3 = 3; i3 < L_SUBFR; i3 += STEP) {
*p0 = mult (*p0, psign[i3]); p0++;
*p1 = mult (*p1, psign[i3 + 1]); p1++;
}
}
/*-------------------------------------------------------------------*
* Search the optimum positions of the four pulses which maximize *
* square(correlation) / energy *
*-------------------------------------------------------------------*/
psk = -1;
alpk = 1;
ptr_rri0i3_i4 = rri0i3;
ptr_rri1i3_i4 = rri1i3;
ptr_rri2i3_i4 = rri2i3;
ptr_rri3i3_i4 = rri3i3;
/* Initializations only to remove warning from some compilers */
ip0 = 0;
ip1 = 1;
ip2 = 2;
ip3 = 3;
ix = 0;
iy = 0;
ps = 0;
/* search 2 times: track 3 and 4 */
for (track = 3, trk = 0; track < 5; track++, trk++) {
/*------------------------------------------------------------------*
* depth first search 3, phase A: track 2 and 3/4. *
*------------------------------------------------------------------*/
sq = -1;
alp = 1;
/* i0 loop: 2 positions in track 2 */
prev_i0 = -1;
for (i = 0; i < 2; i++) {
max = -1;
/* search "dn[]" maximum position in track 2 */
for (j = 2; j < L_SUBFR; j += STEP) {
if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) {
max = dn[j];
i0 = j;
}
}
prev_i0 = i0;
j = mult (i0, 6554); /* j = i0/5 */
p0 = rri2i2 + j;
ps1 = dn[i0];
alp1 = L_mult (*p0, _1_4);
/* i1 loop: 8 positions in track 2 */
p0 = ptr_rri2i3_i4 + shl (j, 3);
p1 = ptr_rri3i3_i4;
for (i1 = track; i1 < L_SUBFR; i1 += STEP) {
ps2 = add (ps1, dn[i1]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
alp2 = L_mac (alp1, *p0++, _1_2);
alp2 = L_mac (alp2, *p1++, _1_4);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
ps = ps2;
alp = alp_16;
ix = i0;
iy = i1;
}
}
}
i0 = ix;
i1 = iy;
i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */
/*------------------------------------------------------------------*
* depth first search 3, phase B: track 0 and 1. *
*------------------------------------------------------------------*/
ps0 = ps;
alp0 = L_mult (alp, _1_4);
sq = -1;
alp = 1;
/* build vector for next loop to decrease complexity */
p0 = rri1i2 + mult (i0, 6554);
p1 = ptr_rri1i3_i4 + mult (i1, 6554);
p2 = rri1i1;
p3 = tmp_vect;
for (i3 = 1; i3 < L_SUBFR; i3 += STEP) {
/* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */
s = L_mult (*p0, _1_4);
p0 += NB_POS;
s = L_mac (s, *p1, _1_4);
p1 += NB_POS;
s = L_mac (s, *p2++, _1_8);
*p3++ = wround (s);
}
/* i2 loop: 8 positions in track 0 */
p0 = rri0i2 + mult (i0, 6554);
p1 = ptr_rri0i3_i4 + mult (i1, 6554);
p2 = rri0i0;
p3 = rri0i1;
for (i2 = 0; i2 < L_SUBFR; i2 += STEP) {
ps1 = add (ps0, dn[i2]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
alp1 = L_mac (alp0, *p0, _1_8);
p0 += NB_POS;
alp1 = L_mac (alp1, *p1, _1_8);
p1 += NB_POS;
alp1 = L_mac (alp1, *p2++, _1_16);
/* i3 loop: 8 positions in track 1 */
p4 = tmp_vect;
for (i3 = 1; i3 < L_SUBFR; i3 += STEP) {
ps2 = add (ps1, dn[i3]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
alp2 = L_mac (alp1, *p3++, _1_8);
alp2 = L_mac (alp2, *p4++, _1_2);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
alp = alp_16;
ix = i2;
iy = i3;
}
}
}
/*----------------------------------------------------------------*
* depth first search 3: compare codevector with the best case. *
*----------------------------------------------------------------*/
s = L_msu (L_mult (alpk, sq), psk, alp);
if (s > 0) {
psk = sq;
alpk = alp;
ip2 = i0;
ip3 = i1;
ip0 = ix;
ip1 = iy;
}
/*------------------------------------------------------------------*
* depth first search 4, phase A: track 3 and 0. *
*------------------------------------------------------------------*/
sq = -1;
alp = 1;
/* i0 loop: 2 positions in track 3/4 */
prev_i0 = -1;
for (i = 0; i < 2; i++) {
max = -1;
/* search "dn[]" maximum position in track 3/4 */
for (j = track; j < L_SUBFR; j += STEP) {
if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) {
max = dn[j];
i0 = j;
}
}
prev_i0 = i0;
j = mult (i0, 6554); /* j = i0/5 */
p0 = ptr_rri3i3_i4 + j;
ps1 = dn[i0];
alp1 = L_mult (*p0, _1_4);
/* i1 loop: 8 positions in track 0 */
p0 = ptr_rri0i3_i4 + j;
p1 = rri0i0;
for (i1 = 0; i1 < L_SUBFR; i1 += STEP) {
ps2 = add (ps1, dn[i1]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
alp2 = L_mac (alp1, *p0, _1_2);
p0 += NB_POS;
alp2 = L_mac (alp2, *p1++, _1_4);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
ps = ps2;
alp = alp_16;
ix = i0;
iy = i1;
}
}
}
i0 = ix;
i1 = iy;
i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */
/*------------------------------------------------------------------*
* depth first search 4, phase B: track 1 and 2. *
*------------------------------------------------------------------*/
ps0 = ps;
alp0 = L_mult (alp, _1_4);
sq = -1;
alp = 1;
/* build vector for next loop to decrease complexity */
p0 = ptr_rri2i3_i4 + mult (i0, 6554);
p1 = rri0i2 + i1_offset;
p2 = rri2i2;
p3 = tmp_vect;
for (i3 = 2; i3 < L_SUBFR; i3 += STEP) {
/* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */
s = L_mult (*p0, _1_4);
p0 += NB_POS;
s = L_mac (s, *p1++, _1_4);
s = L_mac (s, *p2++, _1_8);
*p3++ = wround (s);
}
/* i2 loop: 8 positions in track 1 */
p0 = ptr_rri1i3_i4 + mult (i0, 6554);
p1 = rri0i1 + i1_offset;
p2 = rri1i1;
p3 = rri1i2;
for (i2 = 1; i2 < L_SUBFR; i2 += STEP) {
ps1 = add (ps0, dn[i2]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
alp1 = L_mac (alp0, *p0, _1_8);
p0 += NB_POS;
alp1 = L_mac (alp1, *p1++, _1_8);
alp1 = L_mac (alp1, *p2++, _1_16);
/* i3 loop: 8 positions in track 2 */
p4 = tmp_vect;
for (i3 = 2; i3 < L_SUBFR; i3 += STEP) {
ps2 = add (ps1, dn[i3]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
alp2 = L_mac (alp1, *p3++, _1_8);
alp2 = L_mac (alp2, *p4++, _1_2);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
alp = alp_16;
ix = i2;
iy = i3;
}
}
}
/*----------------------------------------------------------------*
* depth first search 1: compare codevector with the best case. *
*----------------------------------------------------------------*/
s = L_msu (L_mult (alpk, sq), psk, alp);
if (s > 0) {
psk = sq;
alpk = alp;
ip3 = i0;
ip0 = i1;
ip1 = ix;
ip2 = iy;
}
ptr_rri0i3_i4 = rri0i4;
ptr_rri1i3_i4 = rri1i4;
ptr_rri2i3_i4 = rri2i4;
ptr_rri3i3_i4 = rri4i4;
}
/* Set the sign of impulses */
i0 = sign_dn[ip0];
i1 = sign_dn[ip1];
i2 = sign_dn[ip2];
i3 = sign_dn[ip3];
/* Find the codeword corresponding to the selected positions */
for (i = 0; i < L_SUBFR; i++) {
cod[i] = 0;
}
cod[ip0] = shr (i0, 2); /* From Q15 to Q13 */
cod[ip1] = shr (i1, 2);
cod[ip2] = shr (i2, 2);
cod[ip3] = shr (i3, 2);
/* find the filtered codeword */
for (i = 0; i < ip0; i++)
y[i] = 0;
if (i0 > 0)
for (i = ip0, j = 0; i < L_SUBFR; i++, j++)
y[i] = h[j];
else
for (i = ip0, j = 0; i < L_SUBFR; i++, j++)
y[i] = negate (h[j]);
if (i1 > 0)
for (i = ip1, j = 0; i < L_SUBFR; i++, j++)
y[i] = add (y[i], h[j]);
else
for (i = ip1, j = 0; i < L_SUBFR; i++, j++)
y[i] = sub (y[i], h[j]);
if (i2 > 0)
for (i = ip2, j = 0; i < L_SUBFR; i++, j++)
y[i] = add (y[i], h[j]);
else
for (i = ip2, j = 0; i < L_SUBFR; i++, j++)
y[i] = sub (y[i], h[j]);
if (i3 > 0)
for (i = ip3, j = 0; i < L_SUBFR; i++, j++)
y[i] = add (y[i], h[j]);
else
for (i = ip3, j = 0; i < L_SUBFR; i++, j++)
y[i] = sub (y[i], h[j]);
/* find codebook index; 17-bit address */
i = 0;
if (i0 > 0)
i = add (i, 1);
if (i1 > 0)
i = add (i, 2);
if (i2 > 0)
i = add (i, 4);
if (i3 > 0)
i = add (i, 8);
*sign = i;
ip0 = mult (ip0, 6554); /* ip0/5 */
ip1 = mult (ip1, 6554); /* ip1/5 */
ip2 = mult (ip2, 6554); /* ip2/5 */
i = mult (ip3, 6554); /* ip3/5 */
j = add (i, shl (i, 2)); /* j = i*5 */
j = sub (ip3, add (j, 3)); /* j= ip3%5 -3 */
ip3 = add (shl (i, 1), j);
i = add (ip0, shl (ip1, 3));
i = add (i, shl (ip2, 6));
i = add (i, shl (ip3, 9));
return i;
}

2013
src/libs/libg729/basic_op.c Normal file

File diff suppressed because it is too large Load Diff

139
src/libs/libg729/cor_func.c Normal file
View File

@@ -0,0 +1,139 @@
/*
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.
*/
/* Functions Corr_xy2() and Cor_h_x() */
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
/*---------------------------------------------------------------------------*
* Function corr_xy2() *
* ~~~~~~~~~~~~~~~~~~~ *
* Find the correlations between the target xn[], the filtered adaptive *
* codebook excitation y1[], and the filtered 1st codebook innovation y2[]. *
* g_coeff[2]:exp_g_coeff[2] = <y2,y2> *
* g_coeff[3]:exp_g_coeff[3] = -2<xn,y2> *
* g_coeff[4]:exp_g_coeff[4] = 2<y1,y2> *
*---------------------------------------------------------------------------*/
void
Corr_xy2 (Word16 xn[], /* (i) Q0 :Target vector. */
Word16 y1[], /* (i) Q0 :Adaptive codebook. */
Word16 y2[], /* (i) Q12 :Filtered innovative vector. */
Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */
Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */
)
{
Word16 i, exp;
Word16 exp_y2y2, exp_xny2, exp_y1y2;
Word16 y2y2, xny2, y1y2;
Word32 L_acc;
Word16 scaled_y2[L_SUBFR]; /* Q9 */
/*------------------------------------------------------------------*
* Scale down y2[] from Q12 to Q9 to avoid overflow *
*------------------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++) {
scaled_y2[i] = shr (y2[i], 3);
}
/* Compute scalar product <y2[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for (i = 0; i < L_SUBFR; i++)
L_acc = L_mac (L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */
exp = norm_l (L_acc);
y2y2 = wround (L_shl (L_acc, exp));
exp_y2y2 = add (exp, 19 - 16); /* Q[19+exp-16] */
g_coeff[2] = y2y2;
exp_g_coeff[2] = exp_y2y2;
/* Compute scalar product <xn[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for (i = 0; i < L_SUBFR; i++)
L_acc = L_mac (L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */
exp = norm_l (L_acc);
xny2 = wround (L_shl (L_acc, exp));
exp_xny2 = add (exp, 10 - 16); /* Q[10+exp-16] */
g_coeff[3] = negate (xny2);
exp_g_coeff[3] = sub (exp_xny2, 1); /* -2<xn,y2> */
/* Compute scalar product <y1[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for (i = 0; i < L_SUBFR; i++)
L_acc = L_mac (L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */
exp = norm_l (L_acc);
y1y2 = wround (L_shl (L_acc, exp));
exp_y1y2 = add (exp, 10 - 16); /* Q[10+exp-16] */
g_coeff[4] = y1y2;
exp_g_coeff[4] = sub (exp_y1y2, 1);; /* 2<y1,y2> */
return;
}
/*--------------------------------------------------------------------------*
* Function Cor_h_X() *
* ~~~~~~~~~~~~~~~~~~~ *
* Compute correlations of input response h[] with the target vector X[]. *
*--------------------------------------------------------------------------*/
void
Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */
Word16 X[], /* (i) :Target vector */
Word16 D[]
/* (o) :Correlations between h[] and D[] */
/* Normalized to 13 bits */
)
{
Word16 i, j;
Word32 s, max, L_temp;
Word32 y32[L_SUBFR];
/* first keep the result on 32 bits and find absolute maximum */
max = 0;
for (i = 0; i < L_SUBFR; i++) {
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_temp = L_sub (s, max);
if (L_temp > 0L) {
max = s;
}
}
/* Find the number of right shifts to do on y32[] */
/* so that maximum is on 13 bits */
j = norm_l (max);
if (sub (j, 16) > 0) {
j = 16;
}
j = sub (18, j);
for (i = 0; i < L_SUBFR; i++) {
D[i] = extract_l (L_shr (y32[i], j));
}
return;
}

View File

@@ -0,0 +1,73 @@
/*
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 Decod_ACELP() *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Algebraic codebook decoder. *
*----------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
void
Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */
Word16 index, /* (i) : Positions of the 4 pulses. */
Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */
)
{
Word16 i, j;
Word16 pos[4];
/* Decode the positions */
i = index & (Word16) 7;
pos[0] = add (i, shl (i, 2)); /* pos0 =i*5 */
index = shr (index, 3);
i = index & (Word16) 7;
i = add (i, shl (i, 2)); /* pos1 =i*5+1 */
pos[1] = add (i, 1);
index = shr (index, 3);
i = index & (Word16) 7;
i = add (i, shl (i, 2)); /* pos2 =i*5+1 */
pos[2] = add (i, 2);
index = shr (index, 3);
j = index & (Word16) 1;
index = shr (index, 1);
i = index & (Word16) 7;
i = add (i, shl (i, 2)); /* pos3 =i*5+3+j */
i = add (i, 3);
pos[3] = add (i, j);
/* decode the signs and build the codeword */
for (i = 0; i < L_SUBFR; i++) {
cod[i] = 0;
}
for (j = 0; j < 4; j++) {
i = sign & (Word16) 1;
sign = shr (sign, 1);
if (i != 0) {
cod[pos[j]] = 8191; /* Q13 +1.0 */
}
else {
cod[pos[j]] = -8192; /* Q13 -1.0 */
}
}
return;
}

109
src/libs/libg729/dec_gain.c Normal file
View File

@@ -0,0 +1,109 @@
/*
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.
*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
#include "tab_ld8a.h"
/*---------------------------------------------------------------------------*
* Function Dec_gain *
* ~~~~~~~~~~~~~~~~~~ *
* Decode the pitch and codebook gains *
* *
*---------------------------------------------------------------------------*
* input arguments: *
* *
* index :Quantization index *
* code[] :Innovative code vector *
* L_subfr :Subframe size *
* bfi :Bad frame indicator *
* *
* output arguments: *
* *
* gain_pit :Quantized pitch gain *
* gain_cod :Quantized codebook gain *
* *
*---------------------------------------------------------------------------*/
void
Dec_gain (DecState *decoder,
Word16 index, /* (i) :Index of quantization. */
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 bfi, /* (i) :Bad frame indicator */
Word16 * gain_pit, /* (o) Q14 :Pitch gain. */
Word16 * gain_cod /* (o) Q1 :Code gain. */
)
{
Word16 index1, index2, tmp;
Word16 gcode0, exp_gcode0;
Word32 L_gbk12, L_acc, L_accb;
void Gain_predict (Word16 past_qua_en[], Word16 code[], Word16 L_subfr,
Word16 * gcode0, Word16 * exp_gcode0);
void Gain_update (Word16 past_qua_en[], Word32 L_gbk12);
void Gain_update_erasure (Word16 past_qua_en[]);
/* Gain predictor, Past quantized energies = -14.0 in Q10 */
/*-------------- Case of erasure. ---------------*/
if (bfi != 0) {
*gain_pit = mult (*gain_pit, 29491); /* *0.9 in Q15 */
if (sub (*gain_pit, 29491) > 0)
*gain_pit = 29491;
*gain_cod = mult (*gain_cod, 32111); /* *0.98 in Q15 */
/*----------------------------------------------*
* update table of past quantized energies *
* (frame erasure) *
*----------------------------------------------*/
Gain_update_erasure (decoder->past_qua_en);
return;
}
/*-------------- Decode pitch gain ---------------*/
index1 = imap1[shr (index, NCODE2_B)];
index2 = imap2[index & (NCODE2 - 1)];
*gain_pit = add (gbk1[index1][0], gbk2[index2][0]);
/*-------------- Decode codebook gain ---------------*/
/*---------------------------------------------------*
*- energy due to innovation -*
*- predicted energy -*
*- predicted codebook gain => gcode0[exp_gcode0] -*
*---------------------------------------------------*/
Gain_predict (decoder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0);
/*-----------------------------------------------------------------*
* *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; *
*-----------------------------------------------------------------*/
L_acc = L_deposit_l (gbk1[index1][1]);
L_accb = L_deposit_l (gbk2[index2][1]);
L_gbk12 = L_add (L_acc, L_accb); /* Q13 */
tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */
L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */
L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16)));
*gain_cod = extract_h (L_acc); /* Q1 */
/*----------------------------------------------*
* update table of past quantized energies *
*----------------------------------------------*/
Gain_update (decoder->past_qua_en, L_gbk12);
return;
}

View File

@@ -0,0 +1,79 @@
/*
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 Dec_lag3 *
* ~~~~~~~~ *
* Decoding of fractional pitch lag with 1/3 resolution. *
* See "Enc_lag3.c" for more details about the encoding procedure. *
*------------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
void
Dec_lag3 (Word16 index, /* input : received pitch index */
Word16 pit_min, /* input : minimum pitch lag */
Word16 pit_max, /* input : maximum pitch lag */
Word16 i_subfr, /* input : subframe flag */
Word16 * T0, /* output: integer part of pitch lag */
Word16 * T0_frac /* output: fractional part of pitch lag */
)
{
Word16 i;
Word16 T0_min, T0_max;
if (i_subfr == 0) { /* if 1st subframe */
if (sub (index, 197) < 0) {
/* *T0 = (index+2)/3 + 19 */
*T0 = add (mult (add (index, 2), 10923), 19);
/* *T0_frac = index - *T0*3 + 58 */
i = add (add (*T0, *T0), *T0);
*T0_frac = add (sub (index, i), 58);
}
else {
*T0 = sub (index, 112);
*T0_frac = 0;
}
}
else { /* second subframe */
/* find T0_min and T0_max for 2nd subframe */
T0_min = sub (*T0, 5);
if (sub (T0_min, pit_min) < 0) {
T0_min = pit_min;
}
T0_max = add (T0_min, 9);
if (sub (T0_max, pit_max) > 0) {
T0_max = pit_max;
T0_min = sub (T0_max, 9);
}
/* i = (index+2)/3 - 1 */
/* *T0 = i + t0_min; */
i = sub (mult (add (index, 2), 10923), 1);
*T0 = add (i, T0_min);
/* t0_frac = index - 2 - i*3; */
i = add (add (i, i), i);
*T0_frac = sub (sub (index, 2), i);
}
return;
}

182
src/libs/libg729/dspfunc.c Normal file
View File

@@ -0,0 +1,182 @@
/*
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.
*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
#include "tab_ld8a.h"
/*___________________________________________________________________________
| |
| Function Name : Pow2() |
| |
| L_x = pow(2.0, exponent.fraction) |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The function Pow2(L_x) is approximated by a table and linear |
| interpolation. |
| |
| 1- i = bit10-b15 of fraction, 0 <= i <= 31 |
| 2- a = bit0-b9 of fraction |
| 3- L_x = tabpow[i]<<16 - (tabpow[i] - tabpow[i+1]) * a * 2 |
| 4- L_x = L_x >> (30-exponent) (with rounding) |
|___________________________________________________________________________|
*/
Word32
Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */
Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */
Word16 fraction /* (i) Q15 : Fractional part. (range: 0.0<=val<1.0) */
)
{
Word16 exp, i, a, tmp;
Word32 L_x;
L_x = L_mult (fraction, 32); /* L_x = fraction<<6 */
i = extract_h (L_x); /* Extract b10-b15 of fraction */
L_x = L_shr (L_x, 1);
a = extract_l (L_x); /* Extract b0-b9 of fraction */
a = a & (Word16) 0x7fff;
L_x = L_deposit_h (tabpow[i]); /* tabpow[i] << 16 */
tmp = sub (tabpow[i], tabpow[i + 1]); /* tabpow[i] - tabpow[i+1] */
L_x = L_msu (L_x, tmp, a); /* L_x -= tmp*a*2 */
exp = sub (30, exponent);
L_x = L_shr_r (L_x, exp);
return (L_x);
}
/*___________________________________________________________________________
| |
| Function Name : Log2() |
| |
| Compute log2(L_x). |
| L_x is positive. |
| |
| if L_x is negative or zero, result is 0. |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The function Log2(L_x) is approximated by a table and linear |
| interpolation. |
| |
| 1- Normalization of L_x. |
| 2- exponent = 30-exponent |
| 3- i = bit25-b31 of L_x, 32 <= i <= 63 ->because of normalization. |
| 4- a = bit10-b24 |
| 5- i -=32 |
| 6- fraction = tablog[i]<<16 - (tablog[i] - tablog[i+1]) * a * 2 |
|___________________________________________________________________________|
*/
void
Log2 (Word32 L_x, /* (i) Q0 : input value */
Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */
Word16 * fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */
)
{
Word16 exp, i, a, tmp;
Word32 L_y;
if (L_x <= (Word32) 0) {
*exponent = 0;
*fraction = 0;
return;
}
exp = norm_l (L_x);
L_x = L_shl (L_x, exp); /* L_x is normalized */
*exponent = sub (30, exp);
L_x = L_shr (L_x, 9);
i = extract_h (L_x); /* Extract b25-b31 */
L_x = L_shr (L_x, 1);
a = extract_l (L_x); /* Extract b10-b24 of fraction */
a = a & (Word16) 0x7fff;
i = sub (i, 32);
L_y = L_deposit_h (tablog[i]); /* tablog[i] << 16 */
tmp = sub (tablog[i], tablog[i + 1]); /* tablog[i] - tablog[i+1] */
L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
*fraction = extract_h (L_y);
return;
}
/*___________________________________________________________________________
| |
| Function Name : Inv_sqrt |
| |
| Compute 1/sqrt(L_x). |
| L_x is positive. |
| |
| if L_x is negative or zero, result is 1 (3fff ffff). |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The function 1/sqrt(L_x) is approximated by a table and linear |
| interpolation. |
| |
| 1- Normalization of L_x. |
| 2- If (30-exponent) is even then shift right once. |
| 3- exponent = (30-exponent)/2 +1 |
| 4- i = bit25-b31 of L_x, 16 <= i <= 63 ->because of normalization. |
| 5- a = bit10-b24 |
| 6- i -=16 |
| 7- L_y = tabsqr[i]<<16 - (tabsqr[i] - tabsqr[i+1]) * a * 2 |
| 8- L_y >>= exponent |
|___________________________________________________________________________|
*/
Word32
Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */
Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */
)
{
Word16 exp, i, a, tmp;
Word32 L_y;
if (L_x <= (Word32) 0)
return ((Word32) 0x3fffffffL);
exp = norm_l (L_x);
L_x = L_shl (L_x, exp); /* L_x is normalize */
exp = sub (30, exp);
if ((exp & 1) == 0) /* If exponent even -> shift right */
L_x = L_shr (L_x, 1);
exp = shr (exp, 1);
exp = add (exp, 1);
L_x = L_shr (L_x, 9);
i = extract_h (L_x); /* Extract b25-b31 */
L_x = L_shr (L_x, 1);
a = extract_l (L_x); /* Extract b10-b24 */
a = a & (Word16) 0x7fff;
i = sub (i, 16);
L_y = L_deposit_h (tabsqr[i]); /* tabsqr[i] << 16 */
tmp = sub (tabsqr[i], tabsqr[i + 1]); /* tabsqr[i] - tabsqr[i+1]) */
L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
L_y = L_shr (L_y, exp); /* denormalization */
return (L_y);
}

View File

@@ -0,0 +1,991 @@
/*
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 "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_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 */
void Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */
Word16 * rr /* (o) :Correlations of H[] */
);
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. *
*--------------------------------------------------------------------------*/
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 *
*------------------------------------------------------------------------*/
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;
rri2i4 = rri2i3 + MSIZE;
/*-----------------------------------------------------------------------*
* Chose the sign of the impulse. *
*-----------------------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++) {
if (dn[i] >= 0) {
sign_dn[i] = MAX_16;
sign_dn_inv[i] = MIN_16;
}
else {
sign_dn[i] = MIN_16;
sign_dn_inv[i] = MAX_16;
dn[i] = negate (dn[i]);
}
}
/*-------------------------------------------------------------------*
* Modification of rrixiy[] to take signs into account. *
*-------------------------------------------------------------------*/
p0 = rri0i1;
p1 = rri0i2;
p2 = rri0i3;
p3 = rri0i4;
for (i0 = 0; i0 < L_SUBFR; i0 += STEP) {
psign = sign_dn;
if (psign[i0] < 0)
psign = sign_dn_inv;
for (i1 = 1; i1 < L_SUBFR; i1 += STEP) {
*p0 = mult (*p0, psign[i1]); p0++;
*p1 = mult (*p1, psign[i1 + 1]); p1++;
*p2 = mult (*p2, psign[i1 + 2]); p2++;
*p3 = mult (*p3, psign[i1 + 3]); p3++;
}
}
p0 = rri1i2;
p1 = rri1i3;
p2 = rri1i4;
for (i1 = 1; i1 < L_SUBFR; i1 += STEP) {
psign = sign_dn;
if (psign[i1] < 0)
psign = sign_dn_inv;
for (i2 = 2; i2 < L_SUBFR; i2 += STEP) {
*p0 = mult (*p0, psign[i2]); p0++;
*p1 = mult (*p1, psign[i2 + 1]); p1++;
*p2 = mult (*p2, psign[i2 + 2]); p2++;
}
}
p0 = rri2i3;
p1 = rri2i4;
for (i2 = 2; i2 < L_SUBFR; i2 += STEP) {
psign = sign_dn;
if (psign[i2] < 0)
psign = sign_dn_inv;
for (i3 = 3; i3 < L_SUBFR; i3 += STEP) {
*p0 = mult (*p0, psign[i3]); p0++;
*p1 = mult (*p1, psign[i3 + 1]); p1++;
}
}
/*-------------------------------------------------------------------*
* Search the optimum positions of the four pulses which maximize *
* square(correlation) / energy *
*-------------------------------------------------------------------*/
psk = -1;
alpk = 1;
ptr_rri0i3_i4 = rri0i3;
ptr_rri1i3_i4 = rri1i3;
ptr_rri2i3_i4 = rri2i3;
ptr_rri3i3_i4 = rri3i3;
/* Initializations only to remove warning from some compilers */
ip0 = 0;
ip1 = 1;
ip2 = 2;
ip3 = 3;
ix = 0;
iy = 0;
ps = 0;
/* search 2 times: track 3 and 4 */
for (track = 3, trk = 0; track < 5; track++, trk++) {
/*------------------------------------------------------------------*
* depth first search 3, phase A: track 2 and 3/4. *
*------------------------------------------------------------------*/
sq = -1;
alp = 1;
/* i0 loop: 2 positions in track 2 */
prev_i0 = -1;
for (i = 0; i < 2; i++) {
max = -1;
/* search "dn[]" maximum position in track 2 */
for (j = 2; j < L_SUBFR; j += STEP) {
if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) {
max = dn[j];
i0 = j;
}
}
prev_i0 = i0;
j = mult (i0, 6554); /* j = i0/5 */
p0 = rri2i2 + j;
ps1 = dn[i0];
alp1 = L_mult (*p0, _1_4);
/* i1 loop: 8 positions in track 2 */
p0 = ptr_rri2i3_i4 + shl (j, 3);
p1 = ptr_rri3i3_i4;
for (i1 = track; i1 < L_SUBFR; i1 += STEP) {
ps2 = add (ps1, dn[i1]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
alp2 = L_mac (alp1, *p0++, _1_2);
alp2 = L_mac (alp2, *p1++, _1_4);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
ps = ps2;
alp = alp_16;
ix = i0;
iy = i1;
}
}
}
i0 = ix;
i1 = iy;
i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */
/*------------------------------------------------------------------*
* depth first search 3, phase B: track 0 and 1. *
*------------------------------------------------------------------*/
ps0 = ps;
alp0 = L_mult (alp, _1_4);
sq = -1;
alp = 1;
/* build vector for next loop to decrease complexity */
p0 = rri1i2 + mult (i0, 6554);
p1 = ptr_rri1i3_i4 + mult (i1, 6554);
p2 = rri1i1;
p3 = tmp_vect;
for (i3 = 1; i3 < L_SUBFR; i3 += STEP) {
/* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */
s = L_mult (*p0, _1_4);
p0 += NB_POS;
s = L_mac (s, *p1, _1_4);
p1 += NB_POS;
s = L_mac (s, *p2++, _1_8);
*p3++ = wround (s);
}
/* i2 loop: 8 positions in track 0 */
p0 = rri0i2 + mult (i0, 6554);
p1 = ptr_rri0i3_i4 + mult (i1, 6554);
p2 = rri0i0;
p3 = rri0i1;
for (i2 = 0; i2 < L_SUBFR; i2 += STEP) {
ps1 = add (ps0, dn[i2]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
alp1 = L_mac (alp0, *p0, _1_8);
p0 += NB_POS;
alp1 = L_mac (alp1, *p1, _1_8);
p1 += NB_POS;
alp1 = L_mac (alp1, *p2++, _1_16);
/* i3 loop: 8 positions in track 1 */
p4 = tmp_vect;
for (i3 = 1; i3 < L_SUBFR; i3 += STEP) {
ps2 = add (ps1, dn[i3]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
alp2 = L_mac (alp1, *p3++, _1_8);
alp2 = L_mac (alp2, *p4++, _1_2);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
alp = alp_16;
ix = i2;
iy = i3;
}
}
}
/*----------------------------------------------------------------*
* depth first search 3: compare codevector with the best case. *
*----------------------------------------------------------------*/
s = L_msu (L_mult (alpk, sq), psk, alp);
if (s > 0) {
psk = sq;
alpk = alp;
ip2 = i0;
ip3 = i1;
ip0 = ix;
ip1 = iy;
}
/*------------------------------------------------------------------*
* depth first search 4, phase A: track 3 and 0. *
*------------------------------------------------------------------*/
sq = -1;
alp = 1;
/* i0 loop: 2 positions in track 3/4 */
prev_i0 = -1;
for (i = 0; i < 2; i++) {
max = -1;
/* search "dn[]" maximum position in track 3/4 */
for (j = track; j < L_SUBFR; j += STEP) {
if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) {
max = dn[j];
i0 = j;
}
}
prev_i0 = i0;
j = mult (i0, 6554); /* j = i0/5 */
p0 = ptr_rri3i3_i4 + j;
ps1 = dn[i0];
alp1 = L_mult (*p0, _1_4);
/* i1 loop: 8 positions in track 0 */
p0 = ptr_rri0i3_i4 + j;
p1 = rri0i0;
for (i1 = 0; i1 < L_SUBFR; i1 += STEP) {
ps2 = add (ps1, dn[i1]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
alp2 = L_mac (alp1, *p0, _1_2);
p0 += NB_POS;
alp2 = L_mac (alp2, *p1++, _1_4);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
ps = ps2;
alp = alp_16;
ix = i0;
iy = i1;
}
}
}
i0 = ix;
i1 = iy;
i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */
/*------------------------------------------------------------------*
* depth first search 4, phase B: track 1 and 2. *
*------------------------------------------------------------------*/
ps0 = ps;
alp0 = L_mult (alp, _1_4);
sq = -1;
alp = 1;
/* build vector for next loop to decrease complexity */
p0 = ptr_rri2i3_i4 + mult (i0, 6554);
p1 = rri0i2 + i1_offset;
p2 = rri2i2;
p3 = tmp_vect;
for (i3 = 2; i3 < L_SUBFR; i3 += STEP) {
/* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */
s = L_mult (*p0, _1_4);
p0 += NB_POS;
s = L_mac (s, *p1++, _1_4);
s = L_mac (s, *p2++, _1_8);
*p3++ = wround (s);
}
/* i2 loop: 8 positions in track 1 */
p0 = ptr_rri1i3_i4 + mult (i0, 6554);
p1 = rri0i1 + i1_offset;
p2 = rri1i1;
p3 = rri1i2;
for (i2 = 1; i2 < L_SUBFR; i2 += STEP) {
ps1 = add (ps0, dn[i2]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
alp1 = L_mac (alp0, *p0, _1_8);
p0 += NB_POS;
alp1 = L_mac (alp1, *p1++, _1_8);
alp1 = L_mac (alp1, *p2++, _1_16);
/* i3 loop: 8 positions in track 2 */
p4 = tmp_vect;
for (i3 = 2; i3 < L_SUBFR; i3 += STEP) {
ps2 = add (ps1, dn[i3]); /* index increment = STEP */
/* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
alp2 = L_mac (alp1, *p3++, _1_8);
alp2 = L_mac (alp2, *p4++, _1_2);
sq2 = mult (ps2, ps2);
alp_16 = wround (alp2);
s = L_msu (L_mult (alp, sq2), sq, alp_16);
if (s > 0) {
sq = sq2;
alp = alp_16;
ix = i2;
iy = i3;
}
}
}
/*----------------------------------------------------------------*
* depth first search 1: compare codevector with the best case. *
*----------------------------------------------------------------*/
s = L_msu (L_mult (alpk, sq), psk, alp);
if (s > 0) {
psk = sq;
alpk = alp;
ip3 = i0;
ip0 = i1;
ip1 = ix;
ip2 = iy;
}
ptr_rri0i3_i4 = rri0i4;
ptr_rri1i3_i4 = rri1i4;
ptr_rri2i3_i4 = rri2i4;
ptr_rri3i3_i4 = rri4i4;
}
/* Set the sign of impulses */
i0 = sign_dn[ip0];
i1 = sign_dn[ip1];
i2 = sign_dn[ip2];
i3 = sign_dn[ip3];
/* Find the codeword corresponding to the selected positions */
for (i = 0; i < L_SUBFR; i++) {
cod[i] = 0;
}
cod[ip0] = shr (i0, 2); /* From Q15 to Q13 */
cod[ip1] = shr (i1, 2);
cod[ip2] = shr (i2, 2);
cod[ip3] = shr (i3, 2);
/* find the filtered codeword */
for (i = 0; i < ip0; i++)
y[i] = 0;
if (i0 > 0)
for (i = ip0, j = 0; i < L_SUBFR; i++, j++)
y[i] = h[j];
else
for (i = ip0, j = 0; i < L_SUBFR; i++, j++)
y[i] = negate (h[j]);
if (i1 > 0)
for (i = ip1, j = 0; i < L_SUBFR; i++, j++)
y[i] = add (y[i], h[j]);
else
for (i = ip1, j = 0; i < L_SUBFR; i++, j++)
y[i] = sub (y[i], h[j]);
if (i2 > 0)
for (i = ip2, j = 0; i < L_SUBFR; i++, j++)
y[i] = add (y[i], h[j]);
else
for (i = ip2, j = 0; i < L_SUBFR; i++, j++)
y[i] = sub (y[i], h[j]);
if (i3 > 0)
for (i = ip3, j = 0; i < L_SUBFR; i++, j++)
y[i] = add (y[i], h[j]);
else
for (i = ip3, j = 0; i < L_SUBFR; i++, j++)
y[i] = sub (y[i], h[j]);
/* find codebook index; 17-bit address */
i = 0;
if (i0 > 0)
i = add (i, 1);
if (i1 > 0)
i = add (i, 2);
if (i2 > 0)
i = add (i, 4);
if (i3 > 0)
i = add (i, 8);
*sign = i;
ip0 = mult (ip0, 6554); /* ip0/5 */
ip1 = mult (ip1, 6554); /* ip1/5 */
ip2 = mult (ip2, 6554); /* ip2/5 */
i = mult (ip3, 6554); /* ip3/5 */
j = add (i, shl (i, 2)); /* j = i*5 */
j = sub (ip3, add (j, 3)); /* j= ip3%5 -3 */
ip3 = add (shl (i, 1), j);
i = add (ip0, shl (ip1, 3));
i = add (i, shl (ip2, 6));
i = add (i, shl (ip3, 9));
return i;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
#define MAX_32 (Word32)0x7fffffffL
#define MIN_32 (Word32)0x80000000L
#define MAX_16 (Word16)0x7fff
#define MIN_16 (Word16)0x8000
Word16 sature (Word32 L_var1); /* Limit to 16 bits, 1 */
Word16 sature_o (Word32 L_var1, Flag *Overflow); /* Limit to 16 bits, 1 */
Word16 add (Word16 var1, Word16 var2); /* Short add, 1 */
Word16 sub (Word16 var1, Word16 var2); /* Short sub, 1 */
Word16 add_o (Word16 var1, Word16 var2, Flag *Overflow); /* Short add, 1 */
Word16 sub_o (Word16 var1, Word16 var2, Flag *Overflow); /* Short sub, 1 */
Word16 abs_s (Word16 var1); /* Short abs, 1 */
Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */
Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */
Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */
Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */
Word32 L_mult_o (Word16 var1, Word16 var2, Flag *Overflow); /* Long mult, 1 */
Word16 negate (Word16 var1); /* Short negate, 1 */
Word16 extract_h (Word32 L_var1); /* Extract high, 1 */
Word16 extract_l (Word32 L_var1); /* Extract low, 1 */
Word16 wround (Word32 L_var1); /* Round, 1 */
Word16 wround_o (Word32 L_var1, Flag *Overflow); /* Round, 1 */
Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */
Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */
Word32 L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow); /* Mac, 1 */
Word32 L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow); /* Msu, 1 */
Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */
Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */
Word32 L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow); /* Long add, 2 */
Word32 L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow); /* Long sub, 2 */
Word32 L_negate (Word32 L_var1); /* Long negate, 2 */
Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */
Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */
Word32 L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow); /* Long shift left, 2 */
Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2 */
Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with round, 2 */
Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with rounding, 2 */
Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with rounding, 2 */
Word32 L_deposit_h (Word16 var1); /* 16 bit var1 -> MSB, 2 */
Word32 L_deposit_l (Word16 var1); /* 16 bit var1 -> LSB, 2 */
Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */
Word32 L_abs (Word32 L_var1); /* Long abs, 3 */
Word16 norm_s (Word16 var1); /* Short norm, 15 */
Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */
Word16 norm_l (Word32 L_var1); /* Long norm, 30 */

View File

@@ -0,0 +1,430 @@
/*
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.
*/
/*-----------------------------------------------------------------*
* Functions Coder_ld8a and Init_Coder_ld8a *
* ~~~~~~~~~~ ~~~~~~~~~~~~~~~ *
* *
* Init_Coder_ld8a(void); *
* *
* ->Initialization of variables for the coder section. *
* *
* *
* Coder_ld8a(Word16 ana[]); *
* *
* ->Main coder function. *
* *
* *
* Input: *
* *
* 80 speech data should have beee copy to vector new_speech[]. *
* This vector is global and is declared in this function. *
* *
* Ouputs: *
* *
* ana[] ->analysis parameters. *
* *
*-----------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_util.h"
#include "g729_lsp.h"
#include "g729_taming.h"
#include "g729_gain.h"
/*-----------------------------------------------------------*
* Coder constant parameters (defined in "ld8a.h") *
*-----------------------------------------------------------*
* L_WINDOW : LPC analysis window size. *
* L_NEXT : Samples of next frame needed for autocor. *
* L_FRAME : Frame size. *
* L_SUBFR : Sub-frame size. *
* M : LPC order. *
* MP1 : LPC order+1 *
* L_TOTAL : Total size of speech buffer. *
* PIT_MIN : Minimum pitch lag. *
* PIT_MAX : Maximum pitch lag. *
* L_INTERPOL : Length of filter for interpolation *
*-----------------------------------------------------------*/
/*-----------------------------------------------------------------*
* Function Init_Coder_ld8a *
* ~~~~~~~~~~~~~~~ *
* *
* Init_Coder_ld8a(void); *
* *
* ->Initialization of variables for the coder section. *
* - initialize pointers to speech buffer *
* - initialize pointers *
* - set vectors to zero *
* *
*-----------------------------------------------------------------*/
CodState*
Init_Coder_ld8a (void)
{
CodState *coder;
coder = (CodState *) malloc (sizeof (CodState));
/*----------------------------------------------------------------------*
* Initialize pointers to speech vector. *
* *
* *
* |--------------------|-------------|-------------|------------| *
* previous speech sf1 sf2 L_NEXT *
* *
* <---------------- Total speech vector (L_TOTAL) -----------> *
* <---------------- LPC analysis window (L_WINDOW) -----------> *
* | <-- present frame (L_FRAME) --> *
* old_speech | <-- new speech (L_FRAME) --> *
* p_window | | *
* speech | *
* new_speech *
*-----------------------------------------------------------------------*/
coder->new_speech = coder->old_speech + L_TOTAL - L_FRAME; /* New speech */
coder->speech = coder->new_speech - L_NEXT; /* Present frame */
coder->p_window = coder->old_speech + L_TOTAL - L_WINDOW; /* For LPC window */
/* Initialize pointers */
coder->wsp = coder->old_wsp + PIT_MAX;
coder->exc = coder->old_exc + PIT_MAX + L_INTERPOL;
/* Static vectors to zero */
Set_zero (coder->old_speech, L_TOTAL);
Set_zero (coder->old_exc, PIT_MAX + L_INTERPOL);
Set_zero (coder->old_wsp, PIT_MAX);
Set_zero (coder->mem_w, M10);
Set_zero (coder->mem_w0, M10);
Set_zero (coder->mem_zero, M10);
coder->sharp = SHARPMIN;
/* Initialize lsp_old_q[] */
Copy (lsp_old_init, coder->lsp_old, M10);
Copy (lsp_old_init, coder->lsp_old_q, M10);
Lsp_encw_reset (coder);
Init_exc_err (coder);
Copy (past_qua_en_init, coder->past_qua_en, 4);
Set_zero (coder->old_A, M10 + 1);
coder->old_A [0] = 4096;
Set_zero (coder->old_rc, 2);
return coder;
}
/*-----------------------------------------------------------------*
* Functions Coder_ld8a *
* ~~~~~~~~~~ *
* Coder_ld8a(Word16 ana[]); *
* *
* ->Main coder function. *
* *
* *
* Input: *
* *
* 80 speech data should have beee copy to vector new_speech[]. *
* This vector is global and is declared in this function. *
* *
* Ouputs: *
* *
* ana[] ->analysis parameters. *
* *
*-----------------------------------------------------------------*/
void
Coder_ld8a (CodState *coder, Word16 ana[])
{
/* LPC analysis */
Word16 Aq_t[(MP1) * 2]; /* A(z) quantized for the 2 subframes */
Word16 Ap_t[(MP1) * 2]; /* A(z/gamma) for the 2 subframes */
Word16 *Aq, *Ap; /* Pointer on Aq_t and Ap_t */
/* Other vectors */
Word16 h1[L_SUBFR]; /* Impulse response h1[] */
Word16 xn[L_SUBFR]; /* Target vector for pitch search */
Word16 xn2[L_SUBFR]; /* Target vector for codebook search */
Word16 code[L_SUBFR]; /* Fixed codebook excitation */
Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */
Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */
Word16 g_coeff[4]; /* Correlations between xn & y1 */
Word16 g_coeff_cs[5];
Word16 exp_g_coeff_cs[5]; /* Correlations between xn, y1, & y2
<y1,y1>, -2<xn,y1>,
<y2,y2>, -2<xn,y2>, 2<y1,y2> */
/* Scalars */
Word16 i, j, k, i_subfr;
Word16 T_op, T0, T0_min, T0_max, T0_frac;
Word16 gain_pit, gain_code, index;
Word16 temp, taming;
Word32 L_temp;
/*------------------------------------------------------------------------*
* - Perform LPC analysis: *
* * autocorrelation + lag windowing *
* * Levinson-durbin algorithm to find a[] *
* * convert a[] to lsp[] *
* * quantize and code the LSPs *
* * find the interpolated LSPs and convert to a[] for the 2 *
* subframes (both quantized and unquantized) *
*------------------------------------------------------------------------*/
{
/* Temporary vectors */
Word16 r_l[MP1], r_h[MP1]; /* Autocorrelations low and hi */
Word16 rc[M10]; /* Reflection coefficients. */
Word16 lsp_new[M10], lsp_new_q[M10]; /* LSPs at 2th subframe */
/* LP analysis */
Autocorr (coder->p_window, M10, r_h, r_l); /* Autocorrelations */
Lag_window (M10, r_h, r_l); /* Lag windowing */
Levinson (coder, r_h, r_l, Ap_t, rc); /* Levinson Durbin */
Az_lsp (Ap_t, lsp_new, coder->lsp_old); /* From A(z) to lsp */
/* LSP quantization */
Qua_lsp (coder, lsp_new, lsp_new_q, ana);
ana += 2; /* Advance analysis parameters pointer */
/*--------------------------------------------------------------------*
* Find interpolated LPC parameters in all subframes *
* The interpolated parameters are in array Aq_t[]. *
*--------------------------------------------------------------------*/
Int_qlpc (coder->lsp_old_q, lsp_new_q, Aq_t);
/* Compute A(z/gamma) */
Weight_Az (&Aq_t[0], GAMMA1, M10, &Ap_t[0]);
Weight_Az (&Aq_t[MP1], GAMMA1, M10, &Ap_t[MP1]);
/* update the LSPs for the next frame */
Copy (lsp_new, coder->lsp_old, M10);
Copy (lsp_new_q, coder->lsp_old_q, M10);
}
/*----------------------------------------------------------------------*
* - Find the weighted input speech w_sp[] for the whole speech frame *
* - Find the open-loop pitch delay *
*----------------------------------------------------------------------*/
Residu (&Aq_t[0], &coder->speech[0], &coder->exc[0], L_SUBFR);
Residu (&Aq_t[MP1], &coder->speech[L_SUBFR], &coder->exc[L_SUBFR], L_SUBFR);
{
Word16 Ap1[MP1];
Ap = Ap_t;
Ap1[0] = 4096;
for (i = 1; i <= M10; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */
Ap1[i] = sub (Ap[i], mult (Ap[i - 1], 22938));
Syn_filt (Ap1, &coder->exc[0], &coder->wsp[0], L_SUBFR, coder->mem_w, 1, NULL);
Ap += MP1;
for (i = 1; i <= M10; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */
Ap1[i] = sub (Ap[i], mult (Ap[i - 1], 22938));
Syn_filt (Ap1, &coder->exc[L_SUBFR], &coder->wsp[L_SUBFR], L_SUBFR, coder->mem_w, 1, NULL);
}
/* Find open loop pitch lag */
T_op = Pitch_ol_fast (coder->wsp, PIT_MAX, L_FRAME);
/* Range for closed loop pitch search in 1st subframe */
T0_min = sub (T_op, 3);
if (sub (T0_min, PIT_MIN) < 0) {
T0_min = PIT_MIN;
}
T0_max = add (T0_min, 6);
if (sub (T0_max, PIT_MAX) > 0) {
T0_max = PIT_MAX;
T0_min = sub (T0_max, 6);
}
/*------------------------------------------------------------------------*
* Loop for every subframe in the analysis frame *
*------------------------------------------------------------------------*
* To find the pitch and innovation parameters. The subframe size is *
* L_SUBFR and the loop is repeated 2 times. *
* - find the weighted LPC coefficients *
* - find the LPC residual signal res[] *
* - compute the target signal for pitch search *
* - compute impulse response of weighted synthesis filter (h1[]) *
* - find the closed-loop pitch parameters *
* - encode the pitch delay *
* - find target vector for codebook search *
* - codebook search *
* - VQ of pitch and codebook gains *
* - update states of weighting filter *
*------------------------------------------------------------------------*/
Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */
Ap = Ap_t; /* pointer to weighted LPC coefficients */
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
/*---------------------------------------------------------------*
* Compute impulse response, h1[], of weighted synthesis filter *
*---------------------------------------------------------------*/
h1[0] = 4096;
Set_zero (&h1[1], L_SUBFR - 1);
Syn_filt (Ap, h1, h1, L_SUBFR, &h1[1], 0, NULL);
/*----------------------------------------------------------------------*
* Find the target vector for pitch search: *
*----------------------------------------------------------------------*/
Syn_filt (Ap, &coder->exc[i_subfr], xn, L_SUBFR, coder->mem_w0, 0, NULL);
/*---------------------------------------------------------------------*
* Closed-loop fractional pitch search *
*---------------------------------------------------------------------*/
T0 = Pitch_fr3_fast (&coder->exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max,
i_subfr, &T0_frac);
index =
Enc_lag3 (T0, T0_frac, &T0_min, &T0_max, PIT_MIN, PIT_MAX, i_subfr);
*ana++ = index;
if (i_subfr == 0) {
*ana++ = Parity_Pitch (index);
}
/*-----------------------------------------------------------------*
* - find filtered pitch exc *
* - compute pitch gain and limit between 0 and 1.2 *
* - update target vector for codebook search *
*-----------------------------------------------------------------*/
Syn_filt (Ap, &coder->exc[i_subfr], y1, L_SUBFR, coder->mem_zero, 0, NULL);
gain_pit = G_pitch (xn, y1, g_coeff, L_SUBFR);
/* clip pitch gain if taming is necessary */
taming = test_err (coder, T0, T0_frac);
if (taming == 1) {
if (sub (gain_pit, GPCLIP) > 0) {
gain_pit = GPCLIP;
}
}
/* xn2[i] = xn[i] - y1[i] * gain_pit */
for (i = 0; i < L_SUBFR; i++) {
L_temp = L_mult (y1[i], gain_pit);
L_temp = L_shl (L_temp, 1); /* gain_pit in Q14 */
xn2[i] = sub (xn[i], extract_h (L_temp));
}
/*-----------------------------------------------------*
* - Innovative codebook search. *
*-----------------------------------------------------*/
index = ACELP_Code_A (xn2, h1, T0, coder->sharp, code, y2, &i);
*ana++ = index; /* Positions index */
*ana++ = i; /* Signs index */
/*-----------------------------------------------------*
* - Quantization of gains. *
*-----------------------------------------------------*/
g_coeff_cs[0] = g_coeff[0]; /* <y1,y1> */
exp_g_coeff_cs[0] = negate (g_coeff[1]); /* Q-Format:XXX -> JPN */
g_coeff_cs[1] = negate (g_coeff[2]); /* (xn,y1) -> -2<xn,y1> */
exp_g_coeff_cs[1] = negate (add (g_coeff[3], 1)); /* Q-Format:XXX -> JPN */
Corr_xy2 (xn, y1, y2, g_coeff_cs, exp_g_coeff_cs); /* Q0 Q0 Q12 ^Qx ^Q0 */
/* g_coeff_cs[3]:exp_g_coeff_cs[3] = <y2,y2> */
/* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2<xn,y2> */
/* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2<y1,y2> */
*ana++ = Qua_gain (coder, code, g_coeff_cs, exp_g_coeff_cs,
L_SUBFR, &gain_pit, &gain_code, taming);
/*------------------------------------------------------------*
* - Update pitch sharpening "sharp" with quantized gain_pit *
*------------------------------------------------------------*/
coder->sharp = gain_pit;
if (sub (coder->sharp, SHARPMAX) > 0) {
coder->sharp = SHARPMAX;
}
if (sub (coder->sharp, SHARPMIN) < 0) {
coder->sharp = SHARPMIN;
}
/*------------------------------------------------------*
* - Find the total excitation *
* - update filters memories for finding the target *
* vector in the next subframe *
*------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++) {
/* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */
/* exc[i] in Q0 gain_pit in Q14 */
/* code[i] in Q13 gain_cod in Q1 */
L_temp = L_mult (coder->exc[i + i_subfr], gain_pit);
L_temp = L_mac (L_temp, code[i], gain_code);
L_temp = L_shl (L_temp, 1);
coder->exc[i + i_subfr] = wround (L_temp);
}
update_exc_err (coder, gain_pit, T0);
for (i = L_SUBFR - M10, j = 0; i < L_SUBFR; i++, j++) {
temp = extract_h (L_shl (L_mult (y1[i], gain_pit), 1));
k = extract_h (L_shl (L_mult (y2[i], gain_code), 2));
coder->mem_w0[j] = sub (xn[i], add (temp, k));
}
Aq += MP1; /* interpolated LPC parameters for next subframe */
Ap += MP1;
}
/*--------------------------------------------------*
* Update signal for next frame. *
* -> shift to the left by L_FRAME: *
* speech[], wsp[] and exc[] *
*--------------------------------------------------*/
Copy (&coder->old_speech[L_FRAME], &coder->old_speech[0], L_TOTAL - L_FRAME);
Copy (&coder->old_wsp[L_FRAME], &coder->old_wsp[0], PIT_MAX);
Copy (&coder->old_exc[L_FRAME], &coder->old_exc[0], PIT_MAX + L_INTERPOL);
return;
}

View File

@@ -0,0 +1,139 @@
/*
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.
*/
/* Functions Corr_xy2() and Cor_h_x() */
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
/*---------------------------------------------------------------------------*
* Function corr_xy2() *
* ~~~~~~~~~~~~~~~~~~~ *
* Find the correlations between the target xn[], the filtered adaptive *
* codebook excitation y1[], and the filtered 1st codebook innovation y2[]. *
* g_coeff[2]:exp_g_coeff[2] = <y2,y2> *
* g_coeff[3]:exp_g_coeff[3] = -2<xn,y2> *
* g_coeff[4]:exp_g_coeff[4] = 2<y1,y2> *
*---------------------------------------------------------------------------*/
void
Corr_xy2 (Word16 xn[], /* (i) Q0 :Target vector. */
Word16 y1[], /* (i) Q0 :Adaptive codebook. */
Word16 y2[], /* (i) Q12 :Filtered innovative vector. */
Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */
Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */
)
{
Word16 i, exp;
Word16 exp_y2y2, exp_xny2, exp_y1y2;
Word16 y2y2, xny2, y1y2;
Word32 L_acc;
Word16 scaled_y2[L_SUBFR]; /* Q9 */
/*------------------------------------------------------------------*
* Scale down y2[] from Q12 to Q9 to avoid overflow *
*------------------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++) {
scaled_y2[i] = shr (y2[i], 3);
}
/* Compute scalar product <y2[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for (i = 0; i < L_SUBFR; i++)
L_acc = L_mac (L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */
exp = norm_l (L_acc);
y2y2 = wround (L_shl (L_acc, exp));
exp_y2y2 = add (exp, 19 - 16); /* Q[19+exp-16] */
g_coeff[2] = y2y2;
exp_g_coeff[2] = exp_y2y2;
/* Compute scalar product <xn[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for (i = 0; i < L_SUBFR; i++)
L_acc = L_mac (L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */
exp = norm_l (L_acc);
xny2 = wround (L_shl (L_acc, exp));
exp_xny2 = add (exp, 10 - 16); /* Q[10+exp-16] */
g_coeff[3] = negate (xny2);
exp_g_coeff[3] = sub (exp_xny2, 1); /* -2<xn,y2> */
/* Compute scalar product <y1[],y2[]> */
L_acc = 1; /* Avoid case of all zeros */
for (i = 0; i < L_SUBFR; i++)
L_acc = L_mac (L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */
exp = norm_l (L_acc);
y1y2 = wround (L_shl (L_acc, exp));
exp_y1y2 = add (exp, 10 - 16); /* Q[10+exp-16] */
g_coeff[4] = y1y2;
exp_g_coeff[4] = sub (exp_y1y2, 1);; /* 2<y1,y2> */
return;
}
/*--------------------------------------------------------------------------*
* Function Cor_h_X() *
* ~~~~~~~~~~~~~~~~~~~ *
* Compute correlations of input response h[] with the target vector X[]. *
*--------------------------------------------------------------------------*/
void
Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */
Word16 X[], /* (i) :Target vector */
Word16 D[]
/* (o) :Correlations between h[] and D[] */
/* Normalized to 13 bits */
)
{
Word16 i, j;
Word32 s, max, L_temp;
Word32 y32[L_SUBFR];
/* first keep the result on 32 bits and find absolute maximum */
max = 0;
for (i = 0; i < L_SUBFR; i++) {
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_temp = L_sub (s, max);
if (L_temp > 0L) {
max = s;
}
}
/* Find the number of right shifts to do on y32[] */
/* so that maximum is on 13 bits */
j = norm_l (max);
if (sub (j, 16) > 0) {
j = 16;
}
j = sub (18, j);
for (i = 0; i < L_SUBFR; i++) {
D[i] = extract_l (L_shr (y32[i], j));
}
return;
}

View File

@@ -0,0 +1,73 @@
/*
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 Decod_ACELP() *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Algebraic codebook decoder. *
*----------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
void
Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */
Word16 index, /* (i) : Positions of the 4 pulses. */
Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */
)
{
Word16 i, j;
Word16 pos[4];
/* Decode the positions */
i = index & (Word16) 7;
pos[0] = add (i, shl (i, 2)); /* pos0 =i*5 */
index = shr (index, 3);
i = index & (Word16) 7;
i = add (i, shl (i, 2)); /* pos1 =i*5+1 */
pos[1] = add (i, 1);
index = shr (index, 3);
i = index & (Word16) 7;
i = add (i, shl (i, 2)); /* pos2 =i*5+1 */
pos[2] = add (i, 2);
index = shr (index, 3);
j = index & (Word16) 1;
index = shr (index, 1);
i = index & (Word16) 7;
i = add (i, shl (i, 2)); /* pos3 =i*5+3+j */
i = add (i, 3);
pos[3] = add (i, j);
/* decode the signs and build the codeword */
for (i = 0; i < L_SUBFR; i++) {
cod[i] = 0;
}
for (j = 0; j < 4; j++) {
i = sign & (Word16) 1;
sign = shr (sign, 1);
if (i != 0) {
cod[pos[j]] = 8191; /* Q13 +1.0 */
}
else {
cod[pos[j]] = -8192; /* Q13 -1.0 */
}
}
return;
}

View File

@@ -0,0 +1,109 @@
/*
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.
*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
/*---------------------------------------------------------------------------*
* Function Dec_gain *
* ~~~~~~~~~~~~~~~~~~ *
* Decode the pitch and codebook gains *
* *
*---------------------------------------------------------------------------*
* input arguments: *
* *
* index :Quantization index *
* code[] :Innovative code vector *
* L_subfr :Subframe size *
* bfi :Bad frame indicator *
* *
* output arguments: *
* *
* gain_pit :Quantized pitch gain *
* gain_cod :Quantized codebook gain *
* *
*---------------------------------------------------------------------------*/
void
Dec_gain (DecState *decoder,
Word16 index, /* (i) :Index of quantization. */
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 bfi, /* (i) :Bad frame indicator */
Word16 * gain_pit, /* (o) Q14 :Pitch gain. */
Word16 * gain_cod /* (o) Q1 :Code gain. */
)
{
Word16 index1, index2, tmp;
Word16 gcode0, exp_gcode0;
Word32 L_gbk12, L_acc, L_accb;
void Gain_predict (Word16 past_qua_en[], Word16 code[], Word16 L_subfr,
Word16 * gcode0, Word16 * exp_gcode0);
void Gain_update (Word16 past_qua_en[], Word32 L_gbk12);
void Gain_update_erasure (Word16 past_qua_en[]);
/* Gain predictor, Past quantized energies = -14.0 in Q10 */
/*-------------- Case of erasure. ---------------*/
if (bfi != 0) {
*gain_pit = mult (*gain_pit, 29491); /* *0.9 in Q15 */
if (sub (*gain_pit, 29491) > 0)
*gain_pit = 29491;
*gain_cod = mult (*gain_cod, 32111); /* *0.98 in Q15 */
/*----------------------------------------------*
* update table of past quantized energies *
* (frame erasure) *
*----------------------------------------------*/
Gain_update_erasure (decoder->past_qua_en);
return;
}
/*-------------- Decode pitch gain ---------------*/
index1 = imap1[shr (index, NCODE2_B)];
index2 = imap2[index & (NCODE2 - 1)];
*gain_pit = add (gbk1[index1][0], gbk2[index2][0]);
/*-------------- Decode codebook gain ---------------*/
/*---------------------------------------------------*
*- energy due to innovation -*
*- predicted energy -*
*- predicted codebook gain => gcode0[exp_gcode0] -*
*---------------------------------------------------*/
Gain_predict (decoder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0);
/*-----------------------------------------------------------------*
* *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; *
*-----------------------------------------------------------------*/
L_acc = L_deposit_l (gbk1[index1][1]);
L_accb = L_deposit_l (gbk2[index2][1]);
L_gbk12 = L_add (L_acc, L_accb); /* Q13 */
tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */
L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */
L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16)));
*gain_cod = extract_h (L_acc); /* Q1 */
/*----------------------------------------------*
* update table of past quantized energies *
*----------------------------------------------*/
Gain_update (decoder->past_qua_en, L_gbk12);
return;
}

View File

@@ -0,0 +1,18 @@
/*
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.
*/
void Dec_gain (DecState *decoder,
Word16 index, /* (i) : Index of quantization. */
Word16 code[], /* (i) Q13 : Innovative vector. */
Word16 L_subfr, /* (i) : Subframe length. */
Word16 bfi, /* (i) : Bad frame indicator */
Word16 * gain_pit, /* (o) Q14 : Pitch gain. */
Word16 * gain_cod /* (o) Q1 : Code gain. */
);

View File

@@ -0,0 +1,79 @@
/*
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 Dec_lag3 *
* ~~~~~~~~ *
* Decoding of fractional pitch lag with 1/3 resolution. *
* See "Enc_lag3.c" for more details about the encoding procedure. *
*------------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
void
Dec_lag3 (Word16 index, /* input : received pitch index */
Word16 pit_min, /* input : minimum pitch lag */
Word16 pit_max, /* input : maximum pitch lag */
Word16 i_subfr, /* input : subframe flag */
Word16 * T0, /* output: integer part of pitch lag */
Word16 * T0_frac /* output: fractional part of pitch lag */
)
{
Word16 i;
Word16 T0_min, T0_max;
if (i_subfr == 0) { /* if 1st subframe */
if (sub (index, 197) < 0) {
/* *T0 = (index+2)/3 + 19 */
*T0 = add (mult (add (index, 2), 10923), 19);
/* *T0_frac = index - *T0*3 + 58 */
i = add (add (*T0, *T0), *T0);
*T0_frac = add (sub (index, i), 58);
}
else {
*T0 = sub (index, 112);
*T0_frac = 0;
}
}
else { /* second subframe */
/* find T0_min and T0_max for 2nd subframe */
T0_min = sub (*T0, 5);
if (sub (T0_min, pit_min) < 0) {
T0_min = pit_min;
}
T0_max = add (T0_min, 9);
if (sub (T0_max, pit_max) > 0) {
T0_max = pit_max;
T0_min = sub (T0_max, 9);
}
/* i = (index+2)/3 - 1 */
/* *T0 = i + t0_min; */
i = sub (mult (add (index, 2), 10923), 1);
*T0 = add (i, T0_min);
/* t0_frac = index - 2 - i*3; */
i = add (add (i, i), i);
*T0_frac = sub (sub (index, 2), i);
}
return;
}

View File

@@ -0,0 +1,271 @@
/*
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.
*/
/*-----------------------------------------------------------------*
* Functions Init_Decod_ld8a and Decod_ld8a *
*-----------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_lspdec.h"
#include "g729_util.h"
#include "g729_dec_gain.h"
/*---------------------------------------------------------------*
* Decoder constant parameters (defined in "ld8a.h") *
*---------------------------------------------------------------*
* L_FRAME : Frame size. *
* L_SUBFR : Sub-frame size. *
* M : LPC order. *
* MP1 : LPC order+1 *
* PIT_MIN : Minimum pitch lag. *
* PIT_MAX : Maximum pitch lag. *
* L_INTERPOL : Length of filter for interpolation *
* PRM_SIZE : Size of vector containing analysis parameters *
*---------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* Function Init_Decod_ld8a *
* ~~~~~~~~~~~~~~~ *
* *
* ->Initialization of variables for the decoder section. *
* *
*-----------------------------------------------------------------*/
DecState *
Init_Decod_ld8a (void)
{
DecState *decoder;
decoder = (DecState*) malloc (sizeof (DecState));
/* Initialize pointers */
decoder->exc = decoder->old_exc + PIT_MAX + L_INTERPOL;
/* Static vectors to zero */
Set_zero (decoder->old_exc, PIT_MAX + L_INTERPOL);
Set_zero (decoder->mem_syn, M10);
Copy (lsp_old_init, decoder->lsp_old, M10);
decoder->sharp = SHARPMIN;
decoder->old_T0 = 60;
decoder->gain_code = 0;
decoder->gain_pitch = 0;
Lsp_decw_reset (decoder);
decoder->bad_lsf = 0;
Set_zero (decoder->Az_dec, MP1 * 2);
Set_zero (decoder->synth_buf, L_FRAME + M10);
Set_zero (decoder->T2, 2);
Copy (past_qua_en_init, decoder->past_qua_en, 4);
decoder->seed = 21845;
return decoder;
}
/*-----------------------------------------------------------------*
* Function Decod_ld8a *
* ~~~~~~~~~~ *
* ->Main decoder routine. *
* *
*-----------------------------------------------------------------*/
void
Decod_ld8a (DecState *decoder,
Word16 parm[], /* (i) : vector of synthesis parameters
parm[0] = bad frame indicator (bfi) */
Word16 synth[], /* (o) : synthesis speech */
Word16 A_t[], /* (o) : decoded LP filter in 2 subframes */
Word16 * T2, /* (o) : decoded pitch lag in 2 subframes */
Word16 * bad_lsf)
{
Flag Overflow;
Word16 *Az; /* Pointer on A_t */
Word16 lsp_new[M10]; /* LSPs */
Word16 code[L_SUBFR]; /* ACELP codevector */
/* Scalars */
Word16 i, j, i_subfr;
Word16 T0, T0_frac, index;
Word16 bfi;
Word32 L_temp;
Word16 bad_pitch; /* bad pitch indicator */
/* Test bad frame indicator (bfi) */
bfi = *parm++;
/* Decode the LSPs */
D_lsp (decoder, parm, lsp_new, add (bfi, *bad_lsf));
parm += 2;
/*
Note: "bad_lsf" is introduce in case the standard is used with
channel protection.
*/
/* Interpolation of LPC for the 2 subframes */
Int_qlpc (decoder->lsp_old, lsp_new, A_t);
/* update the LSFs for the next frame */
Copy (lsp_new, decoder->lsp_old, M10);
/*------------------------------------------------------------------------*
* Loop for every subframe in the analysis frame *
*------------------------------------------------------------------------*
* The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR *
* times *
* - decode the pitch delay *
* - decode algebraic code *
* - decode pitch and codebook gains *
* - find the excitation and compute synthesis speech *
*------------------------------------------------------------------------*/
Az = A_t; /* pointer to interpolated LPC parameters */
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
index = *parm++; /* pitch index */
if (i_subfr == 0) {
i = *parm++; /* get parity check result */
bad_pitch = add (bfi, i);
if (bad_pitch == 0) {
Dec_lag3 (index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac);
decoder->old_T0 = T0;
}
else { /* Bad frame, or parity error */
T0 = decoder->old_T0;
T0_frac = 0;
decoder->old_T0 = add (decoder->old_T0, 1);
if (sub (decoder->old_T0, PIT_MAX) > 0) {
decoder->old_T0 = PIT_MAX;
}
}
}
else { /* second subframe */
if (bfi == 0) {
Dec_lag3 (index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac);
decoder->old_T0 = T0;
}
else {
T0 = decoder->old_T0;
T0_frac = 0;
decoder->old_T0 = add (decoder->old_T0, 1);
if (sub (decoder->old_T0, PIT_MAX) > 0) {
decoder->old_T0 = PIT_MAX;
}
}
}
*T2++ = T0;
/*-------------------------------------------------*
* - Find the adaptive codebook vector. *
*-------------------------------------------------*/
Pred_lt_3 (&decoder->exc[i_subfr], T0, T0_frac, L_SUBFR);
/*-------------------------------------------------------*
* - Decode innovative codebook. *
* - Add the fixed-gain pitch contribution to code[]. *
*-------------------------------------------------------*/
if (bfi != 0) { /* Bad frame */
parm[0] = Random_16 (&decoder->seed) & (Word16) 0x1fff; /* 13 bits random */
parm[1] = Random_16 (&decoder->seed) & (Word16) 0x000f; /* 4 bits random */
}
Decod_ACELP (parm[1], parm[0], code);
parm += 2;
j = shl (decoder->sharp, 1); /* From Q14 to Q15 */
if (sub (T0, L_SUBFR) < 0) {
for (i = T0; i < L_SUBFR; i++) {
code[i] = add (code[i], mult (code[i - T0], j));
}
}
/*-------------------------------------------------*
* - Decode pitch and codebook gains. *
*-------------------------------------------------*/
index = *parm++; /* index of energy VQ */
Dec_gain (decoder, index, code, L_SUBFR, bfi, &decoder->gain_pitch, &decoder->gain_code);
/*-------------------------------------------------------------*
* - Update pitch sharpening "sharp" with quantized gain_pitch *
*-------------------------------------------------------------*/
decoder->sharp = decoder->gain_pitch;
if (sub (decoder->sharp, SHARPMAX) > 0) {
decoder->sharp = SHARPMAX;
}
if (sub (decoder->sharp, SHARPMIN) < 0) {
decoder->sharp = SHARPMIN;
}
/*-------------------------------------------------------*
* - Find the total excitation. *
* - Find synthesis speech corresponding to exc[]. *
*-------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++) {
/* exc[i] = gain_pitch*exc[i] + gain_code*code[i]; */
/* exc[i] in Q0 gain_pitch in Q14 */
/* code[i] in Q13 gain_codeode in Q1 */
L_temp = L_mult (decoder->exc[i + i_subfr], decoder->gain_pitch);
L_temp = L_mac (L_temp, code[i], decoder->gain_code);
L_temp = L_shl (L_temp, 1);
decoder->exc[i + i_subfr] = wround (L_temp);
}
Overflow = 0;
Syn_filt (Az, &decoder->exc[i_subfr], &synth[i_subfr], L_SUBFR, decoder->mem_syn, 0, &Overflow);
if (Overflow != 0) {
/* In case of overflow in the synthesis */
/* -> Scale down vector exc[] and redo synthesis */
for (i = 0; i < PIT_MAX + L_INTERPOL + L_FRAME; i++)
decoder->old_exc[i] = shr (decoder->old_exc[i], 2);
Syn_filt (Az, &decoder->exc[i_subfr], &synth[i_subfr], L_SUBFR, decoder->mem_syn, 1, NULL);
}
else
Copy (&synth[i_subfr + L_SUBFR - M10], decoder->mem_syn, M10);
Az += MP1; /* interpolated LPC parameters for next subframe */
}
/*--------------------------------------------------*
* Update signal for next frame. *
* -> shift to the left by L_FRAME exc[] *
*--------------------------------------------------*/
Copy (&decoder->old_exc[L_FRAME], &decoder->old_exc[0], PIT_MAX + L_INTERPOL);
return;
}

View File

@@ -0,0 +1,182 @@
/*
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.
*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
/*___________________________________________________________________________
| |
| Function Name : Pow2() |
| |
| L_x = pow(2.0, exponent.fraction) |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The function Pow2(L_x) is approximated by a table and linear |
| interpolation. |
| |
| 1- i = bit10-b15 of fraction, 0 <= i <= 31 |
| 2- a = bit0-b9 of fraction |
| 3- L_x = tabpow[i]<<16 - (tabpow[i] - tabpow[i+1]) * a * 2 |
| 4- L_x = L_x >> (30-exponent) (with rounding) |
|___________________________________________________________________________|
*/
Word32
Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */
Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */
Word16 fraction /* (i) Q15 : Fractional part. (range: 0.0<=val<1.0) */
)
{
Word16 exp, i, a, tmp;
Word32 L_x;
L_x = L_mult (fraction, 32); /* L_x = fraction<<6 */
i = extract_h (L_x); /* Extract b10-b15 of fraction */
L_x = L_shr (L_x, 1);
a = extract_l (L_x); /* Extract b0-b9 of fraction */
a = a & (Word16) 0x7fff;
L_x = L_deposit_h (tabpow[i]); /* tabpow[i] << 16 */
tmp = sub (tabpow[i], tabpow[i + 1]); /* tabpow[i] - tabpow[i+1] */
L_x = L_msu (L_x, tmp, a); /* L_x -= tmp*a*2 */
exp = sub (30, exponent);
L_x = L_shr_r (L_x, exp);
return (L_x);
}
/*___________________________________________________________________________
| |
| Function Name : Log2() |
| |
| Compute log2(L_x). |
| L_x is positive. |
| |
| if L_x is negative or zero, result is 0. |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The function Log2(L_x) is approximated by a table and linear |
| interpolation. |
| |
| 1- Normalization of L_x. |
| 2- exponent = 30-exponent |
| 3- i = bit25-b31 of L_x, 32 <= i <= 63 ->because of normalization. |
| 4- a = bit10-b24 |
| 5- i -=32 |
| 6- fraction = tablog[i]<<16 - (tablog[i] - tablog[i+1]) * a * 2 |
|___________________________________________________________________________|
*/
void
Log2 (Word32 L_x, /* (i) Q0 : input value */
Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */
Word16 * fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */
)
{
Word16 exp, i, a, tmp;
Word32 L_y;
if (L_x <= (Word32) 0) {
*exponent = 0;
*fraction = 0;
return;
}
exp = norm_l (L_x);
L_x = L_shl (L_x, exp); /* L_x is normalized */
*exponent = sub (30, exp);
L_x = L_shr (L_x, 9);
i = extract_h (L_x); /* Extract b25-b31 */
L_x = L_shr (L_x, 1);
a = extract_l (L_x); /* Extract b10-b24 of fraction */
a = a & (Word16) 0x7fff;
i = sub (i, 32);
L_y = L_deposit_h (tablog[i]); /* tablog[i] << 16 */
tmp = sub (tablog[i], tablog[i + 1]); /* tablog[i] - tablog[i+1] */
L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
*fraction = extract_h (L_y);
return;
}
/*___________________________________________________________________________
| |
| Function Name : Inv_sqrt |
| |
| Compute 1/sqrt(L_x). |
| L_x is positive. |
| |
| if L_x is negative or zero, result is 1 (3fff ffff). |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The function 1/sqrt(L_x) is approximated by a table and linear |
| interpolation. |
| |
| 1- Normalization of L_x. |
| 2- If (30-exponent) is even then shift right once. |
| 3- exponent = (30-exponent)/2 +1 |
| 4- i = bit25-b31 of L_x, 16 <= i <= 63 ->because of normalization. |
| 5- a = bit10-b24 |
| 6- i -=16 |
| 7- L_y = tabsqr[i]<<16 - (tabsqr[i] - tabsqr[i+1]) * a * 2 |
| 8- L_y >>= exponent |
|___________________________________________________________________________|
*/
Word32
Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */
Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */
)
{
Word16 exp, i, a, tmp;
Word32 L_y;
if (L_x <= (Word32) 0)
return ((Word32) 0x3fffffffL);
exp = norm_l (L_x);
L_x = L_shl (L_x, exp); /* L_x is normalize */
exp = sub (30, exp);
if ((exp & 1) == 0) /* If exponent even -> shift right */
L_x = L_shr (L_x, 1);
exp = shr (exp, 1);
exp = add (exp, 1);
L_x = L_shr (L_x, 9);
i = extract_h (L_x); /* Extract b25-b31 */
L_x = L_shr (L_x, 1);
a = extract_l (L_x); /* Extract b10-b24 */
a = a & (Word16) 0x7fff;
i = sub (i, 16);
L_y = L_deposit_h (tabsqr[i]); /* tabsqr[i] << 16 */
tmp = sub (tabsqr[i], tabsqr[i + 1]); /* tabsqr[i] - tabsqr[i+1]) */
L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
L_y = L_shr (L_y, exp); /* denormalization */
return (L_y);
}

View File

@@ -0,0 +1,128 @@
/*
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 Convolve: *
* ~~~~~~~~~ *
*-------------------------------------------------------------------*
* Perform the convolution between two vectors x[] and h[] and *
* write the result in the vector y[]. *
* All vectors are of length N. *
*-------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
void
Convolve (Word16 x[], /* (i) : input vector */
Word16 h[], /* (i) Q12 : impulse response */
Word16 y[], /* (o) : output vector */
Word16 L /* (i) : vector size */
)
{
Word16 i, n;
Word32 s;
for (n = 0; n < L; n++) {
s = 0;
for (i = 0; i <= n; i++)
s = L_mac (s, x[i], h[n - i]);
s = L_shl (s, 3); /* h is in Q12 and saturation */
y[n] = extract_h (s);
}
return;
}
/*-----------------------------------------------------*
* procedure Syn_filt: *
* ~~~~~~~~ *
* Do the synthesis filtering 1/A(z). *
*-----------------------------------------------------*/
void
Syn_filt (Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */
Word16 x[], /* (i) : input signal */
Word16 y[], /* (o) : output signal */
Word16 lg, /* (i) : size of filtering */
Word16 mem[], /* (i/o) : memory associated with this filtering. */
Word16 update, /* (i) : 0=no update, 1=update of memory. */
Flag *Overflow
)
{
Flag Over = 0;
Word16 i, j;
Word32 s;
Word16 tmp[100]; /* This is usually done by memory allocation (lg+M) */
Word16 *yy;
/* Copy mem[] to yy[] */
yy = tmp;
for (i = 0; i < M10; i++) {
*yy++ = mem[i];
}
/* Do the filtering. */
for (i = 0; i < lg; i++) {
s = L_mult_o (x[i], a[0], &Over);
for (j = 1; j <= M10; j++)
s = L_msu_o (s, a[j], yy[-j], &Over);
s = L_shl_o (s, 3, &Over);
*yy++ = wround_o (s, &Over);
}
for (i = 0; i < lg; i++) {
y[i] = tmp[i + M10];
}
/* Update of memory if update==1 */
if (update != 0)
for (i = 0; i < M10; i++) {
mem[i] = y[lg - M10 + i];
}
if (Overflow != NULL)
*Overflow = Over;
return;
}
/*-----------------------------------------------------------------------*
* procedure Residu: *
* ~~~~~~ *
* Compute the LPC residual by filtering the input speech through A(z) *
*-----------------------------------------------------------------------*/
void Residu (Word16 a[], /* (i) Q12 : prediction coefficients */
Word16 x[], /* (i) : speech (values x[-m..-1] are needed */
Word16 y[], /* (o) : residual signal */
Word16 lg /* (i) : size of filtering */
)
{
Word16 i, j;
Word32 s;
for (i = 0; i < lg; i++) {
s = L_mult (x[i], a[0]);
for (j = 1; j <= M10; j++)
s = L_mac (s, a[j], x[i - j]);
s = L_shl (s, 3);
y[i] = wround (s);
}
return;
}

View File

@@ -0,0 +1,443 @@
/*
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.
*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_taming.h"
void Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */
/* (i) [1] Q2 : unquantized code gain */
Word16 * cand1, /* (o) : index of best 1st stage vector */
Word16 * cand2, /* (o) : index of best 2nd stage vector */
Word16 gcode0 /* (i) Q4 : presearch for gain codebook */
);
/*---------------------------------------------------------------------------*
* Function Qua_gain *
* ~~~~~~~~~~~~~~~~~~ *
* Inputs: *
* code[] :Innovative codebook. *
* g_coeff[] :Correlations compute for pitch. *
* L_subfr :Subframe length. *
* *
* Outputs: *
* gain_pit :Quantized pitch gain. *
* gain_cod :Quantized code gain. *
* *
* Return: *
* Index of quantization. *
* *
*--------------------------------------------------------------------------*/
Word16
Qua_gain (CodState *coder,
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 g_coeff[], /* (i) :Correlations <xn y1> -2<y1 y1> */
/* <y2,y2>, -2<xn,y2>, 2<y1,y2> */
Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 * gain_pit, /* (o) Q14 :Pitch gain. */
Word16 * gain_cod, /* (o) Q1 :Code gain. */
Word16 tameflag /* (i) : set to 1 if taming is needed */
)
{
Word16 i, j, index1, index2;
Word16 cand1, cand2;
Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min;
Word16 nume, denom, inv_denom;
Word16 exp1, exp2, exp_nume, exp_denom, exp_inv_denom, sft, tmp;
Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
Word16 coeff[5], coeff_lsf[5];
Word16 exp_min[5];
Word32 L_gbk12;
Word32 L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb;
Word16 best_gain[2];
/* Gain predictor, Past quantized energies = -14.0 in Q10 */
/*---------------------------------------------------*
*- energy due to innovation -*
*- predicted energy -*
*- predicted codebook gain => gcode0[exp_gcode0] -*
*---------------------------------------------------*/
Gain_predict (coder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0);
/*-----------------------------------------------------------------*
* pre-selection *
*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* calculate best gain *
* *
* tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; *
* best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; *
* best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; *
* gbk_presel(best_gain,&cand1,&cand2,gcode0) ; *
* *
*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[0], g_coeff[2]);
exp1 = add (add (exp_coeff[0], exp_coeff[2]), 1 - 2);
L_tmp2 = L_mult (g_coeff[4], g_coeff[4]);
exp2 = add (add (exp_coeff[4], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp = L_sub (L_shr (L_tmp1, sub (exp1, exp2)), L_tmp2);
exp = exp2;
}
else {
L_tmp = L_sub (L_tmp1, L_shr (L_tmp2, sub (exp2, exp1)));
exp = exp1;
}
sft = norm_l (L_tmp);
denom = extract_h (L_shl (L_tmp, sft));
exp_denom = sub (add (exp, sft), 16);
inv_denom = div_s (16384, denom);
inv_denom = negate (inv_denom);
exp_inv_denom = sub (14 + 15, exp_denom);
/*-----------------------------------------------------------------*
* best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[2], g_coeff[1]);
exp1 = add (exp_coeff[2], exp_coeff[1]);
L_tmp2 = L_mult (g_coeff[3], g_coeff[4]);
exp2 = add (add (exp_coeff[3], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp =
L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1));
exp = sub (exp2, 1);
}
else {
L_tmp =
L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1)));
exp = sub (exp1, 1);
}
sft = norm_l (L_tmp);
nume = extract_h (L_shl (L_tmp, sft));
exp_nume = sub (add (exp, sft), 16);
sft = sub (add (exp_nume, exp_inv_denom), (9 + 16 - 1));
L_acc = L_shr (L_mult (nume, inv_denom), sft);
best_gain[0] = extract_h (L_acc); /*-- best_gain[0]:Q9 --*/
if (tameflag == 1) {
if (sub (best_gain[0], GPCLIP2) > 0)
best_gain[0] = GPCLIP2;
}
/*-----------------------------------------------------------------*
* best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[0], g_coeff[3]);
exp1 = add (exp_coeff[0], exp_coeff[3]);
L_tmp2 = L_mult (g_coeff[1], g_coeff[4]);
exp2 = add (add (exp_coeff[1], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp =
L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1));
exp = sub (exp2, 1);
}
else {
L_tmp =
L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1)));
exp = sub (exp1, 1);
}
sft = norm_l (L_tmp);
nume = extract_h (L_shl (L_tmp, sft));
exp_nume = sub (add (exp, sft), 16);
sft = sub (add (exp_nume, exp_inv_denom), (2 + 16 - 1));
L_acc = L_shr (L_mult (nume, inv_denom), sft);
best_gain[1] = extract_h (L_acc); /*-- best_gain[1]:Q2 --*/
/*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/
if (sub (exp_gcode0, 4) >= 0) {
gcode0_org = shr (gcode0, sub (exp_gcode0, 4));
}
else {
L_acc = L_deposit_l (gcode0);
L_acc = L_shl (L_acc, sub ((4 + 16), exp_gcode0));
gcode0_org = extract_h (L_acc); /*-- gcode0_org:Q4 --*/
}
/*----------------------------------------------*
* - presearch for gain codebook - *
*----------------------------------------------*/
Gbk_presel (best_gain, &cand1, &cand2, gcode0_org);
/*---------------------------------------------------------------------------*
* *
* Find the best quantizer. *
* *
* dist_min = MAX_32; *
* for ( i=0 ; i<NCAN1 ; i++ ){ *
* for ( j=0 ; j<NCAN2 ; j++ ){ *
* g_pitch = gbk1[cand1+i][0] + gbk2[cand2+j][0]; *
* g_code = gcode0 * (gbk1[cand1+i][1] + gbk2[cand2+j][1]); *
* dist = g_pitch*g_pitch * coeff[0] *
* + g_pitch * coeff[1] *
* + g_code*g_code * coeff[2] *
* + g_code * coeff[3] *
* + g_pitch*g_code * coeff[4] ; *
* *
* if (dist < dist_min){ *
* dist_min = dist; *
* indice1 = cand1 + i ; *
* indice2 = cand2 + j ; *
* } *
* } *
* } *
* *
* g_pitch = Q13 *
* g_pitch*g_pitch = Q11:(13+13+1-16) *
* g_code = Q[exp_gcode0-3]:(exp_gcode0+(13-1)+1-16) *
* g_code*g_code = Q[2*exp_gcode0-21]:(exp_gcode0-3+exp_gcode0-3+1-16) *
* g_pitch*g_code = Q[exp_gcode0-5]:(13+exp_gcode0-3+1-16) *
* *
* term 0: g_pitch*g_pitch*coeff[0] ;exp_min0 = 13 +exp_coeff[0] *
* term 1: g_pitch *coeff[1] ;exp_min1 = 14 +exp_coeff[1] *
* term 2: g_code*g_code *coeff[2] ;exp_min2 = 2*exp_gcode0-21+exp_coeff[2] *
* term 3: g_code *coeff[3] ;exp_min3 = exp_gcode0 - 3+exp_coeff[3] *
* term 4: g_pitch*g_code *coeff[4] ;exp_min4 = exp_gcode0 - 4+exp_coeff[4] *
* *
*---------------------------------------------------------------------------*/
exp_min[0] = add (exp_coeff[0], 13);
exp_min[1] = add (exp_coeff[1], 14);
exp_min[2] = add (exp_coeff[2], sub (shl (exp_gcode0, 1), 21));
exp_min[3] = add (exp_coeff[3], sub (exp_gcode0, 3));
exp_min[4] = add (exp_coeff[4], sub (exp_gcode0, 4));
e_min = exp_min[0];
for (i = 1; i < 5; i++) {
if (sub (exp_min[i], e_min) < 0) {
e_min = exp_min[i];
}
}
/* align coeff[] and save in special 32 bit double precision */
for (i = 0; i < 5; i++) {
j = sub (exp_min[i], e_min);
L_tmp = L_deposit_h (g_coeff[i]);
L_tmp = L_shr (L_tmp, j); /* L_tmp:Q[exp_g_coeff[i]+16-j] */
L_Extract (L_tmp, &coeff[i], &coeff_lsf[i]); /* DPF */
}
/* Codebook search */
L_dist_min = MAX_32;
/* initialization used only to suppress Microsoft Visual C++ warnings */
index1 = cand1;
index2 = cand2;
if (tameflag == 1) {
for (i = 0; i < NCAN1; i++) {
for (j = 0; j < NCAN2; j++) {
g_pitch = add (gbk1[cand1 + i][0], gbk2[cand2 + j][0]); /* Q14 */
if (g_pitch < GP0999) {
L_acc = L_deposit_l (gbk1[cand1 + i][1]);
L_accb = L_deposit_l (gbk2[cand2 + j][1]); /* Q13 */
L_tmp = L_add (L_acc, L_accb);
tmp = extract_l (L_shr (L_tmp, 1)); /* Q12 */
g_code = mult (gcode0, tmp); /* Q[exp_gcode0+12-15] */
g2_pitch = mult (g_pitch, g_pitch); /* Q13 */
g2_code = mult (g_code, g_code); /* Q[2*exp_gcode0-6-15] */
g_pit_cod = mult (g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */
L_tmp = Mpy_32_16 (coeff[0], coeff_lsf[0], g2_pitch);
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[1], coeff_lsf[1], g_pitch));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[2], coeff_lsf[2], g2_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[3], coeff_lsf[3], g_code));
L_tmp =
L_add (L_tmp, Mpy_32_16 (coeff[4], coeff_lsf[4], g_pit_cod));
L_temp = L_sub (L_tmp, L_dist_min);
if (L_temp < 0L) {
L_dist_min = L_tmp;
index1 = add (cand1, i);
index2 = add (cand2, j);
}
}
}
}
}
else {
for (i = 0; i < NCAN1; i++) {
for (j = 0; j < NCAN2; j++) {
g_pitch = add (gbk1[cand1 + i][0], gbk2[cand2 + j][0]); /* Q14 */
L_acc = L_deposit_l (gbk1[cand1 + i][1]);
L_accb = L_deposit_l (gbk2[cand2 + j][1]); /* Q13 */
L_tmp = L_add (L_acc, L_accb);
tmp = extract_l (L_shr (L_tmp, 1)); /* Q12 */
g_code = mult (gcode0, tmp); /* Q[exp_gcode0+12-15] */
g2_pitch = mult (g_pitch, g_pitch); /* Q13 */
g2_code = mult (g_code, g_code); /* Q[2*exp_gcode0-6-15] */
g_pit_cod = mult (g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */
L_tmp = Mpy_32_16 (coeff[0], coeff_lsf[0], g2_pitch);
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[1], coeff_lsf[1], g_pitch));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[2], coeff_lsf[2], g2_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[3], coeff_lsf[3], g_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[4], coeff_lsf[4], g_pit_cod));
L_temp = L_sub (L_tmp, L_dist_min);
if (L_temp < 0L) {
L_dist_min = L_tmp;
index1 = add (cand1, i);
index2 = add (cand2, j);
}
}
}
}
/* Read the quantized gain */
/*-----------------------------------------------------------------*
* *gain_pit = gbk1[indice1][0] + gbk2[indice2][0]; *
*-----------------------------------------------------------------*/
*gain_pit = add (gbk1[index1][0], gbk2[index2][0]); /* Q14 */
/*-----------------------------------------------------------------*
* *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; *
*-----------------------------------------------------------------*/
L_acc = L_deposit_l (gbk1[index1][1]);
L_accb = L_deposit_l (gbk2[index2][1]);
L_gbk12 = L_add (L_acc, L_accb); /* Q13 */
tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */
L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */
L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16)));
*gain_cod = extract_h (L_acc); /* Q1 */
/*----------------------------------------------*
* update table of past quantized energies *
*----------------------------------------------*/
Gain_update (coder->past_qua_en, L_gbk12);
return (add (map1[index1] * (Word16) NCODE2, map2[index2]));
}
/*---------------------------------------------------------------------------*
* Function Gbk_presel *
* ~~~~~~~~~~~~~~~~~~~ *
* - presearch for gain codebook - *
*---------------------------------------------------------------------------*/
void
Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */
/* (i) [1] Q2 : unquantized code gain */
Word16 * cand1, /* (o) : index of best 1st stage vector */
Word16 * cand2, /* (o) : index of best 2nd stage vector */
Word16 gcode0 /* (i) Q4 : presearch for gain codebook */
)
{
Word16 acc_h;
Word16 sft_x, sft_y;
Word32 L_acc, L_preg, L_cfbg, L_tmp, L_tmp_x, L_tmp_y;
Word32 L_temp;
/*--------------------------------------------------------------------------*
x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef;
*--------------------------------------------------------------------------*/
L_cfbg = L_mult (coef[0][0], best_gain[0]); /* L_cfbg:Q20 -> !!y */
L_acc = L_shr (L_coef[1][1], 15); /* L_acc:Q20 */
L_acc = L_add (L_cfbg, L_acc);
acc_h = extract_h (L_acc); /* acc_h:Q4 */
L_preg = L_mult (acc_h, gcode0); /* L_preg:Q9 */
L_acc = L_shl (L_deposit_l (best_gain[1]), 7); /* L_acc:Q9 */
L_acc = L_sub (L_acc, L_preg);
acc_h = extract_h (L_shl (L_acc, 2)); /* L_acc_h:Q[-5] */
L_tmp_x = L_mult (acc_h, INV_COEF); /* L_tmp_x:Q15 */
/*--------------------------------------------------------------------------*
y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0
-coef[0][0]*best_gain[1]) * inv_coef;
*--------------------------------------------------------------------------*/
L_acc = L_shr (L_coef[0][1], 10); /* L_acc:Q20 */
L_acc = L_sub (L_cfbg, L_acc); /* !!x -> L_cfbg:Q20 */
acc_h = extract_h (L_acc); /* acc_h:Q4 */
acc_h = mult (acc_h, gcode0); /* acc_h:Q[-7] */
L_tmp = L_mult (acc_h, coef[1][0]); /* L_tmp:Q10 */
L_preg = L_mult (coef[0][0], best_gain[1]); /* L_preg:Q13 */
L_acc = L_sub (L_tmp, L_shr (L_preg, 3)); /* L_acc:Q10 */
acc_h = extract_h (L_shl (L_acc, 2)); /* acc_h:Q[-4] */
L_tmp_y = L_mult (acc_h, INV_COEF); /* L_tmp_y:Q16 */
sft_y = (14 + 4 + 1) - 16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */
sft_x = (15 + 4 + 1) - 15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */
if (gcode0 > 0) {
/*-- pre select codebook #1 --*/
*cand1 = 0;
do {
L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y));
if (L_temp > 0L) {
(*cand1) = add (*cand1, 1);
}
else
break;
} while (sub ((*cand1), (NCODE1 - NCAN1)) < 0);
/*-- pre select codebook #2 --*/
*cand2 = 0;
do {
L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x));
if (L_temp > 0L) {
(*cand2) = add (*cand2, 1);
}
else
break;
} while (sub ((*cand2), (NCODE2 - NCAN2)) < 0);
}
else {
/*-- pre select codebook #1 --*/
*cand1 = 0;
do {
L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y));
if (L_temp < 0L) {
(*cand1) = add (*cand1, 1);
}
else
break;
} while (sub ((*cand1), (NCODE1 - NCAN1)));
/*-- pre select codebook #2 --*/
*cand2 = 0;
do {
L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x));
if (L_temp < 0L) {
(*cand2) = add (*cand2, 1);
}
else
break;
} while (sub ((*cand2), (NCODE2 - NCAN2)));
}
return;
}

View File

@@ -0,0 +1,23 @@
/*
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.
*/
/*--------------------------------------------------------------------------*
* gain VQ functions. *
*--------------------------------------------------------------------------*/
Word16 Qua_gain (CodState *coder,
Word16 code[], /* (i) Q13 : Innovative vector. */
Word16 g_coeff[], /* (i) : Correlations <xn y1> -2<y1 y1> */
/* <y2,y2>, -2<xn,y2>, 2<y1,y2> */
Word16 exp_coeff[], /* (i) : Q-Format g_coeff[] */
Word16 L_subfr, /* (i) : Subframe length. */
Word16 * gain_pit, /* (o) Q14 : Pitch gain. */
Word16 * gain_cod, /* (o) Q1 : Code gain. */
Word16 tameflag /* (i) : flag set to 1 if taming is needed */
);

View File

@@ -0,0 +1,159 @@
/*
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.
*/
/*---------------------------------------------------------------------------*
* Gain_predict() : make gcode0(exp_gcode0) *
* Gain_update() : update table of past quantized energies. *
* Gain_update_erasure() : update table of past quantized energies. *
* (frame erasure) *
* This function is used both Coder and Decoder. *
*---------------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_oper_32b.h"
/*---------------------------------------------------------------------------*
* Function Gain_predict *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* MA prediction is performed on the innovation energy (in dB with mean *
* removed). *
*---------------------------------------------------------------------------*/
void
Gain_predict (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 * gcode0, /* (o) Qxx :Predicted codebook gain */
Word16 * exp_gcode0 /* (o) :Q-Format(gcode0) */
)
{
Word16 i, exp, frac;
Word32 L_tmp;
/*-------------------------------*
* Energy coming from code *
*-------------------------------*/
L_tmp = 0;
for (i = 0; i < L_subfr; i++)
L_tmp = L_mac (L_tmp, code[i], code[i]);
/*-----------------------------------------------------------------*
* Compute: means_ener - 10log10(ener_code/ L_sufr) *
* Note: mean_ener change from 36 dB to 30 dB because input/2 *
* *
* = 30.0 - 10 log10( ener_code / lcode) + 10log10(2^27) *
* !!ener_code in Q27!! *
* = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) *
* = 30.0 - 3.0103 * log2(ener_code) + 16.02 + 81.278 *
* = 127.298 - 3.0103 * log2(ener_code) *
*-----------------------------------------------------------------*/
Log2 (L_tmp, &exp, &frac); /* Q27->Q0 ^Q0 ^Q15 */
L_tmp = Mpy_32_16 (exp, frac, -24660); /* Q0 Q15 Q13 -> ^Q14 */
/* hi:Q0+Q13+1 */
/* lo:Q15+Q13-15+1 */
/* -24660[Q13]=-3.0103 */
L_tmp = L_mac (L_tmp, 32588, 32); /* 32588*32[Q14]=127.298 */
/*-----------------------------------------------------------------*
* Compute gcode0. *
* = Sum(i=0,3) g729_pred[i]*past_qua_en[i] - ener_code + mean_ener *
*-----------------------------------------------------------------*/
L_tmp = L_shl (L_tmp, 10); /* From Q14 to Q24 */
for (i = 0; i < 4; i++)
L_tmp = L_mac (L_tmp, g729_pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */
*gcode0 = extract_h (L_tmp); /* From Q24 to Q8 */
/*-----------------------------------------------------------------*
* gcode0 = pow(10.0, gcode0/20) *
* = pow(2, 3.3219*gcode0/20) *
* = pow(2, 0.166*gcode0) *
*-----------------------------------------------------------------*/
L_tmp = L_mult (*gcode0, 5439); /* *0.166 in Q15, result in Q24 */
L_tmp = L_shr (L_tmp, 8); /* From Q24 to Q16 */
L_Extract (L_tmp, &exp, &frac); /* Extract exponent of gcode0 */
*gcode0 = extract_l (Pow2 (14, frac)); /* Put 14 as exponent so that */
/* output of Pow2() will be: */
/* 16768 < Pow2() <= 32767 */
*exp_gcode0 = sub (14, exp);
}
/*---------------------------------------------------------------------------*
* Function Gain_update *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* update table of past quantized energies *
*---------------------------------------------------------------------------*/
void
Gain_update (Word16 past_qua_en[], /* (io) Q10 :Past quantized energies */
Word32 L_gbk12 /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */
)
{
Word16 i, tmp;
Word16 exp, frac;
Word32 L_acc;
for (i = 3; i > 0; i--) {
past_qua_en[i] = past_qua_en[i - 1]; /* Q10 */
}
/*----------------------------------------------------------------------*
* -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); -- *
* 2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] ) *
* = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) *
* = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) *
* 24660:Q12(6.0205) *
*----------------------------------------------------------------------*/
Log2 (L_gbk12, &exp, &frac); /* L_gbk12:Q13 */
L_acc = L_Comp (sub (exp, 13), frac); /* L_acc:Q16 */
tmp = extract_h (L_shl (L_acc, 13)); /* tmp:Q13 */
past_qua_en[0] = mult (tmp, 24660); /* past_qua_en[]:Q10 */
}
/*---------------------------------------------------------------------------*
* Function Gain_update_erasure *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* update table of past quantized energies (frame erasure) *
*---------------------------------------------------------------------------*
* av_pred_en = 0.0; *
* for (i = 0; i < 4; i++) *
* av_pred_en += past_qua_en[i]; *
* av_pred_en = av_pred_en*0.25 - 4.0; *
* if (av_pred_en < -14.0) av_pred_en = -14.0; *
*---------------------------------------------------------------------------*/
void
Gain_update_erasure (Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */
)
{
Word16 i, av_pred_en;
Word32 L_tmp;
L_tmp = 0; /* Q10 */
for (i = 0; i < 4; i++)
L_tmp = L_add (L_tmp, L_deposit_l (past_qua_en[i]));
av_pred_en = extract_l (L_shr (L_tmp, 2));
av_pred_en = sub (av_pred_en, 4096); /* Q10 */
if (sub (av_pred_en, -14336) < 0) {
av_pred_en = -14336; /* 14336:14[Q10] */
}
for (i = 3; i > 0; i--) {
past_qua_en[i] = past_qua_en[i - 1];
}
past_qua_en[0] = av_pred_en;
}

View File

@@ -0,0 +1,474 @@
/*
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.
*/
#ifndef _G729_LD8A_H
#define _G729_LD8A_H
#include <stdlib.h>
#include <stdio.h>
typedef struct _CodState CodState;
typedef struct _DecState DecState;
/*---------------------------------------------------------------*
* LD8A.H *
* ~~~~~~ *
* Function prototypes and constants use for G.729A 8kb/s coder. *
* *
*---------------------------------------------------------------*/
/*--------------------------------------------------------------------------*
* Codec constant parameters (coder, decoder, and postfilter) *
*--------------------------------------------------------------------------*/
#define L_TOTAL 240 /* Total size of speech buffer. */
#define L_WINDOW 240 /* Window size in LP analysis. */
#define L_NEXT 40 /* Lookahead in LP analysis. */
#define L_FRAME 80 /* Frame size. */
#define L_SUBFR 40 /* Subframe size. */
#define M10 (10) /* Order of LP filter. */
#define MP1 (M10+1) /* Order of LP filter + 1 */
#define PIT_MIN 20 /* Minimum pitch lag. */
#define PIT_MAX 143 /* Maximum pitch lag. */
#define L_INTERPOL (10+1) /* Length of filter for interpolation. */
#define GAMMA1 24576 /* Bandwitdh factor = 0.75 in Q15 */
#define PRM_SIZE 11 /* Size of vector of analysis parameters. */
#define SERIAL_SIZE (80+2) /* bfi+ number of speech bits */
#define SHARPMAX 13017 /* Maximum value of pitch sharpening 0.8 Q14 */
#define SHARPMIN 3277 /* Minimum value of pitch sharpening 0.2 Q14 */
/*-------------------------------*
* Mathematic functions. *
*-------------------------------*/
extern Word32 Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */
Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */
);
extern void Log2 (Word32 L_x, /* (i) Q0 : input value */
Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */
Word16 * fraction /* (o) Q15: Fractionnal part of Log2. (range: 0<=val<1) */
);
Word32 Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */
Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */
Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */
);
/*-------------------------------*
* Pre and post-process. *
*-------------------------------*/
extern void Init_Post_Process (DecState *decoder);
extern void Post_Process (DecState *decoder,
Word16 signal[], /* Input/output signal */
Word16 lg /* Length of signal */
);
/*-------------------------------*
* LPC analysis and filtering. *
*-------------------------------*/
void Autocorr (Word16 x[], /* (i) : Input signal */
Word16 m, /* (i) : LPC order */
Word16 r_h[], /* (o) : Autocorrelations (msb) */
Word16 r_l[] /* (o) : Autocorrelations (lsb) */
);
void Lag_window (Word16 m, /* (i) : LPC order */
Word16 r_h[], /* (i/o) : Autocorrelations (msb) */
Word16 r_l[] /* (i/o) : Autocorrelations (lsb) */
);
void Levinson (CodState *coder,
Word16 Rh[], /* (i) : Rh[m+1] Vector of autocorrelations (msb) */
Word16 Rl[], /* (i) : Rl[m+1] Vector of autocorrelations (lsb) */
Word16 A[], /* (o) Q12 : A[m] LPC coefficients (m = 10) */
Word16 rc[] /* (o) Q15 : rc[M] Relection coefficients. */
);
void Az_lsp (Word16 a[], /* (i) Q12 : predictor coefficients */
Word16 lsp[], /* (o) Q15 : line spectral pairs */
Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) */
);
void Lsp_Az (Word16 lsp[], /* (i) Q15 : line spectral frequencies */
Word16 a[] /* (o) Q12 : predictor coefficients (order = 10) */
);
void Lsf_lsp (Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */
Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */
Word16 m /* (i) : LPC order */
);
void Lsp_lsf (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */
Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */
Word16 m /* (i) : LPC order */
);
void Int_qlpc (Word16 lsp_old[], /* input : LSP vector of past frame */
Word16 lsp_new[], /* input : LSP vector of present frame */
Word16 Az[] /* output: interpolated Az() for the 2 subframes */
);
void Weight_Az (Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */
Word16 gamma, /* (i) Q15 : Spectral expansion factor. */
Word16 m, /* (i) : LPC order. */
Word16 ap[] /* (o) Q12 : Spectral expanded LPC coefficients */
);
void Residu (Word16 a[], /* (i) Q12 : prediction coefficients */
Word16 x[], /* (i) : speech (values x[-m..-1] are needed (m=10) */
Word16 y[], /* (o) : residual signal */
Word16 lg /* (i) : size of filtering */
);
void Syn_filt (Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */
Word16 x[], /* (i) : input signal */
Word16 y[], /* (o) : output signal */
Word16 lg, /* (i) : size of filtering */
Word16 mem[], /* (i/o) : memory associated with this filtering. */
Word16 update, /* (i) : 0=no update, 1=update of memory. */
Flag *Overflow
);
void Convolve (Word16 x[], /* (i) : input vector */
Word16 h[], /* (i) Q12 : impulse response */
Word16 y[], /* (o) : output vector */
Word16 L /* (i) : vector size */
);
/*--------------------------------------------------------------------------*
* LTP constant parameters *
*--------------------------------------------------------------------------*/
#define UP_SAMP 3
#define L_INTER10 10
#define FIR_SIZE_SYN (UP_SAMP*L_INTER10+1)
/*-----------------------*
* Pitch functions. *
*-----------------------*/
Word16 Pitch_ol_fast ( /* output: open loop pitch lag */
Word16 signal[], /* input : signal used to compute the open loop pitch */
/* signal[-pit_max] to signal[-1] should be known */
Word16 pit_max, /* input : maximum pitch lag */
Word16 L_frame /* input : length of frame to compute pitch */
);
Word16 Pitch_fr3_fast ( /* (o) : pitch period. */
Word16 exc[], /* (i) : excitation buffer */
Word16 xn[], /* (i) : target vector */
Word16 h[], /* (i) Q12 : impulse response of filters. */
Word16 L_subfr, /* (i) : Length of subframe */
Word16 t0_min, /* (i) : minimum value in the searched range. */
Word16 t0_max, /* (i) : maximum value in the searched range. */
Word16 i_subfr, /* (i) : indicator for first subframe. */
Word16 * pit_frac /* (o) : chosen fraction. */
);
Word16 G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */
Word16 xn[], /* (i) : Pitch target. */
Word16 y1[], /* (i) : Filtered adaptive codebook. */
Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */
Word16 L_subfr /* (i) : Length of subframe. */
);
Word16 Enc_lag3 ( /* output: Return index of encoding */
Word16 T0, /* input : Pitch delay */
Word16 T0_frac, /* input : Fractional pitch delay */
Word16 * T0_min, /* in/out: Minimum search delay */
Word16 * T0_max, /* in/out: Maximum search delay */
Word16 pit_min, /* input : Minimum pitch delay */
Word16 pit_max, /* input : Maximum pitch delay */
Word16 pit_flag /* input : Flag for 1st subframe */
);
void Dec_lag3 ( /* output: return integer pitch lag */
Word16 index, /* input : received pitch index */
Word16 pit_min, /* input : minimum pitch lag */
Word16 pit_max, /* input : maximum pitch lag */
Word16 i_subfr, /* input : subframe flag */
Word16 * T0, /* output: integer part of pitch lag */
Word16 * T0_frac /* output: fractional part of pitch lag */
);
Word16 Interpol_3 ( /* (o) : interpolated value */
Word16 * x, /* (i) : input vector */
Word16 frac /* (i) : fraction */
);
void Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */
Word16 T0, /* input : integer pitch lag */
Word16 frac, /* input : fraction of lag */
Word16 L_subfr /* input : subframe size */
);
extern Word16 Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */
Word16 pitch_index /* input : index for which parity to compute */
);
extern Word16 Check_Parity_Pitch ( /* output: 0 = no error, 1= error */
Word16 pitch_index, /* input : index of parameter */
Word16 parity /* input : parity bit */
);
extern void Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */
Word16 X[], /* (i) :Target vector */
Word16 D[]
/* (o) :Correlations between h[] and D[] */
/* Normalized to 13 bits */
);
/*-----------------------*
* Innovative codebook. *
*-----------------------*/
#define DIM_RR 616 /* size of correlation matrix */
#define NB_POS 8 /* Number of positions for each pulse */
#define STEP 5 /* Step betweem position of the same pulse. */
#define MSIZE 64 /* Size of vectors for cross-correlation between 2 pulses */
/* The following constants are Q15 fractions.
These fractions is used to keep maximum precision on "alp" sum */
#define _1_2 (Word16)(16384)
#define _1_4 (Word16)( 8192)
#define _1_8 (Word16)( 4096)
#define _1_16 (Word16)( 2048)
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 */
);
void Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */
Word16 index, /* (i) : Positions of the 4 pulses. */
Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */
);
/*--------------------------------------------------------------------------*
* LSP constant parameters *
*--------------------------------------------------------------------------*/
#define NC 5 /* NC = M/2 */
#define MA_NP 4 /* MA prediction order for LSP */
#define MODE 2 /* number of modes for MA prediction */
#define NC0_B 7 /* number of first stage bits */
#define NC1_B 5 /* number of second stage bits */
#define NC0 (1<<NC0_B)
#define NC1 (1<<NC1_B)
#define L_LIMIT 40 /* Q13:0.005 */
#define M_LIMIT 25681 /* Q13:3.135 */
#define GAP1 10 /* Q13 */
#define GAP2 5 /* Q13 */
#define GAP3 321 /* Q13 */
#define GRID_POINTS 50
#define PI04 ((Word16)1029) /* Q13 pi*0.04 */
#define PI92 ((Word16)23677) /* Q13 pi*0.92 */
#define CONST10 ((Word16)10*(1<<11)) /* Q11 10.0 */
#define CONST12 ((Word16)19661) /* Q14 1.2 */
/*-------------------------------*
* gain VQ constants. *
*-------------------------------*/
#define NCODE1_B 3 /* number of Codebook-bit */
#define NCODE2_B 4 /* number of Codebook-bit */
#define NCODE1 (1<<NCODE1_B) /* Codebook 1 size */
#define NCODE2 (1<<NCODE2_B) /* Codebook 2 size */
#define NCAN1 4 /* Pre-selecting order for #1 */
#define NCAN2 8 /* Pre-selecting order for #2 */
#define INV_COEF -17103 /* Q19 */
extern void Gain_predict (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */
Word16 code[], /* (i) Q13 : Innovative vector. */
Word16 L_subfr, /* (i) : Subframe length. */
Word16 * gcode0, /* (o) Qxx : Predicted codebook gain */
Word16 * exp_gcode0 /* (o) : Q-Format(gcode0) */
);
extern void Gain_update (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */
Word32 L_gbk12 /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */
);
extern void Gain_update_erasure (Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */
);
extern void Corr_xy2 (Word16 xn[], /* (i) Q0 :Target vector. */
Word16 y1[], /* (i) Q0 :Adaptive codebook. */
Word16 y2[], /* (i) Q12 :Filtered innovative vector. */
Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */
Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */
);
/*-----------------------------------*
* Post-filter functions. *
*-----------------------------------*/
#define L_H 22 /* size of truncated impulse response of A(z/g1)/A(z/g2) */
#define GAMMAP 16384 /* 0.5 (Q15) */
#define INV_GAMMAP 21845 /* 1/(1+GAMMAP) (Q15) */
#define GAMMAP_2 10923 /* GAMMAP/(1+GAMMAP) (Q15) */
#define GAMMA2_PST 18022 /* Formant postfilt factor (numerator) 0.55 Q15 */
#define GAMMA1_PST 22938 /* Formant postfilt factor (denominator) 0.70 Q15 */
#define MU 26214 /* Factor for tilt compensation filter 0.8 Q15 */
#define AGC_FAC 29491 /* Factor for automatic gain control 0.9 Q15 */
#define AGC_FAC1 (Word16)(32767 - AGC_FAC) /* 1-AGC_FAC in Q15 */
extern void Init_Post_Filter (DecState *decoder);
extern void Post_Filter (DecState *decoder,
Word16 * syn, /* in/out: synthesis speech (postfiltered is output) */
Word16 * Az_4, /* input : interpolated LPC parameters in all subframes */
Word16 * T /* input : decoded pitch lags in all subframes */
);
void pit_pst_filt (Word16 * signal, /* (i) : input signal */
Word16 * scal_sig, /* (i) : input signal (scaled, divided by 4) */
Word16 t0_min, /* (i) : minimum value in the searched range */
Word16 t0_max, /* (i) : maximum value in the searched range */
Word16 L_subfr, /* (i) : size of filtering */
Word16 * signal_pst /* (o) : harmonically postfiltered signal */
);
void preemphasis (DecState *decoder,
Word16 * signal, /* (i/o) : input signal overwritten by the output */
Word16 g, /* (i) Q15 : preemphasis coefficient */
Word16 L /* (i) : size of filtering */
);
void agc (DecState *decoder,
Word16 * sig_in, /* (i) : postfilter input signal */
Word16 * sig_out, /* (i/o) : postfilter output signal */
Word16 l_trm /* (i) : subframe size */
);
/*----------------------------------*
* Main coder and decoder functions *
*----------------------------------*/
struct _CodState {
/* Speech vector */
Word16 old_speech[L_TOTAL];
Word16 *speech, *p_window;
Word16 *new_speech;
/* Weighted speech vector */
Word16 old_wsp[L_FRAME + PIT_MAX];
Word16 *wsp;
/* Excitation vector */
Word16 old_exc[L_FRAME + PIT_MAX + L_INTERPOL];
Word16 *exc;
/* Lsp (Line spectral pairs) */
Word16 lsp_old[M10];
Word16 lsp_old_q[M10];
/* Filter's memory */
Word16 mem_w0[M10], mem_w[M10], mem_zero[M10];
Word16 sharp;
/* Qua LSP */
Word16 freq_prev[MA_NP][M10]; /* Q13:previous LSP vector */
/* Taming */
Word32 L_exc_err[4];
/* Preprocessor */
/* y[] values is kept in double precision */
Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1;
/* Qua gain */
Word16 past_qua_en[4];
/* Levinson data */
Word16 old_A[M10 + 1];
Word16 old_rc[2];
};
extern CodState* Init_Coder_ld8a (void);
extern void Coder_ld8a (CodState *coder, Word16 ana[] /* output : Analysis parameters */);
struct _DecState {
/* Excitation vector */
Word16 old_exc[L_FRAME + PIT_MAX + L_INTERPOL];
Word16 *exc;
/* Filter's memory */
Word16 mem_syn[M10];
Word16 sharp; /* pitch sharpening of previous frame */
Word16 old_T0; /* integer delay of previous frame */
Word16 gain_code; /* Code gain */
Word16 gain_pitch; /* Pitch gain */
Word16 lsp_old[M10];
/* External params */
Word16 bad_lsf;
Word16 Az_dec[MP1 * 2];
Word16 T2[2];
Word16 synth_buf[L_FRAME + M10];
/* Dec gain */
Word16 past_qua_en[4];
/* LSP decoder */
Word16 freq_prev[MA_NP][M10]; /* Q13 */
/* For frame erase operation */
Word16 prev_ma; /* previous MA prediction coef. */
Word16 prev_lsp[M10]; /* previous LSP vector */
/* Postprocessor */
/* y[] values is keep in double precision */
Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1;
/* For random */
Word16 seed;
/* Postfilter */
Word16 res2_buf[PIT_MAX + L_SUBFR];
Word16 *res2;
Word16 scal_res2_buf[PIT_MAX + L_SUBFR];
Word16 *scal_res2;
/* memory of filter 1/A(z/GAMMA1_PST) */
Word16 mem_syn_pst[M10];
Word16 mem_pre;
Word16 past_gain; /* past_gain = 1.0 (Q12) */
};
extern DecState *Init_Decod_ld8a (void);
extern void Decod_ld8a (DecState *decoder,
Word16 parm[], /* (i) : vector of synthesis parameters
parm[0] = bad frame indicator (bfi) */
Word16 synth[], /* (o) : synthesis speech */
Word16 A_t[], /* (o) : decoded LP filter in 2 subframes */
Word16 * T2, /* (o) : decoded pitch lag in 2 subframes */
Word16 * bad_lsf);
#endif

View File

@@ -0,0 +1,613 @@
/*
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 Autocorr() *
* *
* Compute autocorrelations of signal with windowing *
* *
*-----------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
void
Autocorr (Word16 x[], /* (i) : Input signal */
Word16 m, /* (i) : LPC order */
Word16 r_h[], /* (o) : Autocorrelations (msb) */
Word16 r_l[] /* (o) : Autocorrelations (lsb) */
)
{
Word16 i, j, norm;
Word16 y[L_WINDOW];
Word32 sum;
Flag Overflow;
/* Windowing of signal */
for (i = 0; i < L_WINDOW; i++) {
y[i] = mult_r (x[i], hamwindow[i]);
}
/* Compute r[0] and test for overflow */
do {
Overflow = 0;
sum = 1; /* Avoid case of all zeros */
for (i = 0; i < L_WINDOW; i++)
sum = L_mac_o (sum, y[i], y[i], &Overflow);
/* If overflow divide y[] by 4 */
if (Overflow != 0) {
for (i = 0; i < L_WINDOW; i++) {
y[i] = shr (y[i], 2);
}
}
} while (Overflow != 0);
/* Normalization of r[0] */
norm = norm_l (sum);
sum = L_shl (sum, norm);
L_Extract (sum, &r_h[0], &r_l[0]); /* Put in DPF format (see oper_32b) */
/* r[1] to r[m] */
for (i = 1; i <= m; i++) {
sum = 0;
for (j = 0; j < L_WINDOW - i; j++)
sum = L_mac (sum, y[j], y[j + i]);
sum = L_shl (sum, norm);
L_Extract (sum, &r_h[i], &r_l[i]);
}
return;
}
/*-------------------------------------------------------*
* Function Lag_window() *
* *
* Lag_window on autocorrelations. *
* *
* r[i] *= lag_wind[i] *
* *
* r[i] and lag_wind[i] are in special double precision.*
* See "oper_32b.c" for the format *
* *
*-------------------------------------------------------*/
void
Lag_window (Word16 m, /* (i) : LPC order */
Word16 r_h[], /* (i/o) : Autocorrelations (msb) */
Word16 r_l[] /* (i/o) : Autocorrelations (lsb) */
)
{
Word16 i;
Word32 x;
for (i = 1; i <= m; i++) {
x = Mpy_32 (r_h[i], r_l[i], lag_h[i - 1], lag_l[i - 1]);
L_Extract (x, &r_h[i], &r_l[i]);
}
return;
}
/*___________________________________________________________________________
| |
| LEVINSON-DURBIN algorithm in double precision |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---------------------------------------------------------------------------|
| |
| Algorithm |
| |
| R[i] autocorrelations. |
| A[i] filter coefficients. |
| K reflection coefficients. |
| Alpha prediction gain. |
| |
| Initialization: |
| A[0] = 1 |
| K = -R[1]/R[0] |
| A[1] = K |
| Alpha = R[0] * (1-K**2] |
| |
| Do for i = 2 to M |
| |
| S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] |
| |
| K = -S / Alpha |
| |
| An[j] = A[j] + K*A[i-j] for j=1 to i-1 |
| where An[i] = new A[i] |
| An[i]=K |
| |
| Alpha=Alpha * (1-K**2) |
| |
| END |
| |
| Remarks on the dynamics of the calculations. |
| |
| The numbers used are in double precision in the following format : |
| A = AH <<16 + AL<<1. AH and AL are 16 bit signed integers. |
| Since the LSB's also contain a sign bit, this format does not |
| correspond to standard 32 bit integers. We use this format since |
| it allows fast execution of multiplications and divisions. |
| |
| "DPF" will refer to this special format in the following text. |
| See oper_32b.c |
| |
| The R[i] were normalized in routine AUTO (hence, R[i] < 1.0). |
| The K[i] and Alpha are theoretically < 1.0. |
| The A[i], for a sampling frequency of 8 kHz, are in practice |
| always inferior to 16.0. |
| |
| These characteristics allow straigthforward fixed-point |
| implementation. We choose to represent the parameters as |
| follows : |
| |
| R[i] Q31 +- .99.. |
| K[i] Q31 +- .99.. |
| Alpha Normalized -> mantissa in Q31 plus exponent |
| A[i] Q27 +- 15.999.. |
| |
| The additions are performed in 32 bit. For the summation used |
| to calculate the K[i], we multiply numbers in Q31 by numbers |
| in Q27, with the result of the multiplications in Q27, |
| resulting in a dynamic of +- 16. This is sufficient to avoid |
| overflow, since the final result of the summation is |
| necessarily < 1.0 as both the K[i] and Alpha are |
| theoretically < 1.0. |
|___________________________________________________________________________|
*/
/* Last A(z) for case of unstable filter */
void
Levinson (CodState *coder,
Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */
Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */
Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 10) */
Word16 rc[] /* (o) Q15 : rc[M] Reflection coefficients. */
)
{
Word16 i, j;
Word16 hi, lo;
Word16 Kh, Kl; /* reflection coefficient; hi and lo */
Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
Word16 Ah[M10 + 1], Al[M10 + 1]; /* LPC coef. in double prec. */
Word16 Anh[M10 + 1], Anl[M10 + 1]; /* LPC coef.for next iteration in double prec. */
Word32 t0, t1, t2; /* temporary variable */
/* K = A[1] = -R[1] / R[0] */
t1 = L_Comp (Rh[1], Rl[1]); /* R[1] in Q31 */
t2 = L_abs (t1); /* abs R[1] */
t0 = Div_32 (t2, Rh[0], Rl[0]); /* R[1]/R[0] in Q31 */
if (t1 > 0)
t0 = L_negate (t0); /* -R[1]/R[0] */
L_Extract (t0, &Kh, &Kl); /* K in DPF */
rc[0] = Kh;
t0 = L_shr (t0, 4); /* A[1] in Q27 */
L_Extract (t0, &Ah[1], &Al[1]); /* A[1] in DPF */
/* Alpha = R[0] * (1-K**2) */
t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K in Q31 */
t0 = L_abs (t0); /* Some case <0 !! */
t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */
L_Extract (t0, &hi, &lo); /* DPF format */
t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); /* Alpha in Q31 */
/* Normalize Alpha */
alp_exp = norm_l (t0);
t0 = L_shl (t0, alp_exp);
L_Extract (t0, &alp_h, &alp_l); /* DPF format */
/*--------------------------------------*
* ITERATIONS I=2 to M *
*--------------------------------------*/
for (i = 2; i <= M10; i++) {
/* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */
t0 = 0;
for (j = 1; j < i; j++)
t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j]));
t0 = L_shl (t0, 4); /* result in Q27 -> convert to Q31 */
/* No overflow possible */
t1 = L_Comp (Rh[i], Rl[i]);
t0 = L_add (t0, t1); /* add R[i] in Q31 */
/* K = -t0 / Alpha */
t1 = L_abs (t0);
t2 = Div_32 (t1, alp_h, alp_l); /* abs(t0)/Alpha */
if (t0 > 0)
t2 = L_negate (t2); /* K =-t0/Alpha */
t2 = L_shl (t2, alp_exp); /* denormalize; compare to Alpha */
L_Extract (t2, &Kh, &Kl); /* K in DPF */
rc[i - 1] = Kh;
/* Test for unstable filter. If unstable keep old A(z) */
if (sub (abs_s (Kh), 32750) > 0) {
for (j = 0; j <= M10; j++) {
A[j] = coder->old_A[j];
}
rc[0] = coder->old_rc[0]; /* only two rc coefficients are needed */
rc[1] = coder->old_rc[1];
return;
}
/*------------------------------------------*
* Compute new LPC coeff. -> An[i] *
* An[j]= A[j] + K*A[i-j] , j=1 to i-1 *
* An[i]= K *
*------------------------------------------*/
for (j = 1; j < i; j++) {
t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]);
t0 = L_add (t0, L_Comp (Ah[j], Al[j]));
L_Extract (t0, &Anh[j], &Anl[j]);
}
t2 = L_shr (t2, 4); /* t2 = K in Q31 ->convert to Q27 */
L_Extract (t2, &Anh[i], &Anl[i]); /* An[i] in Q27 */
/* Alpha = Alpha * (1-K**2) */
t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K in Q31 */
t0 = L_abs (t0); /* Some case <0 !! */
t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */
L_Extract (t0, &hi, &lo); /* DPF format */
t0 = Mpy_32 (alp_h, alp_l, hi, lo); /* Alpha in Q31 */
/* Normalize Alpha */
j = norm_l (t0);
t0 = L_shl (t0, j);
L_Extract (t0, &alp_h, &alp_l); /* DPF format */
alp_exp = add (alp_exp, j); /* Add normalization to alp_exp */
/* A[j] = An[j] */
for (j = 1; j <= i; j++) {
Ah[j] = Anh[j];
Al[j] = Anl[j];
}
}
/* Truncate A[i] in Q27 to Q12 with rounding */
A[0] = 4096;
for (i = 1; i <= M10; i++) {
t0 = L_Comp (Ah[i], Al[i]);
coder->old_A[i] = A[i] = wround (L_shl (t0, 1));
}
coder->old_rc[0] = rc[0];
coder->old_rc[1] = rc[1];
return;
}
/*-------------------------------------------------------------*
* procedure Az_lsp: *
* ~~~~~~ *
* Compute the LSPs from the LPC coefficients (order=10) *
*-------------------------------------------------------------*/
Word16 Chebps_11 (Word16 x, Word16 f[], Word16 n);
Word16 Chebps_10 (Word16 x, Word16 f[], Word16 n);
void
Az_lsp (Word16 a[], /* (i) Q12 : predictor coefficients */
Word16 lsp[], /* (o) Q15 : line spectral pairs */
Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) */
)
{
Flag Overflow;
Word16 i, j, nf, ip;
Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
Word16 x, y, sign, exp;
Word16 *coef;
Word16 f1[M10 / 2 + 1], f2[M10 / 2 + 1];
Word32 t0, L_temp;
Flag ovf_coef;
Word16 (*pChebps) (Word16 x, Word16 f[], Word16 n);
/*-------------------------------------------------------------*
* find the sum and diff. pol. F1(z) and F2(z) *
* F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) *
* *
* f1[0] = 1.0; *
* f2[0] = 1.0; *
* *
* for (i = 0; i< NC; i++) *
* { *
* f1[i+1] = a[i+1] + a[M-i] - f1[i] ; *
* f2[i+1] = a[i+1] - a[M-i] + f2[i] ; *
* } *
*-------------------------------------------------------------*/
ovf_coef = 0;
pChebps = Chebps_11;
f1[0] = 2048; /* f1[0] = 1.0 is in Q11 */
f2[0] = 2048; /* f2[0] = 1.0 is in Q11 */
for (i = 0; i < NC; i++) {
Overflow = 0;
t0 = L_mult_o (a[i + 1], 16384, &Overflow); /* x = (a[i+1] + a[M-i]) >> 1 */
t0 = L_mac_o (t0, a[M10 - i], 16384, &Overflow); /* -> From Q12 to Q11 */
x = extract_h (t0);
if (Overflow) {
ovf_coef = 1;
}
Overflow = 0;
f1[i + 1] = sub_o (x, f1[i], &Overflow); /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
if (Overflow) {
ovf_coef = 1;
}
Overflow = 0;
t0 = L_mult_o (a[i + 1], 16384, &Overflow); /* x = (a[i+1] - a[M-i]) >> 1 */
t0 = L_msu_o (t0, a[M10 - i], 16384, &Overflow); /* -> From Q12 to Q11 */
x = extract_h (t0);
if (Overflow) {
ovf_coef = 1;
}
Overflow = 0;
f2[i + 1] = add_o (x, f2[i], &Overflow); /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
if (Overflow) {
ovf_coef = 1;
}
}
if (ovf_coef) {
/*printf("===== OVF ovf_coef =====\n"); */
pChebps = Chebps_10;
f1[0] = 1024; /* f1[0] = 1.0 is in Q10 */
f2[0] = 1024; /* f2[0] = 1.0 is in Q10 */
for (i = 0; i < NC; i++) {
t0 = L_mult (a[i + 1], 8192); /* x = (a[i+1] + a[M-i]) >> 1 */
t0 = L_mac (t0, a[M10 - i], 8192); /* -> From Q11 to Q10 */
x = extract_h (t0);
f1[i + 1] = sub (x, f1[i]); /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
t0 = L_mult (a[i + 1], 8192); /* x = (a[i+1] - a[M-i]) >> 1 */
t0 = L_msu (t0, a[M10 - i], 8192); /* -> From Q11 to Q10 */
x = extract_h (t0);
f2[i + 1] = add (x, f2[i]); /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
}
}
/*-------------------------------------------------------------*
* find the LSPs using the Chebichev pol. evaluation *
*-------------------------------------------------------------*/
nf = 0; /* number of found frequencies */
ip = 0; /* indicator for f1 or f2 */
coef = f1;
xlow = grid[0];
ylow = (*pChebps) (xlow, coef, NC);
j = 0;
while ((nf < M10) && (j < GRID_POINTS)) {
j = add (j, 1);
xhigh = xlow;
yhigh = ylow;
xlow = grid[j];
ylow = (*pChebps) (xlow, coef, NC);
L_temp = L_mult (ylow, yhigh);
if (L_temp <= (Word32) 0) {
/* divide 2 times the interval */
for (i = 0; i < 2; i++) {
xmid = add (shr (xlow, 1), shr (xhigh, 1)); /* xmid = (xlow + xhigh)/2 */
ymid = (*pChebps) (xmid, coef, NC);
L_temp = L_mult (ylow, ymid);
if (L_temp <= (Word32) 0) {
yhigh = ymid;
xhigh = xmid;
}
else {
ylow = ymid;
xlow = xmid;
}
}
/*-------------------------------------------------------------*
* Linear interpolation *
* xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); *
*-------------------------------------------------------------*/
x = sub (xhigh, xlow);
y = sub (yhigh, ylow);
if (y == 0) {
xint = xlow;
}
else {
sign = y;
y = abs_s (y);
exp = norm_s (y);
y = shl (y, exp);
y = div_s ((Word16) 16383, y);
t0 = L_mult (x, y);
t0 = L_shr (t0, sub (20, exp));
y = extract_l (t0); /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */
if (sign < 0)
y = negate (y);
t0 = L_mult (ylow, y); /* result in Q26 */
t0 = L_shr (t0, 11); /* result in Q15 */
xint = sub (xlow, extract_l (t0)); /* xint = xlow - ylow*y */
}
lsp[nf] = xint;
xlow = xint;
nf = add (nf, 1);
if (ip == 0) {
ip = 1;
coef = f2;
}
else {
ip = 0;
coef = f1;
}
ylow = (*pChebps) (xlow, coef, NC);
}
}
/* Check if M roots found */
if (sub (nf, M10) < 0) {
for (i = 0; i < M10; i++) {
lsp[i] = old_lsp[i];
}
/* printf("\n !!Not 10 roots found in Az_lsp()!!!\n"); */
}
return;
}
/*--------------------------------------------------------------*
* function Chebps_11, Chebps_10: *
* ~~~~~~~~~~~~~~~~~~~~ *
* Evaluates the Chebichev polynomial series *
*--------------------------------------------------------------*
* *
* The polynomial order is *
* n = M/2 (M is the prediction order) *
* The polynomial is given by *
* C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *
* Arguments: *
* x: input value of evaluation; x = cos(frequency) in Q15 *
* f[]: coefficients of the pol. *
* in Q11(Chebps_11), in Q10(Chebps_10) *
* n: order of the pol. *
* *
* The value of C(x) is returned. (Saturated to +-1.99 in Q14) *
* *
*--------------------------------------------------------------*/
Word16
Chebps_11 (Word16 x, Word16 f[], Word16 n)
{
Word16 i, cheb;
Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
Word32 t0;
/* Note: All computation are done in Q24. */
b2_h = 256; /* b2 = 1.0 in Q24 DPF */
b2_l = 0;
t0 = L_mult (x, 512); /* 2*x in Q24 */
t0 = L_mac (t0, f[1], 4096); /* + f[1] in Q24 */
L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */
for (i = 2; i < n; i++) {
t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */
t0 = L_shl (t0, 1);
t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = 2.0*x*b1 - b2 */
t0 = L_msu (t0, b2_l, 1);
t0 = L_mac (t0, f[i], 4096); /* t0 = 2.0*x*b1 - b2 + f[i]; */
L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]; */
b2_l = b1_l; /* b2 = b1; */
b2_h = b1_h;
b1_l = b0_l; /* b1 = b0; */
b1_h = b0_h;
}
t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */
t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = x*b1 - b2 */
t0 = L_msu (t0, b2_l, 1);
t0 = L_mac (t0, f[i], 2048); /* t0 = x*b1 - b2 + f[i]/2 */
t0 = L_shl (t0, 6); /* Q24 to Q30 with saturation */
cheb = extract_h (t0); /* Result in Q14 */
return (cheb);
}
Word16
Chebps_10 (Word16 x, Word16 f[], Word16 n)
{
Word16 i, cheb;
Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
Word32 t0;
/* Note: All computation are done in Q23. */
b2_h = 128; /* b2 = 1.0 in Q23 DPF */
b2_l = 0;
t0 = L_mult (x, 256); /* 2*x in Q23 */
t0 = L_mac (t0, f[1], 4096); /* + f[1] in Q23 */
L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */
for (i = 2; i < n; i++) {
t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */
t0 = L_shl (t0, 1);
t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = 2.0*x*b1 - b2 */
t0 = L_msu (t0, b2_l, 1);
t0 = L_mac (t0, f[i], 4096); /* t0 = 2.0*x*b1 - b2 + f[i]; */
L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]; */
b2_l = b1_l; /* b2 = b1; */
b2_h = b1_h;
b1_l = b0_l; /* b1 = b0; */
b1_h = b0_h;
}
t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */
t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = x*b1 - b2 */
t0 = L_msu (t0, b2_l, 1);
t0 = L_mac (t0, f[i], 2048); /* t0 = x*b1 - b2 + f[i]/2 */
t0 = L_shl (t0, 7); /* Q23 to Q30 with saturation */
cheb = extract_h (t0); /* Result in Q14 */
return (cheb);
}

View File

@@ -0,0 +1,300 @@
/*
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.
*/
/*-------------------------------------------------------------*
* Procedure Lsp_Az: *
* ~~~~~~ *
* Compute the LPC coefficients from lsp (order=10) *
*-------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
/* local function */
void Get_lsp_pol (Word16 * lsp, Word32 * f);
void
Lsp_Az (Word16 lsp[], /* (i) Q15 : line spectral frequencies */
Word16 a[] /* (o) Q12 : predictor coefficients (order = 10) */
)
{
Word16 i, j;
Word32 f1[6], f2[6];
Word32 t0;
Get_lsp_pol (&lsp[0], f1);
Get_lsp_pol (&lsp[1], f2);
for (i = 5; i > 0; i--) {
f1[i] = L_add (f1[i], f1[i - 1]); /* f1[i] += f1[i-1]; */
f2[i] = L_sub (f2[i], f2[i - 1]); /* f2[i] -= f2[i-1]; */
}
a[0] = 4096;
for (i = 1, j = 10; i <= 5; i++, j--) {
t0 = L_add (f1[i], f2[i]); /* f1[i] + f2[i] */
a[i] = extract_l (L_shr_r (t0, 13)); /* from Q24 to Q12 and * 0.5 */
t0 = L_sub (f1[i], f2[i]); /* f1[i] - f2[i] */
a[j] = extract_l (L_shr_r (t0, 13)); /* from Q24 to Q12 and * 0.5 */
}
return;
}
/*-----------------------------------------------------------*
* procedure Get_lsp_pol: *
* ~~~~~~~~~~~ *
* Find the polynomial F1(z) or F2(z) from the LSPs *
*-----------------------------------------------------------*
* *
* Parameters: *
* lsp[] : line spectral freq. (cosine domain) in Q15 *
* f[] : the coefficients of F1 or F2 in Q24 *
*-----------------------------------------------------------*/
void
Get_lsp_pol (Word16 * lsp, Word32 * f)
{
Word16 i, j, hi, lo;
Word32 t0;
/* All computation in Q24 */
*f = L_mult (4096, 2048); /* f[0] = 1.0; in Q24 */
f++;
*f = L_msu ((Word32) 0, *lsp, 512); /* f[1] = -2.0 * lsp[0]; in Q24 */
f++;
lsp += 2; /* Advance lsp pointer */
for (i = 2; i <= 5; i++) {
*f = f[-2];
for (j = 1; j < i; j++, f--) {
L_Extract (f[-1], &hi, &lo);
t0 = Mpy_32_16 (hi, lo, *lsp); /* t0 = f[-1] * lsp */
t0 = L_shl (t0, 1);
*f = L_add (*f, f[-2]); /* *f += f[-2] */
*f = L_sub (*f, t0); /* *f -= t0 */
}
*f = L_msu (*f, *lsp, 512); /* *f -= lsp<<9 */
f += i; /* Advance f pointer */
lsp += 2; /* Advance lsp pointer */
}
return;
}
/*___________________________________________________________________________
| |
| Functions : Lsp_lsf and Lsf_lsp |
| |
| Lsp_lsf Transformation lsp to lsf |
| Lsf_lsp Transformation lsf to lsp |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are |
| approximated by a look-up table and interpolation. |
|___________________________________________________________________________|
*/
void
Lsf_lsp (Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */
Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */
Word16 m /* (i) : LPC order */
)
{
Word16 i, ind, offset;
Word32 L_tmp;
for (i = 0; i < m; i++) {
ind = shr (lsf[i], 8); /* ind = b8-b15 of lsf[i] */
offset = lsf[i] & (Word16) 0x00ff; /* offset = b0-b7 of lsf[i] */
/* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */
L_tmp = L_mult (sub (table[ind + 1], table[ind]), offset);
lsp[i] = add (table[ind], extract_l (L_shr (L_tmp, 9)));
}
return;
}
void
Lsp_lsf (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */
Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */
Word16 m /* (i) : LPC order */
)
{
Word16 i, ind, tmp;
Word32 L_tmp;
ind = 63; /* begin at end of table -1 */
for (i = m - (Word16) 1; i >= 0; i--) {
/* find value in table that is just greater than lsp[i] */
while (sub (table[ind], lsp[i]) < 0) {
ind = sub (ind, 1);
}
/* acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) * slope[ind] )/4096 */
L_tmp = L_mult (sub (lsp[i], table[ind]), slope[ind]);
tmp = wround (L_shl (L_tmp, 3)); /*(lsp[i]-table[ind])*slope[ind])>>12 */
lsf[i] = add (tmp, shl (ind, 8));
}
return;
}
/*___________________________________________________________________________
| |
| Functions : Lsp_lsf and Lsf_lsp |
| |
| Lsp_lsf Transformation lsp to lsf |
| Lsf_lsp Transformation lsf to lsp |
|---------------------------------------------------------------------------|
| Algorithm: |
| |
| The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are |
| approximated by a look-up table and interpolation. |
|___________________________________________________________________________|
*/
void
Lsf_lsp2 (Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val<PI) */
Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */
Word16 m /* (i) : LPC order */
)
{
Word16 i, ind;
Word16 offset; /* in Q8 */
Word16 freq; /* normalized frequency in Q15 */
Word32 L_tmp;
for (i = 0; i < m; i++) {
/* freq = abs_s(freq);*/
freq = mult (lsf[i], 20861); /* 20861: 1.0/(2.0*PI) in Q17 */
ind = shr (freq, 8); /* ind = b8-b15 of freq */
offset = freq & (Word16) 0x00ff; /* offset = b0-b7 of freq */
if (sub (ind, 63) > 0) {
ind = 63; /* 0 <= ind <= 63 */
}
/* lsp[i] = table2[ind]+ (slope_cos[ind]*offset >> 12) */
L_tmp = L_mult (slope_cos[ind], offset); /* L_tmp in Q28 */
lsp[i] = add (table2[ind], extract_l (L_shr (L_tmp, 13)));
}
return;
}
void
Lsp_lsf2 (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */
Word16 lsf[], /* (o) Q13 : lsf[m] (range: 0.0<=val<PI) */
Word16 m /* (i) : LPC order */
)
{
Word16 i, ind;
Word16 offset; /* in Q15 */
Word16 freq; /* normalized frequency in Q16 */
Word32 L_tmp;
ind = 63; /* begin at end of table2 -1 */
for (i = m - (Word16) 1; i >= 0; i--) {
/* find value in table2 that is just greater than lsp[i] */
while (sub (table2[ind], lsp[i]) < 0) {
ind = sub (ind, 1);
if (ind <= 0)
break;
}
offset = sub (lsp[i], table2[ind]);
/* acos(lsp[i])= ind*512 + (slope_acos[ind]*offset >> 11) */
L_tmp = L_mult (slope_acos[ind], offset); /* L_tmp in Q28 */
freq = add (shl (ind, 9), extract_l (L_shr (L_tmp, 12)));
lsf[i] = mult (freq, 25736); /* 25736: 2.0*PI in Q12 */
}
return;
}
/*-------------------------------------------------------------*
* procedure Weight_Az *
* ~~~~~~~~~ *
* Weighting of LPC coefficients. *
* ap[i] = a[i] * (gamma ** i) *
* *
*-------------------------------------------------------------*/
void
Weight_Az (Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */
Word16 gamma, /* (i) Q15 : Spectral expansion factor. */
Word16 m, /* (i) : LPC order. */
Word16 ap[] /* (o) Q12 : Spectral expanded LPC coefficients */
)
{
Word16 i, fac;
ap[0] = a[0];
fac = gamma;
for (i = 1; i < m; i++) {
ap[i] = wround (L_mult (a[i], fac));
fac = wround (L_mult (fac, gamma));
}
ap[m] = wround (L_mult (a[m], fac));
return;
}
/*----------------------------------------------------------------------*
* Function Int_qlpc() *
* ~~~~~~~~~~~~~~~~~~~ *
* Interpolation of the LPC parameters. *
*----------------------------------------------------------------------*/
/* Interpolation of the quantized LSP's */
void
Int_qlpc (Word16 lsp_old[], /* input : LSP vector of past frame */
Word16 lsp_new[], /* input : LSP vector of present frame */
Word16 Az[] /* output: interpolated Az() for the 2 subframes */
)
{
Word16 i;
Word16 lsp[M10];
/* lsp[i] = lsp_new[i] * 0.5 + lsp_old[i] * 0.5 */
for (i = 0; i < M10; i++) {
lsp[i] = add (shr (lsp_new[i], 1), shr (lsp_old[i], 1));
}
Lsp_Az (lsp, Az); /* Subframe 1 */
Lsp_Az (lsp_new, &Az[MP1]); /* Subframe 2 */
return;
}

View File

@@ -0,0 +1,18 @@
/*
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.
*/
void Lsf_lsp2 (Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val<PI) */
Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */
Word16 m /* (i) : LPC order */
);
void Lsp_lsf2 (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */
Word16 lsf[], /* (o) Q13 : lsf[m] (range: 0.0<=val<PI) */
Word16 m /* (i) : LPC order */
);

View File

@@ -0,0 +1,347 @@
/*
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 Qua_lsp: *
* ~~~~~~~~ *
*-------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_util.h"
#include "g729_lsp.h"
#include "g729_lspgetq.h"
#include "g729_lpcfunc.h"
void
Qua_lsp (CodState *coder,
Word16 lsp[], /* (i) Q15 : Unquantized LSP */
Word16 lsp_q[], /* (o) Q15 : Quantized LSP */
Word16 ana[] /* (o) : indexes */
)
{
Word16 lsf[M10], lsf_q[M10]; /* domain 0.0<= lsf <PI in Q13 */
/* Convert LSPs to LSFs */
Lsp_lsf2 (lsp, lsf, M10);
Lsp_qua_cs (coder, lsf, lsf_q, ana);
/* Convert LSFs to LSPs */
Lsf_lsp2 (lsf_q, lsp_q, M10);
return;
}
void
Lsp_encw_reset (CodState *coder)
{
Word16 i;
for (i = 0; i < MA_NP; i++)
Copy (&freq_prev_reset[0], &coder->freq_prev[i][0], M10);
}
void
Lsp_qua_cs (CodState *coder,
Word16 flsp_in[M10], /* (i) Q13 : Original LSP parameters */
Word16 lspq_out[M10], /* (o) Q13 : Quantized LSP parameters */
Word16 * code /* (o) : codes of the selected LSP */
)
{
Word16 wegt[M10]; /* Q11->normalized : weighting coefficients */
Get_wegt (flsp_in, wegt);
Relspwed (flsp_in, wegt, lspq_out, lspcb1, lspcb2, fg,
coder->freq_prev, fg_sum, fg_sum_inv, code);
}
void
Relspwed (Word16 lsp[], /* (i) Q13 : unquantized LSP parameters */
Word16 wegt[], /* (i) norm: weighting coefficients */
Word16 lspq[], /* (o) Q13 : quantized LSP parameters */
Word16 lspcb1[][M10], /* (i) Q13 : first stage LSP codebook */
Word16 lspcb2[][M10], /* (i) Q13 : Second stage LSP codebook */
Word16 fg[MODE][MA_NP][M10], /* (i) Q15 : MA prediction coefficients */
Word16 freq_prev[MA_NP][M10], /* (i) Q13 : previous LSP vector */
Word16 fg_sum[MODE][M10], /* (i) Q15 : present MA prediction coef. */
Word16 fg_sum_inv[MODE][M10], /* (i) Q12 : inverse coef. */
Word16 code_ana[] /* (o) : codes of the selected LSP */
)
{
Word16 mode, j;
Word16 index, mode_index;
Word16 cand[MODE], cand_cur;
Word16 tindex1[MODE], tindex2[MODE];
Word32 L_tdist[MODE]; /* Q26 */
Word16 rbuf[M10]; /* Q13 */
Word16 buf[M10]; /* Q13 */
for (mode = 0; mode < MODE; mode++) {
Lsp_prev_extract (lsp, rbuf, fg[mode], freq_prev, fg_sum_inv[mode]);
Lsp_pre_select (rbuf, lspcb1, &cand_cur);
cand[mode] = cand_cur;
Lsp_select_1 (rbuf, lspcb1[cand_cur], wegt, lspcb2, &index);
tindex1[mode] = index;
for (j = 0; j < NC; j++)
buf[j] = add (lspcb1[cand_cur][j], lspcb2[index][j]);
Lsp_expand_1 (buf, GAP1);
Lsp_select_2 (rbuf, lspcb1[cand_cur], wegt, lspcb2, &index);
tindex2[mode] = index;
for (j = NC; j < M10; j++)
buf[j] = add (lspcb1[cand_cur][j], lspcb2[index][j]);
Lsp_expand_2 (buf, GAP1);
Lsp_expand_1_2 (buf, GAP2);
Lsp_get_tdist (wegt, buf, &L_tdist[mode], rbuf, fg_sum[mode]);
}
Lsp_last_select (L_tdist, &mode_index);
code_ana[0] = shl (mode_index, NC0_B) | cand[mode_index];
code_ana[1] = shl (tindex1[mode_index], NC1_B) | tindex2[mode_index];
Lsp_get_quant (lspcb1, lspcb2, cand[mode_index],
tindex1[mode_index], tindex2[mode_index],
fg[mode_index], freq_prev, lspq, fg_sum[mode_index]);
return;
}
void
Lsp_pre_select (Word16 rbuf[], /* (i) Q13 : target vetor */
Word16 lspcb1[][M10], /* (i) Q13 : first stage LSP codebook */
Word16 * cand /* (o) : selected code */
)
{
Word16 i, j;
Word16 tmp; /* Q13 */
Word32 L_dmin; /* Q26 */
Word32 L_tmp; /* Q26 */
Word32 L_temp;
/* avoid the worst case. (all over flow) */
*cand = 0;
L_dmin = MAX_32;
for (i = 0; i < NC0; i++) {
L_tmp = 0;
for (j = 0; j < M10; j++) {
tmp = sub (rbuf[j], lspcb1[i][j]);
L_tmp = L_mac (L_tmp, tmp, tmp);
}
L_temp = L_sub (L_tmp, L_dmin);
if (L_temp < 0L) {
L_dmin = L_tmp;
*cand = i;
}
}
return;
}
void
Lsp_select_1 (Word16 rbuf[], /* (i) Q13 : target vector */
Word16 lspcb1[], /* (i) Q13 : first stage lsp codebook */
Word16 wegt[], /* (i) norm: weighting coefficients */
Word16 lspcb2[][M10], /* (i) Q13 : second stage lsp codebook */
Word16 * index /* (o) : selected codebook index */
)
{
Word16 j, k1;
Word16 buf[M10]; /* Q13 */
Word32 L_dist; /* Q26 */
Word32 L_dmin; /* Q26 */
Word16 tmp, tmp2; /* Q13 */
Word32 L_temp;
for (j = 0; j < NC; j++)
buf[j] = sub (rbuf[j], lspcb1[j]);
/* avoid the worst case. (all over flow) */
*index = 0;
L_dmin = MAX_32;
for (k1 = 0; k1 < NC1; k1++) {
L_dist = 0;
for (j = 0; j < NC; j++) {
tmp = sub (buf[j], lspcb2[k1][j]);
tmp2 = mult (wegt[j], tmp);
L_dist = L_mac (L_dist, tmp2, tmp);
}
L_temp = L_sub (L_dist, L_dmin);
if (L_temp < 0L) {
L_dmin = L_dist;
*index = k1;
}
}
return;
}
void
Lsp_select_2 (Word16 rbuf[], /* (i) Q13 : target vector */
Word16 lspcb1[], /* (i) Q13 : first stage lsp codebook */
Word16 wegt[], /* (i) norm: weighting coef. */
Word16 lspcb2[][M10], /* (i) Q13 : second stage lsp codebook */
Word16 * index /* (o) : selected codebook index */
)
{
Word16 j, k1;
Word16 buf[M10]; /* Q13 */
Word32 L_dist; /* Q26 */
Word32 L_dmin; /* Q26 */
Word16 tmp, tmp2; /* Q13 */
Word32 L_temp;
for (j = NC; j < M10; j++)
buf[j] = sub (rbuf[j], lspcb1[j]);
/* avoid the worst case. (all over flow) */
*index = 0;
L_dmin = MAX_32;
for (k1 = 0; k1 < NC1; k1++) {
L_dist = 0;
for (j = NC; j < M10; j++) {
tmp = sub (buf[j], lspcb2[k1][j]);
tmp2 = mult (wegt[j], tmp);
L_dist = L_mac (L_dist, tmp2, tmp);
}
L_temp = L_sub (L_dist, L_dmin);
if (L_temp < 0L) {
L_dmin = L_dist;
*index = k1;
}
}
return;
}
void
Lsp_get_tdist (Word16 wegt[], /* (i) norm: weight coef. */
Word16 buf[], /* (i) Q13 : candidate LSP vector */
Word32 * L_tdist, /* (o) Q27 : distortion */
Word16 rbuf[], /* (i) Q13 : target vector */
Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */
)
{
Word16 j;
Word16 tmp, tmp2; /* Q13 */
Word32 L_acc; /* Q25 */
*L_tdist = 0;
for (j = 0; j < M10; j++) {
/* tmp = (buf - rbuf)*fg_sum */
tmp = sub (buf[j], rbuf[j]);
tmp = mult (tmp, fg_sum[j]);
/* *L_tdist += wegt * tmp * tmp */
L_acc = L_mult (wegt[j], tmp);
tmp2 = extract_h (L_shl (L_acc, 4));
*L_tdist = L_mac (*L_tdist, tmp2, tmp);
}
return;
}
void
Lsp_last_select (Word32 L_tdist[], /* (i) Q27 : distortion */
Word16 * mode_index /* (o) : the selected mode */
)
{
Word32 L_temp;
*mode_index = 0;
L_temp = L_sub (L_tdist[1], L_tdist[0]);
if (L_temp < 0L) {
*mode_index = 1;
}
return;
}
void
Get_wegt (Word16 flsp[], /* (i) Q13 : M LSP parameters */
Word16 wegt[] /* (o) Q11->norm : M weighting coefficients */
)
{
Word16 i;
Word16 tmp;
Word32 L_acc;
Word16 sft;
Word16 buf[M10]; /* in Q13 */
buf[0] = sub (flsp[1], (PI04 + 8192)); /* 8192:1.0(Q13) */
for (i = 1; i < M10 - 1; i++) {
tmp = sub (flsp[i + 1], flsp[i - 1]);
buf[i] = sub (tmp, 8192);
}
buf[M10 - 1] = sub ((PI92 - 8192), flsp[M10 - 2]);
/* */
for (i = 0; i < M10; i++) {
if (buf[i] > 0) {
wegt[i] = 2048; /* 2048:1.0(Q11) */
}
else {
L_acc = L_mult (buf[i], buf[i]); /* L_acc in Q27 */
tmp = extract_h (L_shl (L_acc, 2)); /* tmp in Q13 */
L_acc = L_mult (tmp, CONST10); /* L_acc in Q25 */
tmp = extract_h (L_shl (L_acc, 2)); /* tmp in Q11 */
wegt[i] = add (tmp, 2048); /* wegt in Q11 */
}
}
/* */
L_acc = L_mult (wegt[4], CONST12); /* L_acc in Q26 */
wegt[4] = extract_h (L_shl (L_acc, 1)); /* wegt in Q11 */
L_acc = L_mult (wegt[5], CONST12); /* L_acc in Q26 */
wegt[5] = extract_h (L_shl (L_acc, 1)); /* wegt in Q11 */
/* wegt: Q11 -> normalized */
tmp = 0;
for (i = 0; i < M10; i++) {
if (sub (wegt[i], tmp) > 0) {
tmp = wegt[i];
}
}
sft = norm_s (tmp);
for (i = 0; i < M10; i++) {
wegt[i] = shl (wegt[i], sft); /* wegt in Q(11+sft) */
}
return;
}

View File

@@ -0,0 +1,67 @@
/*
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.
*/
/*-------------------------------*
* LSP VQ functions. *
*-------------------------------*/
void Lsp_qua_cs (CodState *coder,
Word16 flsp_in[M10], /* Q13 */
Word16 lspq_out[M10], /* Q13 */
Word16 * code);
void Lsp_get_tdist (Word16 wegt[], /* normalized */
Word16 buf[], /* Q13 */
Word32 * L_tdist, /* Q27 */
Word16 rbuf[], /* Q13 */
Word16 fg_sum[] /* Q15 */
);
void Lsp_last_select (Word32 L_tdist[], /* Q27 */
Word16 * mode_index);
void Lsp_pre_select (Word16 rbuf[], /* Q13 */
Word16 lspcb1[][M10], /* Q13 */
Word16 * cand);
void Lsp_select_1 (Word16 rbuf[], /* Q13 */
Word16 lspcb1[], /* Q13 */
Word16 wegt[], /* normalized */
Word16 lspcb2[][M10], /* Q13 */
Word16 * index);
void Lsp_select_2 (Word16 rbuf[], /* Q13 */
Word16 lspcb1[], /* Q13 */
Word16 wegt[], /* normalized */
Word16 lspcb2[][M10], /* Q13 */
Word16 * index);
void Relspwed (Word16 lsp[], /* Q13 */
Word16 wegt[], /* normalized */
Word16 lspq[], /* Q13 */
Word16 lspcb1[][M10], /* Q13 */
Word16 lspcb2[][M10], /* Q13 */
Word16 fg[MODE][MA_NP][M10], /* Q15 */
Word16 freq_prev[MA_NP][M10], /* Q13 */
Word16 fg_sum[MODE][M10], /* Q15 */
Word16 fg_sum_inv[MODE][M10], /* Q12 */
Word16 code_ana[]
);
void Qua_lsp (CodState *coder,
Word16 lsp[], /* (i) Q15 : Unquantized LSP */
Word16 lsp_q[], /* (o) Q15 : Quantized LSP */
Word16 ana[] /* (o) : indexes */
);
void Get_wegt (Word16 flsp[], /* Q13 */
Word16 wegt[] /* Q11 -> normalized */
);
void Lsp_encw_reset (CodState *coder);

View File

@@ -0,0 +1,110 @@
/*
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.
*/
#include "g729_typedef.h"
#include "g729_ld8a.h"
#include "g729_basic_op.h"
#include "g729_tab_ld8a.h"
#include "g729_util.h"
#include "g729_lspgetq.h"
#include "g729_lpcfunc.h"
/*----------------------------------------------------------------------------
* Lsp_decw_reset - set the previous LSP vectors
*----------------------------------------------------------------------------
*/
void
Lsp_decw_reset (DecState *decoder)
{
Word16 i;
for (i = 0; i < MA_NP; i++)
Copy (&freq_prev_reset[0], &decoder->freq_prev[i][0], M10);
decoder->prev_ma = 0;
Copy (freq_prev_reset, decoder->prev_lsp, M10);
}
/*----------------------------------------------------------------------------
* Lsp_iqua_cs - LSP main quantization routine
*----------------------------------------------------------------------------
*/
void
Lsp_iqua_cs (DecState *decoder,
Word16 prm[], /* (i) : indexes of the selected LSP */
Word16 lsp_q[], /* (o) Q13 : Quantized LSP parameters */
Word16 erase /* (i) : frame erase information */
)
{
Word16 mode_index;
Word16 code0;
Word16 code1;
Word16 code2;
Word16 buf[M10]; /* Q13 */
if (erase == 0) { /* Not frame erasure */
mode_index = shr (prm[0], NC0_B) & (Word16) 1;
code0 = prm[0] & (Word16) (NC0 - 1);
code1 = shr (prm[1], NC1_B) & (Word16) (NC1 - 1);
code2 = prm[1] & (Word16) (NC1 - 1);
/* compose quantized LSP (lsp_q) from indexes */
Lsp_get_quant (lspcb1, lspcb2, code0, code1, code2,
fg[mode_index], decoder->freq_prev, lsp_q, fg_sum[mode_index]);
/* save parameters to use in case of the frame erased situation */
Copy (lsp_q, decoder->prev_lsp, M10);
decoder->prev_ma = mode_index;
}
else { /* Frame erased */
/* use revious LSP */
Copy (decoder->prev_lsp, lsp_q, M10);
/* update freq_prev */
Lsp_prev_extract (decoder->prev_lsp, buf,
fg[decoder->prev_ma], decoder->freq_prev, fg_sum_inv[decoder->prev_ma]);
Lsp_prev_update (buf, decoder->freq_prev);
}
return;
}
/*-------------------------------------------------------------------*
* Function D_lsp: *
* ~~~~~~ *
*-------------------------------------------------------------------*/
void
D_lsp (DecState *decoder,
Word16 prm[], /* (i) : indexes of the selected LSP */
Word16 lsp_q[], /* (o) Q15 : Quantized LSP parameters */
Word16 erase /* (i) : frame erase information */
)
{
Word16 lsf_q[M10]; /* domain 0.0<= lsf_q <PI in Q13 */
Lsp_iqua_cs (decoder, prm, lsf_q, erase);
/* Convert LSFs to LSPs */
Lsf_lsp2 (lsf_q, lsp_q, M10);
return;
}

View File

@@ -0,0 +1,27 @@
/*
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.
*/
/*-------------------------------*
* LSP VQ functions. *
*-------------------------------*/
void D_lsp (DecState *decoder,
Word16 prm[], /* (i) : indexes of the selected LSP */
Word16 lsp_q[], /* (o) Q15 : Quantized LSP parameters */
Word16 erase /* (i) : frame erase information */
);
void Lsp_decw_reset (DecState *decoder);
void Lsp_iqua_cs (DecState *decoder,
Word16 prm[], /* input : codes of the selected LSP */
Word16 lsp_q[], /* output: Quantized LSP parameters */
Word16 erase /* input : frame erase information */
);

View File

@@ -0,0 +1,235 @@
/*
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.
*/
#include <stdio.h>
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_util.h"
#include "g729_lspgetq.h"
void
Lsp_get_quant (Word16 lspcb1[][M10], /* (i) Q13 : first stage LSP codebook */
Word16 lspcb2[][M10], /* (i) Q13 : Second stage LSP codebook */
Word16 code0, /* (i) : selected code of first stage */
Word16 code1, /* (i) : selected code of second stage */
Word16 code2, /* (i) : selected code of second stage */
Word16 fg[][M10], /* (i) Q15 : MA prediction coef. */
Word16 freq_prev[][M10], /* (i) Q13 : previous LSP vector */
Word16 lspq[], /* (o) Q13 : quantized LSP parameters */
Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */
)
{
Word16 j;
Word16 buf[M10]; /* Q13 */
for (j = 0; j < NC; j++)
buf[j] = add (lspcb1[code0][j], lspcb2[code1][j]);
for (j = NC; j < M10; j++)
buf[j] = add (lspcb1[code0][j], lspcb2[code2][j]);
Lsp_expand_1_2 (buf, GAP1);
Lsp_expand_1_2 (buf, GAP2);
Lsp_prev_compose (buf, lspq, fg, freq_prev, fg_sum);
Lsp_prev_update (buf, freq_prev);
Lsp_stability (lspq);
return;
}
void
Lsp_expand_1 (Word16 buf[], /* (i/o) Q13 : LSP vectors */
Word16 gap /* (i) Q13 : gap */
)
{
Word16 j, tmp;
Word16 diff; /* Q13 */
for (j = 1; j < NC; j++) {
diff = sub (buf[j - 1], buf[j]);
tmp = shr (add (diff, gap), 1);
if (tmp > 0) {
buf[j - 1] = sub (buf[j - 1], tmp);
buf[j] = add (buf[j], tmp);
}
}
return;
}
void
Lsp_expand_2 (Word16 buf[], /* (i/o) Q13 : LSP vectors */
Word16 gap /* (i) Q13 : gap */
)
{
Word16 j, tmp;
Word16 diff; /* Q13 */
for (j = NC; j < M10; j++) {
diff = sub (buf[j - 1], buf[j]);
tmp = shr (add (diff, gap), 1);
if (tmp > 0) {
buf[j - 1] = sub (buf[j - 1], tmp);
buf[j] = add (buf[j], tmp);
}
}
return;
}
void
Lsp_expand_1_2 (Word16 buf[], /* (i/o) Q13 : LSP vectors */
Word16 gap /* (i) Q13 : gap */
)
{
Word16 j, tmp;
Word16 diff; /* Q13 */
for (j = 1; j < M10; j++) {
diff = sub (buf[j - 1], buf[j]);
tmp = shr (add (diff, gap), 1);
if (tmp > 0) {
buf[j - 1] = sub (buf[j - 1], tmp);
buf[j] = add (buf[j], tmp);
}
}
return;
}
/*
Functions which use previous LSP parameter (freq_prev).
*/
/*
compose LSP parameter from elementary LSP with previous LSP.
*/
void
Lsp_prev_compose (Word16 lsp_ele[], /* (i) Q13 : LSP vectors */
Word16 lsp[], /* (o) Q13 : quantized LSP parameters */
Word16 fg[][M10], /* (i) Q15 : MA prediction coef. */
Word16 freq_prev[][M10], /* (i) Q13 : previous LSP vector */
Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */
)
{
Word16 j, k;
Word32 L_acc; /* Q29 */
for (j = 0; j < M10; j++) {
L_acc = L_mult (lsp_ele[j], fg_sum[j]);
for (k = 0; k < MA_NP; k++)
L_acc = L_mac (L_acc, freq_prev[k][j], fg[k][j]);
lsp[j] = extract_h (L_acc);
}
return;
}
/*
extract elementary LSP from composed LSP with previous LSP
*/
void
Lsp_prev_extract (Word16 lsp[M10], /* (i) Q13 : unquantized LSP parameters */
Word16 lsp_ele[M10], /* (o) Q13 : target vector */
Word16 fg[MA_NP][M10], /* (i) Q15 : MA prediction coef. */
Word16 freq_prev[MA_NP][M10], /* (i) Q13 : previous LSP vector */
Word16 fg_sum_inv[M10] /* (i) Q12 : inverse previous LSP vector */
)
{
Word16 j, k;
Word32 L_temp; /* Q19 */
Word16 temp; /* Q13 */
for (j = 0; j < M10; j++) {
L_temp = L_deposit_h (lsp[j]);
for (k = 0; k < MA_NP; k++)
L_temp = L_msu (L_temp, freq_prev[k][j], fg[k][j]);
temp = extract_h (L_temp);
L_temp = L_mult (temp, fg_sum_inv[j]);
lsp_ele[j] = extract_h (L_shl (L_temp, 3));
}
return;
}
/*
update previous LSP parameter
*/
void
Lsp_prev_update (Word16 lsp_ele[M10], /* (i) Q13 : LSP vectors */
Word16 freq_prev[MA_NP][M10] /* (i/o) Q13 : previous LSP vectors */
)
{
Word16 k;
for (k = MA_NP - 1; k > 0; k--)
Copy (freq_prev[k - 1], freq_prev[k], M10);
Copy (lsp_ele, freq_prev[0], M10);
return;
}
void
Lsp_stability (Word16 buf[] /* (i/o) Q13 : quantized LSP parameters */
)
{
Word16 j;
Word16 tmp;
Word32 L_diff;
Word32 L_acc, L_accb;
for (j = 0; j < M10 - 1; j++) {
L_acc = L_deposit_l (buf[j + 1]);
L_accb = L_deposit_l (buf[j]);
L_diff = L_sub (L_acc, L_accb);
if (L_diff < 0L) {
/* exchange buf[j]<->buf[j+1] */
tmp = buf[j + 1];
buf[j + 1] = buf[j];
buf[j] = tmp;
}
}
if (sub (buf[0], L_LIMIT) < 0) {
buf[0] = L_LIMIT;
printf ("lsp_stability warning Low \n");
}
for (j = 0; j < M10 - 1; j++) {
L_acc = L_deposit_l (buf[j + 1]);
L_accb = L_deposit_l (buf[j]);
L_diff = L_sub (L_acc, L_accb);
if (L_sub (L_diff, GAP3) < 0L) {
buf[j + 1] = add (buf[j], GAP3);
}
}
if (sub (buf[M10 - 1], M_LIMIT) > 0) {
buf[M10 - 1] = M_LIMIT;
printf ("lsp_stability warning High \n");
}
return;
}

View File

@@ -0,0 +1,50 @@
/*
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.
*/
void Lsp_get_quant (Word16 lspcb1[][M10], /* Q13 */
Word16 lspcb2[][M10], /* Q13 */
Word16 code0, Word16 code1, Word16 code2, Word16 fg[][M10], /* Q15 */
Word16 freq_prev[][M10], /* Q13 */
Word16 lspq[], /* Q13 */
Word16 fg_sum[] /* Q15 */
);
void Lsp_expand_1 (Word16 buf[], /* Q13 */
Word16 gap /* Q13 */
);
void Lsp_expand_2 (Word16 buf[], /* Q13 */
Word16 gap /* Q13 */
);
void Lsp_expand_1_2 (Word16 buf[], /* Q13 */
Word16 gap /* Q13 */
);
void Lsp_stability (Word16 buf[] /* Q13 */
);
void Lsp_prev_compose (Word16 lsp_ele[], /* Q13 */
Word16 lsp[], /* Q13 */
Word16 fg[][M10], /* Q15 */
Word16 freq_prev[][M10], /* Q13 */
Word16 fg_sum[] /* Q15 */
);
void Lsp_prev_extract (Word16 lsp[M10], /* Q13 */
Word16 lsp_ele[M10], /* Q13 */
Word16 fg[MA_NP][M10], /* Q15 */
Word16 freq_prev[MA_NP][M10], /* Q13 */
Word16 fg_sum_inv[M10] /* Q12 */
);
void Lsp_prev_update (Word16 lsp_ele[M10], /* Q13 */
Word16 freq_prev[MA_NP][M10] /* Q13 */
);

View File

@@ -0,0 +1,228 @@
/*
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.
*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
/*___________________________________________________________________________
| |
| This file contains operations in double precision. |
| These operations are not standard double precision operations. |
| They are used where single precision is not enough but the full 32 bits |
| precision is not necessary. For example, the function Div_32() has a |
| 24 bits precision which is enough for our purposes. |
| |
| The double precision numbers use a special representation: |
| |
| L_32 = hi<<16 + lo<<1 |
| |
| L_32 is a 32 bit integer. |
| hi and lo are 16 bit signed integers. |
| As the low part also contains the sign, this allows fast multiplication. |
| |
| 0x8000 0000 <= L_32 <= 0x7fff fffe. |
| |
| We will use DPF (Double Precision Format )in this file to specify |
| this special format. |
|___________________________________________________________________________|
*/
/*___________________________________________________________________________
| |
| Function L_Extract() |
| |
| Extract from a 32 bit integer two 16 bit DPF. |
| |
| Arguments: |
| |
| L_32 : 32 bit integer. |
| 0x8000 0000 <= L_32 <= 0x7fff ffff. |
| hi : b16 to b31 of L_32 |
| lo : (L_32 - hi<<16)>>1 |
|___________________________________________________________________________|
*/
void
L_Extract (Word32 L_32, Word16 * hi, Word16 * lo)
{
*hi = extract_h (L_32);
*lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); /* lo = L_32>>1 */
return;
}
/*___________________________________________________________________________
| |
| Function L_Comp() |
| |
| Compose from two 16 bit DPF a 32 bit integer. |
| |
| L_32 = hi<<16 + lo<<1 |
| |
| Arguments: |
| |
| hi msb |
| lo lsf (with sign) |
| |
| Return Value : |
| |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_32 <= 0x7fff fff0. |
| |
|___________________________________________________________________________|
*/
Word32
L_Comp (Word16 hi, Word16 lo)
{
Word32 L_32;
L_32 = L_deposit_h (hi);
return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */
}
/*___________________________________________________________________________
| Function Mpy_32() |
| |
| Multiply two 32 bit integers (DPF). The result is divided by 2**31 |
| |
| L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 |
| |
| This operation can also be viewed as the multiplication of two Q31 |
| number and the result is also in Q31. |
| |
| Arguments: |
| |
| hi1 hi part of first number |
| lo1 lo part of first number |
| hi2 hi part of second number |
| lo2 lo part of second number |
| |
|___________________________________________________________________________|
*/
Word32
Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
{
Word32 L_32;
L_32 = L_mult (hi1, hi2);
L_32 = L_mac (L_32, mult (hi1, lo2), 1);
L_32 = L_mac (L_32, mult (lo1, hi2), 1);
return (L_32);
}
/*___________________________________________________________________________
| Function Mpy_32_16() |
| |
| Multiply a 16 bit integer by a 32 bit (DPF). The result is divided |
| by 2**15 |
| |
| This operation can also be viewed as the multiplication of a Q31 |
| number by a Q15 number, the result is in Q31. |
| |
| L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 |
| |
| Arguments: |
| |
| hi hi part of 32 bit number. |
| lo lo part of 32 bit number. |
| n 16 bit number. |
| |
|___________________________________________________________________________|
*/
Word32
Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
{
Word32 L_32;
L_32 = L_mult (hi, n);
L_32 = L_mac (L_32, mult (lo, n), 1);
return (L_32);
}
/*___________________________________________________________________________
| |
| Function Name : Div_32 |
| |
| Purpose : |
| Fractional integer division of two 32 bit numbers. |
| L_num / L_denom. |
| L_num and L_denom must be positive and L_num < L_denom. |
| L_denom = denom_hi<<16 + denom_lo<<1 |
| denom_hi is a normalize number. |
| The result is in Q30. |
| |
| Inputs : |
| |
| L_num |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x0000 0000 < L_num < L_denom |
| |
| L_denom = denom_hi<<16 + denom_lo<<1 (DPF) |
| |
| denom_hi |
| 16 bit positive normalized integer whose value falls in the |
| range : 0x4000 < hi < 0x7fff |
| denom_lo |
| 16 bit positive integer whose value falls in the |
| range : 0 < lo < 0x7fff |
| |
| Return Value : |
| |
| L_div |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x0000 0000 <= L_div <= 0x7fff ffff. |
| It's a Q31 value |
| |
| Algorithm: |
| |
| - find = 1/L_denom. |
| First approximation: approx = 1 / denom_hi |
| 1/L_denom = approx * (2.0 - L_denom * approx ) |
| |
| - result = L_num * (1/L_denom) |
|___________________________________________________________________________|
*/
Word32
Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo)
{
Word16 approx, hi, lo, n_hi, n_lo;
Word32 L_32;
/* First approximation: 1 / L_denom = 1/denom_hi */
approx = div_s ((Word16) 0x3fff, denom_hi); /* result in Q14 */
/* Note: 3fff = 0.5 in Q15 */
/* 1/L_denom = approx * (2.0 - L_denom * approx) */
L_32 = Mpy_32_16 (denom_hi, denom_lo, approx); /* result in Q30 */
L_32 = L_sub ((Word32) 0x7fffffffL, L_32); /* result in Q30 */
L_Extract (L_32, &hi, &lo);
L_32 = Mpy_32_16 (hi, lo, approx); /* = 1/L_denom in Q29 */
/* L_num * (1/L_denom) */
L_Extract (L_32, &hi, &lo);
L_Extract (L_num, &n_hi, &n_lo);
L_32 = Mpy_32 (n_hi, n_lo, hi, lo); /* result in Q29 */
L_32 = L_shl (L_32, 2); /* From Q29 to Q31 */
return (L_32);
}

View File

@@ -0,0 +1,16 @@
/*
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.
*/
/* Double precision operations */
void L_Extract (Word32 L_32, Word16 * hi, Word16 * lo);
Word32 L_Comp (Word16 hi, Word16 lo);
Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);
Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n);
Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo);

View File

@@ -0,0 +1,63 @@
/*
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.
*/
/*------------------------------------------------------*
* Parity_pitch - compute parity bit for first 6 MSBs *
*------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
Word16
Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */
Word16 pitch_index /* input : index for which parity to compute */
)
{
Word16 temp, sum, i, bit;
temp = shr (pitch_index, 1);
sum = 1;
for (i = 0; i <= 5; i++) {
temp = shr (temp, 1);
bit = temp & (Word16) 1;
sum = add (sum, bit);
}
sum = sum & (Word16) 1;
return sum;
}
/*--------------------------------------------------------------------*
* check_parity_pitch - check parity of index with transmitted parity *
*--------------------------------------------------------------------*/
Word16
Check_Parity_Pitch ( /* output: 0 = no error, 1= error */
Word16 pitch_index, /* input : index of parameter */
Word16 parity /* input : parity bit */
)
{
Word16 temp, sum, i, bit;
temp = shr (pitch_index, 1);
sum = 1;
for (i = 0; i <= 5; i++) {
temp = shr (temp, 1);
bit = temp & (Word16) 1;
sum = add (sum, bit);
}
sum = add (sum, parity);
sum = sum & (Word16) 1;
return sum;
}

View File

@@ -0,0 +1,570 @@
/*
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.
*/
/*---------------------------------------------------------------------------*
* Pitch related functions *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
*---------------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_util.h"
/*---------------------------------------------------------------------------*
* Function Pitch_ol_fast *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Compute the open loop pitch lag. (fast version) *
* *
*---------------------------------------------------------------------------*/
Word16
Pitch_ol_fast ( /* output: open loop pitch lag */
Word16 signal[], /* input : signal used to compute the open loop pitch */
/* signal[-pit_max] to signal[-1] should be known */
Word16 pit_max, /* input : maximum pitch lag */
Word16 L_frame /* input : length of frame to compute pitch */
)
{
Flag Overflow;
Word16 i, j;
Word16 max1, max2, max3;
Word16 max_h, max_l, ener_h, ener_l;
Word16 T1, T2, T3;
Word16 *p, *p1;
Word32 max, sum, L_temp;
/* Scaled signal */
Word16 scaled_signal[L_FRAME + PIT_MAX];
Word16 *scal_sig;
scal_sig = &scaled_signal[pit_max];
/*--------------------------------------------------------*
* Verification for risk of overflow. *
*--------------------------------------------------------*/
Overflow = 0;
sum = 0;
for (i = -pit_max; i < L_frame; i += 2)
sum = L_mac_o (sum, signal[i], signal[i], &Overflow);
/*--------------------------------------------------------*
* Scaling of input signal. *
* *
* if Overflow -> scal_sig[i] = signal[i]>>3 *
* else if sum < 1^20 -> scal_sig[i] = signal[i]<<3 *
* else -> scal_sig[i] = signal[i] *
*--------------------------------------------------------*/
if (Overflow == 1) {
for (i = -pit_max; i < L_frame; i++) {
scal_sig[i] = shr (signal[i], 3);
}
}
else {
L_temp = L_sub (sum, (Word32) 1048576L);
if (L_temp < (Word32) 0) { /* if (sum < 2^20) */
for (i = -pit_max; i < L_frame; i++) {
scal_sig[i] = shl (signal[i], 3);
}
}
else {
for (i = -pit_max; i < L_frame; i++) {
scal_sig[i] = signal[i];
}
}
}
/*--------------------------------------------------------------------*
* The pitch lag search is divided in three sections. *
* Each section cannot have a pitch multiple. *
* We find a maximum for each section. *
* We compare the maxima of each section by favoring small lag. *
* *
* First section: lag delay = 20 to 39 *
* Second section: lag delay = 40 to 79 *
* Third section: lag delay = 80 to 143 *
*--------------------------------------------------------------------*/
/* First section */
max = MIN_32;
T1 = 20; /* Only to remove warning from some compilers */
for (i = 20; i < 40; i++) {
p = scal_sig;
p1 = &scal_sig[-i];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T1 = i;
}
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T1];
for (i = 0; i < L_frame; i += 2, p += 2)
sum = L_mac (sum, *p, *p);
/* max1 = max/sqrt(energy) */
/* This result will always be on 16 bits !! */
sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */
L_Extract (max, &max_h, &max_l);
L_Extract (sum, &ener_h, &ener_l);
sum = Mpy_32 (max_h, max_l, ener_h, ener_l);
max1 = extract_l (sum);
/* Second section */
max = MIN_32;
T2 = 40; /* Only to remove warning from some compilers */
for (i = 40; i < 80; i++) {
p = scal_sig;
p1 = &scal_sig[-i];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T2 = i;
}
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T2];
for (i = 0; i < L_frame; i += 2, p += 2)
sum = L_mac (sum, *p, *p);
/* max2 = max/sqrt(energy) */
/* This result will always be on 16 bits !! */
sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */
L_Extract (max, &max_h, &max_l);
L_Extract (sum, &ener_h, &ener_l);
sum = Mpy_32 (max_h, max_l, ener_h, ener_l);
max2 = extract_l (sum);
/* Third section */
max = MIN_32;
T3 = 80; /* Only to remove warning from some compilers */
for (i = 80; i < 143; i += 2) {
p = scal_sig;
p1 = &scal_sig[-i];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T3 = i;
}
}
/* Test around max3 */
i = T3;
p = scal_sig;
p1 = &scal_sig[-(i + 1)];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T3 = i + (Word16) 1;
}
p = scal_sig;
p1 = &scal_sig[-(i - 1)];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T3 = i - (Word16) 1;
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T3];
for (i = 0; i < L_frame; i += 2, p += 2)
sum = L_mac (sum, *p, *p);
/* max1 = max/sqrt(energy) */
/* This result will always be on 16 bits !! */
sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */
L_Extract (max, &max_h, &max_l);
L_Extract (sum, &ener_h, &ener_l);
sum = Mpy_32 (max_h, max_l, ener_h, ener_l);
max3 = extract_l (sum);
/*-----------------------*
* Test for multiple. *
*-----------------------*/
/* if( abs(T2*2 - T3) < 5) */
/* max2 += max3 * 0.25; */
i = sub (shl (T2, 1), T3);
j = sub (abs_s (i), 5);
if (j < 0)
max2 = add (max2, shr (max3, 2));
/* if( abs(T2*3 - T3) < 7) */
/* max2 += max3 * 0.25; */
i = add (i, T2);
j = sub (abs_s (i), 7);
if (j < 0)
max2 = add (max2, shr (max3, 2));
/* if( abs(T1*2 - T2) < 5) */
/* max1 += max2 * 0.20; */
i = sub (shl (T1, 1), T2);
j = sub (abs_s (i), 5);
if (j < 0)
max1 = add (max1, mult (max2, 6554));
/* if( abs(T1*3 - T2) < 7) */
/* max1 += max2 * 0.20; */
i = add (i, T1);
j = sub (abs_s (i), 7);
if (j < 0)
max1 = add (max1, mult (max2, 6554));
/*--------------------------------------------------------------------*
* Compare the 3 sections maxima. *
*--------------------------------------------------------------------*/
if (sub (max1, max2) < 0) {
max1 = max2;
T1 = T2;
}
if (sub (max1, max3) < 0) {
T1 = T3;
}
return T1;
}
/*--------------------------------------------------------------------------*
* Function Dot_Product() *
* ~~~~~~~~~~~~~~~~~~~~~~ *
*--------------------------------------------------------------------------*/
Word32
Dot_Product ( /* (o) :Result of scalar product. */
Word16 x[], /* (i) :First vector. */
Word16 y[], /* (i) :Second vector. */
Word16 lg /* (i) :Number of point. */
)
{
Word16 i;
Word32 sum;
sum = 0;
for (i = 0; i < lg; i++)
sum = L_mac (sum, x[i], y[i]);
return sum;
}
/*--------------------------------------------------------------------------*
* Function Pitch_fr3_fast() *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* Fast version of the pitch close loop. *
*--------------------------------------------------------------------------*/
Word16
Pitch_fr3_fast ( /* (o) : pitch period. */
Word16 exc[], /* (i) : excitation buffer */
Word16 xn[], /* (i) : target vector */
Word16 h[], /* (i) Q12 : impulse response of filters. */
Word16 L_subfr, /* (i) : Length of subframe */
Word16 t0_min, /* (i) : minimum value in the searched range. */
Word16 t0_max, /* (i) : maximum value in the searched range. */
Word16 i_subfr, /* (i) : indicator for first subframe. */
Word16 * pit_frac /* (o) : chosen fraction. */
)
{
Word16 t, t0;
Word16 Dn[L_SUBFR];
Word16 exc_tmp[L_SUBFR];
Word32 max, corr, L_temp;
/*-----------------------------------------------------------------*
* Compute correlation of target vector with impulse response. *
*-----------------------------------------------------------------*/
Cor_h_X (h, xn, Dn);
/*-----------------------------------------------------------------*
* Find maximum integer delay. *
*-----------------------------------------------------------------*/
max = MIN_32;
t0 = t0_min; /* Only to remove warning from some compilers */
for (t = t0_min; t <= t0_max; t++) {
corr = Dot_Product (Dn, &exc[-t], L_subfr);
L_temp = L_sub (corr, max);
if (L_temp > 0) {
max = corr;
t0 = t;
}
}
/*-----------------------------------------------------------------*
* Test fractions. *
*-----------------------------------------------------------------*/
/* Fraction 0 */
Pred_lt_3 (exc, t0, 0, L_subfr);
max = Dot_Product (Dn, exc, L_subfr);
*pit_frac = 0;
/* If first subframe and lag > 84 do not search fractional pitch */
if ((i_subfr == 0) && (sub (t0, 84) > 0))
return t0;
Copy (exc, exc_tmp, L_subfr);
/* Fraction -1/3 */
Pred_lt_3 (exc, t0, -1, L_subfr);
corr = Dot_Product (Dn, exc, L_subfr);
L_temp = L_sub (corr, max);
if (L_temp > 0) {
max = corr;
*pit_frac = -1;
Copy (exc, exc_tmp, L_subfr);
}
/* Fraction +1/3 */
Pred_lt_3 (exc, t0, 1, L_subfr);
corr = Dot_Product (Dn, exc, L_subfr);
L_temp = L_sub (corr, max);
if (L_temp > 0) {
max = corr;
*pit_frac = 1;
}
else
Copy (exc_tmp, exc, L_subfr);
return t0;
}
/*---------------------------------------------------------------------*
* Function G_pitch: *
* ~~~~~~~~ *
*---------------------------------------------------------------------*
* Compute correlations <xn,y1> and <y1,y1> to use in gains quantizer. *
* Also compute the gain of pitch. Result in Q14 *
* if (gain < 0) gain =0 *
* if (gain >1.2) gain =1.2 *
*---------------------------------------------------------------------*/
Word16
G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */
Word16 xn[], /* (i) : Pitch target. */
Word16 y1[], /* (i) : Filtered adaptive codebook. */
Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */
Word16 L_subfr /* (i) : Length of subframe. */
)
{
Flag Overflow;
Word16 i;
Word16 xy, yy, exp_xy, exp_yy, gain;
Word32 s;
Word16 scaled_y1[L_SUBFR];
/* divide "y1[]" by 4 to avoid overflow */
for (i = 0; i < L_subfr; i++)
scaled_y1[i] = shr (y1[i], 2);
/* Compute scalar product <y1[],y1[]> */
Overflow = 0;
s = 1; /* Avoid case of all zeros */
for (i = 0; i < L_subfr; i++)
s = L_mac_o (s, y1[i], y1[i], &Overflow);
if (Overflow == 0) {
exp_yy = norm_l (s);
yy = wround (L_shl (s, exp_yy));
}
else {
s = 1; /* Avoid case of all zeros */
for (i = 0; i < L_subfr; i++)
s = L_mac (s, scaled_y1[i], scaled_y1[i]);
exp_yy = norm_l (s);
yy = wround (L_shl (s, exp_yy));
exp_yy = sub (exp_yy, 4);
}
/* Compute scalar product <xn[],y1[]> */
Overflow = 0;
s = 0;
for (i = 0; i < L_subfr; i++)
s = L_mac_o (s, xn[i], y1[i], &Overflow);
if (Overflow == 0) {
exp_xy = norm_l (s);
xy = wround (L_shl (s, exp_xy));
}
else {
s = 0;
for (i = 0; i < L_subfr; i++)
s = L_mac (s, xn[i], scaled_y1[i]);
exp_xy = norm_l (s);
xy = wround (L_shl (s, exp_xy));
exp_xy = sub (exp_xy, 2);
}
g_coeff[0] = yy;
g_coeff[1] = sub (15, exp_yy);
g_coeff[2] = xy;
g_coeff[3] = sub (15, exp_xy);
/* If (xy <= 0) gain = 0 */
if (xy <= 0) {
g_coeff[3] = -15; /* Force exp_xy to -15 = (15-30) */
return ((Word16) 0);
}
/* compute gain = xy/yy */
xy = shr (xy, 1); /* Be sure xy < yy */
gain = div_s (xy, yy);
i = sub (exp_xy, exp_yy);
gain = shr (gain, i); /* saturation if > 1.99 in Q14 */
/* if(gain >1.2) gain = 1.2 in Q14 */
if (sub (gain, 19661) > 0) {
gain = 19661;
}
return (gain);
}
/*----------------------------------------------------------------------*
* Function Enc_lag3 *
* ~~~~~~~~ *
* Encoding of fractional pitch lag with 1/3 resolution. *
*----------------------------------------------------------------------*
* The pitch range for the first subframe is divided as follows: *
* 19 1/3 to 84 2/3 resolution 1/3 *
* 85 to 143 resolution 1 *
* *
* The period in the first subframe is encoded with 8 bits. *
* For the range with fractions: *
* index = (T-19)*3 + frac - 1; where T=[19..85] and frac=[-1,0,1] *
* and for the integer only range *
* index = (T - 85) + 197; where T=[86..143] *
*----------------------------------------------------------------------*
* For the second subframe a resolution of 1/3 is always used, and the *
* search range is relative to the lag in the first subframe. *
* If t0 is the lag in the first subframe then *
* t_min=t0-5 and t_max=t0+4 and the range is given by *
* t_min - 2/3 to t_max + 2/3 *
* *
* The period in the 2nd subframe is encoded with 5 bits: *
* index = (T-(t_min-1))*3 + frac - 1; where T[t_min-1 .. t_max+1] *
*----------------------------------------------------------------------*/
Word16
Enc_lag3 ( /* output: Return index of encoding */
Word16 T0, /* input : Pitch delay */
Word16 T0_frac, /* input : Fractional pitch delay */
Word16 * T0_min, /* in/out: Minimum search delay */
Word16 * T0_max, /* in/out: Maximum search delay */
Word16 pit_min, /* input : Minimum pitch delay */
Word16 pit_max, /* input : Maximum pitch delay */
Word16 pit_flag /* input : Flag for 1st subframe */
)
{
Word16 index, i;
if (pit_flag == 0) { /* if 1st subframe */
/* encode pitch delay (with fraction) */
if (sub (T0, 85) <= 0) {
/* index = t0*3 - 58 + t0_frac */
i = add (add (T0, T0), T0);
index = add (sub (i, 58), T0_frac);
}
else {
index = add (T0, 112);
}
/* find T0_min and T0_max for second subframe */
*T0_min = sub (T0, 5);
if (sub (*T0_min, pit_min) < 0) {
*T0_min = pit_min;
}
*T0_max = add (*T0_min, 9);
if (sub (*T0_max, pit_max) > 0) {
*T0_max = pit_max;
*T0_min = sub (*T0_max, 9);
}
}
else { /* if second subframe */
/* i = t0 - t0_min; */
/* index = i*3 + 2 + t0_frac; */
i = sub (T0, *T0_min);
i = add (add (i, i), i);
index = add (add (i, 2), T0_frac);
}
return index;
}

View File

@@ -0,0 +1,84 @@
/*
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 Post_Process() *
* *
* Post-processing of output speech. *
* - 2nd order high pass filter with cut off frequency at 100 Hz. *
* - Multiplication by two of output speech with saturation. *
*-----------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
/*------------------------------------------------------------------------*
* 2nd order high pass filter with cut off frequency at 100 Hz. *
* Designed with SPPACK efi command -40 dB att, 0.25 ri. *
* *
* Algorithm: *
* *
* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] *
* + a[1]*y[i-1] + a[2]*y[i-2]; *
* *
* b[3] = {0.93980581E+00, -0.18795834E+01, 0.93980581E+00}; *
* a[3] = {0.10000000E+01, 0.19330735E+01, -0.93589199E+00}; *
*-----------------------------------------------------------------------*/
/* Initialization of values */
void
Init_Post_Process (DecState *decoder)
{
decoder->y2_hi = 0;
decoder->y2_lo = 0;
decoder->y1_hi = 0;
decoder->y1_lo = 0;
decoder->x0 = 0;
decoder->x1 = 0;
}
void
Post_Process (DecState *decoder,
Word16 signal[], /* input/output signal */
Word16 lg)
{ /* length of signal */
Word16 i, x2;
Word32 L_tmp;
for (i = 0; i < lg; i++) {
x2 = decoder->x1;
decoder->x1 = decoder->x0;
decoder->x0 = signal[i];
/* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
/* + a[1]*y[i-1] + a[2] * y[i-2]; */
L_tmp = Mpy_32_16 (decoder->y1_hi, decoder->y1_lo, a100[1]);
L_tmp = L_add (L_tmp, Mpy_32_16 (decoder->y2_hi, decoder->y2_lo, a100[2]));
L_tmp = L_mac (L_tmp, decoder->x0, b100[0]);
L_tmp = L_mac (L_tmp, decoder->x1, b100[1]);
L_tmp = L_mac (L_tmp, x2, b100[2]);
L_tmp = L_shl (L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */
/* Multiplication by two of output speech with saturation. */
signal[i] = wround (L_shl (L_tmp, 1));
decoder->y2_hi = decoder->y1_hi;
decoder->y2_lo = decoder->y1_lo;
L_Extract (L_tmp, &decoder->y1_hi, &decoder->y1_lo);
}
return;
}

View File

@@ -0,0 +1,441 @@
/*
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.
*/
/*------------------------------------------------------------------------*
* POSTFILTER.C *
*------------------------------------------------------------------------*
* Performs adaptive postfiltering on the synthesis speech *
* This file contains all functions related to the post filter. *
*------------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_oper_32b.h"
#include "g729_util.h"
/*---------------------------------------------------------------*
* Postfilter constant parameters (defined in "ld8a.h") *
*---------------------------------------------------------------*
* L_FRAME : Frame size. *
* L_SUBFR : Sub-frame size. *
* M : LPC order. *
* MP1 : LPC order+1 *
* PIT_MAX : Maximum pitch lag. *
* GAMMA2_PST : Formant postfiltering factor (numerator) *
* GAMMA1_PST : Formant postfiltering factor (denominator) *
* GAMMAP : Harmonic postfiltering factor *
* MU : Factor for tilt compensation filter *
* AGC_FAC : Factor for automatic gain control *
*---------------------------------------------------------------*/
/*------------------------------------------------------------*
* vectors *
*------------------------------------------------------------*/
/* inverse filtered synthesis (with A(z/GAMMA2_PST)) */
/*---------------------------------------------------------------*
* Procedure Init_Post_Filter: *
* ~~~~~~~~~~~~~~~~ *
* Initializes the postfilter parameters: *
*---------------------------------------------------------------*/
void
Init_Post_Filter (DecState *decoder)
{
decoder->res2 = decoder->res2_buf + PIT_MAX;
decoder->scal_res2 = decoder->scal_res2_buf + PIT_MAX;
Set_zero (decoder->mem_syn_pst, M10);
Set_zero (decoder->res2_buf, PIT_MAX + L_SUBFR);
Set_zero (decoder->scal_res2_buf, PIT_MAX + L_SUBFR);
decoder->mem_pre = 0;
decoder->past_gain = 4096;
return;
}
/*------------------------------------------------------------------------*
* Procedure Post_Filter: *
* ~~~~~~~~~~~ *
*------------------------------------------------------------------------*
* The postfiltering process is described as follows: *
* *
* - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[] *
* - use res2[] to compute pitch parameters *
* - perform pitch postfiltering *
* - tilt compensation filtering; 1 - MU*k*z^-1 *
* - synthesis filtering through 1/A(z/GAMMA1_PST) *
* - adaptive gain control *
*------------------------------------------------------------------------*/
void
Post_Filter (DecState *decoder,
Word16 * syn, /* in/out: synthesis speech (postfiltered is output) */
Word16 * Az_4, /* input : interpolated LPC parameters in all subframes */
Word16 * T /* input : decoded pitch lags in all subframes */
)
{
/*-------------------------------------------------------------------*
* Declaration of parameters *
*-------------------------------------------------------------------*/
Word16 res2_pst[L_SUBFR]; /* res2[] after pitch postfiltering */
Word16 syn_pst[L_FRAME]; /* post filtered synthesis speech */
Word16 Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */
Word16 *Az; /* pointer to Az_4: */
/* LPC parameters in each subframe */
Word16 t0_max, t0_min; /* closed-loop pitch search range */
Word16 i_subfr; /* index for beginning of subframe */
Word16 h[L_H];
Word16 i, j;
Word16 temp1, temp2;
Word32 L_tmp;
/*-----------------------------------------------------*
* Post filtering *
*-----------------------------------------------------*/
Az = Az_4;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
/* Find pitch range t0_min - t0_max */
t0_min = sub (*T++, 3);
t0_max = add (t0_min, 6);
if (sub (t0_max, PIT_MAX) > 0) {
t0_max = PIT_MAX;
t0_min = sub (t0_max, 6);
}
/* Find weighted filter coefficients Ap3[] and ap[4] */
Weight_Az (Az, GAMMA2_PST, M10, Ap3);
Weight_Az (Az, GAMMA1_PST, M10, Ap4);
/* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */
Residu (Ap3, &syn[i_subfr], decoder->res2, L_SUBFR);
/* scaling of "res2[]" to avoid energy overflow */
for (j = 0; j < L_SUBFR; j++) {
decoder->scal_res2[j] = shr (decoder->res2[j], 2);
}
/* pitch postfiltering */
pit_pst_filt (decoder->res2, decoder->scal_res2, t0_min, t0_max, L_SUBFR, res2_pst);
/* tilt compensation filter */
/* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */
Copy (Ap3, h, M10 + 1);
Set_zero (&h[M10 + 1], L_H - M10 - 1);
Syn_filt (Ap4, h, h, L_H, &h[M10 + 1], 0, NULL);
/* 1st correlation of h[] */
L_tmp = L_mult (h[0], h[0]);
for (i = 1; i < L_H; i++)
L_tmp = L_mac (L_tmp, h[i], h[i]);
temp1 = extract_h (L_tmp);
L_tmp = L_mult (h[0], h[1]);
for (i = 1; i < L_H - 1; i++)
L_tmp = L_mac (L_tmp, h[i], h[i + 1]);
temp2 = extract_h (L_tmp);
if (temp2 <= 0) {
temp2 = 0;
}
else {
temp2 = mult (temp2, MU);
temp2 = div_s (temp2, temp1);
}
preemphasis (decoder, res2_pst, temp2, L_SUBFR);
/* filtering through 1/A(z/GAMMA1_PST) */
Syn_filt (Ap4, res2_pst, &syn_pst[i_subfr], L_SUBFR, decoder->mem_syn_pst, 1, NULL);
/* scale output to input */
agc (decoder, &syn[i_subfr], &syn_pst[i_subfr], L_SUBFR);
/* update res2[] buffer; shift by L_SUBFR */
Copy (&decoder->res2[L_SUBFR - PIT_MAX], &decoder->res2[-PIT_MAX], PIT_MAX);
Copy (&decoder->scal_res2[L_SUBFR - PIT_MAX], &decoder->scal_res2[-PIT_MAX], PIT_MAX);
Az += MP1;
}
/* update syn[] buffer */
Copy (&syn[L_FRAME - M10], &syn[-M10], M10);
/* overwrite synthesis speech by postfiltered synthesis speech */
Copy (syn_pst, syn, L_FRAME);
return;
}
/*---------------------------------------------------------------------------*
* procedure pitch_pst_filt *
* ~~~~~~~~~~~~~~~~~~~~~~~~ *
* Find the pitch period around the transmitted pitch and perform *
* harmonic postfiltering. *
* Filtering through (1 + g z^-T) / (1+g) ; g = min(pit_gain*gammap, 1) *
*--------------------------------------------------------------------------*/
void
pit_pst_filt (Word16 * signal, /* (i) : input signal */
Word16 * scal_sig, /* (i) : input signal (scaled, divided by 4) */
Word16 t0_min, /* (i) : minimum value in the searched range */
Word16 t0_max, /* (i) : maximum value in the searched range */
Word16 L_subfr, /* (i) : size of filtering */
Word16 * signal_pst /* (o) : harmonically postfiltered signal */
)
{
Word16 i, j, t0;
Word16 g0, gain, cmax, en, en0;
Word16 *p, *p1, *deb_sig;
Word32 corr, cor_max, ener, ener0, temp;
Word32 L_temp;
/*---------------------------------------------------------------------------*
* Compute the correlations for all delays *
* and select the delay which maximizes the correlation *
*---------------------------------------------------------------------------*/
deb_sig = &scal_sig[-t0_min];
cor_max = MIN_32;
t0 = t0_min; /* Only to remove warning from some compilers */
for (i = t0_min; i <= t0_max; i++) {
corr = 0;
p = scal_sig;
p1 = deb_sig;
for (j = 0; j < L_subfr; j++)
corr = L_mac (corr, *p++, *p1++);
L_temp = L_sub (corr, cor_max);
if (L_temp > (Word32) 0) {
cor_max = corr;
t0 = i;
}
deb_sig--;
}
/* Compute the energy of the signal delayed by t0 */
ener = 1;
p = scal_sig - t0;
for (i = 0; i < L_subfr; i++, p++)
ener = L_mac (ener, *p, *p);
/* Compute the signal energy in the present subframe */
ener0 = 1;
p = scal_sig;
for (i = 0; i < L_subfr; i++, p++)
ener0 = L_mac (ener0, *p, *p);
if (cor_max < 0) {
cor_max = 0;
}
/* scale "cor_max", "ener" and "ener0" on 16 bits */
temp = cor_max;
if (ener > temp) {
temp = ener;
}
if (ener0 > temp) {
temp = ener0;
}
j = norm_l (temp);
cmax = wround (L_shl (cor_max, j));
en = wround (L_shl (ener, j));
en0 = wround (L_shl (ener0, j));
/* prediction gain (dB)= -10 log(1-cor_max*cor_max/(ener*ener0)) */
/* temp = (cor_max * cor_max) - (0.5 * ener * ener0) */
temp = L_mult (cmax, cmax);
temp = L_sub (temp, L_shr (L_mult (en, en0), 1));
if (temp < (Word32) 0) { /* if prediction gain < 3 dB *//* switch off pitch postfilter */
for (i = 0; i < L_subfr; i++)
signal_pst[i] = signal[i];
return;
}
if (sub (cmax, en) > 0) { /* if pitch gain > 1 */
g0 = INV_GAMMAP;
gain = GAMMAP_2;
}
else {
cmax = shr (mult (cmax, GAMMAP), 1); /* cmax(Q14) = cmax(Q15) * GAMMAP */
en = shr (en, 1); /* Q14 */
i = add (cmax, en);
if (i > 0) {
gain = div_s (cmax, i); /* gain(Q15) = cor_max/(cor_max+ener) */
g0 = sub (32767, gain); /* g0(Q15) = 1 - gain */
}
else {
g0 = 32767;
gain = 0;
}
}
for (i = 0; i < L_subfr; i++) {
/* signal_pst[i] = g0*signal[i] + gain*signal[i-t0]; */
signal_pst[i] = add (mult (g0, signal[i]), mult (gain, signal[i - t0]));
}
return;
}
/*---------------------------------------------------------------------*
* routine preemphasis() *
* ~~~~~~~~~~~~~~~~~~~~~ *
* Preemphasis: filtering through 1 - g z^-1 *
*---------------------------------------------------------------------*/
void
preemphasis (DecState *decoder,
Word16 * signal, /* (i/o) : input signal overwritten by the output */
Word16 g, /* (i) Q15 : preemphasis coefficient */
Word16 L /* (i) : size of filtering */
)
{
Word16 *p1, *p2, temp, i;
p1 = signal + L - 1;
p2 = p1 - 1;
temp = *p1;
for (i = 0; i <= L - 2; i++) {
*p1 = sub (*p1, mult (g, *p2)); p1--; p2--;
}
*p1 = sub (*p1, mult (g, decoder->mem_pre));
decoder->mem_pre = temp;
return;
}
/*----------------------------------------------------------------------*
* routine agc() *
* ~~~~~~~~~~~~~ *
* Scale the postfilter output on a subframe basis by automatic control *
* of the subframe gain. *
* gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out *
*----------------------------------------------------------------------*/
void
agc (DecState *decoder,
Word16 * sig_in, /* (i) : postfilter input signal */
Word16 * sig_out, /* (i/o) : postfilter output signal */
Word16 l_trm /* (i) : subframe size */
)
{
Word16 i, exp;
Word16 gain_in, gain_out, g0, gain; /* Q12 */
Word32 s;
Word16 signal[L_SUBFR];
/* calculate gain_out with exponent */
for (i = 0; i < l_trm; i++)
signal[i] = shr (sig_out[i], 2);
s = 0;
for (i = 0; i < l_trm; i++)
s = L_mac (s, signal[i], signal[i]);
if (s == 0) {
decoder->past_gain = 0;
return;
}
exp = sub (norm_l (s), 1);
gain_out = wround (L_shl (s, exp));
/* calculate gain_in with exponent */
for (i = 0; i < l_trm; i++)
signal[i] = shr (sig_in[i], 2);
s = 0;
for (i = 0; i < l_trm; i++)
s = L_mac (s, signal[i], signal[i]);
if (s == 0) {
g0 = 0;
}
else {
i = norm_l (s);
gain_in = wround (L_shl (s, i));
exp = sub (exp, i);
/*---------------------------------------------------*
* g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out); *
*---------------------------------------------------*/
s = L_deposit_l (div_s (gain_out, gain_in)); /* Q15 */
s = L_shl (s, 7); /* s(Q22) = gain_out / gain_in */
s = L_shr (s, exp); /* Q22, add exponent */
/* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */
s = Inv_sqrt (s); /* Q19 */
i = wround (L_shl (s, 9)); /* Q12 */
/* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */
g0 = mult (i, AGC_FAC1); /* Q12 */
}
/* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
/* sig_out(n) = gain(n) sig_out(n) */
gain = decoder->past_gain;
for (i = 0; i < l_trm; i++) {
gain = mult (gain, AGC_FAC);
gain = add (gain, g0);
sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3));
}
decoder->past_gain = gain;
return;
}

View File

@@ -0,0 +1,85 @@
/*
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 Pre_Process() *
* *
* Preprocessing of input speech. *
* - 2nd order high pass filter with cut off frequency at 140 Hz. *
* - Divide input by two. *
*-----------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
/*------------------------------------------------------------------------*
* 2nd order high pass filter with cut off frequency at 140 Hz. *
* Designed with SPPACK efi command -40 dB att, 0.25 ri. *
* *
* Algorithm: *
* *
* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2 *
* + a[1]*y[i-1] + a[2]*y[i-2]; *
* *
* b[3] = {0.92727435E+00, -0.18544941E+01, 0.92727435E+00}; *
* a[3] = {0.10000000E+01, 0.19059465E+01, -0.91140240E+00}; *
* *
* Input are divided by two in the filtering process. *
*-----------------------------------------------------------------------*/
/* Initialization of values */
void Init_Pre_Process (CodState *coder)
{
coder->y2_hi = 0;
coder->y2_lo = 0;
coder->y1_hi = 0;
coder->y1_lo = 0;
coder->x0 = 0;
coder->x1 = 0;
}
void
Pre_Process (CodState *coder,
Word16 signal[], /* input/output signal */
Word16 lg)
{ /* length of signal */
Word16 i, x2;
Word32 L_tmp;
for (i = 0; i < lg; i++) {
x2 = coder->x1;
coder->x1 = coder->x0;
coder->x0 = signal[i];
/* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */
/* + a[1]*y[i-1] + a[2] * y[i-2]; */
L_tmp = Mpy_32_16 (coder->y1_hi, coder->y1_lo, a140[1]);
L_tmp = L_add (L_tmp, Mpy_32_16 (coder->y2_hi, coder->y2_lo, a140[2]));
L_tmp = L_mac (L_tmp, coder->x0, b140[0]);
L_tmp = L_mac (L_tmp, coder->x1, b140[1]);
L_tmp = L_mac (L_tmp, x2, b140[2]);
L_tmp = L_shl (L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */
signal[i] = wround (L_tmp);
coder->y2_hi = coder->y1_hi;
coder->y2_lo = coder->y1_lo;
L_Extract (L_tmp, &coder->y1_hi, &coder->y1_lo);
}
return;
}

View File

@@ -0,0 +1,19 @@
/*
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.
*/
#ifndef _G729_PRE_PROC_H
#define _G729_PRE_PROC_H
extern void Init_Pre_Process (CodState *coder);
extern void Pre_Process (CodState *coder,
Word16 signal[], /* Input/output signal */
Word16 lg /* Length of signal */ );
#endif

View File

@@ -0,0 +1,61 @@
/*
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 Pred_lt_3() *
* ~~~~~~~~~~~ *
*-------------------------------------------------------------------*
* Compute the result of long term prediction with fractional *
* interpolation of resolution 1/3. *
* *
* On return exc[0..L_subfr-1] contains the interpolated signal *
* (adaptive codebook excitation) *
*-------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
void
Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */
Word16 T0, /* input : integer pitch lag */
Word16 frac, /* input : fraction of lag */
Word16 L_subfr /* input : subframe size */
)
{
Word16 i, j, k;
Word16 *x0, *x1, *x2, *c1, *c2;
Word32 s;
x0 = &exc[-T0];
frac = negate (frac);
if (frac < 0) {
frac = add (frac, UP_SAMP);
x0--;
}
for (j = 0; j < L_subfr; j++) {
x1 = x0++;
x2 = x0;
c1 = &inter_3l[frac];
c2 = &inter_3l[sub (UP_SAMP, frac)];
s = 0;
for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP) {
s = L_mac (s, x1[-i], c1[k]);
s = L_mac (s, x2[i], c2[k]);
}
exc[j] = wround (s);
}
return;
}

View File

@@ -0,0 +1,786 @@
/*
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.
*/
/* This file contains all the tables used by the G.729A codec */
#include "g729_typedef.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
/* Hamming_cos window for LPC analysis. */
/* Create with function ham_cos(window,200,40) */
Word16 hamwindow[L_WINDOW] = {
2621, 2623, 2629, 2638, 2651, 2668, 2689, 2713, 2741, 2772,
2808, 2847, 2890, 2936, 2986, 3040, 3097, 3158, 3223, 3291,
3363, 3438, 3517, 3599, 3685, 3774, 3867, 3963, 4063, 4166,
4272, 4382, 4495, 4611, 4731, 4853, 4979, 5108, 5240, 5376,
5514, 5655, 5800, 5947, 6097, 6250, 6406, 6565, 6726, 6890,
7057, 7227, 7399, 7573, 7750, 7930, 8112, 8296, 8483, 8672,
8863, 9057, 9252, 9450, 9650, 9852, 10055, 10261, 10468, 10677,
10888, 11101, 11315, 11531, 11748, 11967, 12187, 12409, 12632, 12856,
13082, 13308, 13536, 13764, 13994, 14225, 14456, 14688, 14921, 15155,
15389, 15624, 15859, 16095, 16331, 16568, 16805, 17042, 17279, 17516,
17754, 17991, 18228, 18465, 18702, 18939, 19175, 19411, 19647, 19882,
20117, 20350, 20584, 20816, 21048, 21279, 21509, 21738, 21967, 22194,
22420, 22644, 22868, 23090, 23311, 23531, 23749, 23965, 24181, 24394,
24606, 24816, 25024, 25231, 25435, 25638, 25839, 26037, 26234, 26428,
26621, 26811, 26999, 27184, 27368, 27548, 27727, 27903, 28076, 28247,
28415, 28581, 28743, 28903, 29061, 29215, 29367, 29515, 29661, 29804,
29944, 30081, 30214, 30345, 30472, 30597, 30718, 30836, 30950, 31062,
31170, 31274, 31376, 31474, 31568, 31659, 31747, 31831, 31911, 31988,
32062, 32132, 32198, 32261, 32320, 32376, 32428, 32476, 32521, 32561,
32599, 32632, 32662, 32688, 32711, 32729, 32744, 32755, 32763, 32767,
32767, 32741, 32665, 32537, 32359, 32129, 31850, 31521, 31143, 30716,
30242, 29720, 29151, 28538, 27879, 27177, 26433, 25647, 24821, 23957,
23055, 22117, 21145, 20139, 19102, 18036, 16941, 15820, 14674, 13505,
12315, 11106, 9879, 8637, 7381, 6114, 4838, 3554, 2264, 971
};
/*-----------------------------------------------------*
| Table of lag_window for autocorrelation. |
| noise floor = 1.0001 = (0.9999 on r[1] ..r[10]) |
| Bandwidth expansion = 60 Hz |
| |
| Special double precision format. See "oper_32b.c" |
| |
| lag_wind[0] = 1.00000000 (not stored) |
| lag_wind[1] = 0.99879038 |
| lag_wind[2] = 0.99546897 |
| lag_wind[3] = 0.98995781 |
| lag_wind[4] = 0.98229337 |
| lag_wind[5] = 0.97252619 |
| lag_wind[6] = 0.96072036 |
| lag_wind[7] = 0.94695264 |
| lag_wind[8] = 0.93131179 |
| lag_wind[9] = 0.91389757 |
| lag_wind[10]= 0.89481968 |
-----------------------------------------------------*/
Word16 lag_h[M10] = {
32728,
32619,
32438,
32187,
31867,
31480,
31029,
30517,
29946,
29321
};
Word16 lag_l[M10] = {
11904,
17280,
30720,
25856,
24192,
28992,
24384,
7360,
19520,
14784
};
/*-----------------------------------------------------*
| Tables for function Lsf_lsp() and Lsp_lsf() |
-----------------------------------------------------*/
/* table of cos(x) in Q15 */
Word16 table[65] = {
32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
-12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
-23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
-30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729,
-32768L
};
/* slope in Q12 used to compute y = acos(x) */
Word16 slope[64] = {
-26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811,
-1608, -1450, -1322, -1219, -1132, -1059, -998, -946,
-901, -861, -827, -797, -772, -750, -730, -713,
-699, -687, -677, -668, -662, -657, -654, -652,
-652, -654, -657, -662, -668, -677, -687, -699,
-713, -730, -750, -772, -797, -827, -861, -901,
-946, -998, -1059, -1132, -1219, -1322, -1450, -1608,
-1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887
};
/*-----------------------------------------------------*
| Tables for function Lsf_lsp() and Lsp_lsf() |
-----------------------------------------------------*/
/* table of cos(x) in Q15 */
Word16 table2[64] = {
32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
-12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
-23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
-30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729
};
/* slope in Q19 used to compute y = cos(x) */
Word16 slope_cos[64] = {
-632, -1893, -3150, -4399, -5638, -6863, -8072, -9261,
-10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744,
-18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526,
-24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726,
-25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009,
-23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637,
-17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428,
-9261, -8072, -6863, -5638, -4399, -3150, -1893, -632
};
/* slope in Q12 used to compute y = acos(x) */
Word16 slope_acos[64] = {
-26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811,
-1608, -1450, -1322, -1219, -1132, -1059, -998, -946,
-901, -861, -827, -797, -772, -750, -730, -713,
-699, -687, -677, -668, -662, -657, -654, -652,
-652, -654, -657, -662, -668, -677, -687, -699,
-713, -730, -750, -772, -797, -827, -861, -901,
-946, -998, -1059, -1132, -1219, -1322, -1450, -1608,
-1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887
};
/* lsp code book <../f7s55m1.v2> */
Word16 lspcb1[NC0][M10] = { /* Q13 */
{1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190, 21820}
,
{1730, 2640, 3450, 4870, 6126, 7876, 15644, 17817, 20294, 21902}
,
{1568, 2256, 3088, 4874, 11063, 13393, 18307, 19293, 21109, 21741}
,
{1733, 2512, 3357, 4708, 6977, 10296, 17024, 17956, 19145, 20350}
,
{1744, 2436, 3308, 8731, 10432, 12007, 15614, 16639, 21359, 21913}
,
{1786, 2369, 3372, 4521, 6795, 12963, 17674, 18988, 20855, 21640}
,
{1631, 2433, 3361, 6328, 10709, 12013, 13277, 13904, 19441, 21088}
,
{1489, 2364, 3291, 6250, 9227, 10403, 13843, 15278, 17721, 21451}
,
{1869, 2533, 3475, 4365, 9152, 14513, 15908, 17022, 20611, 21411}
,
{2070, 3025, 4333, 5854, 7805, 9231, 10597, 16047, 20109, 21834}
,
{1910, 2673, 3419, 4261, 11168, 15111, 16577, 17591, 19310, 20265}
,
{1141, 1815, 2624, 4623, 6495, 9588, 13968, 16428, 19351, 21286}
,
{2192, 3171, 4707, 5808, 10904, 12500, 14162, 15664, 21124, 21789}
,
{1286, 1907, 2548, 3453, 9574, 11964, 15978, 17344, 19691, 22495}
,
{1921, 2720, 4604, 6684, 11503, 12992, 14350, 15262, 16997, 20791}
,
{2052, 2759, 3897, 5246, 6638, 10267, 15834, 16814, 18149, 21675}
,
{1798, 2497, 5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182}
,
{1009, 1647, 2889, 5709, 9541, 12354, 15231, 18494, 20966, 22033}
,
{3016, 3794, 5406, 7469, 12488, 13984, 15328, 16334, 19952, 20791}
,
{2203, 3040, 3796, 5442, 11987, 13512, 14931, 16370, 17856, 18803}
,
{2912, 4292, 7988, 9572, 11562, 13244, 14556, 16529, 20004, 21073}
,
{2861, 3607, 5923, 7034, 9234, 12054, 13729, 18056, 20262, 20974}
,
{3069, 4311, 5967, 7367, 11482, 12699, 14309, 16233, 18333, 19172}
,
{2434, 3661, 4866, 5798, 10383, 11722, 13049, 15668, 18862, 19831}
,
{2020, 2605, 3860, 9241, 13275, 14644, 16010, 17099, 19268, 20251}
,
{1877, 2809, 3590, 4707, 11056, 12441, 15622, 17168, 18761, 19907}
,
{2107, 2873, 3673, 5799, 13579, 14687, 15938, 17077, 18890, 19831}
,
{1612, 2284, 2944, 3572, 8219, 13959, 15924, 17239, 18592, 20117}
,
{2420, 3156, 6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880}
,
{1667, 2612, 3534, 5237, 10513, 11696, 12940, 16798, 18058, 19378}
,
{2388, 3017, 4839, 9333, 11413, 12730, 15024, 16248, 17449, 18677}
,
{1875, 2786, 4231, 6320, 8694, 10149, 11785, 17013, 18608, 19960}
,
{679, 1411, 4654, 8006, 11446, 13249, 15763, 18127, 20361, 21567}
,
{1838, 2596, 3578, 4608, 5650, 11274, 14355, 15886, 20579, 21754}
,
{1303, 1955, 2395, 3322, 12023, 13764, 15883, 18077, 20180, 21232}
,
{1438, 2102, 2663, 3462, 8328, 10362, 13763, 17248, 19732, 22344}
,
{860, 1904, 6098, 7775, 9815, 12007, 14821, 16709, 19787, 21132}
,
{1673, 2723, 3704, 6125, 7668, 9447, 13683, 14443, 20538, 21731}
,
{1246, 1849, 2902, 4508, 7221, 12710, 14835, 16314, 19335, 22720}
,
{1525, 2260, 3862, 5659, 7342, 11748, 13370, 14442, 18044, 21334}
,
{1196, 1846, 3104, 7063, 10972, 12905, 14814, 17037, 19922, 22636}
,
{2147, 3106, 4475, 6511, 8227, 9765, 10984, 12161, 18971, 21300}
,
{1585, 2405, 2994, 4036, 11481, 13177, 14519, 15431, 19967, 21275}
,
{1778, 2688, 3614, 4680, 9465, 11064, 12473, 16320, 19742, 20800}
,
{1862, 2586, 3492, 6719, 11708, 13012, 14364, 16128, 19610, 20425}
,
{1395, 2156, 2669, 3386, 10607, 12125, 13614, 16705, 18976, 21367}
,
{1444, 2117, 3286, 6233, 9423, 12981, 14998, 15853, 17188, 21857}
,
{2004, 2895, 3783, 4897, 6168, 7297, 12609, 16445, 19297, 21465}
,
{1495, 2863, 6360, 8100, 11399, 14271, 15902, 17711, 20479, 22061}
,
{2484, 3114, 5718, 7097, 8400, 12616, 14073, 14847, 20535, 21396}
,
{2424, 3277, 5296, 6284, 11290, 12903, 16022, 17508, 19333, 20283}
,
{2565, 3778, 5360, 6989, 8782, 10428, 14390, 15742, 17770, 21734}
,
{2727, 3384, 6613, 9254, 10542, 12236, 14651, 15687, 20074, 21102}
,
{1916, 2953, 6274, 8088, 9710, 10925, 12392, 16434, 20010, 21183}
,
{3384, 4366, 5349, 7667, 11180, 12605, 13921, 15324, 19901, 20754}
,
{3075, 4283, 5951, 7619, 9604, 11010, 12384, 14006, 20658, 21497}
,
{1751, 2455, 5147, 9966, 11621, 13176, 14739, 16470, 20788, 21756}
,
{1442, 2188, 3330, 6813, 8929, 12135, 14476, 15306, 19635, 20544}
,
{2294, 2895, 4070, 8035, 12233, 13416, 14762, 17367, 18952, 19688}
,
{1937, 2659, 4602, 6697, 9071, 12863, 14197, 15230, 16047, 18877}
,
{2071, 2663, 4216, 9445, 10887, 12292, 13949, 14909, 19236, 20341}
,
{1740, 2491, 3488, 8138, 9656, 11153, 13206, 14688, 20896, 21907}
,
{2199, 2881, 4675, 8527, 10051, 11408, 14435, 15463, 17190, 20597}
,
{1943, 2988, 4177, 6039, 7478, 8536, 14181, 15551, 17622, 21579}
,
{1825, 3175, 7062, 9818, 12824, 15450, 18330, 19856, 21830, 22412}
,
{2464, 3046, 4822, 5977, 7696, 15398, 16730, 17646, 20588, 21320}
,
{2550, 3393, 5305, 6920, 10235, 14083, 18143, 19195, 20681, 21336}
,
{3003, 3799, 5321, 6437, 7919, 11643, 15810, 16846, 18119, 18980}
,
{3455, 4157, 6838, 8199, 9877, 12314, 15905, 16826, 19949, 20892}
,
{3052, 3769, 4891, 5810, 6977, 10126, 14788, 15990, 19773, 20904}
,
{3671, 4356, 5827, 6997, 8460, 12084, 14154, 14939, 19247, 20423}
,
{2716, 3684, 5246, 6686, 8463, 10001, 12394, 14131, 16150, 19776}
,
{1945, 2638, 4130, 7995, 14338, 15576, 17057, 18206, 20225, 20997}
,
{2304, 2928, 4122, 4824, 5640, 13139, 15825, 16938, 20108, 21054}
,
{1800, 2516, 3350, 5219, 13406, 15948, 17618, 18540, 20531, 21252}
,
{1436, 2224, 2753, 4546, 9657, 11245, 15177, 16317, 17489, 19135}
,
{2319, 2899, 4980, 6936, 8404, 13489, 15554, 16281, 20270, 20911}
,
{2187, 2919, 4610, 5875, 7390, 12556, 14033, 16794, 20998, 21769}
,
{2235, 2923, 5121, 6259, 8099, 13589, 15340, 16340, 17927, 20159}
,
{1765, 2638, 3751, 5730, 7883, 10108, 13633, 15419, 16808, 18574}
,
{3460, 5741, 9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601}
,
{3735, 4426, 6199, 7363, 9250, 14489, 16035, 17026, 19873, 20876}
,
{3521, 4778, 6887, 8680, 12717, 14322, 15950, 18050, 20166, 21145}
,
{2141, 2968, 6865, 8051, 10010, 13159, 14813, 15861, 17528, 18655}
,
{4148, 6128, 9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595}
,
{4403, 5367, 6634, 8371, 10163, 11599, 14963, 16331, 17982, 18768}
,
{4091, 5386, 6852, 8770, 11563, 13290, 15728, 16930, 19056, 20102}
,
{2746, 3625, 5299, 7504, 10262, 11432, 13172, 15490, 16875, 17514}
,
{2248, 3556, 8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247}
,
{1279, 1960, 3920, 7793, 10153, 14753, 16646, 18139, 20679, 21466}
,
{2440, 3475, 6737, 8654, 12190, 14588, 17119, 17925, 19110, 19979}
,
{1879, 2514, 4497, 7572, 10017, 14948, 16141, 16897, 18397, 19376}
,
{2804, 3688, 7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126}
,
{2023, 2682, 3873, 8268, 10255, 11645, 15187, 17102, 18965, 19788}
,
{2823, 3605, 5815, 8595, 10085, 11469, 16568, 17462, 18754, 19876}
,
{2851, 3681, 5280, 7648, 9173, 10338, 14961, 16148, 17559, 18474}
,
{1348, 2645, 5826, 8785, 10620, 12831, 16255, 18319, 21133, 22586}
,
{2141, 3036, 4293, 6082, 7593, 10629, 17158, 18033, 21466, 22084}
,
{1608, 2375, 3384, 6878, 9970, 11227, 16928, 17650, 20185, 21120}
,
{2774, 3616, 5014, 6557, 7788, 8959, 17068, 18302, 19537, 20542}
,
{1934, 4813, 6204, 7212, 8979, 11665, 15989, 17811, 20426, 21703}
,
{2288, 3507, 5037, 6841, 8278, 9638, 15066, 16481, 21653, 22214}
,
{2951, 3771, 4878, 7578, 9016, 10298, 14490, 15242, 20223, 20990}
,
{3256, 4791, 6601, 7521, 8644, 9707, 13398, 16078, 19102, 20249}
,
{1827, 2614, 3486, 6039, 12149, 13823, 16191, 17282, 21423, 22041}
,
{1000, 1704, 3002, 6335, 8471, 10500, 14878, 16979, 20026, 22427}
,
{1646, 2286, 3109, 7245, 11493, 12791, 16824, 17667, 18981, 20222}
,
{1708, 2501, 3315, 6737, 8729, 9924, 16089, 17097, 18374, 19917}
,
{2623, 3510, 4478, 5645, 9862, 11115, 15219, 18067, 19583, 20382}
,
{2518, 3434, 4728, 6388, 8082, 9285, 13162, 18383, 19819, 20552}
,
{1726, 2383, 4090, 6303, 7805, 12845, 14612, 17608, 19269, 20181}
,
{2860, 3735, 4838, 6044, 7254, 8402, 14031, 16381, 18037, 19410}
,
{4247, 5993, 7952, 9792, 12342, 14653, 17527, 18774, 20831, 21699}
,
{3502, 4051, 5680, 6805, 8146, 11945, 16649, 17444, 20390, 21564}
,
{3151, 4893, 5899, 7198, 11418, 13073, 15124, 17673, 20520, 21861}
,
{3960, 4848, 5926, 7259, 8811, 10529, 15661, 16560, 18196, 20183}
,
{4499, 6604, 8036, 9251, 10804, 12627, 15880, 17512, 20020, 21046}
,
{4251, 5541, 6654, 8318, 9900, 11686, 15100, 17093, 20572, 21687}
,
{3769, 5327, 7865, 9360, 10684, 11818, 13660, 15366, 18733, 19882}
,
{3083, 3969, 6248, 8121, 9798, 10994, 12393, 13686, 17888, 19105}
,
{2731, 4670, 7063, 9201, 11346, 13735, 16875, 18797, 20787, 22360}
,
{1187, 2227, 4737, 7214, 9622, 12633, 15404, 17968, 20262, 23533}
,
{1911, 2477, 3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729}
,
{1764, 2519, 3887, 6944, 9150, 12590, 16258, 16984, 17924, 18435}
,
{1400, 3674, 7131, 8718, 10688, 12508, 15708, 17711, 19720, 21068}
,
{2322, 3073, 4287, 8108, 9407, 10628, 15862, 16693, 19714, 21474}
,
{2630, 3339, 4758, 8360, 10274, 11333, 12880, 17374, 19221, 19936}
,
{1721, 2577, 5553, 7195, 8651, 10686, 15069, 16953, 18703, 19929}
};
Word16 lspcb2[NC1][M10] = { /* Q13 */
{-435, -815, -742, 1033, -518, 582, -1201, 829, 86, 385}
,
{-833, -891, 463, -8, -1251, 1450, 72, -231, 864, 661}
,
{-1021, 231, -306, 321, -220, -163, -526, -754, -1633, 267}
,
{57, -198, -339, -33, -1468, 573, 796, -169, -631, 816}
,
{171, -350, 294, 1660, 453, 519, 291, 159, -640, -1296}
,
{-701, -842, -58, 950, 892, 1549, 715, 527, -714, -193}
,
{584, 31, -289, 356, -333, -457, 612, -283, -1381, -741}
,
{-109, -808, 231, 77, -87, -344, 1341, 1087, -654, -569}
,
{-859, 1236, 550, 854, 714, -543, -1752, -195, -98, -276}
,
{-877, -954, -1248, -299, 212, -235, -728, 949, 1517, 895}
,
{-77, 344, -620, 763, 413, 502, -362, -960, -483, 1386}
,
{-314, -307, -256, -1260, -429, 450, -466, -108, 1010, 2223}
,
{711, 693, 521, 650, 1305, -28, -378, 744, -1005, 240}
,
{-112, -271, -500, 946, 1733, 271, -15, 909, -259, 1688}
,
{575, -10, -468, -199, 1101, -1011, 581, -53, -747, 878}
,
{145, -285, -1280, -398, 36, -498, -1377, 18, -444, 1483}
,
{-1133, -835, 1350, 1284, -95, 1015, -222, 443, 372, -354}
,
{-1459, -1237, 416, -213, 466, 669, 659, 1640, 932, 534}
,
{-15, 66, 468, 1019, -748, 1385, -182, -907, -721, -262}
,
{-338, 148, 1445, 75, -760, 569, 1247, 337, 416, -121}
,
{389, 239, 1568, 981, 113, 369, -1003, -507, -587, -904}
,
{-312, -98, 949, 31, 1104, 72, -141, 1465, 63, -785}
,
{1127, 584, 835, 277, -1159, 208, 301, -882, 117, -404}
,
{539, -114, 856, -493, 223, -912, 623, -76, 276, -440}
,
{2197, 2337, 1268, 670, 304, -267, -525, 140, 882, -139}
,
{-1596, 550, 801, -456, -56, -697, 865, 1060, 413, 446}
,
{1154, 593, -77, 1237, -31, 581, -1037, -895, 669, 297}
,
{397, 558, 203, -797, -919, 3, 692, -292, 1050, 782}
,
{334, 1475, 632, -80, 48, -1061, -484, 362, -597, -852}
,
{-545, -330, -429, -680, 1133, -1182, -744, 1340, 262, 63}
,
{1320, 827, -398, -576, 341, -774, -483, -1247, -70, 98}
,
{-163, 674, -11, -886, 531, -1125, -265, -242, 724, 934}
};
Word16 fg[2][MA_NP][M10] = { /* Q15 */
{
{8421, 9109, 9175, 8965, 9034, 9057, 8765, 8775, 9106, 8673}
,
{7018, 7189, 7638, 7307, 7444, 7379, 7038, 6956, 6930, 6868}
,
{5472, 4990, 5134, 5177, 5246, 5141, 5206, 5095, 4830, 5147}
,
{4056, 3031, 2614, 3024, 2916, 2713, 3309, 3237, 2857, 3473}
}
,
{
{7733, 7880, 8188, 8175, 8247, 8490, 8637, 8601, 8359, 7569}
,
{4210, 3031, 2552, 3473, 3876, 3853, 4184, 4154, 3909, 3968}
,
{3214, 1930, 1313, 2143, 2493, 2385, 2755, 2706, 2542, 2919}
,
{3024, 1592, 940, 1631, 1723, 1579, 2034, 2084, 1913, 2601}
}
};
Word16 fg_sum[2][M10] = { /* Q15 */
{7798, 8447, 8205, 8293, 8126, 8477, 8447, 8703, 9043, 8604}
,
{14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708}
};
Word16 fg_sum_inv[2][M10] = { /* Q12 */
{17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597}
,
{9202, 7320, 6788, 7738, 8170, 8154, 8856, 8818, 8366, 8544}
};
/*-------------------------------------------------------------*
* Table for az_lsf() *
* *
* Vector grid[] is in Q15 *
* *
* grid[0] = 1.0; *
* grid[grid_points+1] = -1.0; *
* for (i = 1; i < grid_points; i++) *
* grid[i] = cos((6.283185307*i)/(2.0*grid_points)); *
* *
*-------------------------------------------------------------*/
/* Version 51 points */
Word16 grid[GRID_POINTS + 1] = {
32760, 32703, 32509, 32187, 31738, 31164,
30466, 29649, 28714, 27666, 26509, 25248,
23886, 22431, 20887, 19260, 17557, 15786,
13951, 12062, 10125, 8149, 6140, 4106,
2057, 0, -2057, -4106, -6140, -8149,
-10125, -12062, -13951, -15786, -17557, -19260,
-20887, -22431, -23886, -25248, -26509, -27666,
-28714, -29649, -30466, -31164, -31738, -32187,
-32509, -32703, -32760
};
/*-----------------------------------------------------*
| Tables for pitch related routines . |
-----------------------------------------------------*/
/* 1/3 resolution interpolation filter (-3 dB at 3600 Hz) in Q15 */
Word16 inter_3l[FIR_SIZE_SYN] = {
29443,
25207, 14701, 3143,
-4402, -5850, -2783,
1211, 3130, 2259,
0, -1652, -1666,
-464, 756, 1099,
550, -245, -634,
-451, 0, 308,
296, 78, -120,
-165, -79, 34,
91, 70, 0
};
/*Coefficients in floating point
0.898517,
0.769271, 0.448635, 0.095915,
-0.134333, -0.178528, -0.084919,
0.036952, 0.095533, 0.068936,
-0.000000, -0.050404, -0.050835,
-0.014169, 0.023083, 0.033543,
0.016774, -0.007466, -0.019340,
-0.013755, 0.000000, 0.009400,
0.009029, 0.002381, -0.003658,
-0.005027, -0.002405, 0.001050,
0.002780, 0.002145, 0.000000};
*/
/*-----------------------------------------------------*
| Tables for gain related routines . |
-----------------------------------------------------*/
/* MA gain prediction coeff ={0.68, 0.58, 0.34, 0.19} in Q13 */
Word16 g729_pred[4] = { 5571, 4751, 2785, 1556 };
Word16 gbk1[NCODE1][2] = {
/* Q14 Q13 */
{1, 1516}
,
{1551, 2425}
,
{1831, 5022}
,
{57, 5404}
,
{1921, 9291}
,
{3242, 9949}
,
{356, 14756}
,
{2678, 27162}
};
Word16 gbk2[NCODE2][2] = {
/* Q14 Q13 */
{826, 2005}
,
{1994, 0}
,
{5142, 592}
,
{6160, 2395}
,
{8091, 4861}
,
{9120, 525}
,
{10573, 2966}
,
{11569, 1196}
,
{13260, 3256}
,
{14194, 1630}
,
{15132, 4914}
,
{15161, 14276}
,
{15434, 237}
,
{16112, 3392}
,
{17299, 1861}
,
{18973, 5935}
};
Word16 map1[NCODE1] = {
5, 1, 4, 7, 3, 0, 6, 2
};
Word16 map2[NCODE2] = {
4, 6, 0, 2, 12, 14, 8, 10, 15, 11, 9, 13, 7, 3, 1, 5
};
/* [0][0] [0][1] [1][0] [1][1] */
/* Q10 Q14 Q16 Q19 */
Word16 coef[2][2] = {
{31881, 26416}
,
{31548, 27816}
};
/* [0][0] [0][1] [1][0] [1][1] */
/* Q26 Q30 Q32 Q35 */
Word32 L_coef[2][2] = {
{2089405952L, 1731217536L}
,
{2067549984L, 1822990272L}
};
Word16 thr1[NCODE1 - NCAN1] = { /* Q14 */
10808,
12374,
19778,
32567
};
Word16 thr2[NCODE2 - NCAN2] = { /* Q15 */
14087,
16188,
20274,
21321,
23525,
25232,
27873,
30542
};
Word16 imap1[NCODE1] = {
5, 1, 7, 4, 2, 0, 6, 3
};
Word16 imap2[NCODE2] = {
2, 14, 3, 13, 0, 15, 1, 12, 6, 10, 7, 9, 4, 11, 5, 8
};
/*-----------------------------------------------------*
| Tables for routines post_pro() & pre_proc(). |
-----------------------------------------------------*/
/* filter coefficients (fc = 100 Hz) */
Word16 b100[3] = { 7699, -15398, 7699 }; /* Q13 */
Word16 a100[3] = { 8192, 15836, -7667 }; /* Q13 */
/* filter coefficients (fc = 140 Hz, coeff. b[] is divided by 2) */
Word16 b140[3] = { 1899, -3798, 1899 }; /* 1/2 in Q12 */
Word16 a140[3] = { 4096, 7807, -3733 }; /* Q12 */
/*-----------------------------------------------------*
| Tables for routine bits(). |
-----------------------------------------------------*/
Word16 bitsno[PRM_SIZE] = { 1 + NC0_B, /* MA + 1st stage */
NC1_B * 2, /* 2nd stage */
8, 1, 13, 4, 7, /* first subframe */
5, 13, 4, 7
}; /* second subframe */
/*-----------------------------------------------------*
| Table for routine Pow2(). |
-----------------------------------------------------*/
Word16 tabpow[33] = {
16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
31379, 32066, 32767
};
/*-----------------------------------------------------*
| Table for routine Log2(). |
-----------------------------------------------------*/
Word16 tablog[33] = {
0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716,
12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033,
22951, 23852, 24735, 25603, 26455, 27291, 28113, 28922, 29716, 30497,
31266, 32023, 32767
};
/*-----------------------------------------------------*
| Table for routine Inv_sqrt(). |
-----------------------------------------------------*/
Word16 tabsqr[49] = {
32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155,
21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539,
19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674,
17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384
};
/*-----------------------------------------------------*
| Table for taming procedure test_err. |
-----------------------------------------------------*/
Word16 tab_zone[PIT_MAX + L_INTERPOL - 1] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
Word16 lsp_old_init[M10] =
{
30000, 26000, 21000, 15000, 8000, 0, -8000, -15000, -21000, -26000
};
Word16 freq_prev_reset[M10] = { /* Q13:previous LSP vector(init) */
2339, 4679, 7018, 9358, 11698, 14037, 16377, 18717, 21056, 23396
}; /* PI*(float)(j+1)/(float)(M+1) */
Word16 past_qua_en_init [4] = { -14336, -14336, -14336, -14336 };

View File

@@ -0,0 +1,48 @@
/*
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.
*/
extern Word16 hamwindow[L_WINDOW];
extern Word16 lag_h[M10];
extern Word16 lag_l[M10];
extern Word16 table[65];
extern Word16 slope[64];
extern Word16 table2[64];
extern Word16 slope_cos[64];
extern Word16 slope_acos[64];
extern Word16 lspcb1[NC0][M10];
extern Word16 lspcb2[NC1][M10];
extern Word16 fg[2][MA_NP][M10];
extern Word16 fg_sum[2][M10];
extern Word16 fg_sum_inv[2][M10];
extern Word16 grid[GRID_POINTS + 1];
extern Word16 inter_3l[FIR_SIZE_SYN];
extern Word16 g729_pred[4];
extern Word16 gbk1[NCODE1][2];
extern Word16 gbk2[NCODE2][2];
extern Word16 map1[NCODE1];
extern Word16 map2[NCODE2];
extern Word16 coef[2][2];
extern Word32 L_coef[2][2];
extern Word16 thr1[NCODE1 - NCAN1];
extern Word16 thr2[NCODE2 - NCAN2];
extern Word16 imap1[NCODE1];
extern Word16 imap2[NCODE2];
extern Word16 b100[3];
extern Word16 a100[3];
extern Word16 b140[3];
extern Word16 a140[3];
extern Word16 bitsno[PRM_SIZE];
extern Word16 tabpow[33];
extern Word16 tablog[33];
extern Word16 tabsqr[49];
extern Word16 tab_zone[PIT_MAX + L_INTERPOL - 1];
extern Word16 lsp_old_init [M10];
extern Word16 freq_prev_reset[M10];
extern Word16 past_qua_en_init[4];

View File

@@ -0,0 +1,139 @@
/*
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.
*/
/**************************************************************************
* Taming functions. *
**************************************************************************/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_taming.h"
void
Init_exc_err (CodState *coder)
{
Word16 i;
for (i = 0; i < 4; i++)
coder->L_exc_err[i] = 0x00004000L; /* Q14 */
}
/**************************************************************************
* routine test_err - computes the accumulated potential error in the *
* adaptive codebook contribution *
**************************************************************************/
Word16
test_err (/* (o) flag set to 1 if taming is necessary */
CodState *coder,
Word16 T0, /* (i) integer part of pitch delay */
Word16 T0_frac /* (i) fractional part of pitch delay */
)
{
Word16 i, t1, zone1, zone2, flag;
Word32 L_maxloc, L_acc;
if (T0_frac > 0) {
t1 = add (T0, 1);
}
else {
t1 = T0;
}
i = sub (t1, (L_SUBFR + L_INTER10));
if (i < 0) {
i = 0;
}
zone1 = tab_zone[i];
i = add (t1, (L_INTER10 - 2));
zone2 = tab_zone[i];
L_maxloc = -1L;
flag = 0;
for (i = zone2; i >= zone1; i--) {
L_acc = L_sub (coder->L_exc_err[i], L_maxloc);
if (L_acc > 0L) {
L_maxloc = coder->L_exc_err[i];
}
}
L_acc = L_sub (L_maxloc, L_THRESH_ERR);
if (L_acc > 0L) {
flag = 1;
}
return (flag);
}
/**************************************************************************
*routine update_exc_err - maintains the memory used to compute the error *
* function due to an adaptive codebook mismatch between encoder and *
* decoder *
**************************************************************************/
void
update_exc_err (CodState *coder,
Word16 gain_pit, /* (i) pitch gain */
Word16 T0 /* (i) integer part of pitch delay */
)
{
Word16 i, zone1, zone2, n;
Word32 L_worst, L_temp, L_acc;
Word16 hi, lo;
L_worst = -1L;
n = sub (T0, L_SUBFR);
if (n < 0) {
L_Extract (coder->L_exc_err[0], &hi, &lo);
L_temp = Mpy_32_16 (hi, lo, gain_pit);
L_temp = L_shl (L_temp, 1);
L_temp = L_add (0x00004000L, L_temp);
L_acc = L_sub (L_temp, L_worst);
if (L_acc > 0L) {
L_worst = L_temp;
}
L_Extract (L_temp, &hi, &lo);
L_temp = Mpy_32_16 (hi, lo, gain_pit);
L_temp = L_shl (L_temp, 1);
L_temp = L_add (0x00004000L, L_temp);
L_acc = L_sub (L_temp, L_worst);
if (L_acc > 0L) {
L_worst = L_temp;
}
}
else {
zone1 = tab_zone[n];
i = sub (T0, 1);
zone2 = tab_zone[i];
for (i = zone1; i <= zone2; i++) {
L_Extract (coder->L_exc_err[i], &hi, &lo);
L_temp = Mpy_32_16 (hi, lo, gain_pit);
L_temp = L_shl (L_temp, 1);
L_temp = L_add (0x00004000L, L_temp);
L_acc = L_sub (L_temp, L_worst);
if (L_acc > 0L)
L_worst = L_temp;
}
}
for (i = 3; i >= 1; i--) {
coder->L_exc_err[i] = coder->L_exc_err[i - 1];
}
coder->L_exc_err[0] = L_worst;
return;
}

View File

@@ -0,0 +1,22 @@
/*
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.
*/
/*--------------------------------------------------------------------------*
* Constants and prototypes for taming procedure. *
*--------------------------------------------------------------------------*/
#define GPCLIP 15564 /* Maximum pitch gain if taming is needed Q14 */
#define GPCLIP2 481 /* Maximum pitch gain if taming is needed Q9 */
#define GP0999 16383 /* Maximum pitch gain if taming is needed */
#define L_THRESH_ERR 983040000L /* Error threshold taming 16384. * 60000. */
void Init_exc_err (CodState *coder);
void update_exc_err (CodState *coder, Word16 gain_pit, Word16 t0);
Word16 test_err (CodState *coder, Word16 t0, Word16 t0_frac);

View File

@@ -0,0 +1,16 @@
/*
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.
*/
/*
Types definitions
*/
typedef short Word16;
typedef int Word32;
typedef int Flag;

View File

@@ -0,0 +1,145 @@
/*
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 Set zero() *
* ~~~~~~~~~~ *
* Set vector x[] to zero *
*-------------------------------------------------------------------*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
void
Set_zero (Word16 x[], Word16 L)
{
Word16 i;
for (i = 0; i < L; i++)
x[i] = 0;
return;
}
/*-------------------------------------------------------------------*
* Function Copy: *
* ~~~~~ *
* Copy vector x[] to y[] *
*-------------------------------------------------------------------*/
void
Copy (Word16 x[], Word16 y[], Word16 L)
{
Word16 i;
for (i = 0; i < L; i++)
y[i] = x[i];
return;
}
/* Random generator */
Word16
Random_16 (Word16* seed)
{
/* seed = seed*31821 + 13849; */
*seed = extract_l (L_add (L_shr (L_mult (*seed, 31821), 1), 13849L));
return (*seed);
}
/*----------------------------------------------------------------------------
* Store_Param - converts encoder parameter vector into frame
* Restore_Params - converts serial received frame to encoder parameter vector
*
* The transmitted parameters are:
*
* LPC: 1st codebook 7+1 bit
* 2nd codebook 5+5 bit
*
* 1st subframe:
* pitch period 8 bit
* parity check on 1st period 1 bit
* codebook index1 (positions) 13 bit
* codebook index2 (signs) 4 bit
* pitch and codebook gains 4+3 bit
*
* 2nd subframe:
* pitch period (relative) 5 bit
* codebook index1 (positions) 13 bit
* codebook index2 (signs) 4 bit
* pitch and codebook gains 4+3 bit
*----------------------------------------------------------------------------
*/
void
Store_Params(Word16 * parm, void *to)
{
int i, j;
unsigned char mask, *to_b;
Word16 value, val_mask;
to_b = (unsigned char *)to;
mask = 0x80;
for (i = 0; i < PRM_SIZE; i++) {
value = parm[i];
val_mask = 1 << (bitsno[i] - 1);
for (j = 0; j < bitsno[i]; j++) {
if (value & val_mask)
*to_b |= mask;
else
*to_b &= ~mask;
value = value << 1;
mask = mask >> 1;
if (mask == 0) {
mask = 0x80;
to_b++;
}
}
}
return;
}
void Restore_Params(const void *from, Word16 * parm)
{
int i, j;
unsigned char mask, *from_b;
Word16 value;
mask = 0x80;
from_b = (unsigned char *)from;
for (i = 0; i < PRM_SIZE; i++) {
value = 0;
for (j = 0; j < bitsno[i]; j++) {
value = value << 1;
if (mask & (*from_b))
value += 1;
mask = mask >> 1;
if (mask == 0) {
mask = 0x80;
from_b++;
}
}
parm[i] = value;
}
return;
}

View File

@@ -0,0 +1,22 @@
/*
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.
*/
/*--------------------------------------------------------------------------*
* Prototypes for auxiliary functions. *
*--------------------------------------------------------------------------*/
void Copy (Word16 x[], Word16 y[], Word16 L);
void Set_zero (Word16 x[], Word16 L);
Word16 Random_16 (Word16 *seed);
void Store_Params(Word16 * parm, void *to);
void Restore_Params(const void *from, Word16 * parm);

159
src/libs/libg729/gainpred.c Normal file
View File

@@ -0,0 +1,159 @@
/*
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.
*/
/*---------------------------------------------------------------------------*
* Gain_predict() : make gcode0(exp_gcode0) *
* Gain_update() : update table of past quantized energies. *
* Gain_update_erasure() : update table of past quantized energies. *
* (frame erasure) *
* This function is used both Coder and Decoder. *
*---------------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
#include "tab_ld8a.h"
#include "oper_32b.h"
/*---------------------------------------------------------------------------*
* Function Gain_predict *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* MA prediction is performed on the innovation energy (in dB with mean *
* removed). *
*---------------------------------------------------------------------------*/
void
Gain_predict (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 * gcode0, /* (o) Qxx :Predicted codebook gain */
Word16 * exp_gcode0 /* (o) :Q-Format(gcode0) */
)
{
Word16 i, exp, frac;
Word32 L_tmp;
/*-------------------------------*
* Energy coming from code *
*-------------------------------*/
L_tmp = 0;
for (i = 0; i < L_subfr; i++)
L_tmp = L_mac (L_tmp, code[i], code[i]);
/*-----------------------------------------------------------------*
* Compute: means_ener - 10log10(ener_code/ L_sufr) *
* Note: mean_ener change from 36 dB to 30 dB because input/2 *
* *
* = 30.0 - 10 log10( ener_code / lcode) + 10log10(2^27) *
* !!ener_code in Q27!! *
* = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) *
* = 30.0 - 3.0103 * log2(ener_code) + 16.02 + 81.278 *
* = 127.298 - 3.0103 * log2(ener_code) *
*-----------------------------------------------------------------*/
Log2 (L_tmp, &exp, &frac); /* Q27->Q0 ^Q0 ^Q15 */
L_tmp = Mpy_32_16 (exp, frac, -24660); /* Q0 Q15 Q13 -> ^Q14 */
/* hi:Q0+Q13+1 */
/* lo:Q15+Q13-15+1 */
/* -24660[Q13]=-3.0103 */
L_tmp = L_mac (L_tmp, 32588, 32); /* 32588*32[Q14]=127.298 */
/*-----------------------------------------------------------------*
* Compute gcode0. *
* = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
*-----------------------------------------------------------------*/
L_tmp = L_shl (L_tmp, 10); /* From Q14 to Q24 */
for (i = 0; i < 4; i++)
L_tmp = L_mac (L_tmp, pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */
*gcode0 = extract_h (L_tmp); /* From Q24 to Q8 */
/*-----------------------------------------------------------------*
* gcode0 = pow(10.0, gcode0/20) *
* = pow(2, 3.3219*gcode0/20) *
* = pow(2, 0.166*gcode0) *
*-----------------------------------------------------------------*/
L_tmp = L_mult (*gcode0, 5439); /* *0.166 in Q15, result in Q24 */
L_tmp = L_shr (L_tmp, 8); /* From Q24 to Q16 */
L_Extract (L_tmp, &exp, &frac); /* Extract exponent of gcode0 */
*gcode0 = extract_l (Pow2 (14, frac)); /* Put 14 as exponent so that */
/* output of Pow2() will be: */
/* 16768 < Pow2() <= 32767 */
*exp_gcode0 = sub (14, exp);
}
/*---------------------------------------------------------------------------*
* Function Gain_update *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* update table of past quantized energies *
*---------------------------------------------------------------------------*/
void
Gain_update (Word16 past_qua_en[], /* (io) Q10 :Past quantized energies */
Word32 L_gbk12 /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */
)
{
Word16 i, tmp;
Word16 exp, frac;
Word32 L_acc;
for (i = 3; i > 0; i--) {
past_qua_en[i] = past_qua_en[i - 1]; /* Q10 */
}
/*----------------------------------------------------------------------*
* -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); -- *
* 2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] ) *
* = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) *
* = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) *
* 24660:Q12(6.0205) *
*----------------------------------------------------------------------*/
Log2 (L_gbk12, &exp, &frac); /* L_gbk12:Q13 */
L_acc = L_Comp (sub (exp, 13), frac); /* L_acc:Q16 */
tmp = extract_h (L_shl (L_acc, 13)); /* tmp:Q13 */
past_qua_en[0] = mult (tmp, 24660); /* past_qua_en[]:Q10 */
}
/*---------------------------------------------------------------------------*
* Function Gain_update_erasure *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* update table of past quantized energies (frame erasure) *
*---------------------------------------------------------------------------*
* av_pred_en = 0.0; *
* for (i = 0; i < 4; i++) *
* av_pred_en += past_qua_en[i]; *
* av_pred_en = av_pred_en*0.25 - 4.0; *
* if (av_pred_en < -14.0) av_pred_en = -14.0; *
*---------------------------------------------------------------------------*/
void
Gain_update_erasure (Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */
)
{
Word16 i, av_pred_en;
Word32 L_tmp;
L_tmp = 0; /* Q10 */
for (i = 0; i < 4; i++)
L_tmp = L_add (L_tmp, L_deposit_l (past_qua_en[i]));
av_pred_en = extract_l (L_shr (L_tmp, 2));
av_pred_en = sub (av_pred_en, 4096); /* Q10 */
if (sub (av_pred_en, -14336) < 0) {
av_pred_en = -14336; /* 14336:14[Q10] */
}
for (i = 3; i > 0; i--) {
past_qua_en[i] = past_qua_en[i - 1];
}
past_qua_en[0] = av_pred_en;
}

228
src/libs/libg729/oper_32b.c Normal file
View File

@@ -0,0 +1,228 @@
/*
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.
*/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
/*___________________________________________________________________________
| |
| This file contains operations in double precision. |
| These operations are not standard double precision operations. |
| They are used where single precision is not enough but the full 32 bits |
| precision is not necessary. For example, the function Div_32() has a |
| 24 bits precision which is enough for our purposes. |
| |
| The double precision numbers use a special representation: |
| |
| L_32 = hi<<16 + lo<<1 |
| |
| L_32 is a 32 bit integer. |
| hi and lo are 16 bit signed integers. |
| As the low part also contains the sign, this allows fast multiplication. |
| |
| 0x8000 0000 <= L_32 <= 0x7fff fffe. |
| |
| We will use DPF (Double Precision Format )in this file to specify |
| this special format. |
|___________________________________________________________________________|
*/
/*___________________________________________________________________________
| |
| Function L_Extract() |
| |
| Extract from a 32 bit integer two 16 bit DPF. |
| |
| Arguments: |
| |
| L_32 : 32 bit integer. |
| 0x8000 0000 <= L_32 <= 0x7fff ffff. |
| hi : b16 to b31 of L_32 |
| lo : (L_32 - hi<<16)>>1 |
|___________________________________________________________________________|
*/
void
L_Extract (Word32 L_32, Word16 * hi, Word16 * lo)
{
*hi = extract_h (L_32);
*lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); /* lo = L_32>>1 */
return;
}
/*___________________________________________________________________________
| |
| Function L_Comp() |
| |
| Compose from two 16 bit DPF a 32 bit integer. |
| |
| L_32 = hi<<16 + lo<<1 |
| |
| Arguments: |
| |
| hi msb |
| lo lsf (with sign) |
| |
| Return Value : |
| |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x8000 0000 <= L_32 <= 0x7fff fff0. |
| |
|___________________________________________________________________________|
*/
Word32
L_Comp (Word16 hi, Word16 lo)
{
Word32 L_32;
L_32 = L_deposit_h (hi);
return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */
}
/*___________________________________________________________________________
| Function Mpy_32() |
| |
| Multiply two 32 bit integers (DPF). The result is divided by 2**31 |
| |
| L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 |
| |
| This operation can also be viewed as the multiplication of two Q31 |
| number and the result is also in Q31. |
| |
| Arguments: |
| |
| hi1 hi part of first number |
| lo1 lo part of first number |
| hi2 hi part of second number |
| lo2 lo part of second number |
| |
|___________________________________________________________________________|
*/
Word32
Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
{
Word32 L_32;
L_32 = L_mult (hi1, hi2);
L_32 = L_mac (L_32, mult (hi1, lo2), 1);
L_32 = L_mac (L_32, mult (lo1, hi2), 1);
return (L_32);
}
/*___________________________________________________________________________
| Function Mpy_32_16() |
| |
| Multiply a 16 bit integer by a 32 bit (DPF). The result is divided |
| by 2**15 |
| |
| This operation can also be viewed as the multiplication of a Q31 |
| number by a Q15 number, the result is in Q31. |
| |
| L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 |
| |
| Arguments: |
| |
| hi hi part of 32 bit number. |
| lo lo part of 32 bit number. |
| n 16 bit number. |
| |
|___________________________________________________________________________|
*/
Word32
Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
{
Word32 L_32;
L_32 = L_mult (hi, n);
L_32 = L_mac (L_32, mult (lo, n), 1);
return (L_32);
}
/*___________________________________________________________________________
| |
| Function Name : Div_32 |
| |
| Purpose : |
| Fractional integer division of two 32 bit numbers. |
| L_num / L_denom. |
| L_num and L_denom must be positive and L_num < L_denom. |
| L_denom = denom_hi<<16 + denom_lo<<1 |
| denom_hi is a normalize number. |
| The result is in Q30. |
| |
| Inputs : |
| |
| L_num |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x0000 0000 < L_num < L_denom |
| |
| L_denom = denom_hi<<16 + denom_lo<<1 (DPF) |
| |
| denom_hi |
| 16 bit positive normalized integer whose value falls in the |
| range : 0x4000 < hi < 0x7fff |
| denom_lo |
| 16 bit positive integer whose value falls in the |
| range : 0 < lo < 0x7fff |
| |
| Return Value : |
| |
| L_div |
| 32 bit long signed integer (Word32) whose value falls in the |
| range : 0x0000 0000 <= L_div <= 0x7fff ffff. |
| It's a Q31 value |
| |
| Algorithm: |
| |
| - find = 1/L_denom. |
| First approximation: approx = 1 / denom_hi |
| 1/L_denom = approx * (2.0 - L_denom * approx ) |
| |
| - result = L_num * (1/L_denom) |
|___________________________________________________________________________|
*/
Word32
Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo)
{
Word16 approx, hi, lo, n_hi, n_lo;
Word32 L_32;
/* First approximation: 1 / L_denom = 1/denom_hi */
approx = div_s ((Word16) 0x3fff, denom_hi); /* result in Q14 */
/* Note: 3fff = 0.5 in Q15 */
/* 1/L_denom = approx * (2.0 - L_denom * approx) */
L_32 = Mpy_32_16 (denom_hi, denom_lo, approx); /* result in Q30 */
L_32 = L_sub ((Word32) 0x7fffffffL, L_32); /* result in Q30 */
L_Extract (L_32, &hi, &lo);
L_32 = Mpy_32_16 (hi, lo, approx); /* = 1/L_denom in Q29 */
/* L_num * (1/L_denom) */
L_Extract (L_32, &hi, &lo);
L_Extract (L_num, &n_hi, &n_lo);
L_32 = Mpy_32 (n_hi, n_lo, hi, lo); /* result in Q29 */
L_32 = L_shl (L_32, 2); /* From Q29 to Q31 */
return (L_32);
}

View File

@@ -0,0 +1,63 @@
/*
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.
*/
/*------------------------------------------------------*
* Parity_pitch - compute parity bit for first 6 MSBs *
*------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
Word16
Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */
Word16 pitch_index /* input : index for which parity to compute */
)
{
Word16 temp, sum, i, bit;
temp = shr (pitch_index, 1);
sum = 1;
for (i = 0; i <= 5; i++) {
temp = shr (temp, 1);
bit = temp & (Word16) 1;
sum = add (sum, bit);
}
sum = sum & (Word16) 1;
return sum;
}
/*--------------------------------------------------------------------*
* check_parity_pitch - check parity of index with transmitted parity *
*--------------------------------------------------------------------*/
Word16
Check_Parity_Pitch ( /* output: 0 = no error, 1= error */
Word16 pitch_index, /* input : index of parameter */
Word16 parity /* input : parity bit */
)
{
Word16 temp, sum, i, bit;
temp = shr (pitch_index, 1);
sum = 1;
for (i = 0; i <= 5; i++) {
temp = shr (temp, 1);
bit = temp & (Word16) 1;
sum = add (sum, bit);
}
sum = add (sum, parity);
sum = sum & (Word16) 1;
return sum;
}

570
src/libs/libg729/pitch_a.c Normal file
View File

@@ -0,0 +1,570 @@
/*
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.
*/
/*---------------------------------------------------------------------------*
* Pitch related functions *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
*---------------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "ld8a.h"
#include "tab_ld8a.h"
#include "util.h"
/*---------------------------------------------------------------------------*
* Function Pitch_ol_fast *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Compute the open loop pitch lag. (fast version) *
* *
*---------------------------------------------------------------------------*/
Word16
Pitch_ol_fast ( /* output: open loop pitch lag */
Word16 signal[], /* input : signal used to compute the open loop pitch */
/* signal[-pit_max] to signal[-1] should be known */
Word16 pit_max, /* input : maximum pitch lag */
Word16 L_frame /* input : length of frame to compute pitch */
)
{
Flag Overflow;
Word16 i, j;
Word16 max1, max2, max3;
Word16 max_h, max_l, ener_h, ener_l;
Word16 T1, T2, T3;
Word16 *p, *p1;
Word32 max, sum, L_temp;
/* Scaled signal */
Word16 scaled_signal[L_FRAME + PIT_MAX];
Word16 *scal_sig;
scal_sig = &scaled_signal[pit_max];
/*--------------------------------------------------------*
* Verification for risk of overflow. *
*--------------------------------------------------------*/
Overflow = 0;
sum = 0;
for (i = -pit_max; i < L_frame; i += 2)
sum = L_mac_o (sum, signal[i], signal[i], &Overflow);
/*--------------------------------------------------------*
* Scaling of input signal. *
* *
* if Overflow -> scal_sig[i] = signal[i]>>3 *
* else if sum < 1^20 -> scal_sig[i] = signal[i]<<3 *
* else -> scal_sig[i] = signal[i] *
*--------------------------------------------------------*/
if (Overflow == 1) {
for (i = -pit_max; i < L_frame; i++) {
scal_sig[i] = shr (signal[i], 3);
}
}
else {
L_temp = L_sub (sum, (Word32) 1048576L);
if (L_temp < (Word32) 0) { /* if (sum < 2^20) */
for (i = -pit_max; i < L_frame; i++) {
scal_sig[i] = shl (signal[i], 3);
}
}
else {
for (i = -pit_max; i < L_frame; i++) {
scal_sig[i] = signal[i];
}
}
}
/*--------------------------------------------------------------------*
* The pitch lag search is divided in three sections. *
* Each section cannot have a pitch multiple. *
* We find a maximum for each section. *
* We compare the maxima of each section by favoring small lag. *
* *
* First section: lag delay = 20 to 39 *
* Second section: lag delay = 40 to 79 *
* Third section: lag delay = 80 to 143 *
*--------------------------------------------------------------------*/
/* First section */
max = MIN_32;
T1 = 20; /* Only to remove warning from some compilers */
for (i = 20; i < 40; i++) {
p = scal_sig;
p1 = &scal_sig[-i];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T1 = i;
}
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T1];
for (i = 0; i < L_frame; i += 2, p += 2)
sum = L_mac (sum, *p, *p);
/* max1 = max/sqrt(energy) */
/* This result will always be on 16 bits !! */
sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */
L_Extract (max, &max_h, &max_l);
L_Extract (sum, &ener_h, &ener_l);
sum = Mpy_32 (max_h, max_l, ener_h, ener_l);
max1 = extract_l (sum);
/* Second section */
max = MIN_32;
T2 = 40; /* Only to remove warning from some compilers */
for (i = 40; i < 80; i++) {
p = scal_sig;
p1 = &scal_sig[-i];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T2 = i;
}
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T2];
for (i = 0; i < L_frame; i += 2, p += 2)
sum = L_mac (sum, *p, *p);
/* max2 = max/sqrt(energy) */
/* This result will always be on 16 bits !! */
sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */
L_Extract (max, &max_h, &max_l);
L_Extract (sum, &ener_h, &ener_l);
sum = Mpy_32 (max_h, max_l, ener_h, ener_l);
max2 = extract_l (sum);
/* Third section */
max = MIN_32;
T3 = 80; /* Only to remove warning from some compilers */
for (i = 80; i < 143; i += 2) {
p = scal_sig;
p1 = &scal_sig[-i];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T3 = i;
}
}
/* Test around max3 */
i = T3;
p = scal_sig;
p1 = &scal_sig[-(i + 1)];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T3 = i + (Word16) 1;
}
p = scal_sig;
p1 = &scal_sig[-(i - 1)];
sum = 0;
for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2)
sum = L_mac (sum, *p, *p1);
L_temp = L_sub (sum, max);
if (L_temp > 0) {
max = sum;
T3 = i - (Word16) 1;
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T3];
for (i = 0; i < L_frame; i += 2, p += 2)
sum = L_mac (sum, *p, *p);
/* max1 = max/sqrt(energy) */
/* This result will always be on 16 bits !! */
sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */
L_Extract (max, &max_h, &max_l);
L_Extract (sum, &ener_h, &ener_l);
sum = Mpy_32 (max_h, max_l, ener_h, ener_l);
max3 = extract_l (sum);
/*-----------------------*
* Test for multiple. *
*-----------------------*/
/* if( abs(T2*2 - T3) < 5) */
/* max2 += max3 * 0.25; */
i = sub (shl (T2, 1), T3);
j = sub (abs_s (i), 5);
if (j < 0)
max2 = add (max2, shr (max3, 2));
/* if( abs(T2*3 - T3) < 7) */
/* max2 += max3 * 0.25; */
i = add (i, T2);
j = sub (abs_s (i), 7);
if (j < 0)
max2 = add (max2, shr (max3, 2));
/* if( abs(T1*2 - T2) < 5) */
/* max1 += max2 * 0.20; */
i = sub (shl (T1, 1), T2);
j = sub (abs_s (i), 5);
if (j < 0)
max1 = add (max1, mult (max2, 6554));
/* if( abs(T1*3 - T2) < 7) */
/* max1 += max2 * 0.20; */
i = add (i, T1);
j = sub (abs_s (i), 7);
if (j < 0)
max1 = add (max1, mult (max2, 6554));
/*--------------------------------------------------------------------*
* Compare the 3 sections maxima. *
*--------------------------------------------------------------------*/
if (sub (max1, max2) < 0) {
max1 = max2;
T1 = T2;
}
if (sub (max1, max3) < 0) {
T1 = T3;
}
return T1;
}
/*--------------------------------------------------------------------------*
* Function Dot_Product() *
* ~~~~~~~~~~~~~~~~~~~~~~ *
*--------------------------------------------------------------------------*/
Word32
Dot_Product ( /* (o) :Result of scalar product. */
Word16 x[], /* (i) :First vector. */
Word16 y[], /* (i) :Second vector. */
Word16 lg /* (i) :Number of point. */
)
{
Word16 i;
Word32 sum;
sum = 0;
for (i = 0; i < lg; i++)
sum = L_mac (sum, x[i], y[i]);
return sum;
}
/*--------------------------------------------------------------------------*
* Function Pitch_fr3_fast() *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* Fast version of the pitch close loop. *
*--------------------------------------------------------------------------*/
Word16
Pitch_fr3_fast ( /* (o) : pitch period. */
Word16 exc[], /* (i) : excitation buffer */
Word16 xn[], /* (i) : target vector */
Word16 h[], /* (i) Q12 : impulse response of filters. */
Word16 L_subfr, /* (i) : Length of subframe */
Word16 t0_min, /* (i) : minimum value in the searched range. */
Word16 t0_max, /* (i) : maximum value in the searched range. */
Word16 i_subfr, /* (i) : indicator for first subframe. */
Word16 * pit_frac /* (o) : chosen fraction. */
)
{
Word16 t, t0;
Word16 Dn[L_SUBFR];
Word16 exc_tmp[L_SUBFR];
Word32 max, corr, L_temp;
/*-----------------------------------------------------------------*
* Compute correlation of target vector with impulse response. *
*-----------------------------------------------------------------*/
Cor_h_X (h, xn, Dn);
/*-----------------------------------------------------------------*
* Find maximum integer delay. *
*-----------------------------------------------------------------*/
max = MIN_32;
t0 = t0_min; /* Only to remove warning from some compilers */
for (t = t0_min; t <= t0_max; t++) {
corr = Dot_Product (Dn, &exc[-t], L_subfr);
L_temp = L_sub (corr, max);
if (L_temp > 0) {
max = corr;
t0 = t;
}
}
/*-----------------------------------------------------------------*
* Test fractions. *
*-----------------------------------------------------------------*/
/* Fraction 0 */
Pred_lt_3 (exc, t0, 0, L_subfr);
max = Dot_Product (Dn, exc, L_subfr);
*pit_frac = 0;
/* If first subframe and lag > 84 do not search fractional pitch */
if ((i_subfr == 0) && (sub (t0, 84) > 0))
return t0;
Copy (exc, exc_tmp, L_subfr);
/* Fraction -1/3 */
Pred_lt_3 (exc, t0, -1, L_subfr);
corr = Dot_Product (Dn, exc, L_subfr);
L_temp = L_sub (corr, max);
if (L_temp > 0) {
max = corr;
*pit_frac = -1;
Copy (exc, exc_tmp, L_subfr);
}
/* Fraction +1/3 */
Pred_lt_3 (exc, t0, 1, L_subfr);
corr = Dot_Product (Dn, exc, L_subfr);
L_temp = L_sub (corr, max);
if (L_temp > 0) {
max = corr;
*pit_frac = 1;
}
else
Copy (exc_tmp, exc, L_subfr);
return t0;
}
/*---------------------------------------------------------------------*
* Function G_pitch: *
* ~~~~~~~~ *
*---------------------------------------------------------------------*
* Compute correlations <xn,y1> and <y1,y1> to use in gains quantizer. *
* Also compute the gain of pitch. Result in Q14 *
* if (gain < 0) gain =0 *
* if (gain >1.2) gain =1.2 *
*---------------------------------------------------------------------*/
Word16
G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */
Word16 xn[], /* (i) : Pitch target. */
Word16 y1[], /* (i) : Filtered adaptive codebook. */
Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */
Word16 L_subfr /* (i) : Length of subframe. */
)
{
Flag Overflow;
Word16 i;
Word16 xy, yy, exp_xy, exp_yy, gain;
Word32 s;
Word16 scaled_y1[L_SUBFR];
/* divide "y1[]" by 4 to avoid overflow */
for (i = 0; i < L_subfr; i++)
scaled_y1[i] = shr (y1[i], 2);
/* Compute scalar product <y1[],y1[]> */
Overflow = 0;
s = 1; /* Avoid case of all zeros */
for (i = 0; i < L_subfr; i++)
s = L_mac_o (s, y1[i], y1[i], &Overflow);
if (Overflow == 0) {
exp_yy = norm_l (s);
yy = wround (L_shl (s, exp_yy));
}
else {
s = 1; /* Avoid case of all zeros */
for (i = 0; i < L_subfr; i++)
s = L_mac (s, scaled_y1[i], scaled_y1[i]);
exp_yy = norm_l (s);
yy = wround (L_shl (s, exp_yy));
exp_yy = sub (exp_yy, 4);
}
/* Compute scalar product <xn[],y1[]> */
Overflow = 0;
s = 0;
for (i = 0; i < L_subfr; i++)
s = L_mac_o (s, xn[i], y1[i], &Overflow);
if (Overflow == 0) {
exp_xy = norm_l (s);
xy = wround (L_shl (s, exp_xy));
}
else {
s = 0;
for (i = 0; i < L_subfr; i++)
s = L_mac (s, xn[i], scaled_y1[i]);
exp_xy = norm_l (s);
xy = wround (L_shl (s, exp_xy));
exp_xy = sub (exp_xy, 2);
}
g_coeff[0] = yy;
g_coeff[1] = sub (15, exp_yy);
g_coeff[2] = xy;
g_coeff[3] = sub (15, exp_xy);
/* If (xy <= 0) gain = 0 */
if (xy <= 0) {
g_coeff[3] = -15; /* Force exp_xy to -15 = (15-30) */
return ((Word16) 0);
}
/* compute gain = xy/yy */
xy = shr (xy, 1); /* Be sure xy < yy */
gain = div_s (xy, yy);
i = sub (exp_xy, exp_yy);
gain = shr (gain, i); /* saturation if > 1.99 in Q14 */
/* if(gain >1.2) gain = 1.2 in Q14 */
if (sub (gain, 19661) > 0) {
gain = 19661;
}
return (gain);
}
/*----------------------------------------------------------------------*
* Function Enc_lag3 *
* ~~~~~~~~ *
* Encoding of fractional pitch lag with 1/3 resolution. *
*----------------------------------------------------------------------*
* The pitch range for the first subframe is divided as follows: *
* 19 1/3 to 84 2/3 resolution 1/3 *
* 85 to 143 resolution 1 *
* *
* The period in the first subframe is encoded with 8 bits. *
* For the range with fractions: *
* index = (T-19)*3 + frac - 1; where T=[19..85] and frac=[-1,0,1] *
* and for the integer only range *
* index = (T - 85) + 197; where T=[86..143] *
*----------------------------------------------------------------------*
* For the second subframe a resolution of 1/3 is always used, and the *
* search range is relative to the lag in the first subframe. *
* If t0 is the lag in the first subframe then *
* t_min=t0-5 and t_max=t0+4 and the range is given by *
* t_min - 2/3 to t_max + 2/3 *
* *
* The period in the 2nd subframe is encoded with 5 bits: *
* index = (T-(t_min-1))*3 + frac - 1; where T[t_min-1 .. t_max+1] *
*----------------------------------------------------------------------*/
Word16
Enc_lag3 ( /* output: Return index of encoding */
Word16 T0, /* input : Pitch delay */
Word16 T0_frac, /* input : Fractional pitch delay */
Word16 * T0_min, /* in/out: Minimum search delay */
Word16 * T0_max, /* in/out: Maximum search delay */
Word16 pit_min, /* input : Minimum pitch delay */
Word16 pit_max, /* input : Maximum pitch delay */
Word16 pit_flag /* input : Flag for 1st subframe */
)
{
Word16 index, i;
if (pit_flag == 0) { /* if 1st subframe */
/* encode pitch delay (with fraction) */
if (sub (T0, 85) <= 0) {
/* index = t0*3 - 58 + t0_frac */
i = add (add (T0, T0), T0);
index = add (sub (i, 58), T0_frac);
}
else {
index = add (T0, 112);
}
/* find T0_min and T0_max for second subframe */
*T0_min = sub (T0, 5);
if (sub (*T0_min, pit_min) < 0) {
*T0_min = pit_min;
}
*T0_max = add (*T0_min, 9);
if (sub (*T0_max, pit_max) > 0) {
*T0_max = pit_max;
*T0_min = sub (*T0_max, 9);
}
}
else { /* if second subframe */
/* i = t0 - t0_min; */
/* index = i*3 + 2 + t0_frac; */
i = sub (T0, *T0_min);
i = add (add (i, i), i);
index = add (add (i, 2), T0_frac);
}
return index;
}

View File

@@ -0,0 +1,84 @@
/*
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 Post_Process() *
* *
* Post-processing of output speech. *
* - 2nd order high pass filter with cut off frequency at 100 Hz. *
* - Multiplication by two of output speech with saturation. *
*-----------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "ld8a.h"
#include "tab_ld8a.h"
/*------------------------------------------------------------------------*
* 2nd order high pass filter with cut off frequency at 100 Hz. *
* Designed with SPPACK efi command -40 dB att, 0.25 ri. *
* *
* Algorithm: *
* *
* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] *
* + a[1]*y[i-1] + a[2]*y[i-2]; *
* *
* b[3] = {0.93980581E+00, -0.18795834E+01, 0.93980581E+00}; *
* a[3] = {0.10000000E+01, 0.19330735E+01, -0.93589199E+00}; *
*-----------------------------------------------------------------------*/
/* Initialization of values */
void
Init_Post_Process (DecState *decoder)
{
decoder->y2_hi = 0;
decoder->y2_lo = 0;
decoder->y1_hi = 0;
decoder->y1_lo = 0;
decoder->x0 = 0;
decoder->x1 = 0;
}
void
Post_Process (DecState *decoder,
Word16 signal[], /* input/output signal */
Word16 lg)
{ /* length of signal */
Word16 i, x2;
Word32 L_tmp;
for (i = 0; i < lg; i++) {
x2 = decoder->x1;
decoder->x1 = decoder->x0;
decoder->x0 = signal[i];
/* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
/* + a[1]*y[i-1] + a[2] * y[i-2]; */
L_tmp = Mpy_32_16 (decoder->y1_hi, decoder->y1_lo, a100[1]);
L_tmp = L_add (L_tmp, Mpy_32_16 (decoder->y2_hi, decoder->y2_lo, a100[2]));
L_tmp = L_mac (L_tmp, decoder->x0, b100[0]);
L_tmp = L_mac (L_tmp, decoder->x1, b100[1]);
L_tmp = L_mac (L_tmp, x2, b100[2]);
L_tmp = L_shl (L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */
/* Multiplication by two of output speech with saturation. */
signal[i] = wround (L_shl (L_tmp, 1));
decoder->y2_hi = decoder->y1_hi;
decoder->y2_lo = decoder->y1_lo;
L_Extract (L_tmp, &decoder->y1_hi, &decoder->y1_lo);
}
return;
}

View File

@@ -0,0 +1,85 @@
/*
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 Pre_Process() *
* *
* Preprocessing of input speech. *
* - 2nd order high pass filter with cut off frequency at 140 Hz. *
* - Divide input by two. *
*-----------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "ld8a.h"
#include "tab_ld8a.h"
/*------------------------------------------------------------------------*
* 2nd order high pass filter with cut off frequency at 140 Hz. *
* Designed with SPPACK efi command -40 dB att, 0.25 ri. *
* *
* Algorithm: *
* *
* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2 *
* + a[1]*y[i-1] + a[2]*y[i-2]; *
* *
* b[3] = {0.92727435E+00, -0.18544941E+01, 0.92727435E+00}; *
* a[3] = {0.10000000E+01, 0.19059465E+01, -0.91140240E+00}; *
* *
* Input are divided by two in the filtering process. *
*-----------------------------------------------------------------------*/
/* Initialization of values */
void Init_Pre_Process (CodState *coder)
{
coder->y2_hi = 0;
coder->y2_lo = 0;
coder->y1_hi = 0;
coder->y1_lo = 0;
coder->x0 = 0;
coder->x1 = 0;
}
void
Pre_Process (CodState *coder,
Word16 signal[], /* input/output signal */
Word16 lg)
{ /* length of signal */
Word16 i, x2;
Word32 L_tmp;
for (i = 0; i < lg; i++) {
x2 = coder->x1;
coder->x1 = coder->x0;
coder->x0 = signal[i];
/* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */
/* + a[1]*y[i-1] + a[2] * y[i-2]; */
L_tmp = Mpy_32_16 (coder->y1_hi, coder->y1_lo, a140[1]);
L_tmp = L_add (L_tmp, Mpy_32_16 (coder->y2_hi, coder->y2_lo, a140[2]));
L_tmp = L_mac (L_tmp, coder->x0, b140[0]);
L_tmp = L_mac (L_tmp, coder->x1, b140[1]);
L_tmp = L_mac (L_tmp, x2, b140[2]);
L_tmp = L_shl (L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */
signal[i] = wround (L_tmp);
coder->y2_hi = coder->y1_hi;
coder->y2_lo = coder->y1_lo;
L_Extract (L_tmp, &coder->y1_hi, &coder->y1_lo);
}
return;
}

View File

@@ -0,0 +1,61 @@
/*
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 Pred_lt_3() *
* ~~~~~~~~~~~ *
*-------------------------------------------------------------------*
* Compute the result of long term prediction with fractional *
* interpolation of resolution 1/3. *
* *
* On return exc[0..L_subfr-1] contains the interpolated signal *
* (adaptive codebook excitation) *
*-------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
#include "tab_ld8a.h"
void
Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */
Word16 T0, /* input : integer pitch lag */
Word16 frac, /* input : fraction of lag */
Word16 L_subfr /* input : subframe size */
)
{
Word16 i, j, k;
Word16 *x0, *x1, *x2, *c1, *c2;
Word32 s;
x0 = &exc[-T0];
frac = negate (frac);
if (frac < 0) {
frac = add (frac, UP_SAMP);
x0--;
}
for (j = 0; j < L_subfr; j++) {
x1 = x0++;
x2 = x0;
c1 = &inter_3l[frac];
c2 = &inter_3l[sub (UP_SAMP, frac)];
s = 0;
for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP) {
s = L_mac (s, x1[-i], c1[k]);
s = L_mac (s, x2[i], c2[k]);
}
exc[j] = wround (s);
}
return;
}

443
src/libs/libg729/qua_gain.c Normal file
View File

@@ -0,0 +1,443 @@
/*
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.
*/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "ld8a.h"
#include "tab_ld8a.h"
#include "taming.h"
void Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */
/* (i) [1] Q2 : unquantized code gain */
Word16 * cand1, /* (o) : index of best 1st stage vector */
Word16 * cand2, /* (o) : index of best 2nd stage vector */
Word16 gcode0 /* (i) Q4 : presearch for gain codebook */
);
/*---------------------------------------------------------------------------*
* Function Qua_gain *
* ~~~~~~~~~~~~~~~~~~ *
* Inputs: *
* code[] :Innovative codebook. *
* g_coeff[] :Correlations compute for pitch. *
* L_subfr :Subframe length. *
* *
* Outputs: *
* gain_pit :Quantized pitch gain. *
* gain_cod :Quantized code gain. *
* *
* Return: *
* Index of quantization. *
* *
*--------------------------------------------------------------------------*/
Word16
Qua_gain (CodState *coder,
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 g_coeff[], /* (i) :Correlations <xn y1> -2<y1 y1> */
/* <y2,y2>, -2<xn,y2>, 2<y1,y2> */
Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 * gain_pit, /* (o) Q14 :Pitch gain. */
Word16 * gain_cod, /* (o) Q1 :Code gain. */
Word16 tameflag /* (i) : set to 1 if taming is needed */
)
{
Word16 i, j, index1, index2;
Word16 cand1, cand2;
Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min;
Word16 nume, denom, inv_denom;
Word16 exp1, exp2, exp_nume, exp_denom, exp_inv_denom, sft, tmp;
Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
Word16 coeff[5], coeff_lsf[5];
Word16 exp_min[5];
Word32 L_gbk12;
Word32 L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb;
Word16 best_gain[2];
/* Gain predictor, Past quantized energies = -14.0 in Q10 */
/*---------------------------------------------------*
*- energy due to innovation -*
*- predicted energy -*
*- predicted codebook gain => gcode0[exp_gcode0] -*
*---------------------------------------------------*/
Gain_predict (coder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0);
/*-----------------------------------------------------------------*
* pre-selection *
*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* calculate best gain *
* *
* tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; *
* best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; *
* best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; *
* gbk_presel(best_gain,&cand1,&cand2,gcode0) ; *
* *
*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[0], g_coeff[2]);
exp1 = add (add (exp_coeff[0], exp_coeff[2]), 1 - 2);
L_tmp2 = L_mult (g_coeff[4], g_coeff[4]);
exp2 = add (add (exp_coeff[4], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp = L_sub (L_shr (L_tmp1, sub (exp1, exp2)), L_tmp2);
exp = exp2;
}
else {
L_tmp = L_sub (L_tmp1, L_shr (L_tmp2, sub (exp2, exp1)));
exp = exp1;
}
sft = norm_l (L_tmp);
denom = extract_h (L_shl (L_tmp, sft));
exp_denom = sub (add (exp, sft), 16);
inv_denom = div_s (16384, denom);
inv_denom = negate (inv_denom);
exp_inv_denom = sub (14 + 15, exp_denom);
/*-----------------------------------------------------------------*
* best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[2], g_coeff[1]);
exp1 = add (exp_coeff[2], exp_coeff[1]);
L_tmp2 = L_mult (g_coeff[3], g_coeff[4]);
exp2 = add (add (exp_coeff[3], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp =
L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1));
exp = sub (exp2, 1);
}
else {
L_tmp =
L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1)));
exp = sub (exp1, 1);
}
sft = norm_l (L_tmp);
nume = extract_h (L_shl (L_tmp, sft));
exp_nume = sub (add (exp, sft), 16);
sft = sub (add (exp_nume, exp_inv_denom), (9 + 16 - 1));
L_acc = L_shr (L_mult (nume, inv_denom), sft);
best_gain[0] = extract_h (L_acc); /*-- best_gain[0]:Q9 --*/
if (tameflag == 1) {
if (sub (best_gain[0], GPCLIP2) > 0)
best_gain[0] = GPCLIP2;
}
/*-----------------------------------------------------------------*
* best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[0], g_coeff[3]);
exp1 = add (exp_coeff[0], exp_coeff[3]);
L_tmp2 = L_mult (g_coeff[1], g_coeff[4]);
exp2 = add (add (exp_coeff[1], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp =
L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1));
exp = sub (exp2, 1);
}
else {
L_tmp =
L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1)));
exp = sub (exp1, 1);
}
sft = norm_l (L_tmp);
nume = extract_h (L_shl (L_tmp, sft));
exp_nume = sub (add (exp, sft), 16);
sft = sub (add (exp_nume, exp_inv_denom), (2 + 16 - 1));
L_acc = L_shr (L_mult (nume, inv_denom), sft);
best_gain[1] = extract_h (L_acc); /*-- best_gain[1]:Q2 --*/
/*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/
if (sub (exp_gcode0, 4) >= 0) {
gcode0_org = shr (gcode0, sub (exp_gcode0, 4));
}
else {
L_acc = L_deposit_l (gcode0);
L_acc = L_shl (L_acc, sub ((4 + 16), exp_gcode0));
gcode0_org = extract_h (L_acc); /*-- gcode0_org:Q4 --*/
}
/*----------------------------------------------*
* - presearch for gain codebook - *
*----------------------------------------------*/
Gbk_presel (best_gain, &cand1, &cand2, gcode0_org);
/*---------------------------------------------------------------------------*
* *
* Find the best quantizer. *
* *
* dist_min = MAX_32; *
* for ( i=0 ; i<NCAN1 ; i++ ){ *
* for ( j=0 ; j<NCAN2 ; j++ ){ *
* g_pitch = gbk1[cand1+i][0] + gbk2[cand2+j][0]; *
* g_code = gcode0 * (gbk1[cand1+i][1] + gbk2[cand2+j][1]); *
* dist = g_pitch*g_pitch * coeff[0] *
* + g_pitch * coeff[1] *
* + g_code*g_code * coeff[2] *
* + g_code * coeff[3] *
* + g_pitch*g_code * coeff[4] ; *
* *
* if (dist < dist_min){ *
* dist_min = dist; *
* indice1 = cand1 + i ; *
* indice2 = cand2 + j ; *
* } *
* } *
* } *
* *
* g_pitch = Q13 *
* g_pitch*g_pitch = Q11:(13+13+1-16) *
* g_code = Q[exp_gcode0-3]:(exp_gcode0+(13-1)+1-16) *
* g_code*g_code = Q[2*exp_gcode0-21]:(exp_gcode0-3+exp_gcode0-3+1-16) *
* g_pitch*g_code = Q[exp_gcode0-5]:(13+exp_gcode0-3+1-16) *
* *
* term 0: g_pitch*g_pitch*coeff[0] ;exp_min0 = 13 +exp_coeff[0] *
* term 1: g_pitch *coeff[1] ;exp_min1 = 14 +exp_coeff[1] *
* term 2: g_code*g_code *coeff[2] ;exp_min2 = 2*exp_gcode0-21+exp_coeff[2] *
* term 3: g_code *coeff[3] ;exp_min3 = exp_gcode0 - 3+exp_coeff[3] *
* term 4: g_pitch*g_code *coeff[4] ;exp_min4 = exp_gcode0 - 4+exp_coeff[4] *
* *
*---------------------------------------------------------------------------*/
exp_min[0] = add (exp_coeff[0], 13);
exp_min[1] = add (exp_coeff[1], 14);
exp_min[2] = add (exp_coeff[2], sub (shl (exp_gcode0, 1), 21));
exp_min[3] = add (exp_coeff[3], sub (exp_gcode0, 3));
exp_min[4] = add (exp_coeff[4], sub (exp_gcode0, 4));
e_min = exp_min[0];
for (i = 1; i < 5; i++) {
if (sub (exp_min[i], e_min) < 0) {
e_min = exp_min[i];
}
}
/* align coeff[] and save in special 32 bit double precision */
for (i = 0; i < 5; i++) {
j = sub (exp_min[i], e_min);
L_tmp = L_deposit_h (g_coeff[i]);
L_tmp = L_shr (L_tmp, j); /* L_tmp:Q[exp_g_coeff[i]+16-j] */
L_Extract (L_tmp, &coeff[i], &coeff_lsf[i]); /* DPF */
}
/* Codebook search */
L_dist_min = MAX_32;
/* initialization used only to suppress Microsoft Visual C++ warnings */
index1 = cand1;
index2 = cand2;
if (tameflag == 1) {
for (i = 0; i < NCAN1; i++) {
for (j = 0; j < NCAN2; j++) {
g_pitch = add (gbk1[cand1 + i][0], gbk2[cand2 + j][0]); /* Q14 */
if (g_pitch < GP0999) {
L_acc = L_deposit_l (gbk1[cand1 + i][1]);
L_accb = L_deposit_l (gbk2[cand2 + j][1]); /* Q13 */
L_tmp = L_add (L_acc, L_accb);
tmp = extract_l (L_shr (L_tmp, 1)); /* Q12 */
g_code = mult (gcode0, tmp); /* Q[exp_gcode0+12-15] */
g2_pitch = mult (g_pitch, g_pitch); /* Q13 */
g2_code = mult (g_code, g_code); /* Q[2*exp_gcode0-6-15] */
g_pit_cod = mult (g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */
L_tmp = Mpy_32_16 (coeff[0], coeff_lsf[0], g2_pitch);
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[1], coeff_lsf[1], g_pitch));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[2], coeff_lsf[2], g2_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[3], coeff_lsf[3], g_code));
L_tmp =
L_add (L_tmp, Mpy_32_16 (coeff[4], coeff_lsf[4], g_pit_cod));
L_temp = L_sub (L_tmp, L_dist_min);
if (L_temp < 0L) {
L_dist_min = L_tmp;
index1 = add (cand1, i);
index2 = add (cand2, j);
}
}
}
}
}
else {
for (i = 0; i < NCAN1; i++) {
for (j = 0; j < NCAN2; j++) {
g_pitch = add (gbk1[cand1 + i][0], gbk2[cand2 + j][0]); /* Q14 */
L_acc = L_deposit_l (gbk1[cand1 + i][1]);
L_accb = L_deposit_l (gbk2[cand2 + j][1]); /* Q13 */
L_tmp = L_add (L_acc, L_accb);
tmp = extract_l (L_shr (L_tmp, 1)); /* Q12 */
g_code = mult (gcode0, tmp); /* Q[exp_gcode0+12-15] */
g2_pitch = mult (g_pitch, g_pitch); /* Q13 */
g2_code = mult (g_code, g_code); /* Q[2*exp_gcode0-6-15] */
g_pit_cod = mult (g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */
L_tmp = Mpy_32_16 (coeff[0], coeff_lsf[0], g2_pitch);
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[1], coeff_lsf[1], g_pitch));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[2], coeff_lsf[2], g2_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[3], coeff_lsf[3], g_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[4], coeff_lsf[4], g_pit_cod));
L_temp = L_sub (L_tmp, L_dist_min);
if (L_temp < 0L) {
L_dist_min = L_tmp;
index1 = add (cand1, i);
index2 = add (cand2, j);
}
}
}
}
/* Read the quantized gain */
/*-----------------------------------------------------------------*
* *gain_pit = gbk1[indice1][0] + gbk2[indice2][0]; *
*-----------------------------------------------------------------*/
*gain_pit = add (gbk1[index1][0], gbk2[index2][0]); /* Q14 */
/*-----------------------------------------------------------------*
* *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; *
*-----------------------------------------------------------------*/
L_acc = L_deposit_l (gbk1[index1][1]);
L_accb = L_deposit_l (gbk2[index2][1]);
L_gbk12 = L_add (L_acc, L_accb); /* Q13 */
tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */
L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */
L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16)));
*gain_cod = extract_h (L_acc); /* Q1 */
/*----------------------------------------------*
* update table of past quantized energies *
*----------------------------------------------*/
Gain_update (coder->past_qua_en, L_gbk12);
return (add (map1[index1] * (Word16) NCODE2, map2[index2]));
}
/*---------------------------------------------------------------------------*
* Function Gbk_presel *
* ~~~~~~~~~~~~~~~~~~~ *
* - presearch for gain codebook - *
*---------------------------------------------------------------------------*/
void
Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */
/* (i) [1] Q2 : unquantized code gain */
Word16 * cand1, /* (o) : index of best 1st stage vector */
Word16 * cand2, /* (o) : index of best 2nd stage vector */
Word16 gcode0 /* (i) Q4 : presearch for gain codebook */
)
{
Word16 acc_h;
Word16 sft_x, sft_y;
Word32 L_acc, L_preg, L_cfbg, L_tmp, L_tmp_x, L_tmp_y;
Word32 L_temp;
/*--------------------------------------------------------------------------*
x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef;
*--------------------------------------------------------------------------*/
L_cfbg = L_mult (coef[0][0], best_gain[0]); /* L_cfbg:Q20 -> !!y */
L_acc = L_shr (L_coef[1][1], 15); /* L_acc:Q20 */
L_acc = L_add (L_cfbg, L_acc);
acc_h = extract_h (L_acc); /* acc_h:Q4 */
L_preg = L_mult (acc_h, gcode0); /* L_preg:Q9 */
L_acc = L_shl (L_deposit_l (best_gain[1]), 7); /* L_acc:Q9 */
L_acc = L_sub (L_acc, L_preg);
acc_h = extract_h (L_shl (L_acc, 2)); /* L_acc_h:Q[-5] */
L_tmp_x = L_mult (acc_h, INV_COEF); /* L_tmp_x:Q15 */
/*--------------------------------------------------------------------------*
y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0
-coef[0][0]*best_gain[1]) * inv_coef;
*--------------------------------------------------------------------------*/
L_acc = L_shr (L_coef[0][1], 10); /* L_acc:Q20 */
L_acc = L_sub (L_cfbg, L_acc); /* !!x -> L_cfbg:Q20 */
acc_h = extract_h (L_acc); /* acc_h:Q4 */
acc_h = mult (acc_h, gcode0); /* acc_h:Q[-7] */
L_tmp = L_mult (acc_h, coef[1][0]); /* L_tmp:Q10 */
L_preg = L_mult (coef[0][0], best_gain[1]); /* L_preg:Q13 */
L_acc = L_sub (L_tmp, L_shr (L_preg, 3)); /* L_acc:Q10 */
acc_h = extract_h (L_shl (L_acc, 2)); /* acc_h:Q[-4] */
L_tmp_y = L_mult (acc_h, INV_COEF); /* L_tmp_y:Q16 */
sft_y = (14 + 4 + 1) - 16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */
sft_x = (15 + 4 + 1) - 15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */
if (gcode0 > 0) {
/*-- pre select codebook #1 --*/
*cand1 = 0;
do {
L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y));
if (L_temp > 0L) {
(*cand1) = add (*cand1, 1);
}
else
break;
} while (sub ((*cand1), (NCODE1 - NCAN1)) < 0);
/*-- pre select codebook #2 --*/
*cand2 = 0;
do {
L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x));
if (L_temp > 0L) {
(*cand2) = add (*cand2, 1);
}
else
break;
} while (sub ((*cand2), (NCODE2 - NCAN2)) < 0);
}
else {
/*-- pre select codebook #1 --*/
*cand1 = 0;
do {
L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y));
if (L_temp < 0L) {
(*cand1) = add (*cand1, 1);
}
else
break;
} while (sub ((*cand1), (NCODE1 - NCAN1)));
/*-- pre select codebook #2 --*/
*cand2 = 0;
do {
L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x));
if (L_temp < 0L) {
(*cand2) = add (*cand2, 1);
}
else
break;
} while (sub ((*cand2), (NCODE2 - NCAN2)));
}
return;
}

139
src/libs/libg729/taming.c Normal file
View File

@@ -0,0 +1,139 @@
/*
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.
*/
/**************************************************************************
* Taming functions. *
**************************************************************************/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "ld8a.h"
#include "tab_ld8a.h"
#include "taming.h"
void
Init_exc_err (CodState *coder)
{
Word16 i;
for (i = 0; i < 4; i++)
coder->L_exc_err[i] = 0x00004000L; /* Q14 */
}
/**************************************************************************
* routine test_err - computes the accumulated potential error in the *
* adaptive codebook contribution *
**************************************************************************/
Word16
test_err (/* (o) flag set to 1 if taming is necessary */
CodState *coder,
Word16 T0, /* (i) integer part of pitch delay */
Word16 T0_frac /* (i) fractional part of pitch delay */
)
{
Word16 i, t1, zone1, zone2, flag;
Word32 L_maxloc, L_acc;
if (T0_frac > 0) {
t1 = add (T0, 1);
}
else {
t1 = T0;
}
i = sub (t1, (L_SUBFR + L_INTER10));
if (i < 0) {
i = 0;
}
zone1 = tab_zone[i];
i = add (t1, (L_INTER10 - 2));
zone2 = tab_zone[i];
L_maxloc = -1L;
flag = 0;
for (i = zone2; i >= zone1; i--) {
L_acc = L_sub (coder->L_exc_err[i], L_maxloc);
if (L_acc > 0L) {
L_maxloc = coder->L_exc_err[i];
}
}
L_acc = L_sub (L_maxloc, L_THRESH_ERR);
if (L_acc > 0L) {
flag = 1;
}
return (flag);
}
/**************************************************************************
*routine update_exc_err - maintains the memory used to compute the error *
* function due to an adaptive codebook mismatch between encoder and *
* decoder *
**************************************************************************/
void
update_exc_err (CodState *coder,
Word16 gain_pit, /* (i) pitch gain */
Word16 T0 /* (i) integer part of pitch delay */
)
{
Word16 i, zone1, zone2, n;
Word32 L_worst, L_temp, L_acc;
Word16 hi, lo;
L_worst = -1L;
n = sub (T0, L_SUBFR);
if (n < 0) {
L_Extract (coder->L_exc_err[0], &hi, &lo);
L_temp = Mpy_32_16 (hi, lo, gain_pit);
L_temp = L_shl (L_temp, 1);
L_temp = L_add (0x00004000L, L_temp);
L_acc = L_sub (L_temp, L_worst);
if (L_acc > 0L) {
L_worst = L_temp;
}
L_Extract (L_temp, &hi, &lo);
L_temp = Mpy_32_16 (hi, lo, gain_pit);
L_temp = L_shl (L_temp, 1);
L_temp = L_add (0x00004000L, L_temp);
L_acc = L_sub (L_temp, L_worst);
if (L_acc > 0L) {
L_worst = L_temp;
}
}
else {
zone1 = tab_zone[n];
i = sub (T0, 1);
zone2 = tab_zone[i];
for (i = zone1; i <= zone2; i++) {
L_Extract (coder->L_exc_err[i], &hi, &lo);
L_temp = Mpy_32_16 (hi, lo, gain_pit);
L_temp = L_shl (L_temp, 1);
L_temp = L_add (0x00004000L, L_temp);
L_acc = L_sub (L_temp, L_worst);
if (L_acc > 0L)
L_worst = L_temp;
}
}
for (i = 3; i >= 1; i--) {
coder->L_exc_err[i] = coder->L_exc_err[i - 1];
}
coder->L_exc_err[0] = L_worst;
return;
}

145
src/libs/libg729/util.c Normal file
View File

@@ -0,0 +1,145 @@
/*
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 Set zero() *
* ~~~~~~~~~~ *
* Set vector x[] to zero *
*-------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "ld8a.h"
#include "tab_ld8a.h"
void
Set_zero (Word16 x[], Word16 L)
{
Word16 i;
for (i = 0; i < L; i++)
x[i] = 0;
return;
}
/*-------------------------------------------------------------------*
* Function Copy: *
* ~~~~~ *
* Copy vector x[] to y[] *
*-------------------------------------------------------------------*/
void
Copy (Word16 x[], Word16 y[], Word16 L)
{
Word16 i;
for (i = 0; i < L; i++)
y[i] = x[i];
return;
}
/* Random generator */
Word16
Random_16 (Word16* seed)
{
/* seed = seed*31821 + 13849; */
*seed = extract_l (L_add (L_shr (L_mult (*seed, 31821), 1), 13849L));
return (*seed);
}
/*----------------------------------------------------------------------------
* Store_Param - converts encoder parameter vector into frame
* Restore_Params - converts serial received frame to encoder parameter vector
*
* The transmitted parameters are:
*
* LPC: 1st codebook 7+1 bit
* 2nd codebook 5+5 bit
*
* 1st subframe:
* pitch period 8 bit
* parity check on 1st period 1 bit
* codebook index1 (positions) 13 bit
* codebook index2 (signs) 4 bit
* pitch and codebook gains 4+3 bit
*
* 2nd subframe:
* pitch period (relative) 5 bit
* codebook index1 (positions) 13 bit
* codebook index2 (signs) 4 bit
* pitch and codebook gains 4+3 bit
*----------------------------------------------------------------------------
*/
void
Store_Params(Word16 * parm, void *to)
{
int i, j;
unsigned char mask, *to_b;
Word16 value, val_mask;
to_b = (unsigned char *)to;
mask = 0x80;
for (i = 0; i < PRM_SIZE; i++) {
value = parm[i];
val_mask = 1 << (bitsno[i] - 1);
for (j = 0; j < bitsno[i]; j++) {
if (value & val_mask)
*to_b |= mask;
else
*to_b &= ~mask;
value = value << 1;
mask = mask >> 1;
if (mask == 0) {
mask = 0x80;
to_b++;
}
}
}
return;
}
void Restore_Params(const void *from, Word16 * parm)
{
int i, j;
unsigned char mask, *from_b;
Word16 value;
mask = 0x80;
from_b = (unsigned char *)from;
for (i = 0; i < PRM_SIZE; i++) {
value = 0;
for (j = 0; j < bitsno[i]; j++) {
value = value << 1;
if (mask & (*from_b))
value += 1;
mask = mask >> 1;
if (mask == 0) {
mask = 0x80;
from_b++;
}
}
parm[i] = value;
}
return;
}