www.pudn.com > p_voice.rar > CODLD8CP.C
/*
ITU-T G.729 Annex C+ - Reference C code for floating point
implementation of G.729 Annex C+
(integration of Annexes B, D and E)
Version 2.1 of October 1999
*/
/*
File : CODLD8CP.C
*/
/*-----------------------------------------------------------------*
* Functions coder_ld8c and init_coder_ld8c *
* ~~~~~~~~~~ ~~~~~~~~~~~~~~~ *
*-----------------------------------------------------------------*/
#include
#include "typedef.h"
#include "ld8k.h"
#include "ld8cp.h"
#include "tab_ld8k.h"
#include "vad.h"
#include "dtx.h"
#include "sid.h"
/*-----------------------------------------------------------*
* Coder constant parameters (defined in "ld8k.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 *
*-----------------------------------------------------------*/
/*--------------------------------------------------------*
* Static memory allocation. *
*--------------------------------------------------------*/
/* Speech vector */
static FLOAT old_speech[L_TOTAL];
static FLOAT *speech, *p_window;
FLOAT *new_speech; /* Global variable */
/* Weighted speech vector */
static FLOAT old_wsp[L_FRAME+PIT_MAX];
static FLOAT *wsp;
/* Excitation vector */
static FLOAT old_exc[L_FRAME+PIT_MAX+L_INTERPOL];
static FLOAT *exc;
/* Zero vector */
static FLOAT ai_zero[L_SUBFR+M_BWDP1];
static FLOAT *zero;
/* Lsp (Line spectral pairs) */
static FLOAT lsp_old[M]=
{ (F)0.9595, (F)0.8413, (F)0.6549, (F)0.4154, (F)0.1423,
(F)-0.1423, (F)-0.4154, (F)-0.6549, (F)-0.8413, (F)-0.9595};
static FLOAT lsp_old_q[M];
/* Filter's memory */
static FLOAT mem_syn[M_BWD], mem_w0[M_BWD], mem_w[M_BWD];
static FLOAT mem_err[M_BWD+L_SUBFR], *error;
static FLOAT pit_sharp;
/* For G.729B */
/* DTX variables */
static int pastVad;
static int ppastVad;
static INT16 seed;
/* for G.729E */
/* for the backward analysis */
static FLOAT prev_filter[M_BWDP1]; /* Previous selected filter */
static FLOAT rexp[M_BWDP1];
static FLOAT synth[L_ANA_BWD];
static FLOAT *synth_ptr;
static int prev_lp_mode ;
static FLOAT gamma1[2], gamma2[2]; /* Weighting factor for the 2 subframes */
static FLOAT A_t_bwd_mem[M_BWDP1];
static int bwd_dominant;
static FLOAT C_int; /* See file bwfw.c */
static INT16 glob_stat; /* Mesure of global stationnarity */
static INT16 stat_bwd; /* Nbre of consecutive backward frames */
static INT16 val_stat_bwd; /* Value associated with stat_bwd */
/* Last backward A(z) for case of unstable filter */
static FLOAT old_A_bwd[M_BWDP1];
static FLOAT old_rc_bwd[2];
/* Last forkward A(z) for case of unstable filter */
static FLOAT old_A_fwd[MP1];
static FLOAT old_rc_fwd[2];
static FLOAT freq_prev[MA_NP][M]; /* previous LSP vector */
static int lag_buf[5]={20,20, 20, 20,20};
static FLOAT pgain_buf[5]={(F)0.7,(F)0.7, (F)0.7, (F)0.7,(F)0.7};
#define AVG(a,b,c,d) (int)(((a)+(b)+(c)+(d))/((F)4.0)+(F)0.5)
/*----------------------------------------------------------------------------
* init_coder_ld8c - initialization of variables for the encoder
*----------------------------------------------------------------------------
*/
void init_coder_ld8c(
int dtx_enable /* input : DTX enable flag */
)
{
/*-----------------------------------------------------------------------*
* 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_wind | | *
* speech | *
* new_speech *
*-----------------------------------------------------------------------*/
int i;
new_speech = old_speech + L_TOTAL - L_FRAME; /* New speech */
speech = new_speech - L_NEXT; /* Present frame */
p_window = old_speech + L_TOTAL - L_WINDOW; /* For LPC window */
/* Initialize static pointers */
wsp = old_wsp + PIT_MAX;
exc = old_exc + PIT_MAX + L_INTERPOL;
zero = ai_zero + M_BWDP1;
error = mem_err + M_BWD;
/* Static vectors to zero */
set_zero(old_speech, L_TOTAL);
set_zero(old_exc, PIT_MAX+L_INTERPOL);
set_zero(old_wsp, PIT_MAX);
set_zero(mem_syn, M_BWD);
set_zero(mem_w, M_BWD);
set_zero(mem_w0, M_BWD);
set_zero(mem_err, M_BWD);
set_zero(zero, L_SUBFR);
pit_sharp = SHARPMIN;
/* Initialize lsp_old_q[] */
copy(lsp_old, lsp_old_q, M);
lsp_encw_resete(freq_prev);
init_exc_err();
/* For G.729B */
/* Initialize VAD/DTX parameters */
if(dtx_enable == 1) {
pastVad = 1;
ppastVad = 1;
seed = INIT_SEED;
vad_init();
init_lsfq_noise();
}
/* for G.729E */
/* for the backward analysis */
set_zero(synth, L_ANA_BWD);
synth_ptr = synth + MEM_SYN_BWD;
prev_lp_mode = 0;
bwd_dominant = 0; /* See file bwfw.c */
C_int = (F)1.1; /* Filter interpolation parameter */
glob_stat = 10000; /* Mesure of global stationnarity */
stat_bwd = 0; /* Nbre of consecutive backward frames */
val_stat_bwd = 0; /* Value associated with stat_bwd */
for(i=0; i, , , ,*/
/* Scalars */
int i, j, i_gamma, i_subfr;
int T_op, t0, t0_min, t0_max, t0_frac;
int index, taming;
FLOAT gain_pit, gain_code;
/* for G.729E */
int sat_filter;
FLOAT freq_cur[M];
/* For G.729B */
FLOAT r_nbe[MP1];
FLOAT lsfq_mem[MA_NP][M];
int Vad;
FLOAT Energy_db;
int avg_lag;
/*------------------------------------------------------------------------*
* - 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) *
*------------------------------------------------------------------------*/
/* ------------------- */
/* LP Forward analysis */
/* ------------------- */
autocorr(p_window, NP, r_fwd); /* Autocorrelations */
copy(r_fwd, r_nbe, MP1);
lag_window(NP, r_fwd); /* Lag windowing */
levinsone(M, r_fwd, &A_t_fwd[MP1], rc_fwd, /* Levinson Durbin */
old_A_fwd, old_rc_fwd );
az_lsp(&A_t_fwd[MP1], lsp_new, lsp_old); /* From A(z) to lsp */
/* For G.729B */
/* ------ VAD ------- */
if (dtx_enable == 1) {
lsp_lsf(lsp_new, lsf_new, M);
vad(rc_fwd[1], lsf_new, r_fwd, p_window, frame,
pastVad, ppastVad, &Vad, &Energy_db);
musdetect( rate, r_fwd[0],rc_fwd, lag_buf , pgain_buf,
prev_lp_mode, frame,pastVad, &Vad, Energy_db);
update_cng(r_nbe, Vad);
}
else Vad = 1;
/* -------------------- */
/* LP Backward analysis */
/* -------------------- */
if ( (rate-(1-Vad))== G729E) {
/* LPC recursive Window as in G728 */
autocorr_hyb_window(synth, r_bwd, rexp); /* Autocorrelations */
lag_window_bwd(r_bwd); /* Lag windowing */
levinsone(M_BWD, r_bwd, &A_t_bwd[M_BWDP1], rc_bwd,
old_A_bwd, old_rc_bwd );
/* Tests saturation of A_t_bwd */
sat_filter = 0;
for (i=M_BWDP1; i<2*M_BWDP1; i++) if (A_t_bwd[i] >= (F)8.) sat_filter = 1;
if (sat_filter == 1) copy(A_t_bwd_mem, &A_t_bwd[M_BWDP1], M_BWDP1);
else copy(&A_t_bwd[M_BWDP1], A_t_bwd_mem, M_BWDP1);
/* Additional bandwidth expansion on backward filter */
weight_az(&A_t_bwd[M_BWDP1], GAMMA_BWD, M_BWD, &A_t_bwd[M_BWDP1]);
}
/*--------------------------------------------------*
* Update synthesis signal for next frame. *
*--------------------------------------------------*/
copy(&synth[L_FRAME], &synth[0], MEM_SYN_BWD);
/*--------------------------------------------------------------------*
* Find interpolated LPC parameters in all subframes unquantized. *
* The interpolated parameters are in array A_t[] of size (M+1)*4 *
*---------------------------------------------------------------------*/
if( prev_lp_mode == 0) {
int_lpc(lsp_old, lsp_new, lsf_int, lsf_new, A_t_fwd);
}
else {
/* no interpolation */
/* unquantized */
lsp_az(lsp_new, A_t_fwd); /* Subframe 1 */
lsp_lsf(lsp_new, lsf_new, M); /* transformation from LSP to LSF (freq.domain) */
copy(lsf_new, lsf_int, M); /* Subframe 1 */
}
if(Vad == 1) {
/* ---------------- */
/* LSP quantization */
/* ---------------- */
qua_lspe(lsp_new, lsp_new_q, code_lsp, freq_prev, freq_cur);
/*-------------------------------------------------------------------*
* Find interpolated LPC parameters in all subframes quantized. *
* and the quantized interpolated parameters are in array Aq_t[] *
*--------------------------------------------------------------------*/
if( prev_lp_mode == 0) {
int_qlpc(lsp_old_q, lsp_new_q, A_t_fwd_q);
}
else {
/* no interpolation */
lsp_az(lsp_new_q, &A_t_fwd_q[MP1]); /* Subframe 2 */
copy(&A_t_fwd_q[MP1], A_t_fwd_q, MP1); /* Subframe 1 */
}
/*---------------------------------------------------------------------*
* - Decision for the switch Forward / Backward *
*---------------------------------------------------------------------*/
if(rate == G729E) {
set_lpc_mode(speech, A_t_fwd_q, A_t_bwd, &lp_mode,
lsp_new, lsp_old, &bwd_dominant, prev_lp_mode, prev_filter, &C_int,
&glob_stat, &stat_bwd, &val_stat_bwd);
}
else
update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat);
}
else
update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat);
/* ---------------------------------- */
/* update the LSPs for the next frame */
/* ---------------------------------- */
copy(lsp_new, lsp_old, M);
/*----------------------------------------------------------------------*
* - Find the weighted input speech w_sp[] for the whole speech frame *
*----------------------------------------------------------------------*/
if(lp_mode == 0) {
m_ap = M;
if (bwd_dominant == 0) Ap = A_t_fwd;
else Ap = A_t_fwd_q;
perc_var(gamma1, gamma2, lsf_int, lsf_new, rc_fwd);
}
else {
if (bwd_dominant == 0) {
m_ap = M;
Ap = A_t_fwd;
}
else {
m_ap = M_BWD;
Ap = A_t_bwd;
}
perc_vare(gamma1, gamma2, bwd_dominant);
}
pAp = Ap;
for (i=0; i<2; i++) {
weight_az(pAp, gamma1[i], m_ap, Ap1);
weight_az(pAp, gamma2[i], m_ap, Ap2);
residue(m_ap, Ap1, &speech[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR);
syn_filte(m_ap, Ap2, &wsp[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR,
&mem_w[M_BWD-m_ap], 0);
for(j=0; j PIT_MAX) {
t0_max = PIT_MAX;
t0_min = 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 *
* - update the impulse response h1[] by including fixed-gain pitch *
* - find target vector for codebook search *
* - codebook search *
* - encode codebook address *
* - VQ of pitch and codebook gains *
* - find synthesis speech *
* - update states of weighting filter *
*------------------------------------------------------------------------*/
pAp = Ap; /* pointer to interpolated "unquantized"LPC parameters */
pAq = Aq; /* pointer to interpolated "quantized" LPC parameters */
i_gamma = 0;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
/*---------------------------------------------------------------*
* Find the weighted LPC coefficients for the weighting filter. *
*---------------------------------------------------------------*/
weight_az(pAp, gamma1[i_gamma], m_ap, Ap1);
weight_az(pAp, gamma2[i_gamma], m_ap, Ap2);
i_gamma++;
/*---------------------------------------------------------------*
* Compute impulse response, h1[], of weighted synthesis filter *
*---------------------------------------------------------------*/
for (i = 0; i <=m_ap; i++) ai_zero[i] = Ap1[i];
syn_filte(m_aq, pAq, ai_zero, h1, L_SUBFR, zero, 0);
syn_filte(m_ap, Ap2, h1, h1, L_SUBFR, zero, 0);
/*------------------------------------------------------------------------*
* *
* Find the target vector for pitch search: *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* *
* |------| res[n] *
* speech[n]---| A(z) |-------- *
* |------| | |--------| error[n] |------| *
* zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
* exc |--------| |------| *
* *
* Instead of subtracting the zero-input response of filters from *
* the weighted input speech, the above configuration is used to *
* compute the target vector. This configuration gives better performance *
* with fixed-point implementation. The memory of 1/A(z) is updated by *
* filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting *
* the synthesis speech from the input speech: *
* error[n] = speech[n] - syn[n]. *
* The memory of W(z) is updated by filtering error[n] through W(z), *
* or more simply by subtracting the filtered adaptive and fixed *
* codebook excitations from the target: *
* target[n] - gain_pit*y1[n] - gain_code*y2[n] *
* as these signals are already available. *
* *
*------------------------------------------------------------------------*/
residue(m_aq, pAq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); /* LPC residual */
for (i=0; i> 1) & 0x0001);
}
ana++;
}
/*-----------------------------------------------------------------*
* - find unity gain pitch excitation (adaptive codebook entry) *
* with fractional interpolation. *
* - find filtered pitch exc. y1[]=exc[] convolve with h1[]) *
* - compute pitch gain and limit between 0 and 1.2 *
* - update target vector for codebook search *
* - find LTP residual. *
*-----------------------------------------------------------------*/
pred_lt_3(&exc[i_subfr], t0, t0_frac, L_SUBFR);
convolve(&exc[i_subfr], h1, y1, L_SUBFR);
gain_pit = g_pitch(xn, y1, g_coeff, L_SUBFR);
/* clip pitch gain if taming is necessary */
taming = test_err(t0, t0_frac);
if(taming == 1){
if ( gain_pit> GPCLIP) {
gain_pit = GPCLIP;
}
}
for (i = 0; i < L_SUBFR; i++)
xn2[i] = xn[i] - y1[i]*gain_pit;
/*-----------------------------------------------------*
* - Innovative codebook search. *
*-----------------------------------------------------*/
switch (rate) {
case G729: /* 8 kbit/s */
{
index = ACELP_codebook(xn2, h1, t0, pit_sharp, i_subfr, code,
y2, &i);
*ana++ = index; /* Positions index */
*ana++ = i; /* Signs index */
break;
}
case G729D: /* 6.4 kbit/s */
{
index = ACELP_codebook64(xn2, h1, t0, pit_sharp, code, y2, &i);
*ana++ = index; /* Positions index */
*ana++ = i; /* Signs index */
break;
}
case G729E: /* 11.8 kbit/s */
{
/*-----------------------------------------------------------------*
* Include fixed-gain pitch contribution into impulse resp. h[] *
*-----------------------------------------------------------------*/
if(t0 < L_SUBFR) {
for (i = t0; i < L_SUBFR; i++) {
h1[i] += pit_sharp * h1[i-t0];
}
}
/* calculate residual after long term prediction */
for (i = 0; i < L_SUBFR; i++)
res2[i] -= gain_pit*exc[i+i_subfr];
if (lp_mode == 0)
ACELP_10i40_35bits(xn2, res2, h1, code, y2, ana); /* Forward */
else
ACELP_12i40_44bits(xn2, res2, h1, code, y2, ana); /* Backward */
ana += 5;
/*-----------------------------------------------------------------*
* Include fixed-gain pitch contribution into code[]. *
*-----------------------------------------------------------------*/
if(t0 < L_SUBFR)
for (i = t0; i < L_SUBFR; i++)
code[i] += pit_sharp * code[i-t0];
break;
}
default : {
printf("Unrecognized bit rate\n");
exit(-1);
}
} /* end of switch */
/*-----------------------------------------------------*
* - Quantization of gains. *
*-----------------------------------------------------*/
corr_xy2( xn, y1, y2, g_coeff);
if (rate == G729D)
index = qua_gain_6k(code, g_coeff, L_SUBFR, &gain_pit, &gain_code, taming );
else
index = qua_gain(code, g_coeff, L_SUBFR, &gain_pit, &gain_code, taming);
*ana++ = index;
/*------------------------------------------------------------*
* - Update pitch sharpening with quantized gain_pit *
*------------------------------------------------------------*/
for (i= 0; i< 4; i++)
pgain_buf[i] = pgain_buf[i+1];
pgain_buf[4] = gain_pit;
pit_sharp = gain_pit;
if (pit_sharp > SHARPMAX) pit_sharp = SHARPMAX;
if (pit_sharp < SHARPMIN) pit_sharp = SHARPMIN;
/*------------------------------------------------------*
* - Find the total excitation *
* - find synthesis speech corresponding to exc[] *
* - update filters memories for finding the target *
* vector in the next subframe *
* (update error[-m..-1] and mem_w_err[]) *
* update error function for taming process *
*------------------------------------------------------*/
for (i = 0; i < L_SUBFR; i++)
exc[i+i_subfr] = gain_pit*exc[i+i_subfr] + gain_code*code[i];
update_exc_err(gain_pit, t0);
syn_filte(m_aq, pAq, &exc[i_subfr], &synth_ptr[i_subfr], L_SUBFR,
&mem_syn[M_BWD-m_aq], 0);
for(j=0; j shift to the left by L_FRAME: *
* speech[], wsp[] and exc[] *
*--------------------------------------------------*/
copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME);
copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX);
copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL);
prev_lp_mode = lp_mode;
return;
}