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

📄 cod_lf_b.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../include/amr_plus.h"
static void try_tcx(
  int k,
  int mode,     /* 1=TCX20, 2=TCX40 3=TCX80 */
  float *snr,
  float A[],
  float wsp[],
  int mod[],
  short coding_mod[],
  float isp[],
  float isp_q[],
  float AqLF[],
  float speech[],
  float mem_w0[],
  float mem_xnq[],
  float mem_wsyn[],
  float old_exc[],
  float mem_syn[],
  float wovlp[],
  int ovlp_size[],
  float past_isfq[],
  int pit_adj,
  int nbits,
  int nprm_tcx,
  int prm[]);
void coder_lf_b(int codec_mode,    /* (i) : AMR-WB+ mode (see cnst.h)             */ 
				float speech[],    /* (i) : speech vector [-M..L_FRAME_PLUS+L_NEXT]    */ 
				float synth[],     /* (o) : synthesis vector [-M..L_FRAME_PLUS]        */ 
				int mod[],         /* (o) : mode for each 20ms frame (mode[4]     */
				float AqLF[],      /* (o) : quantized coefficients (AdLF[16])     */ 
				float window[],    /* (i) : window for LPC analysis               */
				int param[],       /* (o) : parameters (NB_DIV*NPRM_DIV)          */
				float ol_gain[],   /* (o) : open-loop LTP gain                    */  
				int  ave_T_out[],  /* (o) : average LTP lag                       */ 
				float ave_p_out[], /* (o) : average LTP gain                      */ 
				short coding_mod[],/* (i) : selected mode for each 20ms           */
                int pit_adj,       /* (i) : indicate pitch adjustment             */
				Coder_State_Plus *st /* i/o : coder memory state                  */
				) 
{ 
	/* LPC coefficients */
	float r[M+1];                   /* Autocorrelations of windowed speech  */
	float A[(NB_SUBFR+1)*(M+1)];
	float Ap[M+1];
	float ispnew[M];                /* LSPs at 4nd subframe                 */
	float isfnew[M];
	float isp[(NB_DIV+1)*M];
	float isp_q[(NB_DIV+1)*M];
	float past_isfq[3*M];                  /* past isf quantizer */
	float mem_w0[NB_DIV+1], mem_wsyn[NB_DIV+1];
	float mem_xnq[NB_DIV+1];
	int ovlp_size[NB_DIV+1];
    float *wsp;
    float mem_syn[(NB_DIV+1)*M];
	float wovlp[(NB_DIV+1)*128];
	/* Scalars */
	int i, j, k, i2, i1, nbits, *prm;
	float snr, snr1, snr2;
	float ener, cor_max, t0;
	float *p, *p1;
	float norm_corr[4], norm_corr2[4];
	int T_op[NB_DIV], T_op2[NB_DIV];
	int T_out[4]; /* integer pitch-lag */
	float p_out[4];
	float LTPGain[2];
    int PIT_MIN;				/* Minimum pitch lag with resolution 1/4      */
    int PIT_MAX;				/* Maximum pitch lag                          */
	if(pit_adj ==0) {
		PIT_MIN = PIT_MIN_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_MAX = PIT_MAX_12k8 + (6*i);
	}
	/* number of bits per frame (80 ms) */
	nbits = NBITS_CORE[codec_mode];
	/* remove bits for mode */
	nbits -= NBITS_MODE;
   /*---------------------------------------------------------------*
	*  Perform LP analysis four times (every 20 ms)                 *
	*  - autocorrelation + lag windowing                            *
	*  - Levinson-Durbin algorithm to find a[]                      *
	*  - convert a[] to isp[]                                       *
	*  - interpol isp[]                                             *
	*---------------------------------------------------------------*/
	/* read old isp for LPC interpolation */
	mvr2r(st->ispold, isp, M);
	for (i = 0; i < NB_DIV; i++)
	{
		if (pit_adj<=FSCALE_DENOM) {
			/* Autocorrelations of signal at 12.8kHz */
			E_UTIL_autocorrPlus(&speech[(i*L_DIV)+L_SUBFR], r, M, L_WINDOW, window);
		} else {
			/* Autocorrelations of signal at 12.8kHz */
			E_UTIL_autocorrPlus(&speech[(i*L_DIV)+(L_SUBFR/2)], r, M, L_WINDOW_HIGH_RATE, window);
		}
            /* Lag windowing    */
		lag_wind(r, M);
		/* Levinson Durbin  */
		E_LPC_lev_dur(Ap, r, M);
		/* From A(z) to ISP */
		E_LPC_a_isp_conversion(Ap, ispnew, st->ispold, M);
		for (j = 0; j < M; j++) {
			st->stClass->ApBuf[i*M+j] = Ap[j];
		}
		mvr2r(ispnew, &isp[(i+1)*M], M);
		/* A(z) interpolation every 20 ms (used for weighted speech) */
		int_lpc_np1(st->ispold, ispnew, &A[i*4*(M+1)], 4, M);
		/* update ispold[] for the next LPC analysis */
		mvr2r(ispnew, st->ispold, M);
	}
    mvr2r(synth-M, mem_syn, M);
	wsp = synth;        /* wsp[] use synth[] as tmp buffer */
{
	float old_d_wsp[(PIT_MAX_MAX/OPL_DECIM)+L_DIV];     /* Weighted speech vector */
	float *d_wsp;
	d_wsp = old_d_wsp + PIT_MAX_MAX/OPL_DECIM;
	mvr2r(st->old_d_wsp, old_d_wsp, PIT_MAX_MAX/OPL_DECIM);
	/* Calculate open-loop LTP parameters */
	for (i = 0; i < NB_DIV; i++) {
		/* weighted speech for SNR */
		find_wsp(&A[i*(NB_SUBFR/4)*(M+1)], &speech[i*L_DIV], &wsp[i*L_DIV], &(st->mem_wsp), L_DIV); 
		mvr2r(&wsp[i*L_DIV], d_wsp, L_DIV);
		E_GAIN_lp_decim2(d_wsp, L_DIV, st->mem_lp_decim2);
		/* Find open loop pitch lag for first 1/2 frame */
		T_op[i] = E_GAIN_open_loop_search(d_wsp, (PIT_MIN/OPL_DECIM)+1, PIT_MAX/OPL_DECIM,
			(2*L_SUBFR)/OPL_DECIM, st->old_T0_med, &(st->ol_gain), 
			st->hp_ol_ltp_mem, st->hp_old_wsp, (unsigned char)st->ol_wght_flg);
		LTPGain[1] = st->ol_gain;
		if (st->ol_gain > 0.6) {
			st->old_T0_med = E_GAIN_olag_median(T_op[i], st->old_ol_lag);
			st->ada_w = 1.0;
		}     
		else {
			st->ada_w = st->ada_w * 0.9f;
		}
		if (st->ada_w < 0.8) {
			st->ol_wght_flg = 0;
		}
		else {
			st->ol_wght_flg = 1;
		}
		/* compute max */
		cor_max = 0.0f;
		p = &d_wsp[0];
		p1 = d_wsp - T_op[i];
		for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) {
			cor_max += *p++ * *p1++;
		}
		/* compute energy */
		t0 = 0.01f;
		p = d_wsp - T_op[i];
		for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++, p++) {
			t0 += *p * *p;
		}
		t0 = (float)(1.0 / sqrt(t0));		/* 1/sqrt(energy)    */
		norm_corr[i] = cor_max * t0;        /* max/sqrt(energy)  */
		/* normalized corr (0..1) */
		ener = 0.01f;
		for (j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) {
			ener += d_wsp[j]*d_wsp[j];
		}
		ener = (float)(1.0 / sqrt(ener));	/* 1/sqrt(energy)    */
		norm_corr[i] *= ener;
		/* Find open loop pitch lag for second 1/2 frame */
		T_op2[i] = E_GAIN_open_loop_search(d_wsp + ((2*L_SUBFR)/OPL_DECIM), (PIT_MIN/OPL_DECIM)+1, PIT_MAX/OPL_DECIM,
			(2*L_SUBFR)/OPL_DECIM, st->old_T0_med, &st->ol_gain,
			st->hp_ol_ltp_mem,st->hp_old_wsp, (unsigned char)st->ol_wght_flg);
		LTPGain[0] = st->ol_gain;
		if (st->ol_gain > 0.6) {
			st->old_T0_med = E_GAIN_olag_median(T_op2[i], st->old_ol_lag);
			st->ada_w = 1.0;
		}     
		else {
			st->ada_w = st->ada_w * 0.9f;
		}
		if( st->ada_w < 0.8) {
			st->ol_wght_flg = 0;
		}
		else {
			st->ol_wght_flg = 1;
		}
		/* compute max */
		cor_max = 0.0f;
		p = d_wsp + (2*L_SUBFR)/OPL_DECIM;
		p1 = d_wsp + ((2*L_SUBFR)/OPL_DECIM) - T_op2[i];
		for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) {
			cor_max += *p++ * *p1++;
		}
		/* compute energy */
		t0 = 0.01f;
		p = d_wsp + ((2*L_SUBFR)/OPL_DECIM) - T_op2[i];
		for(j=0; j<(2*L_SUBFR)/OPL_DECIM; j++, p++) {
			t0 += *p * *p;
		}
		t0 = (float)(1.0 / sqrt(t0));		/* 1/sqrt(energy)    */
		norm_corr2[i] = cor_max * t0;        /* max/sqrt(energy)  */
		/* normalized corr (0..1) */
		ener = 0.01f;
		for (j=0; j<(2*L_SUBFR)/OPL_DECIM; j++) {
			ener += d_wsp[((2*L_SUBFR)/OPL_DECIM)+j]*d_wsp[((2*L_SUBFR)/OPL_DECIM)+j];
		}
		ener = (float)(1.0 / sqrt(ener));		/* 1/sqrt(energy)    */
		norm_corr2[i] *= ener;
		ol_gain[i] = st->ol_gain;
		mvr2r(&old_d_wsp[L_DIV/OPL_DECIM], old_d_wsp, PIT_MAX_MAX/OPL_DECIM);
		st->stClass->LTPGain[(2*i+2)] = LTPGain[1];
		st->stClass->LTPGain[(2*i+2)+1] = LTPGain[0];
		st->stClass->LTPLag[(2*i)+2] = T_op[i];
		st->stClass->LTPLag[(2*i+2)+1] = T_op2[i];
		st->stClass->NormCorr[(2*i+2)] = norm_corr[i];
		st->stClass->NormCorr[(2*i+2)+1] = norm_corr2[i];
  }
  mvr2r(old_d_wsp, st->old_d_wsp, PIT_MAX_MAX/OPL_DECIM);   /* d_wsp already shifted */
}
 /*---------------------------------------------------------------*
  *  Call ACELP and TCX codec                                     *
  *---------------------------------------------------------------*/
  ovlp_size[0] = st->old_ovlp_size;
  /*Classification refinement */
  classifyExcitationRef(st->stClass, isp, coding_mod);
  if (st->SwitchFlagPlusToWB && coding_mod[0] != 0) {
	  coding_mod[0] = 0;	
	  st->stClass->NbOfAcelps++;
	  st->SwitchFlagPlusToWB = 0;
  }
  ovlp_size[1] = st->old_ovlp_size;
  ovlp_size[2] = st->old_ovlp_size;
  ovlp_size[3] = st->old_ovlp_size;
  ovlp_size[4] = st->old_ovlp_size;
  mem_w0[0]   = st->old_mem_w0;
  mem_xnq[0]   = st->old_mem_xnq;
  mem_wsyn[0] = st->old_mem_wsyn;
  mvr2r(st->old_wovlp, wovlp, 128);
  mvr2r(st->past_isfq, &past_isfq[0], M);
  mvr2r(st->ispold_q, isp_q, M);
  snr2 = 0.0;
  for (i1=0; i1<2; i1++)
  {
	  mvr2r(&past_isfq[i1*M], &past_isfq[(i1+1)*M], M);
	  snr1 = 0.0;
	  for (i2=0; i2<2; i2++)
	  {
		  k = (i1*2) + i2;
		  if (coding_mod[k] == 0 || (coding_mod[k] == 1 && st->stClass->NbOfAcelps != 0)
			  || (st->stClass->NoMtcx[i1] != 0 &&  st->stClass->NbOfAcelps == 0)
			  ) { 
			  /* set pointer to parameters */
			  prm = param + (k*NPRM_DIV);
			  /*---------------------------------------------------------------*

⌨️ 快捷键说明

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