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

📄 bass_pf.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
字号:
#include <float.h>
#include <stdlib.h>
#include <math.h>
#include "../include/amr_plus.h"
#define L_EXTRA    96
static int short_pitch_tracker(
  float syn[],    /* input:  synthesis [-PIT_MAX..L_SUBFR] */
  int T);         /* input:  pitch period (>= PIT_MIN)     */
void init_bass_postfilter(Decoder_State_Plus *st)
{
  set_zero(st->old_synth_pf, PIT_MAX_MAX+(2*L_SUBFR));
  set_zero(st->old_noise_pf, 2*L_FILT);
  st->old_gain_pf[0] = 0.0;
  st->old_T_pf[0] = 64;
  st->old_gain_pf[1] = 0.0;
  st->old_T_pf[1] = 64;
  return;
}
void bass_postfilter(
  float *synth_in,     /* (i) : 12.8kHz synthesis to postfilter             */
  int *T_sf,           /* (i) : Pitch period for all subframe (T_sf[16])    */
  float *gainT_sf,     /* (i) : Pitch gain for all subframe (gainT_sf[16])  */
  float *synth_out,    /* (o) : filtered synthesis (with delay=L_SUBFR+L_FILT) */
                       /* delay = (2*L_SUBFR)+L_FILT   using EXTENSION_VA   */
  int pit_adj,
  Decoder_State_Plus *st)   /* i/o : decoder memory state                        */
{
  int i, j, i_subfr, T, lg;
  float tmp, ener, gain;
  float syn_buf[PIT_MAX_MAX+(2*L_SUBFR)+L_FRAME_PLUS], *syn;
  float noise_buf[(2*L_FILT)+L_SUBFR], *noise;
  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);
  }
  syn = syn_buf + PIT_MAX_MAX;
  noise = noise_buf + L_FILT;
  if (pit_adj == 0) {
    mvr2r(st->old_synth_pf, syn_buf, PIT_MAX_MAX+L_SUBFR);
    mvr2r(synth_in, syn_buf+PIT_MAX_MAX+L_SUBFR, L_FRAME_PLUS);
    mvr2r(syn_buf+L_FRAME_PLUS, st->old_synth_pf, PIT_MAX_MAX+L_SUBFR);
    mvr2r(&syn[-L_FILT], synth_out, L_FRAME_PLUS);
    T = st->old_T_pf[0];
    gain = st->old_gain_pf[0];
  }
  else {
    mvr2r(st->old_synth_pf, syn_buf, PIT_MAX_MAX+(2*L_SUBFR));
    mvr2r(synth_in, syn_buf+PIT_MAX_MAX+(2*L_SUBFR), L_FRAME_PLUS);
    mvr2r(syn_buf+L_FRAME_PLUS, st->old_synth_pf, PIT_MAX_MAX+(2*L_SUBFR));
    mvr2r(&syn[-L_FILT], synth_out, L_FRAME_PLUS);
  }
  for (i_subfr=0; i_subfr<L_FRAME_PLUS; i_subfr+=L_SUBFR)
  {
    if (pit_adj != 0) {
      i = (i_subfr/64) - 2;
      if (i < 0)
      {
	T = st->old_T_pf[i+2];
	gain = st->old_gain_pf[i+2];
      }
      else {
	T = T_sf[i];
	gain = gainT_sf[i];
      }
    }
    if (gain > 1.0) {
      gain = 1.0;
    }
    if (gain < 0.0) {
      gain = 0.0;
    }  
    T = short_pitch_tracker(&syn[i_subfr], T);
    if (pit_adj == 0) 
    {
      lg = L_SUBFR+L_FRAME_PLUS-T-i_subfr;
    }
    else
    {
      lg = (2*L_SUBFR)+L_FRAME_PLUS-T-i_subfr;
    }
    if (lg < 0) {
      lg = 0;
    }
    if (lg > L_SUBFR) {
      lg = L_SUBFR;
    }
    /* limit gain to avoid problem on burst */
    if (lg > 0)
    {
      tmp = 0.01f;
      for (i=0; i<lg; i++) {
        tmp += syn[i+i_subfr] * syn[i+i_subfr];
      }
      ener = 0.01f;
      for (i=0; i<lg; i++) {
        ener += syn[i+i_subfr+T] * syn[i+i_subfr+T];
      }
      tmp = (float)sqrt(tmp / ener);
      if (tmp < gain) {
        gain = tmp;
      }
    }
    /* calculate noise based on voiced pitch */
    tmp = gain*0.5f;
    for (i=0; i<lg; i++) {
      noise_buf[i+(2*L_FILT)] =
        tmp * (syn[i+i_subfr] - 0.5f*syn[i+i_subfr-T] - 0.5f*syn[i+i_subfr+T]);
    }
    for (i=lg; i<L_SUBFR; i++) {
      noise_buf[i+(2*L_FILT)] = tmp * (syn[i+i_subfr] - syn[i+i_subfr-T]);
    }
    mvr2r(st->old_noise_pf, noise_buf, 2*L_FILT);
    mvr2r(noise_buf+L_SUBFR, st->old_noise_pf, 2*L_FILT);
    /* substract from voiced speech low-pass filtered noise */
    for (i=0; i<L_SUBFR; i++)
    {
      tmp = filt_lp[0] * noise[i];
      for(j=1; j<=L_FILT; j++) {
        tmp += filt_lp[j] * (noise[i-j] + noise[i+j]);
      }
      synth_out[i+i_subfr] -= tmp;
    }
    if(pit_adj == 0) {
      i = i_subfr/64;
      T = T_sf[i];
      gain = gainT_sf[i];
    }
  }
  if (pit_adj == 0) {
    st->old_T_pf[0] = T;
    st->old_gain_pf[0] = gain;
  }
  else {
    st->old_T_pf[0] = T_sf[NB_SUBFR-2];
    st->old_gain_pf[0] = gainT_sf[NB_SUBFR-2];
    st->old_T_pf[1] = T_sf[NB_SUBFR-1];
    st->old_gain_pf[1] = gainT_sf[NB_SUBFR-1];
  }
  return;
}
static int short_pitch_tracker(
  float syn[],    /* input:  synthesis [-PIT_MAX..L_SUBFR] */
  int T)          /* input:  pitch period (>= PIT_MIN)     */
{
  int i, T2;
  float tmp, corr, ener, cn;
  float *v1, *v2;
 /*----------------------------------------------------------------*
  * Test pitch/2 to avoid continuous pitch doubling                *
  * (short pitch is limited to PIT_MIN (34 = 376Hz) by the encoder *
  *----------------------------------------------------------------*/
  T2 = T>>1;
  v1 = &syn[-L_EXTRA];
  v2 = &syn[-T2-L_EXTRA];
  ener = 0.01f;
  for (i=0; i<L_SUBFR+L_EXTRA; i++) {
    ener += v1[i]*v1[i];
  }
  corr = 0.01f;
  for (i=0; i<L_SUBFR+L_EXTRA; i++) {
    corr += v1[i]*v2[i];
  }
  tmp = 0.01f;
  for (i=0; i<L_SUBFR+L_EXTRA; i++) {
    tmp += v2[i]*v2[i];
  }
  /* cn = normalized correlation of pitch/2 */
  cn = corr / (float)sqrt(ener*tmp);
  if (cn > 0.95f) {
    T = T2;
  }
  return(T);
}

⌨️ 快捷键说明

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