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

📄 lpc.dsp

📁 基于ADSP的G.729语音编解码程序
💻 DSP
📖 第 1 页 / 共 2 页
字号:
/************************************************************************/
/* $$01/10/2000 checked LpcMod module data variables and function       */
/* $$01/16/2001 modified and printed,Author: Jason.wang (zhigang wang)  */
/* $$01/16/2001 Email: wzg119@yeah.net,  BP: 86+02195950-161452         */
/* $$01/16/2001 This modlue is not optimized! should be test on Emulator*/
/************************************************************************/
.MODULE/SEG=App_PM        LpcMod;

/************************************************************************/
#include       "ld8a.inc"
#include       "tab_ld8a.inc"

/************************************************************************/
/* Last A(z) for case of unstable filter                                */
/* $$01/10/2000 static memory and pointer                               */
/************************************************************************/
.VAR/DM/RAM/SEG=App_DMmem    old_A[M+1],old_rc[2];

/************************************************************************/
.EXTERNAL      Div_32;
.EXTERNAL      div_s;

/************************************************************************
* Initialize the LPC filter static memory								*
* $$01/10/2000 used both in encoder and decoder							*
* Calling Parameters													*		
* Return Values															*
* Altered Registers: I1,M1												*		
* Computation Time : 18 cycles											*	
*************************************************************************/
.ENTRY         Init_LPCFilt;

Init_LPCFilt:  I1=^old_A;
//			   CNTR=M;
			   DM(I1,M1)=4096;
			   CNTR=M;
			   DO zero_LPCfilt  UNTIL CE;
zero_LPCfilt:  DM(I1,M1)=0;
			   I1=^old_rc;
			   DM(I1,M1)=0;
			   DM(I1,M1)=0;
			   RTS;
/************************************************************************
* LEVINSON-DURBIN algorithm in double precision							*
* $$01/10/2000 used both in encoder and decoder							*
* $$01/11/2000 modify pointer and varaibles to adapt table change		*
* Calling Parameters													*	
*         I3   : Rh[M+1] Vector of autocorrelations (msb)				*
*         I2   : Rl[M+1] Vector of autocorrelations (lsb)				*
* Return Values															*
*         I0   : Q12 A[M]    LPC coefficients  (m = 10)					* 
*         I1   : Q15 rc[M]   Reflection coefficients.					*
*         SR0  : R0 exponent value										*
* Altered Registers: MR,SR,AR,I0,I1,I2,I3,AX0,MY0						*	
* Computation Time : 18 cycles											*	
*************************************************************************/
.ENTRY         Levinson;
.VAR/DM/RAM/SEG=App_DMbuf    Ah[M+1], Al[M+1];       /* LPC coef. in double prec.      */
.VAR/DM/RAM/SEG=App_DMbuf    Anh[M+1], Anl[M+1];     /* LPC coef.for next iteration in double prec. */
.VAR/DM/RAM/SEG=App_DMtmp    alp_h, alp_l, alp_exp;  /* Prediction gain; hi lo and exponent*/
.VAR/DM/RAM/SEG=App_DMtmp    rc, t0hi_save, t0lo_save;

Levinson:	   DM(rc)=I1;
               MY0=DM(I2,M1);
			   MY1=DM(I3,M1);
               MR0=DM(I2,M2);
			   MR1=DM(I3,M2);
			   SR=LSHIFT MR0 BY 1(LO);
     {---------K = A[1] = -R[1] / R[0] ---------------}
               AR=PASS MR1,MR0=SR0;
			   IF GT JUMP abs_rhl;
			   DIS AR_SAT;
			   AR=-MR0;
			   ENA AR_SAT;
			   MR0=AR,AR=-MR1+C-1;
abs_rhl:       MX0=MR0;
			   MX1=AR;
			   AX0=MR0;
			   AX1=MR1;
			   CALL Div_32;  
			   AF=PASS AX1,AR=SR1;
			   IF LE JUMP abs_t0;
			   DIS AR_SAT;
			   AR=-SR0;
			   ENA AR_SAT;
			   SR0=AR,AR=-SR1+C-1;
abs_t0:        SE=-4;
			   I4=^Al+1;
			   I5=^Ah+1;
			   MR0=SR0;
			   SR=LSHIFT SR0 BY -1(LO);
               SR=LSHIFT MR0 (LO),MY0=SR0;
			   SR=SR OR ASHIFT AR (HI),MX1=AR;
     {---------Alpha = R[0] * (1-K**2)------------}
			   AR=PASS 1,DM(I1,M1)=MX1;
			   MR=MX1 * MX1(SS);
			   MF=MX1 * MY0(SS),DM(I5,M4)=SR1;
			   SR=LSHIFT SR0 BY -1(LO);
               MR=MR+AR*MF(SS),DM(I4,M4)=SR0;
			   MF=MX1 * MY0(SS),AY0=DM(I5,M7);
			   MR=MR+AR * MF(SS),AY0=DM(I4,M7);
               AR=PASS MR1;
			   IF GE JUMP abs_t00;
			   DIS AR_SAT;
			   AR=-MR0;
			   ENA AR_SAT;
			   MR0=AR,AR=-MR1+C-1;
abs_t00:	   AY0=H#FFFF;
			   DIS AR_SAT;
			   AR=AY0-MR0,MR1=AR;
			   ENA AR_SAT;
               SR=LSHIFT AR BY -1(LO);
               AY0=H#7FFF;
			   AR=AY0-MR1+C-1,MY1=DM(I3,M1);
			   AR=PASS 1,MX1=AR;
			   MR=MX1 * MY1(SS),MY0=DM(I2,M1);
			   MF=MX1 * MY0(SS);
               MR=MR+AR*MF(SS);
			   MF=SR0 * MY1(SS);
			   MR=MR+AR * MF(SS);
     {---------Normalize Alpha-------------}
			   SE=EXP MR1 (HI);
               SE=EXP MR0 (LO);
			   SR=NORM MR0 (LO),AR=SE;
			   SR=SR OR NORM MR1 (HI);
			   DM(alp_h)=SR1;
			   SR=LSHIFT SR0 BY -1(LO);
			   DM(alp_l)=SR0;
			   AR=-AR;
			   DM(alp_exp)=AR;
	/*--------------------------------------*
	 * ITERATIONS  I=2 to M                 *
	 *--------------------------------------*/
               SI= 1;
			   CNTR=M-1;
			   DO levinson_loop UNTIL CE;
	{-------------t0 = SUM(R[j]*A[i-j],j=1,i-1)+R[i]-------------}
				  AX0=I2;
				  AX1=I3;
				  AY0=I4;
				  AY1=I5;
//			      CNTR=SI;
                  AR=PASS 1,MX1=DM(I5,M7);
 			      MR=0,MY1=DM(I3,M1);
			      CNTR=SI;
			      DO long_add UNTIL CE;
      			  MR=MR+MX1 * MY1(SS),MY0=DM(I2,M1);
			      MF=MX1 * MY0(SS),MX0=DM(I4,M7);
                  MR=MR+AR*MF(SS);
			      MF=MX0 * MY1(SS),MY1=DM(I3,M1);
                  MR=MR+AR * MF(SS),MX1=DM(I5,M7);
long_add:	      IF MV SAT MR;
				  I4=AY0;  
				  I5=AY1;
				  AR=DM(I2,M1);
				  SR=LSHIFT AR BY 1(LO);
				  AY0=SR0;
				  SR=LSHIFT MR0 BY 4(LO);
			      SR=SR OR ASHIFT MR1 BY 4(HI);
			      DIS AR_SAT;
			      AR=SR0+AY0,AY1=MY1;
				  ENA AR_SAT;
				  I2=AX0;  
				  I3=AX1;
			      AX0=AR,AR=SR1+AY1+C;
				  DM(t0lo_save)=AX0;
				  DM(t0hi_save)=AR;
		{---------K = -t0 / Alpha---------------}
				  IF GE JUMP abs_t0t0;
				  AR=-AX0,AX1=AR;
				  AX0=AR,AR=-AX1+C-1;
abs_t0t0:         MX0=AX0;
				  MX1=AR;
				  MY0=DM(alp_l);
				  MY1=DM(alp_h);
				  CALL Div_32;
				  AX0=DM(t0hi_save);
                  AY0=DM(t0lo_save);
				  AF=PASS AX0,AR=SR1;
				  IF LT JUMP abs_t2;
				  NONE=AX0 OR AY0;
			      IF EQ JUMP abs_t2;
				  DIS AR_SAT;
                  AR=-SR0;
				  ENA AR_SAT;
				  SR0=AR,AR=-SR1+C-1;
abs_t2:		      AY0=32750;
			      SE=DM(alp_exp);
			      SR=lSHIFT SR0 (LO);
			      SR=SR OR ASHIFT AR (HI);
    {-------------Test for unstable filter. If unstable keep old A(z)--------}
			      AR=ABS SR1,DM(I1,M0)=SR1;
			      SR=LSHIFT SR0 BY -1(LO);
				  AF=AR-AY0,SR1=DM(I1,M1);
			      IF LE JUMP stable_filter;
//				  CNTR=M;
			      I1=^old_A;
				  CNTR=M;
			      DO copy_oldA UNTIL CE;
			      AR=DM(I1,M1);
copy_oldA:	      DM(I0,M1)=AR;
				  I1=DM(rc);
				  I2=^old_rc;
                  AR=DM(I2,M1);
			      DM(I1,M1)=AR;
			      AR=DM(I2,M1);
			      DM(I1,M1)=AR;
			      RTS;
    /*------------------------------------------*
     *  Compute new LPC coeff. -> An[i]         *
     *  An[j]= A[j] + K*A[i-j]     , j=1 to i-1 *
     *  An[i]= K                                *
     *------------------------------------------*/
stable_filter:    //CNTR=SI;
			      MX0=I0;
				  MX1=I1;
				  AX0=I2;
				  AX1=I3;
				  I0=^Al+1;
			      I1=^Ah+1;
				  I2=^Anl+1;
				  I3=^Anh+1;
				  CNTR=SI;
                  DO extra_khkl UNTIL CE;
                  AR=PASS 1,MY1=DM(I5,M7);
			      MR=SR1 * MY1(SS),MY0=DM(I4,M7);
			      MF=SR1 * MY0(SS),MY0=SR0;
                  MR=MR+AR*MF(SS),AY1=DM(I1,M1);
			      MF=SR0 * MY1(SS),MY1=SR1;
			      MR=MR+AR * MF(SS),AR=DM(I0,M1);
			      SR=LSHIFT AR BY 1(LO);
				  AY0=SR0;
				  DIS AR_SAT;
				  AR=MR0+AY0;
				  ENA AR_SAT;
				  SR=LSHIFT AR BY -1(LO);
				  AR=MR1+AY1+C,DM(I2,M1)=SR0;
                  SR0=MY0; 
				  SR1=MY1;
extra_khkl:	      DM(I3,M1)=AR;
			      I0=MX0;
				  I1=MX1;
				  AR=PASS 1,MY0=SR0;
			      MR=SR1 * SR1(SS);
			      MF=SR1 * MY0(SS);
                  MR=MR+AR*MF(SS);
			      MF=SR1 * MY0(SS);
			      MR=MR+AR * MF(SS),AR=SR1;
				  SR=LSHIFT SR0 BY -3(LO);
			      SR=SR OR ASHIFT AR BY -4(HI);
      {-----------Alpha = Alpha * (1-K**2)-------------}
				  DM(I3,M1)=SR1;
				  SR=LSHIFT SR0 BY -1(LO);
				  AR=PASS MR1,DM(I2,M1)=SR0;
                  IF GE JUMP abs_t02;
			      DIS AR_SAT;
				  AR=-MR0;
				  ENA AR_SAT;
			      MR0=AR,AR=-MR1+C-1;
abs_t02:          AY0=H#FFFF;
				  DIS AR_SAT;
			      AR=AY0-MR0,MR1=AR;
				  ENA AR_SAT;
			      AY0=H#7FFF;
				  SR=LSHIFT AR BY -1(LO);
			      AR=AY0-MR1+C-1;
			      MY0=DM(alp_l);
			      MY1=DM(alp_h);
                  AR=PASS 1,MX0=AR;
			      MR=MX0 * MY1(SS);
			      MF=MX0 * MY0(SS);
                  MR=MR+AR*MF(SS);
			      MF=SR0 * MY1(SS);
			      MR=MR+AR * MF(SS);
     {------------Normalize Alpha----------------}
			      SE=EXP MR1 (HI),AR=SI;
			      SE=EXP MR0 (LO);
			      SR=NORM MR0 (LO),AY0=SE;
			      SR=SR OR NORM MR1 (HI);
			      DM(alp_h)=SR1;
				  SR=LSHIFT SR0 BY -1(LO);
			      DM(alp_l)=SR0;
				  AR=AR+1;
			      SR0=DM(alp_exp);
			      AR=SR0-AY0,SI=AR;
			      DM(alp_exp)=AR;
      {-----------A[j] = An[j]---------------}
//			      CNTR=SI;
			      I4=^Al+1;
			      I5=^Ah+1;
			      I2=^Anl+1;
			      I3=^Anh+1;
			      CNTR=SI;
			      DO copy_anhl UNTIL CE;
			      AR=DM(I2,M1);
			      DM(I4,M4)=AR;
			      AR=DM(I3,M1);
copy_anhl:        DM(I5,M4)=AR;
				  I2=AX0;
				  I3=AX1;	
				  MODIFY(I4,M7); 
levinson_loop: MODIFY(I5,M7);   
     {---------Truncate A[i] in Q27 to Q12 with rounding----------}
			   I4=^Al+1;
			   I5=^Ah+1;
//			   CNTR=M;
			   I1=^old_A+1;
			   DM(I0,M1)=4096;
			   SR0=DM(I4,M4);
			   CNTR=M;
			   DO calc_A UNTIL CE;
			   AR=DM(I5,M4);
			   SR=LSHIFT SR0 BY 2(LO);
			   SR=SR OR ASHIFT AR BY 1(HI);
			   AR=SR0+H#8000;
			   AR=SR1+C,SR0=DM(I4,M4);
			   DM(I0,M1)=AR;
calc_A:		   DM(I1,M1)=AR;
               I1=DM(rc);
			   I2=^old_rc;
			   AR=DM(I1,M1);
			   DM(I2,M1)=AR;
			   AR=DM(I1,M1);
               AX0=DM(alp_exp);
			   AR=-AX0,DM(I2,M1)=AR;
               SE=AR;
			   SR0=DM(alp_h);
			   SR=ASHIFT SR0 (LO);
               RTS;
/**************************************************************************
* procedure Az_lsp:                                                       *
* Compute the LSPs from  the LPC coefficients  (order=10)                 *
* $$01/10/2000 used only in encoder and decoder                           *
* $$01/11/2000 modify pointer and varaibles to adapt table change         *
* Calling Parameters												      *	
*         I1   : Q12 predictor coefficients (+1)                          *
*         I2   : Q12 predictor coefficients (+M)                          *
*         I3   : old lsp[] (in case not found 10 roots)                   *
* Return Values														      *
*         I0  :  Q15 line spectral pairs                                  *
* Altered Registers: MR,SR,AR,AF,AX0,AX1,AY0,AY1,MX0,MX1,MY0,MY1          * 	
* Computation Time : 18 cycles										      *	
***************************************************************************/
.ENTRY         Az_lsp;

.VAR/DM/RAM/SEG=App_DMbuf    f1[M_2+1], f2[M_2+1];
.VAR/DM/RAM/SEG=App_DMtmp    nf, ip, ylow, xhigh, yhigh;
/*-------------------------------------------------------------*
 *  find the sum and diff. pol. F1(z) and F2(z)                *
 *    F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1)  *
 * f1[0] = 1.0;                                                *
 * f2[0] = 1.0;                                                *
 * for (i = 0; i< NC; i++)                                     *
 *   f1[i+1] = a[i+1] + a[M-i] - f1[i] ;                       *
 *   f2[i+1] = a[i+1] - a[M-i] + f2[i] ;                       *

⌨️ 快捷键说明

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