⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bwfw.c

📁 语音编码G.729 语音编码G.729
💻 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*/                                   /* ----------------------------------------------------------------- *//*               DUAL BACKWARD / FORWARD LPC STRUCTURE               *//*                                                                   *//*                 switching and decision procedures                 *//*                                                                   *//*                                                                   *//*                 (C) Copyright 1997 : France Telecom               *//*                                                                   *//* ----------------------------------------------------------------- *//* ----------------------------------------------------------------------- *//*                                                                         *//*  Procedures :             1) SET_LPC_MODE                               *//*                           3) CALC_STAT                                  *//*                                                                         *//* ----------------------------------------------------------------------- */#include <stdio.h>#include <math.h>#include "typedef.h"#include "ld8k.h"#include "ld8cp.h"#include "tabld8cp.h"static void calc_stat(FLOAT gpred_b, FLOAT gpred_f, int mode,		int prev_mode, INT16 *glob_stat, INT16 *stat_bwd, INT16 *val_stat_bwd);/* ---------------------------------------------------------------------- *//*                              SET_LPC_MODE                              *//*                                                                        *//*                    BACKWARD <--> FORWARD DECISION                      *//* ---------------------------------------------------------------------- */void set_lpc_mode(	struct bwd_state_t *state,	FLOAT *signal_ptr,  /* I   Input signal */	FLOAT *a_fwd,       /* I   Forward LPC filter */	FLOAT *a_bwd,       /* I   Backward LPC filter */	int *mode,          /* O  Backward / forward Indication */	FLOAT *lsp_new,     /* I   LSP vector current frame */	FLOAT *lsp_old,     /* I   LSP vector previous frame */	int *bwd_dominant,  /* O   Bwd dominant mode indication */	int prev_mode,      /* I   previous frame Backward / forward Indication */	FLOAT *prev_filter, /* I   previous frame filter */	FLOAT *C_int,       /*I/O filter interpolation parameter */	INT16 *glob_stat,   /* I/O Mre of global stationnarity */	INT16 *stat_bwd,    /* I/O Number of consecutive backward frames */	INT16 *val_stat_bwd /* I/O Value associated with stat_bwd */){    int     i;    FLOAT  res[L_FRAME];    FLOAT  *pa_bwd;    FLOAT  gap;    FLOAT  gpred_f, gpred_b, gpred_bint;    FLOAT  tmp;    FLOAT  thresh_lpc;    FLOAT  dist_lsp, energy;    pa_bwd = a_bwd + M_BWDP1;    /* Backward filter prediction gain (no interpolation ) */    /* --------------------------------------------------- */    residue(M_BWD,pa_bwd, signal_ptr, res, L_FRAME);    gpred_b = ener_dB(signal_ptr, L_FRAME) - ener_dB(res, L_FRAME);    /* Interpolated LPC filter for transition forward -> backward */    /* (used during 10 frames) ( for the second sub-frame )       */    /* Interpolated backward filter for the first sub-frame       */    /* ---------------------------------------------------------- */    int_bwd(a_bwd, prev_filter, C_int);    /* Interpolated backward filter prediction gain */    /* -------------------------------------------- */    residue(M_BWD,a_bwd, signal_ptr, res, L_SUBFR);    residue(M_BWD,pa_bwd, &signal_ptr[L_SUBFR], &res[L_SUBFR], L_SUBFR);    gpred_bint = ener_dB(signal_ptr, L_FRAME) - ener_dB(res, L_FRAME);    /* Forward filter prediction gain */    /* ------------------------------ */    residue(M, a_fwd, signal_ptr, res, L_SUBFR);    residue(M, &a_fwd[MP1], &signal_ptr[L_SUBFR], &res[L_SUBFR], L_SUBFR);    gpred_f = ener_dB(signal_ptr, L_FRAME) - ener_dB(res, L_FRAME);    /* -------------------------------------------------------------- */    /*                  BACKWARD / FORWARD DECISION                   */    /*                                                                */    /* The Main criterion is based on the prediction gains :          */    /* The global stationnarity index is used to adapt the threshold  */    /* value " GAP ".                                                 */    /* This adaptation is used to favour one mode according to the    */    /* stationnarity of the input signal (backward for music and      */    /* forward for speech) which avoids too many switches.            */    /*                                                                */    /* A second criterion based on the LSPs is used to avoid switches */    /* if the successive LPC forward filters are very stationnary     */    /* (which is measured a Euclidean distance on LSPs).              */    /*                                                                */    /* -------------------------------------------------------------- */    /* 1st criterion with prediction gains */    /* ----------------------------------- */    /* Threshold adaptation according to the global stationnarity indicator */    gap = (FLOAT)(*glob_stat) * GAP_FACT;    gap += (F)1.;    if ( (gpred_bint > gpred_f - gap)&& (gpred_b > gpred_f - gap)&&         (gpred_b > (F)0.)               && (gpred_bint > (F)0.) ) *mode = 1;    else *mode = 0;    if (*glob_stat < 13000) *mode = 0; /* => Forward mode imposed */    /* 2nd criterion with a distance between 2 successive LSP vectors */    /* -------------------------------------------------------------- */    /* Computation of the LPC distance */    dist_lsp = 0;    for(i=0; i<M; i++){        tmp = lsp_old[i] - lsp_new[i];        dist_lsp += tmp * tmp;    }    /* Adaptation of the LSPs thresholds */    if (*glob_stat < 32000) {        thresh_lpc = (F)0.;    }    else {        thresh_lpc = (F)0.03;    }    /* Switching backward -> forward forbidden in case of a LPC stationnary */    if ((dist_lsp < thresh_lpc) &&(*mode == 0)&&(prev_mode == 1)         &&(gpred_b > (F)0.)&&(gpred_bint > (F)0.)) {        *mode = 1;    }    /* Low energy frame => Forward mode chosen */    /* --------------------------------------- */    energy = ener_dB(signal_ptr, L_FRAME);    if (energy < THRES_ENERGY) {        *mode = 0;        if (*glob_stat > 13000) *glob_stat = 13000;    }    else		tst_bwd_dominant(state, bwd_dominant, *mode);    /* Adaptation of the global stationnarity indicator */    /* ------------------------------------------------ */    if (energy >= THRES_ENERGY) calc_stat(gpred_b, gpred_f, *mode,                            prev_mode, glob_stat, stat_bwd, val_stat_bwd);    if(*mode == 0)		*C_int = (F)1.1;}void update_bwd(int *mode,        /* O  Backward / forward Indication */                int *bwd_dominant,/* O   Bwd dominant mode indication */                FLOAT *C_int,       /*I/O filter interpolation parameter */                INT16 *glob_stat   /* I/O Mre of global stationnarity */){    /* BIT RATES IN FORWARD MODE ONLY */    /* ------------------------------ */    if (*glob_stat > 10000) {        *glob_stat -= 2621;        if( *glob_stat < 10000) *glob_stat = 10000 ;    }    *mode = 0;/*  tst_bwd_dominant(bwd_dominant, *mode);*/    *bwd_dominant = 0;    *C_int = (F)1.1;}/* ---------------------------------------------------------------------- *//*                             CALC_STAT                                  *//*                                                                        *//* Adaptation of the global stationnarity indicator "stat" in [0 ; 32000] *//*                                                                        *//*                       0 => very low stationnariy                       *//*                   32000 => very high stationnarity                     *//*                                                                        *//*            This indicator is based on the performances of              *//*               the backward and forward LPC predictions                 *//*                                                                        *//* ---------------------------------------------------------------------- */static void calc_stat( FLOAT gpred_b, /* I  Backward prediction gain */                FLOAT gpred_f, /* I  Forward prediction gain */                int mode,      /* I  LPC mode indication */                int prev_mode, /* I  previous frame LPC mode */                INT16 *glob_stat,   /* I/O Mre of global stationnarity  */                INT16 *stat_bwd,   /* I/O Number of consecutive backward frames */                INT16 *val_stat_bwd/* I/O Value associated with stat_bwd */){    INT16 s_temp;    /* --------------------------------------------------------------- */    /* First adaptation based on previous backward / forward decisions */    /* --------------------------------------------------------------- */    if (mode == 1) { /* Backward stationnary mode */        (*stat_bwd)++;        if(*stat_bwd > 21) *stat_bwd = 21;        if(*val_stat_bwd < 32517) *val_stat_bwd  += 250;        else *val_stat_bwd = 32767;        /* after 20 backward frames => increase stat */        if (*stat_bwd == 20) {            if(*glob_stat < 30267) *glob_stat += 2500;            else *glob_stat = 32767;        }        else if (*stat_bwd > 20) *glob_stat += 500;    }    else if ((mode == 0)&&(prev_mode == 1)) { /* Backward -> Forward transition */        /* Transition occurs after less than 20 backward frames => decrease stat */        if (*stat_bwd < 20) {            s_temp = (INT16)(5000 - *val_stat_bwd);            *glob_stat = (INT16)(*glob_stat-s_temp);        }        /* Reset consecutive backward frames counter */        *stat_bwd = 0;        *val_stat_bwd = 0;    }    /* ------------------------------------------- */    /* Second adaptation based on prediction gains */    /* ------------------------------------------- */    if (*glob_stat < 13000) {        if      (gpred_b > gpred_f + TH4) *glob_stat += 3200;        else if (gpred_b > gpred_f + TH3) *glob_stat += 2400;        else if (gpred_b > gpred_f + TH2) *glob_stat += 1600;        else if (gpred_b > gpred_f + TH1) *glob_stat +=  800;        else if (gpred_b > gpred_f +   (F)0.) *glob_stat +=  400;    }    if      (gpred_b < gpred_f -  TH5) *glob_stat -= 6400;    else if (gpred_b < gpred_f -  TH4) *glob_stat -= 3200;    else if (gpred_b < gpred_f -  TH3) *glob_stat -= 1600;    else if (gpred_b < gpred_f -  TH2) *glob_stat -=  800;    else if (gpred_b < gpred_f -  TH1) *glob_stat -=  400;    if( *glob_stat > 32000) *glob_stat = 32000;    else {        if(*glob_stat < 0) *glob_stat = 0;    }    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -