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

📄 dec_util.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   }
   mem[0] = y2_hi;
   mem[1] = y2_lo;
   mem[2] = y1_hi;
   mem[3] = y1_lo;
   mem[4] = x0;
   mem[5] = x1;
   return;
}
/*
 * D_UTIL_synthesis
 *
 * Parameters:
 *    a              I: LP filter coefficients
 *    m              I: order of LP filter
 *    x              I: input signal
 *    y              O: output signal
 *    lg             I: size of filtering
 *    mem          I/O: initial filter states
 *    update_m       I: update memory flag
 *
 * Function:
 *    Perform the synthesis filtering 1/A(z).
 *
 * Returns:
 *    void
 */
static void D_UTIL_synthesis(Word16 a[], Word16 m, Word16 x[], Word16 y[],
                             Word16 lg, Word16 mem[], Word16 update)
{
   Word32 i, j, tmp;
   Word16 y_buf[L_SUBFR16k + M16k], a0;
   Word16 *yy;
   yy = &y_buf[m];
   /* copy initial filter states into synthesis buffer */
   memcpy(y_buf, mem, m * sizeof(Word16));
   a0 = (Word16)(a[0] >> 1);   /* input / 2 */
   /* Do the filtering. */
   for(i = 0; i < lg; i++)
   {
      tmp = x[i] * a0;
      for(j = 1; j <= m; j++)
      {
         tmp -= a[j] * yy[i - j];
      }
      y[i] = yy[i] = (Word16)((tmp + 0x800) >> 12);
   }
   /* Update memory if required */
   if(update)
   {
      memcpy(mem, &yy[lg - m], m * sizeof(Word16));
   }
   return;
}
/*
 * D_UTIL_bp_6k_7k
 *
 * Parameters:
 *    signal       I/O: signal
 *    lg             I: lenght of signal
 *    mem          I/O: filter memory [4]
 *
 * Function:
 *    15th order band pass 6kHz to 7kHz FIR filter.
 *
 * Returns:
 *    void
 */
void D_UTIL_bp_6k_7k(Word16 signal[], Word16 lg, Word16 mem[])
{
   Word32 x[L_SUBFR16k + (L_FIR - 1)];
   Word32 i, j, tmp;
   for(i = 0; i < (L_FIR - 1); i++)
   {
      x[i] = (Word16)mem[i];   /* gain of filter = 4 */
   }
   for(i = 0; i < lg; i++)
   {
      x[i + L_FIR - 1] = signal[i] >> 2;   /* gain of filter = 4 */
   }
   for(i = 0; i < lg; i++)
   {
      tmp = 0;
      for(j = 0; j < L_FIR; j++)
      {
         tmp += x[i + j] * D_ROM_fir_6k_7k[j];
      }
      signal[i] = (Word16)((tmp + 0x4000) >> 15);
   }
   for(i = 0; i < (L_FIR - 1); i++)
   {
      mem[i] = (Word16)x[lg + i];   /* gain of filter = 4 */
   }
   return;
}
/*
 * D_UTIL_hp_7k
 *
 * Parameters:
 *    signal          I/O: ISF vector
 *    lg                I: length of signal
 *    mem             I/O: memory (30)
 *
 * Function:
 *    15th order high pass 7kHz FIR filter
 *
 * Returns:
 *    void
 */
static void D_UTIL_hp_7k(Word16 signal[], Word16 lg, Word16 mem[])
{
   Word32 i, j, tmp;
   Word16 x[L_SUBFR16k + (L_FIR - 1)];
   memcpy(x, mem, (L_FIR - 1) * sizeof(Word16));
   memcpy(&x[L_FIR - 1], signal, lg * sizeof(Word16));
   for(i = 0; i < lg; i++)
   {
      tmp = 0;
      for(j = 0; j < L_FIR; j++)
      {
         tmp += x[i + j] * D_ROM_fir_7k[j];
      }
      signal[i] = (Word16)((tmp + 0x4000) >> 15);
   }
   memcpy(mem, x + lg, (L_FIR - 1) * sizeof(Word16));
   return;
}
/*
 * D_UTIL_Dec_synthesis
 *
 * Parameters:
 *    Aq             I: quantized Az
 *    exc            I: excitation at 12kHz
 *    Q_new          I: scaling performed on exc
 *    synth16k       O: 16kHz synthesis signal
 *    prms           I: parameters
 *    HfIsf        I/O: High frequency ISF:s
 *    mode           I: codec mode
 *    newDTXState    I: dtx state
 *    bfi            I: bad frame indicator
 *    st           I/O: State structure
 *
 * Function:
 *    Synthesis of signal at 16kHz with HF extension.
 *
 * Returns:
 *    void
 */
void D_UTIL_dec_synthesis(Word16 Aq[], Word16 exc[], Word16 Q_new,
                          Word16 synth16k[], Word16 prms, Word16 HfIsf[],
                          Word16 mode, Word16 newDTXState, Word16 bfi,
                          Decoder_State *st)
{
   Word32 tmp, i;
   Word16 exp;
   Word16 ener, exp_ener;
   Word32 fac;
   Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
   Word16 synth[L_SUBFR];
   Word16 *synth_new, *synth_out, synth_buff[PIT_MAX + 2 * L_SUBFR];
   Word16 HF[L_SUBFR16k];   /* High Frequency vector      */
   Word16 Ap[M16k + 1];
   Word16 HfA[M16k + 1];
   Word16 HF_corr_gain;
   Word16 HF_gain_ind;
   Word32 gain1, gain2;
   Word16 weight1, weight2;
   float gain_hf_plus;
   float f_exc[L_SUBFR];
   float f_synth[L_SUBFR];
   float f_HF[L_SUBFR16k];
   /*
    * Speech synthesis
    *
    * - Find synthesis speech corresponding to exc2[].
    * - Perform fixed deemphasis and hp 50hz filtering.
    * - Oversampling from 12.8kHz to 16kHz.
    */
   synth_new = synth_buff + PIT_MAX + L_SUBFR;
   synth_out = synth_buff + PIT_MAX - L_FILT;
   memcpy(synth_buff, st->mem_syn_out, (PIT_MAX + L_SUBFR) * sizeof(Word16));
   memcpy(synth_hi, st->mem_syn_hi, M * sizeof(Word16));
   memcpy(synth_lo, st->mem_syn_lo, M * sizeof(Word16));
   D_UTIL_synthesis_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
   memcpy(st->mem_syn_hi, synth_hi + L_SUBFR, M * sizeof(Word16));
   memcpy(st->mem_syn_lo, synth_lo + L_SUBFR, M * sizeof(Word16));
   D_UTIL_deemph_32(synth_hi + M, synth_lo + M, synth_new, PREEMPH_FAC, L_SUBFR,
      &(st->mem_deemph));
   D_UTIL_hp50_12k8(synth_out, L_SUBFR, st->mem_sig_out);
   D_UTIL_oversamp_16k(synth_out, L_SUBFR, synth16k, st->mem_oversamp);
   if (st->ramp_state > 0)
   {
	   st->ramp_state--;
	   gain_hf_plus = st->gain_hf_plus * gain_hf_ramp[st->ramp_state] *
		              (float)pow(2.0f, -1.0f * (float)Q_new);
	   for (i = 0; i < L_SUBFR; i++)
	   {
		   f_exc[i] = gain_hf_plus * (float)exc[i];
	   }
	   soft_exc_hf(f_exc, &(st->lp_amp_hf));
	   E_UTIL_synthesisPlus(st->lpc_hf_plus, 8, f_exc, f_synth, L_SUBFR,
		                    st->mem_syn_hf_plus, 1);
	   smooth_ener_hf(f_synth, &(st->threshold_hf));
       oversamp_12k8(f_synth, f_HF, L_SUBFR16k, st->mem_oversamp_hf_plus, 1, 0);
	   for (i = 0; i < L_SUBFR16k;i ++)
	   {
		   if (f_HF[i] <= -32768.0f)
		   {
			   HF[i] = (Word16)-32768;
		   }
		   else
		   {
			   if (f_HF[i] >= 32767.0f)
			   {
				   HF[i] = (Word16)32767;
			   }
			   else
			   {
				   HF[i] = (Word16)f_HF[i];
			   }
		   }
	   }
   }
   else
   {
	   memcpy(synth, synth_out, L_SUBFR * sizeof(Word16));
	   /*
		* HF noise synthesis
		*
		* - Generate HF noise between 5.5 and 7.5 kHz.
		* - Set energy of noise according to synthesis tilt.
		*     tilt > 0.8 ==> - 14 dB (voiced)
		*     tilt   0.5 ==> - 6 dB  (voiced or noise)
		*     tilt < 0.0 ==>   0 dB  (noise)
		*/
	   /* generate white noise vector */
	   for(i = 0; i < L_SUBFR16k; i++)
	   {
		  HF[i] = (Word16)(D_UTIL_random(&(st->mem_seed2)) >> 3);
	   }
	   /* energy of excitation */
	   D_UTIL_signal_down_scale(exc, L_SUBFR, 3);
	   Q_new = (Word16)(Q_new - 3);
	   ener = (Word16)(D_UTIL_dot_product12(exc, exc, L_SUBFR, &exp_ener) >> 16);
	   exp_ener = (Word16)(exp_ener - (Q_new << 1));
	   /* set energy of white noise to energy of excitation */
	   tmp = (Word16)(D_UTIL_dot_product12(HF, HF, L_SUBFR16k, &exp) >> 16);
	   if(tmp > ener)
	   {
		  tmp = tmp >> 1;   /* Be sure tmp < ener */
		  exp = (Word16)(exp + 1);
	   }
	   tmp = (tmp << 15) / ener;
	   if(tmp > 32767)
	   {
		  tmp = 32767;
	   }
	   tmp = tmp << 16;   /* result is normalized */
	   exp = (Word16)(exp - exp_ener);
	   D_UTIL_normalised_inverse_sqrt(&tmp, &exp);
	   /* L_tmp x 2, L_tmp in Q31 */
	   /* tmp = 2 x sqrt(ener_exc/ener_hf) */
	   if(exp >= 0)
	   {
		  tmp = tmp >> (15 - exp);
	   }
	   else
	   {
		  tmp = tmp >> (-exp);
		  tmp = tmp >> 15;
	   }
	   /* saturation */
	   if(tmp > 0x7FFF)
	   {
		  tmp = 0x7FFF;
	   }
	   for(i = 0; i < L_SUBFR16k; i++)
	   {
		  HF[i] = (Word16)((HF[i] * tmp) >> 15);
	   }
	   /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
	   D_UTIL_hp400_12k8(synth, L_SUBFR, st->mem_hp400);
	   tmp = 0L;
	   for(i = 0; i < L_SUBFR; i++)
	   {
		  tmp = tmp + (synth[i] * synth[i]);
	   }
	   tmp = (tmp << 1) + 1;
	   exp = D_UTIL_norm_l(tmp);
	   ener = (Word16)((tmp << exp) >> 16);   /* ener = r[0] */
	   tmp = 0L;
	   for(i = 1; i < L_SUBFR; i++)
	   {
		  tmp = tmp + (synth[i] * synth[i - 1]);
	   }
	   tmp = (tmp << 1) + 1;
	   tmp = (tmp << exp) >> 16;   /* tmp = r[1] */
	   if(tmp > 0)
	   {
		  fac = ((tmp << 15) / ener);
		  if(fac > 32767)
		  {
			 fac = 32767;
		  }
	   }
	   else
	   {
		  fac = 0;
	   }
	   /* modify energy of white noise according to synthesis tilt */
	   gain1 = (32767 - fac);
	   gain2 = ((32767 - fac) * 20480) >> 15;
	   gain2 = (gain2 << 1);
	   if(gain2 > 32767)
		  gain2 = 32767;
	   if(st->mem_vad_hist > 0)
	   {
		  weight1 = 0;
		  weight2 = 32767;
	   }
	   else
	   {
		  weight1 = 32767;
		  weight2 = 0;
	   }
	   tmp = (weight1 * gain1) >> 15;
	   tmp = tmp + ((weight2 * gain2) >> 15);
	   if(tmp != 0)
	   {
		  tmp = tmp + 1;
	   }
	   if(tmp < 3277)
	   {
		  tmp = 3277;   /* 0.1 in Q15 */
	   }
	   if((mode == MODE_24k) & (bfi == 0))
	   {
		  /* HF correction gain */
		  HF_gain_ind = prms;
		  HF_corr_gain = D_ROM_hp_gain[HF_gain_ind];
		  /* HF gain */
		  for(i = 0; i < L_SUBFR16k; i++)
		  {
			 HF[i] = (Word16)(((HF[i] * HF_corr_gain) >> 15) << 1);
		  }
	   }
	   else
	   {
		  for(i = 0; i < L_SUBFR16k; i++)
		  {
			 HF[i] = (Word16)((HF[i] * tmp) >> 15);
		  }
	   }
	   if((mode <= MODE_7k) & (newDTXState == SPEECH))
	   {
		  D_LPC_isf_extrapolation(HfIsf);
		  D_LPC_isp_a_conversion(HfIsf, HfA, M16k);
		  D_LPC_a_weight(HfA, Ap, 29491, M16k);   /* fac=0.9 */
		  D_UTIL_synthesis(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
	   }
	   else
	   {
		  /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
		  D_LPC_a_weight(Aq, Ap, 19661, M);   /* fac=0.6 */
		  D_UTIL_synthesis(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf + (M16k - M), 1);
	   }
	   /* noise High Pass filtering (1ms of delay) */
	   D_UTIL_bp_6k_7k(HF, L_SUBFR16k, st->mem_hf);
	   if(mode == MODE_24k)
	   {
		  /* Low Pass filtering (7 kHz) */
		  D_UTIL_hp_7k(HF, L_SUBFR16k, st->mem_hf3);
	   }
   }
   /* add filtered HF noise to speech synthesis */
   for(i = 0; i < L_SUBFR16k; i++)
   {
      tmp = (synth16k[i] + HF[i]);
      synth16k[i] = D_UTIL_saturate(tmp);
   }
   memcpy(st->mem_syn_out, synth_buff + L_SUBFR,
	      (PIT_MAX + L_SUBFR) * sizeof(Word16));
   return;
}
/*
 * D_UTIL_preemph
 *
 * Parameters:
 *    x            I/O: signal
 *    mu             I: preemphasis factor
 *    lg             I: vector size
 *    mem          I/O: memory (x[-1])
 *
 * Function:
 *    Filtering through 1 - mu z^-1
 *
 *
 * Returns:
 *    void
 */
void D_UTIL_preemph(Word16 x[], Word16 mu, Word16 lg, Word16 *mem)
{
   Word32 i, L_tmp;
   Word16 temp;
   temp = x[lg - 1];
   for(i = lg - 1; i > 0; i--)
   {
      L_tmp = x[i] << 15;
      L_tmp = L_tmp - (x[i - 1] * mu);
      x[i] = (Word16)((L_tmp + 0x4000) >> 15);
   }
   L_tmp = x[0] << 15;
   L_tmp = L_tmp - (*mem * mu);
   x[0] = (Word16)((L_tmp + 0x4000) >> 15);
   *mem = temp;
   return;
}

⌨️ 快捷键说明

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