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

📄 g729ev_main_envadaption.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_MAIN_defines.h"#include "G729EV_MAIN_EnvAdaption.h"#include "G729EV_MAIN_DSPFUNC.h"#include "G729EV_MAIN_OPER_32B.h"/*--------------------------------------------------------------------------* *  Function  get_Energy()                                                  * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                   * *  Compute subframe energy                                                 * *--------------------------------------------------------------------------*/void G729EV_MAIN_get_Energy(Word16 * pSample, /* (i)   input samples */                            Word32 * pELow,   /* (o)   energy (LSB) */                            Word16 * pEHigh   /* (o)   energy (MSB) */    ){  Word16    i;  Overflow = 0;#ifdef WMOPS  move16();#endif  FOR(i = 0; i < G729EV_MAIN_PRE_SUBFRAME; i++)  {    *pELow = L_macNs(*pELow, pSample[i], pSample[i]);    if (Overflow != 0)      *pEHigh = add(*pEHigh, 1);    if (Overflow != 0)      *pELow = L_and(*pELow, 0x7fffffff);    if (Overflow != 0)    {      Overflow = 0;#ifdef WMOPS      move16();#endif    }  }}/*--------------------------------------------------------------------------* *  Function  G729EV_MAIN_getV()                                            * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~                 ~                            * *  Compute attenuation factor e_num/e_den                                  * *--------------------------------------------------------------------------*/Word16 G729EV_MAIN_getV(Word32 e_num, /* (i)   numerator */                        Word32 e_den  /* (i)   denominator */    ){  Word16    v;  Word16    n1, n2, d, n;  Word32    v32, e_den32;  Word16    e_num16;  n1 = norm_l(e_num);  n2 = norm_l(e_den);  e_den32 = L_shl(e_den, sub(n2, 1));  e_num16 = extract_l(L_shl(e_num, sub(n1, 16)));  d = div_l(e_den32, e_num16);  v32 = Inv_sqrt(d);  n = add(sub(n2, n1), 14);  v = extract_l(L_shr(v32, sub(23, shr(n, 1))));  /* Q30->Q7 */  IF(L_and(n, 1) != 0)          /* (n%2 !=0) */  {    v32 = L_mult(v, 0x5a82);    /* (REAL)v32*1.41; */    v = shl(extract_h(v32), 1); /* extract_h(v32*4); */  }  v = i_mult(v, 0x100);  return (v);}/*--------------------------------------------------------------------------* *  Function  G729EV_MAIN_smooth()                                          * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                            * *  Smooth gain                                                             * *--------------------------------------------------------------------------*/Word16 G729EV_MAIN_smooth(Word16 lastVal, /* (i)   smoothing filter memory */                          Word16 newVal   /* (i)   input gain */    ){  Word32    acc;  /* return lastVal*0.85 + newVal*0.15 */  acc = L_mult(lastVal, 0x6ccd);  acc = L_mac(acc, newVal, 0x1333);  return round(acc);}/*--------------------------------------------------------------------------* *  Function  G729EV_MAIN_envAdapt()                                        * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                          * *  Reduce pre/postecho in lower and higher band                            * *  Add CELP and TDAC synthesis in lower-band                               * *--------------------------------------------------------------------------*/void G729EV_MAIN_envAdapt(Word16 * sOut_low,      /* (o)   output samples lowband */                          Word16 * sBasic_low,    /* (i)   12k layer contribution (lowband)  */                          Word16 * sTdacAdd_low,  /* (i)   TDAC layer add-on for lowand  */                          Word16 * vmlold,        /* (i)   needed for lowband gain smoothing  */                          Word16 * sOut_hi,       /* (o)   output samples highband */                          Word16 * sBasic_hi,     /* (i)   14k layer contribution (highband) */                          Word16 * sTdacInc_hi,   /* (i)   highband signal TDBWE combinded with TDAC */                          Word16 * vmhold,        /* (i)   needed for highband gain smoothing */                          Word16 work,            /* (i)   if zero ->do not cancel echo (rate<=14000) */                          Word16 begin_index_low, /* (i)   start index for false alarm zone in lower-band  */                          Word16 end_index_low,   /* (i)   stop index for false alarm zone in lower-band */                          Word16 begin_index_high,/* (i)   start index for false alarm zone in higher-band */                          Word16 end_index_high   /* (i)   stop index for false alarm zone in higher-band */    ){  Word16    i, j;  Word16    vl, vh;  Word16    vml[G729EV_MAIN_L_FRAME2];  Word16    vmh[G729EV_MAIN_L_FRAME2];  Word16    sBasicLow_tilt[G729EV_MAIN_L_FRAME2];  Word16    sTdacAddLow_tilt[G729EV_MAIN_L_FRAME2];  Word16   *sHelp1;  Word16   *sHelp2;  Word32    EsBasicLow;  Word32    EsTdacAddLow;  Word32    EsBasicHi;  Word32    EsTdacIncHi;  Word16    EsBasicLowHigh;  Word16    EsTdacAddLowHigh;  Word16    EsBasicHiHigh;  Word16    EsTdacIncHiHigh;  Word32    EsTdacIncHi081;  Word16   *pvl;  Word16   *pvh;  Word16    Hi, Lo;  /* apply tilt on lowband before comparing energies */  sHelp1 = sBasic_low - 1;  sHelp2 = sTdacAdd_low - 1;#ifdef WMOPS  move16();  move16();#endif  FOR(j = 1; j < G729EV_MAIN_L_FRAME2; j++)  {    sBasicLow_tilt[j] = sub(sBasic_low[j], sHelp1[j]);#ifdef WMOPS    move16();#endif    sTdacAddLow_tilt[j] = sub(sTdacAdd_low[j], sHelp2[j]);#ifdef WMOPS    move16();#endif  }  sBasicLow_tilt[0] = 0;#ifdef WMOPS  move16();#endif  sTdacAddLow_tilt[0] = 0;#ifdef WMOPS  move16();#endif  /* compare energies, get scale factors */  FOR(j = 0; j < G729EV_MAIN_L_FRAME2; j = j + G729EV_MAIN_PRE_SUBFRAME)  {    IF(work)    {      /* get energies */      EsBasicLow = 100;      EsTdacAddLow = 100;      EsBasicHi = 100;      EsTdacIncHi = 100;#ifdef WMOPS      move32();      move32();      move32();      move32();#endif      EsBasicLowHigh = 0;      EsTdacAddLowHigh = 0;      EsBasicHiHigh = 0;      EsTdacIncHiHigh = 0;#ifdef WMOPS      move16();      move16();      move16();      move16();#endif      Overflow = 0;      Carry = 0;#ifdef WMOPS      move16();      move16();#endif      G729EV_MAIN_get_Energy(&sBasicLow_tilt[j], &EsBasicLow, &EsBasicLowHigh);      G729EV_MAIN_get_Energy(&sTdacAddLow_tilt[j], &EsTdacAddLow, &EsTdacAddLowHigh);      G729EV_MAIN_get_Energy(&sBasic_hi[j], &EsBasicHi, &EsBasicHiHigh);      G729EV_MAIN_get_Energy(&sTdacInc_hi[j], &EsTdacIncHi, &EsTdacIncHiHigh);      /* if highpart of energy != zero, normalize */      IF(add(EsBasicLowHigh, EsTdacAddLowHigh) != 0)      {        Word16    max16, v, i31mv;        max16 = s_max(EsBasicLowHigh, EsTdacAddLowHigh);        v = norm_l(max16);        i31mv = sub(31, v);        EsBasicLow = L_add(L_shl(EsBasicLowHigh, v), L_shr((EsBasicLow & 0x7fffffff), i31mv));        EsTdacAddLow = L_add(L_shl(EsTdacAddLowHigh, v), L_shr((EsTdacAddLow & 0x7fffffff), i31mv));      }      IF(L_sub(EsBasicLow, EsTdacAddLow) >= 0)  /* if EsBasicLow>=EsTdacAddLow */      {        vl = 0x7fff;            /* vl=1 */#ifdef WMOPS        move16();#endif      }      ELSE      {        vl = G729EV_MAIN_getV(EsBasicLow, EsTdacAddLow);      }      /* if highpart of energy != zero, normalize */      IF(add(EsBasicHiHigh, EsTdacIncHiHigh) != 0)      {        Word16    max16, v, i31mv;        max16 = s_max(EsBasicHiHigh, EsTdacIncHiHigh);        v = norm_l(max16);        i31mv = sub(31, v);        EsBasicHi = L_add(L_shl(EsBasicHiHigh, v), L_shr((EsBasicHi & 0x7fffffff), i31mv));        EsTdacIncHi = L_add(L_shl(EsTdacIncHiHigh, v), L_shr((EsTdacIncHi & 0x7fffffff), i31mv));      }      /* EsTdacIncHi081=EsTdacIncHi*0.81: */      L_Extract(EsTdacIncHi, &Hi, &Lo);      EsTdacIncHi081 = Mpy_32_16(Hi, Lo, 0x67ae);      IF(L_sub(EsBasicHi, EsTdacIncHi081) >= 0)      {        vh = 0x7fff;            /* vh=1 */#ifdef WMOPS        move16();#endif      }      ELSE      {        vh = G729EV_MAIN_getV(EsBasicHi, EsTdacIncHi);      }    }    ELSE    {      vh = 0x7fff;              /* vh=1 */      vl = 0x7fff;              /* vl=1 */#ifdef WMOPS      move16();      move16();#endif    }    pvl = &vml[j];    pvh = &vmh[j];#ifdef WMOPS    move16();    move16();#endif    FOR(i = 0; i < G729EV_MAIN_PRE_SUBFRAME; i++)    {      pvl[i] = vl;      pvh[i] = vh;#ifdef WMOPS      move16();      move16();#endif    }  }/* begin_index_low = 0; end_index_low = 159; no preecho supression */  FOR(i = begin_index_low; i <= end_index_low; i++)  {    vml[i] = 0x7fff;#ifdef WMOPS    move16();#endif  }  FOR(i = begin_index_high; i <= end_index_high; i++)  {    vmh[i] = 0x7fff;#ifdef WMOPS    move16();#endif  }  /* EnvAdaption - smoothing of gains */  vmh[0] = G729EV_MAIN_smooth(*vmhold, vmh[0]);  vml[0] = G729EV_MAIN_smooth(*vmlold, vml[0]);#ifdef WMOPS  move16();  move16();#endif  FOR(i = 1; i < (G729EV_MAIN_L_FRAME2); i++)  {    vmh[i] = G729EV_MAIN_smooth(vmh[i - 1], vmh[i]);    vml[i] = G729EV_MAIN_smooth(vml[i - 1], vml[i]);#ifdef WMOPS    move16();    move16();#endif  }  /* update vmh vml memory */  *vmlold = vml[(G729EV_MAIN_L_FRAME2) - 1];  *vmhold = vmh[(G729EV_MAIN_L_FRAME2) - 1];#ifdef WMOPS  move16();  move16();#endif  FOR(i = 0; i < G729EV_MAIN_L_FRAME2; i++)  {    sOut_low[i] = add(sBasic_low[i], mult_r(sTdacAdd_low[i], vml[i]));    sOut_hi[i] = mult_r(sTdacInc_hi[i], vmh[i]);#ifdef WMOPS    move16();    move16();#endif  }}/*--------------------------------------------------------------------------* *  Function  G729EV_MAIN_PreechoFalseAlarm()                               * *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                          * *  Determine start/stop indices for false alarm zone in lower- and higher- * *  band                                                                    * *--------------------------------------------------------------------------*/void G729EV_MAIN_PreechoFalseAlarm(Word16 * rec_sig,    /* (i)   reconstructed signal, output of the imdct transform */                                   Word16 * imdct_mem,  /* (i)   memory of the imdct transform, used in the next frame */                                   Word32 * max_prev,   /* (i/o) maximum energy in the previous reconstructed frame */                                   Word16 * begin_ind,  /* (o)   starting index of the eventual false alarm zone */                                   Word16 * end_ind     /* (o)   ending index of the eventual false alarm zone */    ){  Word16    i, j;  Word32    es_tdac[6];         /* 0..3: energy of the 4 subframes, 4..5: energy of the future subframes */  Word32    min_es, max_es, max_rec = 0;  Word16   *ptr;  /*energy of low bands 4 present and 2 future sub-frames */  FOR(i = 0; i < 6; i++)  {    es_tdac[i] = 100;#ifdef WMOPS    move32();#endif  }  ptr = rec_sig;#if(WMOPS)  move16();#endif  FOR(j = 0; j < 4; j++)       /*4 present subframes */  {    FOR(i = 0; i < G729EV_MAIN_PRE_SUBFRAME; i++)    {      es_tdac[j] = L_mac0(es_tdac[j], *ptr, *ptr);#ifdef WMOPS      move32();#endif      ptr++;    }  }  ptr = imdct_mem;#if(WMOPS)  move16();#endif  FOR(j = 4; j < 6; j++)       /*2 future subframes */  {    FOR(i = 0; i < G729EV_MAIN_PRE_SUBFRAME; i++)    {      es_tdac[j] = L_mac(es_tdac[j], *ptr, *ptr); /*including *=2 as the max of the synthesis window is sqrt(2) */#ifdef WMOPS      move32();#endif      ptr++;    }  }  min_es = es_tdac[0];          /* for memorising the min energy */  max_es = es_tdac[0];          /* for memorising the max energy */  *begin_ind = 0;#if(WMOPS)  move32();  move32();  move16();#endif  FOR(i = 1; i < 6; i++)  {    if (L_sub(es_tdac[i], max_es) > 0)    {      max_es = es_tdac[i];      /* max energy low band, 4 present and 2 future subframes */      *begin_ind = extract_l(L_mult0(i, G729EV_MAIN_PRE_SUBFRAME));#ifdef WMOPS      move32();#endif    }    if (sub(i, 3) == 0)    {      max_rec = max_es;         /*save partial max result for the 4 present subframes */#ifdef WMOPS      move32();#endif    }  }  IF(L_sub(L_shr(*max_prev, 5), max_rec) >= 0)  /*post-echo situation, preecho false alarm detection desactivated */  {    *begin_ind = G729EV_MAIN_L_FRAME2;    *end_ind = G729EV_MAIN_L_FRAME2 - 1;  /* begin > end --> nothing is done */    *max_prev = max_rec;#ifdef WMOPS    move16();    move16();    move32();#endif  }  ELSE  {    *max_prev = max_rec;#ifdef WMOPS    move32();#endif    FOR(i = 1; i < 4; i++)    {      if (L_sub(es_tdac[i], min_es) < 0)      {        min_es = es_tdac[i];    /* min energy low band, 4 present subframes only */#ifdef WMOPS        move32();#endif      }    }    IF(L_sub(L_shr(max_es, 4), min_es) < 0) /* no big energy change --> no preecho ->false alarm zone:the whole frame */    {      *begin_ind = 0;      *end_ind = G729EV_MAIN_L_FRAME2 - 1;#ifdef WMOPS      move16();      move16();#endif    }    ELSE    {      *end_ind = add(*begin_ind, 2 * G729EV_MAIN_PRE_SUBFRAME - 1); /*length of the false alarm zone is 2 subframes */      if (sub(*end_ind, G729EV_MAIN_L_FRAME2 - 1) > 0)      {        *end_ind = G729EV_MAIN_L_FRAME2 - 1;#ifdef WMOPS        move16();#endif      }    }  }  return;}

⌨️ 快捷键说明

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