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

📄 adapters.c

📁 G729、h263、h264、MPEG4四种最流行的音频和视频标准的压缩和解压算法的源代码.rar
💻 C
字号:
/*************************************************************************//*                                                                       *//*                            LD-CELP  G.728                             *//*                                                                       *//*    Low-Delay Code Excitation Linear Prediction speech compression.    *//*                                                                       *//*                 Copyright: Analog Devices, Inc., 1993                 *//*                                                                       *//*                         Author: Alex Zatsman.                         *//*                                                                       *//*  This program was written mostly for testing  Analog Devices' g21k C  *//*  compiler for the  ADSP21000 architecture  family. While the program  *//*  works  on  Sparc and ADSP21020, it  has  NOT  been  tested with the  *//*  official test data from CCITT/ITU.                                   *//*                                                                       *//*  The program  is   distributed as  is,  WITHOUT ANY WARRANTY, EITHER  *//*  EXPLICIT OR IMPLIED.                                                 *//*                                                                       *//*************************************************************************/#include "common.h"#include "fast.h"#include "parm.h"#include "data.h"#include "prototyp.h"static int sf_levdur (real[], real LPC_MEM []);static int levdur (real[], real LPC_MEM [], int);static void hybwin(int lpsize, int framesize, int nrsize,	    real old_input[], real new_input[], real output[],	    real WIN_MEM window[], real rec[],  real decay);static void bw_expand2(real input[],		       real COEFF_MEM z_out[], real COEFF_MEM p_out[],		       int order, real z_vec[], real p_vec[]);static void bw_expand1(real input[], real COEFF_MEM p_out[],		int order, real p_vec[]);/********************************** Adapter for Perceptual Weighting Filter */static real     pwf_z_vec[LPCW+1],		/* Arrays for band widening: zeros and*/    pwf_p_vec[LPCW+1],		/* poles */    pwf_old_input[LPCW+NFRSZ+NONRW],    pwf_rec[LPCW+1];			/* Recursive Part */    voidpwf_adapter (real input[],	     real COEFF_MEM z_out[], /* zero coefficients */	     real COEFF_MEM p_out[]) /* pole coefficients */{    static real	acorr[LPCW+1],		/* autocorrelation coefficients */	lpcoeff[LPCW+1];    static real LPC_MEM	temp[LPCW+1];    hybwin(LPCW,	/* lpsize */	   NFRSZ,	/* framesize */	   NONRW,	/* nrsize -- nonrecursive size */	   pwf_old_input,	   input,	   acorr,	   hw_percw,	   pwf_rec,	   0.5);    if (levdur(acorr, temp, LPCW))	RCOPY(temp, lpcoeff, LPCW+1);    bw_expand2 (lpcoeff, z_out, p_out, LPCW,		pwf_z_vec, pwf_p_vec);} voidinit_pwf_adapter (real COEFF_MEM z_co[], real COEFF_MEM p_co[]){    real zv = 1.0, pv = 1.0;    int i;    for (i=0; i<=LPCW; i++)    {	pwf_z_vec[i] = zv;	pwf_p_vec[i] = pv;	zv *= WZCF;	pv *= WPCF;	z_co[i] = 0.0;	p_co[i] = 0.0;    }    p_co[0] = 1.0;    z_co[0] = 1.0;    ZARR(pwf_old_input);    ZARR(pwf_rec);}/*************************************** Backward Synthesis Filter Adapter */static real facv[LPC+1];static real    bsf_old_input[LPC+NFRSZ+NONR],    bsf_rec[LPC+1]; voidbsf_adapter (real input[], real COEFF_MEM p_out[]){    static real	old_input[LPC + NFRSZ + NONR],	acorr[LPC+1],		/* autocorrelation coefficients */	lpcoeff[LPC+1];    static real LPC_MEM temp[LPC+1];    hybwin(LPC,		/* lpsize */	   NFRSZ,	/* framesize */	   NONR,	/* nrsize -- nonrecursive size */	   old_input,	   input,	   acorr,	   hw_synth,	   bsf_rec,	   0.75);    if (sf_levdur(acorr, temp))	RCOPY(temp, lpcoeff, LPC+1);    bw_expand1(lpcoeff, p_out, LPC, facv);}/******************************************************* Gain Adapter **/static real gain_p_vec[LPCLG+1];  /* Array for band widening */static real g_rec[LPCLG+1];	/* Recursive part for Hybrid Window */static real g_old_input[LPCLG + NUPDATE + NONRLG];/*** recompute lpc_coeff **/void gain_adapter (real log_gain[], real COEFF_MEM coeff[]){    static real	acorr[LPCLG+1],		/* autocorrelation coefficients */	lpcoeff[LPCLG+1];        static real LPC_MEM temp[LPCLG+1];    hybwin(LPCLG,	/* lpsize */	   NUPDATE,	/* framesize */	   NONRLG,	/* nrsize -- nonrecursive size */	   g_old_input,	   log_gain,	   acorr,	   hw_gain,	   g_rec,	   0.75);    if (levdur(acorr, temp, LPCLG)) {	int i;	for(i=1; i<=LPCLG; i++)	    lpcoeff[i] = temp[i];    }    bw_expand1 (lpcoeff, coeff, LPCLG,		gain_p_vec);}/******************************************** Initializations **/ voidinit_bsf_adapter(real COEFF_MEM co[]){    int i;    real v = 1.0;    for(i=0; i<=LPC; i++) {	facv[i] = v;	v *= FAC;	co[i] = 0;    }    co[0] = 1.0;    ZARR(bsf_old_input);    ZARR(bsf_rec);    }void init_gain_adapter (real COEFF_MEM coeff[]){    real pv = 1.0;    int i;    gain_p_vec[0] = 1.0;    coeff[0] = 1;    for (i=1; i<=LPCLG; i++)    {	pv *= FACGP;	gain_p_vec[i] = pv;	coeff[i] = 0;    }    for(i=0; i<LPCLG+NUPDATE+NONRLG; i++)	g_old_input[i] = 0;    ZARR(g_rec);    ZARR(g_old_input);}/******************************************** Hybrid Window Module **//*  Hybrid Window   LPSIZE	- size of OUTPUT (autocorrelation vector)  FRAMESIZE	- size of NEW_INPUT  NRSIZE	- size of non-recursive part.  OLD_INPUT	- buffer for holding old input (size LPSIZE+FRAMESIZE+NRSIZE)  NEW_INPUT	- new input, or frame (size FRAMESIZE)  OUTPUT	- autocorrelation vector (size LPSIZE)  WINDOW	- window coefficients (size LPSIZE+FRAMESIZE+NRSIZE)  REC	- 	- recursive part (size LPSIZE)  DECAY	- 	- scaling for the old recursive part. */static voidhybwin(int lpsize, int framesize, int nrsize, real old_input[],        real new_input[], real output[],real WIN_MEM window[],		    real rec[],		/* Recursive Part */		    real decay){    int N1 = lpsize + framesize; /* M+L */    int N2 = lpsize + nrsize;	/* M+N */    int N3 = lpsize + framesize + nrsize;    int i;    real ws[N3];    real tmp1[lpsize+1], tmp2[lpsize+1];    /* shift in INPUT into OLD_INPUT and window it*/        for(i=0; i<N2; i++)	old_input[i] = old_input[i+framesize];    for(i=0; i<framesize; i++)	old_input[N2+i] = new_input[i];    VPROD(old_input,window,ws,N3);        AUTOCORR(ws, tmp1, lpsize, lpsize, N1);        for(i=0; i<=lpsize; i++)	rec[i] = decay * rec[i] + tmp1[i];        AUTOCORR(ws, tmp2, lpsize,  N1, N3);        for(i=0; i<=lpsize; i++)	output[i] = rec[i] + tmp2[i];    output[0] *= WNCF;}/********************************************* Levinson-Durbin Routines *//* Levinson-Durbin algorithm *//* return 1 if ok, otherwise 0 */static int levdur(real acorr[], real LPC_MEM coeff[], int order){    real K, E;    int m,j, halfm;    E = acorr[0];    if (E<=0) 	return 0;    coeff[0] = 1.0;    for(m=1; m<=order; m++) {	K =  -acorr[m];	if (m>1)	{	    real c1=coeff[1], a1=acorr[m-1];	    for(j=2; j<=m-1; j++) {		K -= c1 * a1;		c1 = coeff[j];		a1 = acorr[m-j];	    }	    K -= a1*c1;	}	K = K/E;	coeff[m] = K;	halfm = m>>1;	/** this is pipilened version of parallel assignment:  **/	/*  coeff[j]   =     coeff[j] + K * coeff[m-j] */	/*  coeff[m-j] = K * coeff[j] +     coeff[m-j] */      {	  if (halfm>0) {	      real x,y,t1,t2,t3,t4;	      real LPC_MEM *p = coeff+1;	      real LPC_MEM *q = coeff+m-1;	      x=*p;	      y=*q;	      t1 = K * x;	      t2 = K * y;	      for(j=1; j<halfm; j++) {		  t3 = t1 + y;		  t4 = t2 + x;		  x=*(p+1);		  y=*(q-1);		  *p++ = t4;		  *q-- = t3;		  t1 = K * x;		  t2 = K * y;	      }	      t3 = t1 + y;	      t4 = t2 + x;	      *p = t4;	      *q = t3;	  }      }	E = (1 - K * K) * E;	if (E<0)	    return 0;    }    return 1;}/*  Levinson-Durbin algorithm  for Synthesis Filter. Its main   difference from the above is the fact that it saves 10-th  order coefficients for Postfilter, plus some speedup since this   is one of the longest routines in the algorithm.  */ real PSF_LPC_MEM  a10[11];real PSF_LPC_MEM  k10;static int sf_levdur(real acorr[], real LPC_MEM coeff[]){    real E;    register real K REG(r9), c1 REG(r0), tmp REG(r12);    int m, j, halfm;    E = acorr[0];    if (E<=0) 	return 0;    coeff[0] = 1.0;    for(m=1; m<=LPC; m++) {	K =  -acorr[m];	if (m>1)	{	    real a1 REG(r4)=acorr[m-1];	    c1=coeff[1];	    tmp = c1*a1;	    if (m>2) {		c1 = coeff[2]; a1 = acorr[m-2];		for(j=3; j<=m-1; j++) {		    K -= tmp;		    tmp = c1 * a1;		    c1 = coeff[j];		    a1 = acorr[m-j];		}		K -= tmp;		tmp = c1*a1;	    }	    K -= tmp;	}	K = K/E;	coeff[m] = K;	halfm = m>>1;	/** this is pipilened version of parallel assignment:  **/	/*  coeff[j]   =     coeff[j] + K * coeff[m-j] */	/*  coeff[m-j] = K * coeff[j] +     coeff[m-j] */      {	  if (halfm>=1) {	      register real		  x  REG(r1),   y  REG(r5), t1 REG(r10),		  t2 REG(r14), t3 REG(r2), t4 REG(r6);	      register real LPC_MEM *p  REG(i10);	      register real LPC_MEM *pp REG(i11);	      register real LPC_MEM *q  REG(i12);	      register real LPC_MEM *qq REG(i13);	      p = coeff+1;   pp = p;	      q = coeff+m-1; qq = q;	      x=*p++;	      y=*q--;	      t1 = K * x;	      t2 = K * y;	      for(j=2; j<=halfm; j++) {		  t4 = t2 + x;	 x=*p++;		  t3 = t1 + y;   y=*q--;      		  t1 = K * x;	*pp++ = t4;		  t2 = K * y;	*qq-- = t3;	      }	      t3 = t1 + y;	      t4 = t2 + x;	      *pp = t4;	      *qq = t3;	  }      }	if (m==10) {	    int jj;	    for(jj=0; jj<=10; jj++)		a10[jj] = coeff[jj];	    k10 = K;	}	E = (1 - K * K) * E;	if (E<0)	    return 0;    }    return 1;}/******************************************** Band Width Expanders **//* Don't have to worry about i=0 -- z_vec[0] and p_vec[0] should stay 1.0. */static voidbw_expand2(real input[], real COEFF_MEM z_out[], real COEFF_MEM p_out[],		       int order, real z_vec[], real p_vec[]){	int i;	for(i=1; i<=order; i++)	    z_out[i] = z_vec[i] * input[i];	for(i=1; i<=order; i++)	    p_out[i] = p_vec[i]*input[i];}/* Poles only */static voidbw_expand1(real input[], COEFF_MEM real p_out[], int order, real p_vec[]){	int i;	for(i=1; i<=order; i++)	    p_out[i] = p_vec[i]*input[i];}

⌨️ 快捷键说明

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