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

📄 dec_hi_stereo.c

📁 关于AMR-WB+语音压缩编码的实现代码
💻 C
字号:
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../include/amr_plus.h"
#include "../include/s_util.h"
void init_dec_hi_stereo(Decoder_State_Plus *st)
{
	int i;
	cos_window(st->w_window,0,L_SUBFR);
	for(i=0;i<L_SUBFR;i++) 
	{
		st->w_window[i] = st->w_window[i]*st->w_window[i];
	}
	set_zero(st->old_wh,HI_FILT_ORDER);
	set_zero(st->old_wh2,HI_FILT_ORDER);
	set_zero(st->old_exc_mono,HI_FILT_ORDER);
	set_zero(st->old_AqLF,5*(M+1));
	for(i=0;i<5;i++){
		st->old_AqLF[i*(M+1)]=1.0f;
	}
	set_zero(st->left.mem_synth_hi,M);
	set_zero(st->right.mem_synth_hi,M);
	set_zero(st->old_wh_q,HI_FILT_ORDER);
	set_zero(st->old_gm_gain,2);
	for(i=0;i<4;i++){
		st->old_gain_left[i]=1.0f;
		st->old_gain_right[i]=1.0f;	
	}
}
static void dec_filt(int **prm,
					 float wh[],
					 float old_wh[],
					 int bfi,
					 const PMSVQ*	filt_hi_pmsvq
           )
{
	pmsvq_inv(wh, prm, old_wh, bfi, filt_hi_pmsvq);
}
static void dec_gain(int **prm,
					 float *gain_left,
					 float *gain_right,
					 float *old_gain,
					 int bfi,
					 const PMSVQ* gain_hi_pmsvq
					 )
{
	float tmp[2];
	pmsvq_inv(tmp, prm, old_gain, bfi, gain_hi_pmsvq);
	*gain_left  = tmp[0];
	*gain_right = tmp[1];
}
/* this supposes time alignement between encoder and decoder */
void dec_hi_stereo(float synth_hi_t0[],
		   float right_hi[],
		   float left_hi[],
		   float AqLF[],
		   int   param[],
		   int bad_frame[],
		   int fscale,
		   Decoder_State_Plus *st)
{
    float *exc_buf = right_hi;  
	float *exc_mono=exc_buf+HI_FILT_ORDER;
	float *synth_hi_d;
	float *p_Aq,*p_h;
	int i,k;
	int i_subfr;
	int start;
	float gain_left[NB_DIV+2];
	float gain_right[NB_DIV+2];
	float new_gain_left[NB_DIV];
	float new_gain_right[NB_DIV];
    float *left_exc, *right_exc;
	float side_buf[L_DIV+L_SUBFR];
	float buf[L_SUBFR];
	float wh[NB_DIV*HI_FILT_ORDER];
	int *prm;
   /*---------------------------------------------------------------------*
	* Mismatch between received parameters and signal buffer              *
	*                                                                     *
	*                                                                     *
	*                                                                     *
	*	fscale=0														  *
	*                                                                     *
	*                  |    20ms   |    20ms   |     20ms  |   20ms    |  *
	*        -|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|  *
	*        <--------  Total speech buffer ---------------->			  *
	*                                                                     *
	*	fscale!=0                                                         *
	*                                                                     *
	*                  |    20ms   |    20ms   |     20ms  |   20ms    |  *
	*     -|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|  *
	*     <--------  Total speech buffer ---------------->                *
	* g(-2)    g(-1)       g(0)         g(1)        g(2)        g(3)      *
	* f(-2)    f(-1)       f(0)         f(1)        f(2)        f(3)      *
	*---------------------------------------------------------------------*/
    left_exc = left_hi;
    right_exc = right_hi;
	/*-----------------------------------------------------------*
	* Decode gain and filters				    		         *
	*									                         *
	*------------------------------------------------------------*/
	for(i=0;i<NB_DIV;i++){
		prm = param + i*NPRM_STEREO_HI_X;
		dec_filt(&prm,&wh[i*HI_FILT_ORDER],st->old_wh_q, bad_frame[i],
			st->filt_hi_pmsvq);
		dec_gain(&prm,&new_gain_left[i],&new_gain_right[i],
			st->old_gm_gain, bad_frame[i],st->gain_hi_pmsvq);
		new_gain_left[i] = (float)pow(10.0f,new_gain_left[i]/20.0f);
		new_gain_right[i] = (float)pow(10.0f,new_gain_right[i]/20.0f);
	}
	/*-----------------------------------------------------------*
	* Set correct alignement of parameters	    		         *
	*------------------------------------------------------------*/
	mvr2r(st->old_gain_left,gain_left,2);
	mvr2r(st->old_gain_right,gain_right,2);
	mvr2r(new_gain_left,gain_left+2,4);
	mvr2r(new_gain_right,gain_right+2,4);
	mvr2r(new_gain_left+2,st->old_gain_left,2);
	mvr2r(new_gain_right+2,st->old_gain_right,2);
   /*-----------------------------------------------------------*
	* Set correct starting buffer					.           *
	*-----------------------------------------------------------*/
	synth_hi_d = &synth_hi_t0[-L_BSP-D_BPF];
	/*-----------------------------------------------------------*
	* Compute left right pseudo-excitation	    		         *
	*Use the mono LPC filter for whitening                       *
	*------------------------------------------------------------*/
	p_Aq = st->old_AqLF;
	residu(p_Aq,M, synth_hi_d, exc_mono, L_SUBFR/2);
	p_Aq += (M+1);
	for(i_subfr=L_SUBFR/2;i_subfr<3*L_SUBFR+ L_SUBFR/2;i_subfr+=L_SUBFR){
		residu(p_Aq,M, &synth_hi_d[i_subfr], &exc_mono[i_subfr], L_SUBFR);
		p_Aq += (M+1);
	}
	if (fscale != 0) {
		residu(p_Aq,M, &synth_hi_d[i_subfr], &exc_mono[i_subfr], L_SUBFR);
	}
	p_Aq = AqLF;
	if(fscale==0) {
		start = 3*L_SUBFR + L_SUBFR/2;
	}
	else {
		start = 4*L_SUBFR + L_SUBFR/2;
	}
	for (i_subfr=start; i_subfr <L_FRAME_PLUS-L_SUBFR/2; i_subfr+=L_SUBFR)
	{
		residu(p_Aq,M, &synth_hi_d[i_subfr], &exc_mono[i_subfr], L_SUBFR);
		p_Aq += (M+1);
	}
	residu(p_Aq,M, &synth_hi_d[L_FRAME_PLUS-L_SUBFR/2], &exc_mono[L_FRAME_PLUS-L_SUBFR/2], L_SUBFR/2);
	/*-----------------------------------------------------------*
	* prepare excitation buffer for filtering	   		         *
	*------------------------------------------------------------*/	
	mvr2r(st->old_exc_mono,exc_buf,HI_FILT_ORDER);
	mvr2r(exc_buf+L_FRAME_PLUS,st->old_exc_mono,HI_FILT_ORDER);
	/*-----------------------------------------------------------*
	* synthesise left right pseudo excitation with interpolation *
	*------------------------------------------------------------*/	
	if(fscale ==0 ) {
		fir_filt(st->old_wh,HI_FILT_ORDER,exc_mono,side_buf,L_DIV-L_SUBFR/2);
		fir_filt(st->old_wh2,HI_FILT_ORDER,exc_mono,buf,L_SUBFR/2);
		for(i=0;i<L_SUBFR/2;i++){
			left_exc[i] = st->w_window[i+L_SUBFR/2]*gain_left[0]*(buf[i]+exc_mono[i])+
				gain_left[1]*(1.0f-st->w_window[i+L_SUBFR/2])*(exc_mono[i] + side_buf[i]);
			right_exc[i] = st->w_window[i+L_SUBFR/2]*gain_right[0]*(exc_mono[i]-buf[i])+
				gain_right[1]*(1.0f-st->w_window[i+L_SUBFR/2])*(exc_mono[i] - side_buf[i]);
		}
		for(i=L_SUBFR/2;i<L_DIV-L_SUBFR/2;i++){
			left_exc[i] = gain_left[1]*(exc_mono[i] + side_buf[i]);
			right_exc[i]= gain_right[1]*(exc_mono[i] - side_buf[i]);
		}
		fir_filt(st->old_wh,HI_FILT_ORDER,&exc_mono[L_DIV-L_SUBFR/2],buf,L_SUBFR);
		p_h = wh;
		k = 1;
		for(i_subfr=L_DIV-L_SUBFR/2;i_subfr<L_FRAME_PLUS-L_SUBFR/2;i_subfr+=L_DIV)
		{
			fir_filt(p_h,HI_FILT_ORDER,&exc_mono[i_subfr],side_buf,L_DIV);
			for(i=0;i<L_SUBFR;i++){
				left_exc[i_subfr+i] = st->w_window[i]*gain_left[k]*(exc_mono[i_subfr+i]+buf[i]) +
					gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[i_subfr+i]+side_buf[i]);
				right_exc[i_subfr+i] = st->w_window[i]*gain_right[k]*(exc_mono[i_subfr+i]-buf[i]) +
					gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[i_subfr+i]-side_buf[i]);
			}
			for(i=L_SUBFR;i<L_DIV;i++){
				left_exc[i_subfr+i] = gain_left[k+1]*(exc_mono[i_subfr+i]+side_buf[i]);
				right_exc[i_subfr+i] = gain_right[k+1]*(exc_mono[i_subfr+i]-side_buf[i]);
			}
			if(i_subfr + L_DIV + L_SUBFR < L_FRAME_PLUS-L_SUBFR/2)
			{
				fir_filt(p_h,HI_FILT_ORDER,&exc_mono[i_subfr+L_DIV],buf,L_SUBFR);
			}
			else {
				fir_filt(p_h,HI_FILT_ORDER,&exc_mono[i_subfr+L_DIV],buf,L_SUBFR/2);
			}
			p_h += HI_FILT_ORDER;
			k++;
		}
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[L_FRAME_PLUS-L_SUBFR/2],side_buf,L_SUBFR/2);
		for(i=0;i<L_SUBFR/2;i++)
		{
			left_exc[L_FRAME_PLUS-L_SUBFR/2+i] = st->w_window[i]*gain_left[k]*(exc_mono[L_FRAME_PLUS-L_SUBFR/2+i]+buf[i]) +
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_FRAME_PLUS-L_SUBFR/2+i]+side_buf[i]);
			right_exc[L_FRAME_PLUS-L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[i_subfr+i]-buf[i]) +
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_FRAME_PLUS-L_SUBFR/2+i]-side_buf[i]);
		}
	}
	else {
		fir_filt(st->old_wh2,HI_FILT_ORDER,exc_mono,buf,L_SUBFR/2);
		for(i=0;i<L_SUBFR/2;i++){
			left_exc[i] = gain_left[0]*(exc_mono[i] + buf[i]);
			right_exc[i]= gain_right[0]*(exc_mono[i]-buf[i]);
		}
		fir_filt(st->old_wh2,HI_FILT_ORDER,exc_mono +L_SUBFR/2,buf,L_SUBFR);
		fir_filt(st->old_wh,HI_FILT_ORDER, exc_mono + L_SUBFR/2,side_buf,L_DIV);
		for(i=0;i<L_SUBFR;i++){
			left_exc[L_SUBFR/2+i] = st->w_window[i]*gain_left[0]*(exc_mono[L_SUBFR/2+i]+buf[i]) +
				gain_left[1]*(1.0f-st->w_window[i])*(exc_mono[L_SUBFR/2+i]+side_buf[i]);
			right_exc[L_SUBFR/2+i] = st->w_window[i]*gain_right[0]*(exc_mono[L_SUBFR/2+i]-buf[i]) +
				gain_right[1]*(1.0f-st->w_window[i])*(exc_mono[L_SUBFR/2+i]-side_buf[i]);
		}
		for(i=L_SUBFR+L_SUBFR/2;i<L_DIV+L_SUBFR/2;i++){
			left_exc[i] = gain_left[1]*(exc_mono[i] + side_buf[i-L_SUBFR/2]);
			right_exc[i]= gain_right[1]*(exc_mono[i] - side_buf[i-L_SUBFR/2]);
		}
		fir_filt(st->old_wh,HI_FILT_ORDER,&exc_mono[L_DIV+L_SUBFR/2],buf,L_SUBFR);
		p_h = wh;
		k = 1;
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[L_DIV+L_SUBFR/2],side_buf,L_DIV);
		for(i=0;i<L_SUBFR;i++){
			left_exc[L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_left[k]*(exc_mono[L_DIV+L_SUBFR/2+i]+buf[i]) +
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_DIV+L_SUBFR/2+i]+side_buf[i]);
			right_exc[L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[L_DIV+L_SUBFR/2+i]-buf[i]) +
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[L_DIV+L_SUBFR/2+i]-side_buf[i]);
		}
		for(i=L_SUBFR;i<L_DIV;i++){
			left_exc[L_DIV+L_SUBFR/2+i] = gain_left[k+1]*(exc_mono[L_DIV+L_SUBFR/2+i]+side_buf[i]);
			right_exc[L_DIV+L_SUBFR/2+i] = gain_right[k+1]*(exc_mono[L_DIV+L_SUBFR/2+i]-side_buf[i]);
		}
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[(2*L_DIV)+(L_SUBFR/2)],buf,L_SUBFR);
		p_h += HI_FILT_ORDER;
		k++;
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[(2*L_DIV)+L_SUBFR/2],side_buf,L_DIV);
		for(i=0;i<L_SUBFR;i++){
			left_exc[2*L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_left[k]*(exc_mono[2*L_DIV+L_SUBFR/2+i]+buf[i]) +
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[2*L_DIV+L_SUBFR/2+i]+side_buf[i]);
			right_exc[2*L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[2*L_DIV+L_SUBFR/2+i]-buf[i]) +
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[2*L_DIV+L_SUBFR/2+i]-side_buf[i]);
		}
		for(i=L_SUBFR;i<L_DIV;i++){
			left_exc[2*L_DIV+L_SUBFR/2+i] = gain_left[k+1]*(exc_mono[2*L_DIV+L_SUBFR/2+i]+side_buf[i]);
			right_exc[2*L_DIV+L_SUBFR/2+i] = gain_right[k+1]*(exc_mono[2*L_DIV+L_SUBFR/2+i]-side_buf[i]);
		}
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[(3*L_DIV)+(L_SUBFR/2)],buf,L_SUBFR);
		p_h += HI_FILT_ORDER;
		k++;
		fir_filt(p_h,HI_FILT_ORDER,&exc_mono[(3*L_DIV)+L_SUBFR/2],side_buf,L_DIV-L_SUBFR/2);
		for(i=0;i<L_SUBFR;i++){
			left_exc[3*L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_left[k]*(exc_mono[3*L_DIV+L_SUBFR/2+i]+buf[i]) +
				gain_left[k+1]*(1.0f-st->w_window[i])*(exc_mono[3*L_DIV+L_SUBFR/2+i]+side_buf[i]);
			right_exc[3*L_DIV+L_SUBFR/2+i] = st->w_window[i]*gain_right[k]*(exc_mono[3*L_DIV+L_SUBFR/2+i]-buf[i]) +
				gain_right[k+1]*(1.0f-st->w_window[i])*(exc_mono[3*L_DIV+L_SUBFR/2+i]-side_buf[i]);
		}
		for(i=L_SUBFR;i<L_DIV-L_SUBFR/2;i++){
			left_exc[3*L_DIV+L_SUBFR/2+i] = gain_left[k+1]*(exc_mono[3*L_DIV+L_SUBFR/2+i]+side_buf[i]);
			right_exc[3*L_DIV+L_SUBFR/2+i] = gain_right[k+1]*(exc_mono[3*L_DIV+L_SUBFR/2+i]-side_buf[i]);
		}
		p_h += HI_FILT_ORDER;
	}
	/*-----------------------------------------------------------*
	* Save filters in memory for next frame						 *
	*------------------------------------------------------------*/	
	mvr2r(p_h,st->old_wh,HI_FILT_ORDER);
	mvr2r(p_h-HI_FILT_ORDER,st->old_wh2,HI_FILT_ORDER);
	/*-----------------------------------------------------------*
	*															 *
	* Synthesise left right mid band signals					 *
	*															 *
	*------------------------------------------------------------*/	
	p_Aq = st->old_AqLF;
	syn_filt(p_Aq,M, &left_exc[0], left_hi, L_SUBFR/2,st->left.mem_synth_hi,1);
	syn_filt(p_Aq,M, &right_exc[0], right_hi, L_SUBFR/2,st->right.mem_synth_hi,1);
	p_Aq += (M+1);
	for(k=0;k<3;k++){
		syn_filt(p_Aq,M, &left_exc[k*L_SUBFR+L_SUBFR/2], &left_hi[k*L_SUBFR+L_SUBFR/2],
			L_SUBFR,st->left.mem_synth_hi,1);
		syn_filt(p_Aq,M, &right_exc[k*L_SUBFR+L_SUBFR/2], &right_hi[k*L_SUBFR+L_SUBFR/2], 
			L_SUBFR,st->right.mem_synth_hi,1);
		p_Aq += (M+1);
	}
	if (fscale !=0) {	
		syn_filt(p_Aq,M, &left_exc[k*L_SUBFR+L_SUBFR/2], &left_hi[k*L_SUBFR+L_SUBFR/2], 
			L_SUBFR,st->left.mem_synth_hi,1);
		syn_filt(p_Aq,M, &right_exc[k*L_SUBFR+L_SUBFR/2], &right_hi[k*L_SUBFR+L_SUBFR/2], 
			L_SUBFR,st->right.mem_synth_hi,1);
	}
	if(fscale==0) {
		start = 3*L_SUBFR + L_SUBFR/2;
	}
	else {
		start = 4*L_SUBFR + L_SUBFR/2;
	}		
	p_Aq = AqLF;
	for (i_subfr=start; i_subfr <L_FRAME_PLUS-L_SUBFR/2; i_subfr+=L_SUBFR)
	{
		syn_filt(p_Aq,M, &left_exc[i_subfr], &left_hi[i_subfr],L_SUBFR,st->left.mem_synth_hi,1);
		syn_filt(p_Aq,M, &right_exc[i_subfr], &right_hi[i_subfr],L_SUBFR,st->right.mem_synth_hi,1);
		p_Aq += (M+1);
	}
	syn_filt(p_Aq,M, &left_exc[L_FRAME_PLUS-L_SUBFR/2], &left_hi[L_FRAME_PLUS-L_SUBFR/2],
		L_SUBFR/2,st->left.mem_synth_hi,1);
	syn_filt(p_Aq,M, &right_exc[L_FRAME_PLUS-L_SUBFR/2], &right_hi[L_FRAME_PLUS-L_SUBFR/2],
		L_SUBFR/2,st->right.mem_synth_hi,1);
	if(fscale == 0) {
		mvr2r(p_Aq,st->old_AqLF,4*(M+1));
	}
	else {
		mvr2r(p_Aq,st->old_AqLF,5*(M+1));
	}
}

⌨️ 快捷键说明

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