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

📄 g729ev_fec_clasdec.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 <stdio.h>#include <stdlib.h>#include "G729EV_MAIN_defines.h"#include "G729EV_G729_defines.h"#include "G729EV_FEC_fer.h"#include "G729EV_FEC_tools.h"#include "G729EV_G729_ld8k.h"#include "stl.h"#include "G729EV_MAIN_OPER_32B.h"#include "G729EV_MAIN_DSPFUNC.h"/*---------------------------------------------------------------------** - Prototypes*---------------------------------------------------------------------*/static Word16 G729EV_FEC_frame_energy(const Word16 * pitch, const Word16 * speech,                                      const Word16 lp_speech, Word16 * frame_ener, Word16 Q_syn);static void Corre(Word16 * x, Word16 * y, Word16 l, Word16 * gain);/*---------------------------------------------------------------------* * Signal classification at the decoder for FER concealment * Function used only at 8kbps. When bit rate >= 12kbps, the classification  * is sent by the encoder.  *---------------------------------------------------------------------*/void G729EV_FEC_clas_dec(Word16 * clas,         /* i/o: frame classification                      */                         const Word16 * pitch,  /* i:   pitch values for each subframe          Q5 */                         const Word16 last_good,/* i:   type of the last correctly received fr.   */                         Word16 * frame_synth,  /* i/o: synthesis buffer                          */                         Word16 * st_old_synth, /* i/o: synthesis memory                          */                         Word16 * lp_speech     /* i/o: long term active speech energy average Q1 */    ){  Word16    i, j, pos;  Word16   *pt1, *pt2, zc_frame, frame_ener, tmp_scale;  Word16    tiltn, corn, zcn, pcn, fmerit1, enern, ener, tilt;  Word16    voicing, cor_max[3], *synth, tmp16, exp1, exp2;  Word32    Ltmp, Ltmp1, s1, s2;  Word16    tmpS, zc[4], T0, pc, tmp_e, max, tmp_x, tmp_y;  Word16    old_synth[G729EV_G729_PIT_MAX + G729EV_MAIN_L_FRAME2];  Word16    Q_syn;  cor_max[0] = (Word16) 0;  cor_max[1] = (Word16) 0;  cor_max[2] = (Word16) 0;  Q_syn = (Word16) - 1;#if(WMOPS)  move16();  move16();  move16();  move16();  move16();#endif  synth = old_synth + G729EV_G729_PIT_MAX;  /* Pointer to the current frame     */  /* Scaling synth to remove overflow results */  max = (Word16) 0;  FOR(i = 0; i < G729EV_G729_PIT_MAX; i++)  {    tmp_e = abs_s(st_old_synth[i]);    if (sub(tmp_e, max) > 0)    {      max = tmp_e;#if(WMOPS)      move16();#endif    }  }  FOR(i = 0; i < G729EV_MAIN_L_FRAME2; i++)  {    tmp_e = abs_s(frame_synth[i]);    if (sub(tmp_e, max) > 0)    {      max = tmp_e;#if(WMOPS)      move16();#endif    }  }  tmp_scale = sub(norm_s(max), 3);  if (sub(tmp_scale, 6) > 0)  {    tmp_scale = (Word16) 6;#if(WMOPS)    move16();#endif  }  FOR(i = 0; i < G729EV_G729_PIT_MAX; i++)  {    old_synth[i] = shl(st_old_synth[i], tmp_scale);#if(WMOPS)    move16();#endif  }  FOR(i = 0; i < G729EV_MAIN_L_FRAME2; i++)  {    old_synth[i + G729EV_G729_PIT_MAX] = shl(frame_synth[i], tmp_scale);#if(WMOPS)    move16();#endif  }  Q_syn = add(Q_syn, tmp_scale);    /*-----------------------------------------------------------------*      - Compute the zero crossing rate for all subframes    *-----------------------------------------------------------------*/  pt1 = (Word16 *) synth;  pt2 = (Word16 *) synth - 1;  FOR(i = 0; i < 4; i++)  {    tmpS = 0;    FOR(j = 0; j < G729EV_G729_L_SUBFR; j++)    {#if(WMOPS)      test();#endif      IF((*pt1 <= 0.0f) && (*pt2 > 0.0f))      {        tmpS = add(tmpS, 1);;      }      pt1++;      pt2++;    }    zc[i] = tmpS;#if(WMOPS)    move16();    move16();#endif  }  zc_frame = add(zc[0], add(zc[1], add(zc[2], zc[3])));   /*-----------------------------------------------------------------*      Compute the normalized correlation pitch-synch. at the end     of the frame    *-----------------------------------------------------------------*/  T0 = shr(pitch[3], G729EV_FEC_SQPIT);  IF(sub(T0, 3 * (G729EV_G729_L_SUBFR / 2)) > 0)  {    T0 = shr(add(shr(add(pitch[2], pitch[3]), 1), G729EV_FEC_QPIT2), G729EV_FEC_SQPIT);  }#if(WMOPS)  move16();  move16();#endif  pos = G729EV_MAIN_L_FRAME2;  j = (Word16) 0;  pt1 = synth;  WHILE(sub(pos, 3 * G729EV_G729_L_SUBFR) > 0)  {    pos = sub(pos, T0);    Corre(&pt1[pos], &pt1[pos - T0], T0, &cor_max[j]);    IF(sub(sub(pos, T0), 3 * G729EV_G729_L_SUBFR) < 0)    {      T0 = shr(add(shr(add(pitch[2], pitch[3]), 1), G729EV_FEC_QPIT2), G729EV_FEC_SQPIT);    }    j = add(j, 1);  }  Ltmp = L_deposit_l(cor_max[0]);  FOR(i = 1; i < j; i++)  {    Ltmp = L_add(Ltmp, cor_max[i]);  }  IF(sub(j, 3) == 0)  {    voicing = extract_l(L_mls(Ltmp, 10923));  }  ELSE if   (sub(j, 2) == 0)  {    voicing = extract_l(L_shr(Ltmp, 1));  }  ELSE  {    voicing = extract_l(Ltmp);  }  pc = shr(abs_s(sub(add(pitch[3], sub(pitch[2], pitch[1])), pitch[0])), G729EV_FEC_SQPIT);   /*-----------------------------------------------------------------*      Compute spectral tilt    *-----------------------------------------------------------------*/#if(WMOPS)  move32();  move32();#endif  Ltmp = (Word32) 0;  Ltmp1 = (Word32) 0;  pt1 = (Word16 *) synth + G729EV_G729_L_SUBFR;  pt2 = (Word16 *) synth + G729EV_G729_L_SUBFR - 1;  FOR(i = 0; i <= 2; i++)  {#if(WMOPS)    move32();    move32();#endif    s1 = (Word32) 0;    s2 = (Word32) 0;    FOR(j = 0; j < G729EV_G729_L_SUBFR; j++)    {      s1 = L_mac(s1, *pt1, *pt1);      s2 = L_mac(s2, *pt1, *pt2);      pt1++;      pt2++;    }    Ltmp = L_add(s1, L_shr(Ltmp, 1));    Ltmp1 = L_add(s2, L_shr(Ltmp1, 1));  }  tmp16 = (Word16) - 1;  IF(Ltmp1 < 0)  {    tmp16 = negate(tmp16);    Ltmp1 = L_abs(Ltmp1);  }#if(WMOPS)  move16();#endif  if (Ltmp == 0)  {    Ltmp = (Word32) 1;#if(WMOPS)    move32();#endif  }  exp1 = norm_l(Ltmp1);  tmp_y = extract_h(L_shl(Ltmp1, exp1));  exp1 = sub(31 - 1 + 3, exp1);  exp2 = norm_l(Ltmp);  tmp_x = extract_h(L_shl(Ltmp, exp2));  exp2 = sub(31 - 1 + 3, exp2);  IF(sub(tmp_y, tmp_x) > 0)  {    tmp_y = shr(tmp_y, 1);    exp1 = add(exp1, 1);  }  tilt = div_s(tmp_y, tmp_x);  tilt = shl(tilt, sub(exp1, exp2));  /* sature to 1.0 */  if (tmp16 > 0)  {    tilt = negate(tilt);  }    /*-----------------------------------------------------------------*      Compute pitch-synchronous energy at the frame end    *-----------------------------------------------------------------*/  ener = G729EV_FEC_frame_energy(pitch, synth, *lp_speech, &frame_ener, Q_syn);   /*-----------------------------------------------------------------*      * transform parameters between 0 & 1        * find unique merit function                *-----------------------------------------------------------------*/  enern = mac_r(G729EV_FEC_C_ENR, G729EV_FEC_K_ENR, ener);  /*Q8 */  tiltn = extract_h(L_shr(L_mac(G729EV_FEC_C_TILT, G729EV_FEC_K_TILT, tilt), 6)); /*Q14 -> Q8 */  corn = extract_h(L_shr(L_mac(G729EV_FEC_C_COR, G729EV_FEC_K_COR, voicing), 5)); /*Q13 -> Q8 */  zcn = extract_h(L_shl(L_mac(G729EV_FEC_C_ZC_DEC, G729EV_FEC_K_ZC_DEC, zc_frame), 8)); /*Q0 -> Q8 */  pcn = extract_h(L_shl(L_mac(G729EV_FEC_C_PC_DEC, G729EV_FEC_K_PC_DEC, pc), 8)); /*Q0 -> Q8 */#if(WMOPS)  move16();#endif  IF(sub(pcn, 256) > 0)  {    pcn = (Word16) 256;  }  ELSE if   (pcn < 0)  {    pcn = (Word16) 0;  }  /*fmerit1 = (1.0f/6.0f) * (tiltn + 2.0f*corn + zcn + pcn + enern); */  Ltmp = L_mult(tiltn, G729EV_FEC_UNS6);  IF(corn > 0)  {    Ltmp = L_mac(Ltmp, corn, 4 * G729EV_FEC_UNS6);  }  ELSE  {    Ltmp = L_mac(Ltmp, corn, 2 * G729EV_FEC_UNS6);  }  Ltmp = L_mac(Ltmp, zcn, G729EV_FEC_UNS6);  Ltmp = L_mac(Ltmp, pcn, G729EV_FEC_UNS6);  Ltmp = L_mac(Ltmp, enern, G729EV_FEC_UNS6);  fmerit1 = round(L_shl(Ltmp, 15 - 8)); /*Q15 can saturate to 1,0 */   /*-----------------------------------------------------------------*      * frame classification                      *-----------------------------------------------------------------*/#if(WMOPS)  move16();#endif  SWITCH(last_good)  {case G729EV_FEC_VOICED:case G729EV_FEC_ONSET:case G729EV_FEC_SIN_ONSET:case G729EV_FEC_V_TRANSITION:    IF(sub(fmerit1, 12780) < 0)    {      *clas = G729EV_FEC_UNVOICED;    }    ELSE if   (sub(fmerit1, 20644) < 0)    {      *clas = G729EV_FEC_V_TRANSITION;    }    ELSE    {      *clas = G729EV_FEC_VOICED;    }    BREAK;case G729EV_FEC_UNVOICED:case G729EV_FEC_UV_TRANSITION:    IF(sub(fmerit1, 18350) > 0)    {      *clas = G729EV_FEC_ONSET;    }    ELSE if   (sub(fmerit1, 14746) > 0)    {      *clas = G729EV_FEC_UV_TRANSITION;    }    ELSE    {      *clas = G729EV_FEC_UNVOICED;    }    BREAK;default:    *clas = G729EV_FEC_UNVOICED;    BREAK;  }   /*-----------------------------------------------------------------*      * Measure average energy on good, active G729EV_FEC_VOICED frames for FER     * concealment classification    *-----------------------------------------------------------------*/  IF(sub(*clas, G729EV_FEC_VOICED) == 0)  {    Ltmp = L_mult(328, frame_ener);    *lp_speech = mac_r(Ltmp, 32441, *lp_speech);  /* lp_speech update */#if(WMOPS)    move16();#endif  }   /*-----------------------------------------------------------------*      * Update synthesized speech memory    *-----------------------------------------------------------------*/  FOR(i = 0; i < G729EV_G729_PIT_MAX; i++)  {    st_old_synth[i] = shr(old_synth[i + G729EV_MAIN_L_FRAME2], tmp_scale);#if(WMOPS)    move16();#endif  }  return;}/*---------------------------------------------------------------------*  *  Compute pitch-synchronous energy at the frame end*---------------------------------------------------------------------*/static Word16 G729EV_FEC_frame_energy(  /* o:   Pitch synchronus energy                        Q8 */                                       const Word16 * pitch,  /* i:   pitch values for each subframe                 Q5 */                                       const Word16 * speech, /* i:   pointer to speech signal for E computation        */                                       const Word16 lp_speech,/* i:   long term active speech energy average         Q8 */                                       Word16 * frame_ener,   /* o:   pitch-synchronous energy at frame end          Q8 */                                       Word16 Q_syn           /* i:   Scaling of syntesis                               */    ){  Word32    Ltmp;  Word16   *pt1, tmp16, exp1, frac1, tmp1, tmp2;  Word16    len, enern;  /*len = (short)( 0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f ); */  len = shr(add(shr(add(pitch[2], pitch[3]), 1), G729EV_FEC_QPIT2), G729EV_FEC_SQPIT);  if (sub(len, G729EV_G729_L_SUBFR) < 0)  {    len = shl(len, 1);  }  pt1 = (Word16 *) speech + sub(G729EV_MAIN_L_FRAME2, len);    /**frame_ener = 10.0f * log10(dot_product(pt1, pt1, len) / (float)len );*/  tmp1 = norm_s(len);  tmp2 = shl(len, tmp1);  tmp1 = sub(15, tmp1);  tmp16 = extract_h(G729EV_Dot_product12(pt1, pt1, len, &exp1));  IF(sub(tmp16, tmp2) > 0)  {    tmp16 = shr(tmp16, 1);    exp1 = add(exp1, 1);  }  tmp16 = div_s(tmp16, tmp2);  exp1 = sub(exp1, tmp1);  Log2(L_deposit_h(tmp16), &tmp16, &frac1);  exp1 = sub(add(exp1, 31 + 1 - 3), add(tmp16, shl(Q_syn, 1)));  frac1 = mult_r(frac1, tmp2);  Ltmp = Mpy_32_16(exp1, frac1, G729EV_FEC_LG10);  /*enern = *frame_ener - lp_speech; */  *frame_ener = extract_l(L_shr(Ltmp, 14 - 8));  enern = sub(*frame_ener, lp_speech);#if(WMOPS)  move16();#endif  return enern;}/*-----------------------------------------------------------------* * function Corre() *          ~~~~~~~~ * Correlation function.  Signal x is compared to target signal y * Information about the similarity between vectors is returned in *gain *-----------------------------------------------------------------*/static void Corre(Word16 * x,   /* i:   vector 1                     Q12 */                  Word16 * y,   /* i:   vector 2                     Q12 */                  Word16 l,     /* i:   length of vectors                */                  Word16 * gain /* o:   normalized correlation gain  Q15 */    ){  Word16    cor, cor_exp;  Word16    den, den_exp;  Word16    den2, den2_exp;  Word32    tmp;  Word16    tmp_exp;  /* keep Q15 normalized result */  cor = extract_h(G729EV_Dot_product12(x, y, l, &cor_exp));  den = extract_h(G729EV_Dot_product12(y, y, l, &den_exp));  den2 = extract_h(G729EV_Dot_product12(x, x, l, &den2_exp));  /* keep Q31 normalized result */  tmp = L_mult(den, den2);  tmp_exp = norm_l(tmp);  tmp = L_shl(tmp, tmp_exp);  tmp_exp = sub(add(den_exp, den2_exp), tmp_exp);  Isqrt_n(&tmp, &tmp_exp);  /* keep Q15 result */  gain[0] = shl(mult_r(cor, extract_h(tmp)), add(cor_exp, tmp_exp));#if(WMOPS)  move16();  move16();  move16();#endif}

⌨️ 快捷键说明

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