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

📄 g729ev_tdbwe_generate_excitation.c

📁 最新的ITU-T的宽带语音编解码标准G.729.1,是对原先的G.729的最好的调整.码流输出速率可以进行自适应调整.满足未来通信要求.希望对大家有所帮助.
💻 C
字号:
/* ITU-T G.729EV Optimization/Characterization Candidate                         *//* Version:       1.0.a                                                          *//* Revision Date: June 28, 2006                                                  *//*   ITU-T G.729EV Optimization/Characterization Candidate    ANSI-C Source Code   Copyright (c) 2006    France Telecom, Matsushita Electric, Mindspeed, Siemens AG, ETRI, VoiceAge Corp.   All rights reserved*/#include "G729EV_TDBWE_generate_excitation.h"#include "G729EV_MAIN_DSPFUNC.h"#include "G729EV_G729_ld8k.h"/*--------------------------------------------------------------------------* *  Function  G729EV_TDBWE_rand()                                           * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                           * *  TDBWE random generator,                                                 * *  Same as Random() of G.729, except for seed type (Word32)                * *--------------------------------------------------------------------------*/Word16 G729EV_TDBWE_rand(Word32 * seed) /* (i/o) */{  Word16    tmp;  /* seed = seed*31821 + 13849; */  tmp = extract_l(*seed);  *seed = L_add(L_shr(L_mult(tmp, 31821), 1), 13849L);  return extract_l(*seed);}/*--------------------------------------------------------------------------* *  Function  G729EV_TDBWE_generate_excitation_initialize()                 * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                 * *  initialization of TDBWE excitation generator                            * *--------------------------------------------------------------------------*/void G729EV_TDBWE_generate_excitation_initialize(G729EV_TDBWE_generate_excitation_state * state)  /* (i/o) */{  G729EV_G729_Set_zero(state->signal_tonal_buffer, G729EV_TDBWE_LENGTH_PULSE_SHAPE);  G729EV_MAIN_init_lp3k(&(state->lowpass_3_kHz));  state->old_lag = 60;  state->old_gain_tonal = 0;  state->prev_pulse = G729EV_TDBWE_L_FRAME2;  state->prev_pulse_frac = 0;  state->seed = 0x78a426da;     /* (((-1) ^ MASK) + 0x7fffffff) */#ifdef WMOPS  move16();  move16();  move16();  move16();  move32();#endif}/*--------------------------------------------------------------------------* *  Function  G729EV_TDBWE_generate_excitation_initialize()                 * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                 * *  TDBWE excitation generator: produce pitch-synchronous excitation        * *  signal based on G.729 parameters                                        * *--------------------------------------------------------------------------*/void G729EV_TDBWE_generate_excitation(G729EV_TDBWE_generate_excitation_state * state, /* (i/o) */                                      G729EV_TDBWE_g729_info * parameters,            /* (i) parameters from G.729A+ (8k/12k layers) */                                      Word16 * output)                                /* (o) Q.12, output signal */{  Word16    i, l;  Word16    gain_tonal[2];  Word16    new_gain_tonal;  Word16    new_gain_tonal_sq;  Word16    gain_noise[2];  Word16    lag[2] = { 0, 0 };  Word16    frac_lag[2] = { 0, 0 };  Word16    next_pulse;  Word16    next_pulse_frac;  Word16    signal_tonal[G729EV_TDBWE_L_FRAME2 + G729EV_TDBWE_LENGTH_PULSE_SHAPE];  Word16    lfr_raw, lfr;  Word16    lfr_raw_nls, lfr_nls;  Word32    lfrsquare32;  Word16    lfrsq_nls;  Word32    power_fix32;  Word32    power_ltp32;  Word16    power_fix;  Word16    norm1, norm2, tmp;  Word32    acc;  Word16    lag_tmp, wlim;  Word16    gain;  Word16   *ps;  const Word16 *psf;  Word16    factor;  Word16    error;  Word16    new_lag;  /* Compute ltp-to-fix power ratio (LFR) from NB excitation.     We implicitly assume here that the adaptive codebook contributes     only tonal components and the fixed codebook contributes noisy     components only, and that the contributions are orthogonal. */  FOR(l = 0; l < 2; l++)       /* for two 5ms subframes */  {    power_fix32 = parameters->power_fix[l];    power_ltp32 = parameters->power_ltp[l];#ifdef WMOPS    move32();    move32();#endif    IF(power_fix32)    {      norm1 = norm_l(power_fix32);    }    ELSE    {      norm1 = 32;#ifdef WMOPS      move16();#endif    }    IF(power_ltp32)    {      norm2 = sub(norm_l(power_ltp32), 1);    }    ELSE    {      norm2 = 31;#ifdef WMOPS      move16();#endif    }    power_fix = round(L_shl(power_fix32, norm1));    power_ltp32 = L_shl(power_ltp32, norm2);  /* for norm2==-1 this is a rightshift */    /* instantaneous ltp-to-fix ratio (LFR) */    IF(power_fix > 0)    {      lfr_raw = div_l(power_ltp32, power_fix);      lfr_raw_nls = sub(add(norm2, 15), norm1);    }    ELSE    {      lfr_raw = 0;      lfr_raw_nls = 16;#ifdef WMOPS      move16();      move16();#endif    }    /* apply kind of "Wiener filtering" to get "nice" noise segments later */    /* lfr = lfr_raw * lfr_raw / ( 1.0f + lfr_raw ); */    lfrsquare32 = L_mult(lfr_raw, lfr_raw);    lfrsq_nls = add(shl(lfr_raw_nls, 1), 1);    IF(sub(lfr_raw_nls, 14) > 0)    {      lfr_raw = shr(lfr_raw, sub(lfr_raw_nls, 14));      lfr_raw_nls = 14;#ifdef WMOPS      move16();#endif    }    IF(sub(lfr_raw, 0x4000) >= 0)    {      lfr_raw = shr(lfr_raw, 1);      lfr_raw_nls = sub(lfr_raw_nls, 1);    }    lfr_raw = add(shl(1, lfr_raw_nls), lfr_raw);    norm1 = norm_s(lfr_raw);    norm2 = sub(norm_l(lfrsquare32), 1);    lfr = div_l(L_shl(lfrsquare32, norm2), shl(lfr_raw, norm1));    lfr_nls = sub(sub(add(norm2, lfrsq_nls), add(norm1, lfr_raw_nls)), 1);    /* determine gain factors (incl. gliding average length 2) */    IF(sub(lfr_nls, 14) > 0)    {      lfr = shr(lfr, sub(lfr_nls, 14));      lfr_nls = 14;#ifdef WMOPS      move16();#endif    }    IF(sub(lfr, 0x4000) >= 0)    {      lfr = shr(lfr, 1);      lfr_nls = sub(lfr_nls, 1);    }    tmp = add(shl(1, lfr_nls), lfr);    norm1 = norm_s(tmp);    lfr = div_s(shl(lfr, norm1), shl(tmp, norm1));    gain_tonal[l] = sqrt_q15(lfr);  /* gain_tonal is Q.15 */#ifdef WMOPS    move16();#endif    acc = L_mult0(gain_tonal[l], gain_tonal[l]);    acc = L_mac0(acc, state->old_gain_tonal, state->old_gain_tonal);    new_gain_tonal_sq = round(acc); /* new_gain_tonal_sq is Q.15 */    new_gain_tonal = sqrt_q15(new_gain_tonal_sq);    state->old_gain_tonal = gain_tonal[l];    gain_tonal[l] = new_gain_tonal;#ifdef WMOPS    move16();    move16();#endif    tmp = add(new_gain_tonal_sq, -32768);    gain_noise[l] = sqrt_q15(negate(tmp));  /* gain_noise is Q.15 */#ifdef WMOPS    move16();#endif  }  /* Remove certain obvious pitch-doubling errors from pitch lag     contour.  Here, we assume that a rise of the pitch lag by     (about) an integer factor from one sub-frame to another     corresponds to a beginning pitch-doubling error. A small drawback     is that this mechanism may produce half-pitch errors. */  FOR(l = 0; l < 2; l++)       /* for two 5ms subframes */  {    lag_tmp = add(i_mult(6, (Word16) parameters->lag[l]), shl((Word16) parameters->frac_lag[l], 1));    /* (int) floor ( (REAL) lag[l] / (REAL) state->old_lag + 0.5 )); */    factor = shr(add(div_l(shl(lag_tmp, 2), state->old_lag), 1), 1);    /* if factor>1 && factor<5 */    IF(sub(factor, 1) > 0)    {      IF(sub(factor, 5) < 0)      {        tmp = i_mult(factor, state->old_lag);        norm1 = norm_s(tmp);        norm2 = norm_s(lag_tmp);        error = shr(div_s(shl(lag_tmp, sub(norm2, 1)), shl(tmp, norm1)), sub(norm2, norm1));        /* if ( fabs ( 1.0 - R_error ) < 0.1 ) */        IF(sub(abs_s(sub(16384, error)), 1638) < 0)        {          norm1 = norm_s(factor);          norm2 = norm_s(lag_tmp);          lag_tmp = shr(div_s(shl(lag_tmp, sub(norm2, 1)), shl(factor, norm1)), sub(add(norm2, 8), norm1));          /* lag[l] = (int) floor ( (REAL) lag[l] / (REAL) factor + 0.5 ); */          lag_tmp = shr(add(shr(lag_tmp, 5), 1), 1);        }      }    }    /* simple low-pass filtering (gliding average length 2) */    new_lag = shr(add(state->old_lag, lag_tmp), 1);    state->old_lag = lag_tmp;    lag[l] = div_l(shl(new_lag, 1), 6);    frac_lag[l] = sub(new_lag, extract_l(L_mult0(6, lag[l])));#ifdef WMOPS    move16();    move16();    move16();#endif  }  /* produce tonal contributions */  G729EV_G729_Copy(state->signal_tonal_buffer, signal_tonal, G729EV_TDBWE_LENGTH_PULSE_SHAPE);  G729EV_G729_Set_zero(&signal_tonal[G729EV_TDBWE_LENGTH_PULSE_SHAPE], G729EV_TDBWE_L_FRAME2);  state->prev_pulse = sub(state->prev_pulse, G729EV_TDBWE_L_FRAME2);  next_pulse = add(state->prev_pulse, lag[0]);  next_pulse_frac = add(state->prev_pulse_frac, frac_lag[0]);  WHILE(sub(next_pulse_frac, 6) >= 0)  {    next_pulse_frac = sub(next_pulse_frac, 6);    next_pulse = add(next_pulse, 1);  }  if (next_pulse < 0)  {    next_pulse = 0;#ifdef WMOPS    move16();#endif  }  wlim = G729EV_TDBWE_L_FRAME4;#ifdef WMOPS  move16();#endif  FOR(l = 0; l < 2; l++)       /* for two 5ms subframes */  {    WHILE(next_pulse < wlim)    {      acc = L_mult0(frac_lag[l], 1);      acc = L_mac0(acc, lag[l], 6);      tmp = sqrt_qnls(extract_l(acc), 7); /* Q.0 -> Q.7   */      tmp = shl(tmp, 3);        /* Q.7 -> Q.10  */      gain = round(L_mult(tmp, gain_tonal[l])); /* gain is Q.10 */      if (s_and(next_pulse, 1) == 0)        gain = negate(gain);      ps = &signal_tonal[next_pulse];      psf = &G729EV_TDBWE_pulse_shapes_frac6[i_mult(next_pulse_frac, G729EV_TDBWE_LENGTH_PULSE_SHAPE)];      FOR(i = 0; i < G729EV_TDBWE_LENGTH_PULSE_SHAPE; i++)      {        ps[i] = add(ps[i], round(L_mult0(gain, psf[i])));#ifdef WMOPS        move16();#endif      }      state->prev_pulse = next_pulse;      state->prev_pulse_frac = next_pulse_frac;#ifdef WMOPS      move16();      move16();#endif      next_pulse = add(state->prev_pulse, lag[l]);      next_pulse_frac = add(state->prev_pulse_frac, frac_lag[l]);      WHILE(sub(next_pulse_frac, 6) >= 0)      {        next_pulse_frac = sub(next_pulse_frac, 6);        next_pulse = add(next_pulse, 1);      }    }    wlim = add(wlim, G729EV_TDBWE_L_FRAME4);  }  G729EV_G729_Copy(signal_tonal, output, G729EV_TDBWE_L_FRAME2);  G729EV_G729_Copy(&signal_tonal[G729EV_TDBWE_L_FRAME2], state->signal_tonal_buffer, G729EV_TDBWE_LENGTH_PULSE_SHAPE);  /* produce and add noise contributions */  FOR(i = 0; i < G729EV_TDBWE_L_FRAME4; i++)  {    output[i] = add(output[i], round(L_mult(gain_noise[0], shr(G729EV_TDBWE_rand(&(state->seed)), 4))));#ifdef WMOPS    move16();#endif  }  FOR(i = G729EV_TDBWE_L_FRAME4; i < G729EV_TDBWE_L_FRAME2; i++)  {    /* <================================= BUG WARNING ==================================> */    /*  gain_noise[1] has to be used instead of gain_noise[0] below                      */    /*  the impact on quality is very minor                                              */    /* <================================= BUG WARNING ==================================> */    output[i] = add(output[i], round(L_mult(gain_noise[0], shr(G729EV_TDBWE_rand(&(state->seed)), 4))));#ifdef WMOPS    move16();#endif  }  /* apply 3 kHz lowpass */  G729EV_MAIN_lp3k(&(state->lowpass_3_kHz), output, G729EV_TDBWE_L_FRAME2);}

⌨️ 快捷键说明

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