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

📄 dspfunc.dsp

📁 基于ADSP的G.729语音编解码程序
💻 DSP
字号:
/****************************************************************************/
/* $$01/10/2000 checked dsp basic 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        Dspfunc;

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

/*****************************************************************************
* calculate pow value of Z = 2 ^ (Integer.fraction)                          *
* the value is approximated by a table and linear interpolation              *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* $$01/11/2000 move dm data table to pm data table                           *
* Calling Parameters													     *	
*         MR1:   Q0   Integer part.      (range: 0<=val<=30)                 *
*         MR0:   Q15  Fractional part.   (range: 0.0<=val<1.0)               *
* Return Values																 *
*         SR0 = LSW of Z	Q0												 *
*         SR1 = MSW of Z	Q0												 *	
* Altered Registers: MR,SR,SE,AR,I5,AY0,MY0                                  *	
* Computation Time : 18 cycles												 *	
******************************************************************************/
.ENTRY         Pow2;

Pow2:		   I5=^tabpow;
			   SR=ASHIFT MR0 BY 6(LO);          
			   M5=SR1;              
			   MODIFY(I5,M5);
			   AY0=30;
			   AR=MR1-AY0,MR1=PM(I5,M4);
			   AR=PASS SR1,SE=AR;
			   SR=LSHIFT SR0 BY -1 (LO);
			   SR=SR OR ASHIFT AR BY -1(HI);   
			   AR=SR0 AND H#7FFF;
			   AY0=PM(I5,M4);  
			   AR=MR1-AY0,MY0=AR; 
			   MR0=0;			   
			   MR=MR-AR*MY0 (SS);               
			   SR=LSHIFT MR0 (LO);
			   SR=SR OR ASHIFT MR1 (HI);
			   AR=PASS SR1;
			   SR=LSHIFT MR0 (HI),MR1=SR0;
			   MR0=SR0;
			   MR=MR(RND),SR1=AR;
			   SR0=MR1;
			   RTS;
/*****************************************************************************
* calculate log2 value of Z=log2(X)                                          *
* X is positive and if X is negative or zero, result is 0                    *
* The function Log2(X) is approximated by a table and linear interpolation   *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* $$01/11/2000 move dm data table to pm data table                           *
* Calling Parameters													     *	
*      MR0 = LSW of X Q0													 * 
*      MR1 = MSW of X Q0         											 *		
* Return Values																 *
*      SR1: Q0  Integer part of Z    (range: 0<=val<=30)                     *
*      SR0: Q15 Fractional  part of Z (range: 0<=val<1)                      *
* Altered Registers: MR,SR,SE,AR,AF,AY0,MY0,I5          	                 *	
* Computation Time : 30 cycles												 *	
******************************************************************************/
.ENTRY         Log2;

Log2:		   AF=PASS MR1;
               IF GE JUMP Log2_check;
Log2_rts:	   SR0=0;
			   SR1=0; 
			   RTS;
Log2_check:    AR=MR0 OR AF;
			   IF EQ JUMP Log2_rts;
			   I5=^tablog;
			   SE=EXP MR1 (HI);
			   SE=EXP MR0 (LO);
			   SR=NORM MR0 (LO),AY0=SE;
			   SR=SR OR NORM MR1 (HI);
			   MR0=SR1;
			   SR=LSHIFT SR0 BY -9(LO);
			   SR=SR OR ASHIFT MR0 BY -9(HI);
               AR=SR1-32;
			   M5=AR;
			   MODIFY(I5,M5);
			   MR=0;
			   AR=PASS SR1, MR1=PM(I5,M4);           
			   SR=LSHIFT SR0 BY -1(LO);
			   SR=SR OR ASHIFT AR BY -1(HI);
			   AR=SR0 AND H#7FFF;       
               SR0=30;
			   AR=SR0+AY0,MY0=AR;               
			   AY0=PM(I5,M4);
			   AR=MR1-AY0,SR1=AR;
			   MR=MR-AR*MY0 (SS);      
			   SR0=MR1;
			   RTS;
/*****************************************************************************
* calculate value of  Z=1/sqrt(X)                                            *
* X is positive and if X is negative or zero, result is 1 (3fff ffff)        *
* The function 1/sqrt(X) is approximated by a table and linear interpolation *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* $$01/11/2000 move dm data table to pm data table                           *
* Calling Parameters													     *	
*      MR0 = LSW of X Q0													 * 
*      MR1 = MSW of X Q0         											 *		
* Return Values																 *
*      SR0 = LSW of Z Q30	(range: 0<=val<1) 							     * 
*      SR1 = MSW of Z Q30   (range: 0<=val<1)       						 *		
* Altered Registers: MR,SR,SE,AR,AF,I5,AY0,MY0                             	 *	
* Computation Time : 40 cycles												 *	
******************************************************************************/
.ENTRY         Inv_sqrt;

Inv_sqrt:	   AF=PASS MR1;
               IF GE JUMP sqrt_check;
sqrt_rts:	   SR0=H#FFFF;
			   SR1=H#3FFF; 
			   RTS;
sqrt_check:    AR=MR0 OR AF;
			   IF EQ JUMP sqrt_rts;
			   I5=^tabsqr;
			   SE=EXP MR1 (HI);
			   SE=EXP MR0 (LO);
			   SR=NORM MR0 (LO),AY0=SE;
			   SR=SR OR NORM MR1 (HI);
			   AR=30;
			   AR=AR+AY0,MR0=SR1;
			   AF=AR AND H#0001;
			   IF NE JUMP sqrt_next;
			   SR=LSHIFT SR0 BY -1(LO);
			   SR=SR OR ASHIFT MR0 BY -1(HI);
sqrt_next:     MR1=SR1;
			   MR0=SR0;
			   SR=ASHIFT AR BY -1(LO);
			   AR=SR0+1;
			   SR=LSHIFT MR0 BY -9(LO);
		       SR=SR OR ASHIFT MR1 BY -9(HI);
			   AR=PASS SR1,AY0=AR;   
			   SR=LSHIFT SR0 BY -1(LO);
			   SR=SR OR ASHIFT AR BY -1(HI);
			   AR=AR-16;
			   M5=AR;
			   MODIFY(I5,M5);
			   AR=SR0 AND H#7FFF;
			   MR=0,MY0=AR;
			   AR=-AY0,MR1=PM(I5,M4);   
			   AY0=PM(I5,M4);
			   AR=MR1-AY0,SE=AR;
			   MR=MR-AR*MY0(SS);
			   SR=LSHIFT MR0 (LO);
			   SR=SR OR ASHIFT MR1 (HI);
			   RTS;
/*****************************************************************************
* Function Name : Div_32                                                     *
* Fractional integer division of two 32 bit numbers.                         *
* L_num / L_denom. L_num and L_denom must be positive and L_num < L_denom.   *
* L_denom = denom_hi<<16 + denom_lo<<1 denom_hi is a normalize number.       *
* The result is in Q30.                                                      *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* Calling Parameters											             *	
*         MX1,MX0 :  L_num                                                   * 
*         MY1,MY0 :  denom_hi,denom_lo                                       *
* Return Values													             *
*         SR1,SR0 :  result_hi,result_lo                                     *
* Altered Registers: MR,MF,SR,AR,AF,AY0,AY1,MX0,MX1,MY0,MY1                  *	
* Computation Time : 18 cycles									             *	
******************************************************************************/
.ENTRY         Div_32;

Div_32:        MR=0,AR=MY1;
			   MR0=H#3FFF;
               SR=ASHIFT AR BY 0(LO);
			   CALL div_s;
			   AY0=H#FFFF;
			   AY1=H#7FFF;
			   AR=PASS 1,SR0=AR;
			   MF=SR0 * MY0(SS);
			   MR=AR  * MF(SS);
			   MR=MR+SR0*MY1(SS);
			   DIS AR_SAT;
			   AR=AY0-MR0,MY0=SR0;
			   ENA AR_SAT;
			   SR0=AR,AR=AY1-MR1+C-1;
			   SR=LSHIFT SR0 BY -1(LO);
			   AR=PASS 1,SR1=AR;
               MF=SR0 * MY0(SS);
			   MR=AR * MF(SS);
			   MR=MR+SR1*MY0(SS);
			   SR=LSHIFT MR0 BY -1(LO);
			   AR=PASS 1,MY1=MR1;
			   MR=MX1 * MY1(SS),MY0=SR0;
			   MF=MX1 * MY0(SS),SR0=MX0;
			   SR=LSHIFT SR0 BY -1(LO);
               MR=MR+AR*MF(SS),MX0=SR0;
			   MF=MX0 * MY1(SS);
			   MR=MR+AR * MF(SS);
			   SR=LSHIFT MR0 BY 2(LO);
			   SR=SR OR ASHIFT MR1 BY 2(HI);
			   RTS;
/*****************************************************************************
*  Produces a result which is the fractional  integer division of var1 by    *
*  var2; var1 and var2 must be positive and var2 must be greater or equal    *
*  to var1; the result is positive (leading bit equal to 0) and truncated    *
*  to 16 bits.                                                               *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* Calling Parameters												         *	
*         MR = 16-bit dividend											     *
*         SR = 16-bit divisor											     *
* Return Values														         *
*         AR = 16-bit result										         *
* Altered Registers: MR,SR,AR,AF,AY0,AY1                                     *	
* Computation Time : 18 cycles										         *	
******************************************************************************/
.ENTRY         div_s;

div_s:         AR=PASS MR0,AY0=SR0;
			   IF EQ RTS;	
			   AR=MR0-AY0,AY1=SR1;
			   AR=H#7FFF;
			   IF EQ RTS;
//		       CNTR=15;
		       AR=PASS 0;
		       CNTR=15;
		       DO divs_loop UNTIL CE;
		       SR=LSHIFT AR BY 1(LO);
               AF=PASS SR0;
			   SR=LSHIFT MR0 BY 1(LO);
			   SR=SR OR ASHIFT MR1 BY 1(HI);
               AR=SR0-AY0,MR0=SR0; 
			   MR1=SR1,AR=SR1-AY1+C-1;
			   IF LT JUMP divs_loop;
               DIS AR_SAT;
			   AR=MR0-AY0;
			   ENA AR_SAT;
			   MR0=AR,AR=MR1-AY1+C-1;
			   AF=AF+1,MR1=AR;
			   AR=PASS MR1;
			   IF NOT AV JUMP divs_loop;
               AR=H#0000;
			   AR=PASS MR1;
			   IF GE AR=AR-1;
			   MR0=AR;
divs_loop:     AR=PASS AF;
               RTS;
/*****************************************************************************
* Random generator--- seed = seed*31821 + 13849;							 *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* Calling Parameters														 *	
*         MX0  : random seed												 *
* Return Values																 *
*         AR   : random data												 *
* Altered Registers: MR,SR,AR,AY0,MX0,MY0									 *	
* Computation Time : 18 cycles												 *	
******************************************************************************/
.ENTRY         Random;

Random:        MY0=31821;
			   MR=MX0*MY0(SS),AR=AY0;
			   SR=LSHIFT MR0 BY -1(LO);
			   SR=SR OR ASHIFT MR1 BY -1(HI);
			   DIS AR_SAT;
			   AY0=13849;
			   AR=SR0+AY0,AY0=AR;
			   ENA AR_SAT;
			   MX0=AR;
			   RTS;
/*****************************************************************************
* Gaussian generation														 *
* Xi = uniform v.a. in [-32768, 32767]										 *
* Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1)								     *
* output : Z x 512 < 2^12													 *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* Calling Parameters														 *	
*         MX0  : random seed 											     *
* Return Values															     *
*         SR0  : Gauss seed													 *
* Altered Registers: MR,SR,AR,AY0,AY1,MX0,MY0								 *
* Computation Time : 18 cycles												 *	
******************************************************************************/
.ENTRY         Gauss;

Gauss:         AY0=0;
			   AY1=0;
			   CNTR=12;
               DO sum_guass UNTIL CE;
               CALL Random;
			   SR=ASHIFT AR BY 0(LO);
			   DIS AR_SAT;
			   AR=SR0+AY0;
			   ENA AR_SAT;
			   AY0=AR,AR=SR1+AY1+C;
			   AY1=AR; 
			   IF NOT AV JUMP sum_guass;
			   AR=H#0000;
			   AR=PASS AY1;
			   IF GE AR=AR-1;
			   AY0=AR;
sum_guass:     SR0=AY0;
			   SR=LSHIFT SR0 BY -7(LO);
			   SR=SR OR ASHIFT AR BY -7(HI);
			   RTS;
/*****************************************************************************
* Square root function : returns sqrt(Num/2)								 *
* $$01/10/2000 basic DSP function used in encoder and decoder                *
* Calling Parameters													     *	
*         AY1  : MSW of X													 *
*         AY0  : LSW of X													 *
* Return Values																 *
*         AX0  : in UNSIGNED format											 *
* Altered Registers: AX0,AY0,AY1,AR,MR,SR									 *	
* Computation Time : 18 cycles												 *	
******************************************************************************/
.ENTRY         Sqrt;

//Sqrt:          CNTR=14;
Sqrt:          AX0=H#0000;
			   AF=PASS H#4000;
			   CNTR=14;
			   DO sqrt_loop UNTIL CE;
			   AR=AX0+AF;
			   MR=AR * AR(UU);
			   NONE=AY0-MR0;
			   NONE=AY1-MR1+C-1;
               IF NOT AC AR=PASS AX0;
			   AR=PASS AF,AX0=AR;
			   SR=LSHIFT AR BY -1(LO);
sqrt_loop:     AF=PASS SR0;
		       RTS;
/*****************************************************************************/
.ENDMOD;

⌨️ 快捷键说明

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