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

📄 cod_tcx.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
字号:
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../include/amr_plus.h"
void coder_tcx(   
  float A[],         /* input:  coefficients NxAz[M+1]  */
  float speech[],    /* input:  speech[-M..lg]          */
  float *mem_wsp,    /* in/out: memory of target        */
  float *mem_wsyn,   /* in/out: memory of quantized xn  */
  float synth[],     /* in/out: synth[-M..lg]           */
  float exc[],       /* output: exc[0..lg]              */
  float wovlp[],     /* i/o:    wovlp[0..127]           */
  int ovlp_size,     /* input:  0, 64 or 128 (0=acelp)  */
  int L_frame,       /* input:  frame length            */
  int nb_bits,       /* input:  number of bits allowed  */
  int prm[])         /* output: tcx parameters          */
{
  int i, i_subfr, lext, lg, index;
  float tmp, gain, fac_ns;
  float *p_A, Ap[M+1];
  float  *xri, *xn, *xnq;
  float  window[256];              
  xn = synth;
  xnq = xri = exc;
  /*------ set length of overlap (lext) and length of encoded frame (lg) -----*/
  lext = L_OVLP;
  if (L_frame == (L_FRAME_PLUS/2)) {
    lext = L_OVLP/2;
  }
  if (L_frame == (L_FRAME_PLUS/4)) {
    lext = L_OVLP/4;
  }
  lg = L_frame + lext;
  /* built window for overlaps section */
  cos_window(window, ovlp_size, lext);
  /*-----------------------------------------------------------*
   * Find target xn[] (weighted speech when prev mode is TCX)  *
   * Note that memory isn't updated in the overlap area.       *
   *-----------------------------------------------------------*/
  p_A = A;
  for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
    E_LPC_a_weight(p_A, Ap, GAMMA1, M);
    E_UTIL_residu(Ap, &speech[i_subfr], &xn[i_subfr], L_SUBFR);
    p_A += (M+1);
  }
  E_UTIL_deemph(xn, TILT_FAC, L_frame, mem_wsp);
  /* overlap area (xn[L_frame..L_frame+lext]) */
  E_LPC_a_weight(p_A, Ap, GAMMA1, M);
  E_UTIL_residu(Ap, &speech[L_frame], &xn[L_frame], lext);
  tmp = *mem_wsp;
  E_UTIL_deemph(&xn[L_frame], TILT_FAC, lext, &tmp);
  /* remove weighted ZIR when previous frame is ACELP */
  if (ovlp_size == 0) {
    for (i=0; i<(2*L_SUBFR); i++) {
      xn[i] -= wovlp[i];
    }
  }
  /* xn[] windowing for TCX overlap */
  for (i=0; i<ovlp_size; i++) {
    xn[i] *= window[i];
  }
  for (i=0; i<lext; i++) {
    xn[L_frame+i] *= window[ovlp_size+i];
  }
 /*-----------------------------------------------------------*
  * Compute the FFT of xn[].                                  *
  * Coefficients (xri[]) order are                            *
  *    re[0], re[n/2], re[1], re[2], ... re[n/2-1], im[n/2-1] *
  * Note that last FFT element (re[n/2]) is zeroed.           *
  *-----------------------------------------------------------*/
  fft9(xn, xri, (short)lg);
  xri[1] = 0.0;       /* freq bin at 6400 Hz zeroed */
 /*-----------------------------------------------------------*
  * Spectral algebraic quantization                           *
  * with adaptive low frequency emphasis/deemphasis.          *
  * Noise factor is the average level of unquantized freq.    * 
  *-----------------------------------------------------------*/
  adap_low_freq_emph(xri, lg);
  nb_bits -= (3+7);        /* fac_ns = 3 bits, gain = 7 bits */
  /* remove also the redundancy bits of the TCX gain
     TCX-40 -> 6 bits (in 2nd packet)
     TCX-80 -> 9 bits (3 bits in 2nd, 3rd and 4th packet) */
  if (L_frame == (L_FRAME_PLUS/2)) {
    nb_bits -= 6;
  }
  if (L_frame == L_FRAME_PLUS) {
    nb_bits -= 9;
  }
  fac_ns = AVQ_cod(xri, prm+2, nb_bits, lg/8);
  for(i=0; i<lg; i++) {
    xri[i] = (float)prm[i+2];
  }
  adap_low_freq_deemph(xri, lg);
  /* quantize noise factor (noise factor = 0.1 to 0.8) */
  tmp = 8.0f - (10.0f*fac_ns);
  index = (int)floor(tmp + 0.5);
  if (index < 0) {
    index = 0;
  }
  if (index > 7) {
    index = 7;
  }
  prm[0] = index;        /* fac_ns : 3 bits */
 /*-----------------------------------------------------------*
  * Compute inverse FFT for obtaining xnq[] without noise.    *
  * Coefficients (xri[]) order are                            *
  *    re[0], re[n/2], re[1], re[2], ... re[n/2-1], im[n/2-1] *
  * Note that last FFT element (re[n/2]) is zeroed.           *
  *-----------------------------------------------------------*/
  xri[1] = 0.0;       /* freq bin at 6400 Hz zeroed */
  ifft9(xri, xnq, (short)lg);
 /*-----------------------------------------------------------*
  * find and quantize gain, multiply xnq[] by gain.           *
  * windowing of xnq[] for TCX overlap.                       *
  *-----------------------------------------------------------*/
  gain = get_gain(xn, xnq, lg);
  prm[1] = q_gain_tcx(xnq, lg, &gain);
  for (i=0; i<lg; i++) {
    xnq[i] *= gain;
  }
  /* adaptive windowing on overlap (beginning and end of frame) */
  for (i=0; i<ovlp_size; i++) {
    xnq[i] *= window[i];
  }
  for (i=0; i<lext; i++) {
    xnq[i+L_frame] *= window[ovlp_size+i];
  }
 /*-----------------------------------------------------------*
  * TCX overlap and add.  Update memory for next overlap.     *
  *-----------------------------------------------------------*/
  for (i=0; i<L_OVLP; i++) {
    xnq[i] += wovlp[i];
  }
  /* save overlap for next frame */
  for (i=0; i<lext; i++) {
    wovlp[i] = xnq[i+L_frame];
  }
  for (i=lext; i<L_OVLP; i++) {
    wovlp[i] = 0.0;
  }
 /*-----------------------------------------------------------*
  * find excitation and synthesis                             *
  *-----------------------------------------------------------*/
  E_UTIL_f_preemph(xnq, TILT_FAC, L_frame, mem_wsyn);
  p_A = A;
  for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
    E_LPC_a_weight(p_A, Ap, GAMMA1, M);
    E_UTIL_synthesis(Ap, &xnq[i_subfr], &synth[i_subfr], L_SUBFR, &synth[i_subfr-M], 0);
    E_UTIL_residu(p_A, &synth[i_subfr], &exc[i_subfr], L_SUBFR);
    p_A += (M+1);
  }
  return;
}

⌨️ 快捷键说明

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