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

📄 cod_ace.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../include/amr_plus.h"
void coder_acelp(
  float A[],         /* input:  coefficients 4xAz[M+1]   */
  float Aq[],        /* input:  coefficients 4xAz_q[M+1] */
  float speech[],    /* input:  speech[-M..lg]           */
  float *mem_wsp,    /* in/out: wsp memory               */
  float *mem_wsyn,   /* in/out: wsyn memory              */
  float synth[],     /* in/out: synth[-M..lg]            */
  float exc[],       /* in/out: exc[-(PIT_MAX+L_INTERPOL)..lg+1] */
  float wovlp[],     /* out: wovlp[0..128]               */
  int lg,            /* input: frame length              */
  int codec_mode,    /* input: AMR_WB+ mode (see cnst.h) */
  float norm_corr,
  float norm_corr2,
  int T_op,          /* input: open-loop LTP             */  
  int T_op2,         /* input: open-loop LTP             */  
  int T_out[],       /* output: integer pitch-lag        */  
  float p_out[],     /* output: pitch gain               */ 
  float c_out[],	 /* output: fixed codebook gain      */
  int	pit_adj,
  int *prm)          /* output: acelp parameters         */
{
  int i, i_subfr, select;
  int T0, T0_min, T0_max, index, pit_flag;
  long int T0_frac;
  float tmp, ener, max, mean_ener_code;
  float gain_pit, gain_code, voice_fac, gain1, gain2;
  float g_corr[5], g_corr2[2]; /*norm_corr, norm_corr2*/
  float *p_A, *p_Aq, Ap[M+1];
  float h1[L_SUBFR];
  float code[L_SUBFR];
  short code3GPP[L_SUBFR];
  float error[M+L_SUBFR];
  float cn[L_SUBFR];
  float xn[L_SUBFR];
  float xn2[L_SUBFR];
  float dn[L_SUBFR];        /* Correlation between xn and h1      */
  float y1[L_SUBFR];        /* Filtered adaptive excitation       */
  float y2[L_SUBFR];        /* Filtered adaptive excitation       */
  int PIT_MIN;				/* Minimum pitch lag with resolution 1/4      */
  int PIT_FR2;				/* Minimum pitch lag with resolution 1/2      */
  int PIT_FR1;				/* Minimum pitch lag with resolution 1        */
  int PIT_MAX;				/* Maximum pitch lag                          */
  if(pit_adj ==0) {
    PIT_MIN = PIT_MIN_12k8;
    PIT_FR2 = PIT_FR2_12k8;			
    PIT_FR1 = PIT_FR1_12k8;			
    PIT_MAX = PIT_MAX_12k8;			
  }
  else {
    i = (((pit_adj*PIT_MIN_12k8)+(FSCALE_DENOM/2))/FSCALE_DENOM)-PIT_MIN_12k8;
    PIT_MIN = PIT_MIN_12k8 + i;
    PIT_FR2 = PIT_FR2_12k8 - i;
    PIT_FR1 = PIT_FR1_12k8;
    PIT_MAX = PIT_MAX_12k8 + (6*i);
  }
  T_op *= OPL_DECIM;
  T_op2 *= OPL_DECIM;
  /* range for closed loop pitch search in 1st subframe */
  T0_min = T_op - 8;
  if (T0_min < PIT_MIN) {
    T0_min = PIT_MIN;
  }
  T0_max = T0_min + 15;
  if (T0_max > PIT_MAX) {
    T0_max = PIT_MAX;
    T0_min = T0_max - 15;
  }
 /*------------------------------------------------------------------------*
  * Find and quantize mean_ener_code for gain quantizer (q_gain2_live.c)   *
  * This absolute reference replace the gains prediction.                  *
  * This modification for AMR_WB+ have the following advantage:            *
  * - better quantization on attacks (onset, drum impulse, etc.)           *
  * - robust on packet lost.                                               *
  * - independent of previous mode (can be TCX with alg. 7 bits quantizer).*
  *------------------------------------------------------------------------*/
  max=0.0;
  mean_ener_code = 0.0;
  p_Aq = Aq;
  for (i_subfr=0; i_subfr<lg; i_subfr+=L_SUBFR) {
    E_UTIL_residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
    ener = 0.01f;
    for (i=0; i<L_SUBFR; i++) {
      ener += exc[i+i_subfr]*exc[i+i_subfr];
    }
    ener = 10.0f*(float)log10(ener/((float)L_SUBFR));
    if (ener < 0.0) {
      ener = 0.0;          /* ener in log (0..90dB) */
    }
    if (ener > max) {
      max = ener;
    }
    mean_ener_code += 0.25f*ener;
    p_Aq += (M+1);
  } 
  /* reduce mean energy on voiced signal */
  mean_ener_code -= 5.0f*norm_corr;
  mean_ener_code -= 5.0f*norm_corr2;
  /* quantize mean energy with 2 bits : 18, 30, 42 or 54 dB */
  tmp = (mean_ener_code-18.0f) / 12.0f;
  index = (int)floor(tmp + 0.5);
  if (index < 0) {
    index = 0;
  }
  if (index > 3) {
    index = 3;
  }
  mean_ener_code = (((float)index) * 12.0f) + 18.0f;
  /* limit mean energy to be able to quantize attack (table limited to +24dB) */
  while ((mean_ener_code < (max-27.0)) && (index < 3)) {
    index++;
    mean_ener_code += 12.0;
  }
  *prm = index;      prm++;
 /*------------------------------------------------------------------------*
  *          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 L_FRAME_PLUS/L_SUBFR times.          *
  *     - compute impulse response of weighted synthesis filter (h1[])     *
  *     - compute the target signal for pitch search                       *
  *     - find the closed-loop pitch parameters                            *
  *     - encode the pitch dealy                                           *
  *     - update the impulse response h1[] by including fixed-gain pitch   *
  *     - find target vector for codebook search                           *
  *     - correlation between target vector and impulse response           *
  *     - codebook search                                                  *
  *     - encode codebook address                                          *
  *     - VQ of pitch and codebook gains                                   *
  *     - find synthesis speech                                            *
  *     - update states of weighting filter                                *
  *------------------------------------------------------------------------*/
  p_A = A;
  p_Aq = Aq;
  for (i_subfr=0; i_subfr<lg; i_subfr+=L_SUBFR) {
    pit_flag = i_subfr;
    if (i_subfr == (2*L_SUBFR)) {
      pit_flag = 0;
      /* range for closed loop pitch search in 3rd subframe */
      T0_min = T_op2 - 8;
      if (T0_min < PIT_MIN) {
        T0_min = PIT_MIN;
      }
      T0_max = T0_min + 15;
      if (T0_max > PIT_MAX) {
        T0_max = PIT_MAX;
        T0_min = T0_max - 15;
      }
    }
    /*-----------------------------------------------------------------------*
             Find the target vector for pitch search:
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 |------|  res[n]
     speech[n]---| A(z) |--------
                 |------|       |   |-------------|
                       zero -- (-)--| 1/A(z/gamma)|----- target xn[]
                       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.
    *-----------------------------------------------------------------------*/
    /* find WSP (normaly done for pitch ol) */
    E_LPC_a_weight(p_A, Ap, GAMMA1, M);
    E_UTIL_residu(Ap, &speech[i_subfr], xn, L_SUBFR);
    E_UTIL_deemph(xn, TILT_FAC, L_SUBFR, mem_wsp);
    /* find ZIR in weighted domain */
    mvr2r(&synth[i_subfr-M], error, M);
    set_zero(error+M, L_SUBFR);
    E_UTIL_synthesis(p_Aq, error+M, error+M, L_SUBFR, error, 0);
    E_LPC_a_weight(p_A, Ap, GAMMA1, M);
    E_UTIL_residu(Ap, error+M, xn2, L_SUBFR);
    E_UTIL_deemph(xn2, TILT_FAC, L_SUBFR, mem_wsyn);
    /* target xn = wsp - ZIR in weighted domain */
    for (i=0; i<L_SUBFR; i++) {
      xn[i] -= xn2[i];
    }
    /* fill current exc with residu */
    E_UTIL_residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
   /*--------------------------------------------------------------*
    * Find target in residual domain (cn[]) for innovation search. *
    *--------------------------------------------------------------*/
    /* first half: xn[] --> cn[] */
    set_zero(code, M);
    mvr2r(xn, code+M, L_SUBFR/2);
    tmp = 0.0;
    E_UTIL_f_preemph(code+M, TILT_FAC, L_SUBFR/2, &tmp);
    E_LPC_a_weight(p_A, Ap, GAMMA1, M);
    E_UTIL_synthesis(Ap, code+M, code+M, L_SUBFR/2, code, 0);
    E_UTIL_residu(p_Aq, code+M, cn, L_SUBFR/2);
    /* second half: res[] --> cn[] (approximated and faster) */
    mvr2r(&exc[i_subfr+(L_SUBFR/2)], cn+(L_SUBFR/2), L_SUBFR/2);
    /*---------------------------------------------------------------*
     * Compute impulse response, h1[], of weighted synthesis filter  *
     *---------------------------------------------------------------*/
    E_LPC_a_weight(p_A, Ap, GAMMA1, M);
    set_zero(h1, L_SUBFR);
    mvr2r(Ap, h1, M+1);
    E_UTIL_synthesis(p_Aq, h1, h1, L_SUBFR, &h1[M+1], 0);
    tmp = 0.0;
    E_UTIL_deemph(h1, TILT_FAC, L_SUBFR, &tmp);
    /*----------------------------------------------------------------------*
     *                 Closed-loop fractional pitch search                  *
     *----------------------------------------------------------------------*/
    /* find closed loop fractional pitch  lag */
    T0 = E_GAIN_closed_loop_search(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
                     pit_flag, PIT_FR2, PIT_FR1);
      /* encode pitch lag */

⌨️ 快捷键说明

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