www.pudn.com > g729Decoder.rar > d4i40_1fv.asm


;================================================================ 
;  File Name 
;  ---------- 
;  d4i40_1f.asm 
; 
;  Brief Description of the Code: 
;  ------------------------------ 
;  Fixed-codebook search for 4 nor-zero pulses with amplitudes of +1 or -10 
;  Using faster method. 
;  Ref 
;  ------ 
;  Acelp_ca.c(D4i40_17_fast) 
;============================================================== 
	.mmregs 
	.include 	..\include\const.h 
	.include 	..\include\tab_ld8a.h 
	.include 	..\include\ld8a.h 
	.include 	..\include\ld8amem.h 
 
        .text  
	.def D4i40_17_fast 
	 
;---------------------------------------------------------------------- 
;  D4i40_17_fast 
;------------------------------------------------------------------------ 
;  static Word16 D4i40_17_fast( /* (o)    : Index of pulses positions.               */ 
;    Word16 Dn[],          /* (i)    : Correlations between h[] and Xn[].       */ 
;    Word16 rr[],          /* (i)    : Correlations of impulse response h[].    */ 
;    Word16 h[],           /* (i) Q12: Impulse response of filters.             */ 
;    Word16 cod[],         /* (o) Q13: Selected algebraic codeword.             */ 
;    Word16 y[],           /* (o) Q12: Filtered algebraic codeword.             */ 
;    Word16 *sign,         /* (o)    : Signs of 4 pulses.                       */ 
;  ) 
;------------------------------------------------------------------------ 
;  Algebraic codebook for ITU 8 kb/s. 
;  -> 17 bits; 4 pulses in a frame of 40 samples 
;------------------------------------------------------------------------ 
;  The code length is 40, containing 4 nonzero pulses i0, i1, i2, i3. 
;  Each pulses can have 8 possible positions (positive or negative) 
;  except i3 that have 16 possible positions. 
; 
;  i0 (+-1) : 0, 5, 10, 15, 20, 25, 30, 35 
;  i1 (+-1) : 1, 6, 11, 16, 21, 26, 31, 36 
;  i2 (+-1) : 2, 7, 12, 17, 22, 27, 32, 37 
;  i3 (+-1) : 3, 8, 13, 18, 23, 28, 33, 38 
;             4, 9, 14, 19, 24, 29, 34, 39 
;------------------------------------------------------------------------ 
;------------------------------------------------------------------------ 
;  Constants :  
;		Addr_Dn -> Dn 
;              Addr_rr -> rr 
;              Addr_h1 -> h 
;              Addr_yn2 -> y 
;              Addr_cn -> cod 
;              PulseSign ->*sign 
;		SignIndex-->return value 
;------------------------------------------------------------------------- 
;Modified AR0,AR1,AR2,AR3,AR4,AR5,AR6,AR7,A,B,T 
;	initiliaze printer of rr[] 
 
	.asg    "Addr_rr",    rri0i0 
	.asg    "Addr_rr+8",  rri1i1 
	.asg    "Addr_rr+16", rri2i2 
	.asg    "Addr_rr+24", rri3i3 
	.asg    "Addr_rr+32", rri4i4 
	.asg    "Addr_rr+40",  rri0i1 
	.asg    "Addr_rr+104", rri0i2 
	.asg    "Addr_rr+168", rri0i3 
	.asg    "Addr_rr+232", rri0i4 
	.asg    "Addr_rr+296", rri1i2 
	.asg    "Addr_rr+360", rri1i3 
	.asg    "Addr_rr+424", rri1i4 
	.asg    "Addr_rr+488", rri2i3 
	.asg    "Addr_rr+552", rri2i4 
	 
	;initialize local veraible memory eara 
	.asg	"Addr_local_buf3",i0 
	.asg	"Addr_local_buf3+1",i1 
	.asg	"Addr_local_buf3+2",i2 
	.asg	"Addr_local_buf3+3",i3 
	.asg	"Addr_local_buf3+4",ip0 
	.asg	"Addr_local_buf3+5",ip1 
	.asg	"Addr_local_buf3+6",ip2 
	.asg	"Addr_local_buf3+7",ip3 
	.asg	"Addr_local_buf3+8",ix 
	.asg	"Addr_local_buf3+9",iy 
	.asg	"Addr_local_buf3+10",ptr_rri0i3_i4 
	.asg	"Addr_local_buf3+11",ptr_rri1i3_i4 
	.asg	"Addr_local_buf3+12",max 
	.asg	"Addr_local_buf3+13",prev_i0 
	.asg	"Addr_local_buf3+14",i1_offset 
	.asg	"Addr_local_buf3+15",psk 
	.asg	"Addr_local_buf3+16",ps 
	.asg	"Addr_local_buf3+17",ps0 
	.asg	"Addr_local_buf3+18",ps1 
	.asg	"Addr_local_buf3+19",ps2 
	.asg	"Addr_local_buf3+20",sq 
	.asg	"Addr_local_buf3+21",sq2 
	.asg	"Addr_local_buf3+22",alpk 
	.asg	"Addr_local_buf3+23",alp 
	.asg	"Addr_local_buf3+24",alp_16 
	.asg	"Addr_local_buf3+25",constnum 
	.asg	"Addr_local_buf3+26",s			;32bits 
	.asg	"Addr_local_buf3+28",alp0		;32bits 
	.asg	"Addr_local_buf3+30",alp1		;32bits 
	.asg	"Addr_local_buf3+32",alp2		;32bits 
	 
	.asg	"Addr_local_buf3+34",sign_dn		;sign_dn[L_SUBFR] thereinto L_SUBFR=40 
	.asg	"Addr_local_buf3+74",sign_dn_inv	;sign_dn_inv[L_SUBFR]	 
	.asg	"Addr_local_buf3+114",addr_dn	;temp address of Dn 
	.asg	"Addr_local_buf3+115",ptr_rri2i3_i4 
	.asg	"Addr_local_buf3+116",ptr_rri3i3_i4 
	.asg	"Addr_local_buf3+117",tmp_vect	;tmp_vect[NB_POS] thereinto NB_POS=8 
	.asg	"Addr_local_buf3+128",page_end	;just a indicate 
	 
;Register map 
	.asg	"AR5",pDn 
	.asg	"AR2",pSignDn 
	.asg	"AR7",pSignDn2 
	.asg	"AR3",pSignDnInv 
	.asg	"AR4",pSign 
	 
	.asg	"AR0",p0 
	.asg	"AR1",p1 
	.asg	"AR2",p2 
	.asg	"AR3",p3 
	.asg 	"AR4",p4 
	 
	.asg	"AR2",pCn	 
	.asg	"AR3",pYn2 
	.asg	"AR4",pH1 
	.asg	"AR6",AR_INDEX2 
	.asg	"AR7",AR_INDEX 
D4i40_17_fast: 
	;Chose the sign of the impulse. 
	STM 	#Addr_Dn,pDn				;pDn=AR5 
	STM 	#sign_dn,pSignDn			;pSignDn=AR2 
	STM 	#L_SUBFR-1,BRC			;Use the delay cirlce!! 
	RPTBD 	ChoseSignEnd-1 
	STM 	#sign_dn_inv,pSignDnInv		;pSignDnInv=AR3 
		LD *pDn,A 
		BC PositiveNumber,AGEQ		;if (dn[i]<0) 
			ABS A				;when dn[i]<0,abs(dn[i]) equal dn[i]=-dn[i] 
			STL A,*pDn 
			ST #MIN_16,*pSignDn+ 
			ST #MAX_16,*pSignDnInv+ 
			B ChoseSignNext 
PositiveNumber:						;else 
			ST #MAX_16,*pSignDn+ 
			ST #MIN_16,*pSignDnInv+ 
ChoseSignNext: 
		MAR *pDn+ 
ChoseSignEnd: 
;Modification of rrixiy[] to take signs into account 
	STM #rri0i1,p0	;p0=AR0 
	STM #rri0i2,p1	;p1=AR1 
	STM #rri0i3,p2	;p2=AR2 
	STM #rri0i4,p3	;p3=AR3 
	STM #NB_POS-1,AR_INDEX2		;AR6 
	STM #sign_dn,pSignDn2			;AR7 
LoopRi0: 
;	STM #sign_dn,pSign				;pSignDn=AR4.psign=sign_dn 
	LD *pSignDn2,A				;pSignDn2 point at psign[i0]. 
	BCD LoopRi0Next,AGEQ			;if(psign[i0]<0) psign=sign_dn_inv 
	STM #sign_dn,pSign				;pSignDn=AR4.psign=sign_dn 
								;Use delay circle!! 
		STM #sign_dn_inv,pSign 
LoopRi0Next: 
;	STM #NB_POS-1,BRC 
	MAR *pSign+ 
	RPTBD InnerLoopOfRi0End-1	;for(i1=1;i10) 
				LD sq2,A 
				STL A,sq 
				LD ps2,A 
				STL A,ps 
				LD alp_16,A 
				STL a,alp 
				LD i0,A 
				STL A,ix 
				LD i1,A 
				STL A,iy 
BeforLoopTrackEnd: 
		MAR *+pDn(STEP) 
		ADDM #STEP,i1					;i1+=STEP 
LoopTrackEnd: 
	BANZ	Loopi0,*AR_INDEX2- 
	LD ix,A 
	STL A,i0 
	LD iy,A 
	STL A,i1	 
	STM #6554,T 
	MPY i1,A 
	LD A,-16 
	LD A,3 
;	LD A,-13			;Note :shl(shr(A,-16),3)!=shr(A,-13). 
	STL A,i1_offset 
	LD ps,A 
	STL A,ps0 
	STM #8192,T 
	MPY alp,A 
	DST A,alp0 
	ST #-1,sq 
	ST #1,alp 
	 
	STM #6554,T 
	STM #rri1i2,p0		;p0=rri1i2+mult(i0,6554) 
	MPY i0,A 
	LD A,-16 
	ADD *(p0),A 
	STLM A,p0 
	MVDM ptr_rri1i3_i4,p1 
	MPY i1,A 
	LD A,-16 
	ADD *(p1),A 
	STLM A,p1 
	STM #rri1i1,p2			;p2=rri1i1 
	STM #tmp_vect,p3		;p3=tmp_vect 
;for(i3=1;i30) 
			LD sq2,A 
			STL A,sq 
			LD alp_16,A 
			STL A,alp		 
			LD i2,A 
			STL A,ix 
			LD i3,A 
			STL A,iy 
BeforeLoopi3End: 
	MAR *+pDn(STEP) 
	ADDM #STEP,i3 
Loopi3End: 
	ADDM #STEP,i2 
	BANZD Loopi2,*AR_INDEX2-	 
		MVDM addr_dn,pDn 
		 
;s=L_msu(L_mult(alpk,sq),psk,alp) 
	LD alpk,T 
	MPY sq,A 
	LD psk,T 
	MPY alp,B 
	SUB B,A 
	BC BeforeSearch4,ALEQ		;if(s>0) 
		LD sq,A 
		STL A,psk 
		LD alp,A 
		STL A,alpk 
		LD i0,A 
		STL A,ip2 
		LD i1,A 
		STL A,ip3 
		LD ix,A 
		STL A,ip0 
		LD iy,A 
		STL A,ip1 
BeforeSearch4: 
	ST #-1,sq			;sq=-1 
	ST #1,alp			;alp=1; 
;i0 loop:2 positions in track 3/4 
	ST #-1,prev_i0 
	STM #2-1,AR_INDEX2		;for(i=0;i<2;i++) 
Loop_3_4_i0: 
		ST #-1,max 
		LD #4 ,A 
		SUB *(AR_INDEX),A 
		STLM A,AR0			;j=4-AR_INDEX  ------>AR0 
		STM #Addr_Dn,pDn		;calculate the head address of Dn 
		ADD *(pDn),A		;A=dn[j] 
		STLM A,pDn 
;search "dn[]" maximum posiition in track 3/4 
		STM #NB_POS-1,BRC 
		RPTB SearchMaxDn_3_4_End-1 
			LD *pDn,A 
			LD max,B 
			MAX A 
			STLM A,T						;T for the temp result 
			BCD BeforeSearchMaxDn_3_4_End,C		;if A0) 
				LD sq2,A 
				STL A,sq 
				LD ps2,A 
				STL A,ps 
				LD alp_16,A 
				STL A,alp 
				LD i0,A 
				STL A,ix 
				LD  i1,A 
				STL A,iy 
BeforLoopTrack_3_4_End: 
		MAR *+pDn(STEP) 
		ADDM #STEP,i1 
LoopTrack_3_4_End: 
	BANZ Loop_3_4_i0,*AR_INDEX2- 
	LD ix,A 
	STL A,i0 
	LD iy,A 
	STL A,i1 
	STM #6554,T 
	MPY i1,A 
	LD A,-16 
	LD A,3 
	STL A,i1_offset 
	LD ps,A 
	STL A,ps0 
	STM #8192,T 
	MPY alp,A 
	DST A,alp0 
	ST #-1,sq 
	ST #1,alp 
	 
	STM #6554,T 
	 
	MVDM ptr_rri2i3_i4,p0			;p0=ptr_rri2i3_i4+mult(i0,6554) 
	MPY i0,A 
	LD A,-16 
	ADD *(p0),A 
	STLM A,p0 
	STM #rri0i2,p1		;p1=rri0i2+i1_offset 
	LD i1_offset,A 
	ADD *(p1),A 
	STLM A,p1 
	STM #rri2i2,p2		;p2=rri2i2 
	STM #tmp_vect,p3		;p3=tmp_vect 
;for(i3=2;i30) 
			LD sq2,A 
			STL A,sq 
			LD alp_16,A 
			STL A,alp 
			LD i2,A 
			STL A,ix 
			LD i3,A 
			STL A,iy 
BeforeLoopi3_3_4_End: 
		MAR *+pDn(STEP) 
		ADDM #STEP,i3 
Loopi3_3_4_End: 
	ADDM #STEP,i2 
	BANZD Loop_3_4_i2,*AR_INDEX2-	 
		MVDM addr_dn,pDn	 
;s=L_msu(L_mult(alpk,sq),psk,alp) 
	LD alpk,T 
	MPY sq,A 
	LD psk,T 
	MPY alp,B 
	SUB B,A 
	BC BeforeSetSign,ALEQ		;if(s>0) 
		LD sq,A 
		STL A,psk 
		LD alp,A 
		STL A,alpk 
		LD i0,A 
		STL A,ip3 
		LD i1,A 
		STL A,ip0 
		LD ix,A 
		STL A,ip1 
		LD iy,A 
		STL A,ip2 
BeforeSetSign: 
	;modify pointer of rrixiy 
	ST #rri0i4,ptr_rri0i3_i4 
	ST #rri1i4,ptr_rri1i3_i4 
	ST #rri2i4,ptr_rri2i3_i4 
	ST #rri4i4,ptr_rri3i3_i4 
	BANZ SearchPosLoop,*AR_INDEX- 
;Find the codeword corresponding to the selected positions 
	STM #(L_SUBFR>>1)-1,BRC 
	LD #0,A 
	RPTBD InitCodEnd-1 
	STM #Addr_cn,pCn			;pCn=AR2 
		DST A,*pCn+ 
InitCodEnd: 
;Set the sign oimpulses 
;note:the following code can be optimized.	 
	LD ip0,A					;i0=sign_dn[ip0] 
	STM #sign_dn,pSignDn		 
	ADD *(pSignDn),A 
	STLM A,pSignDn 
	NOP 
	NOP 
	LD *pSignDn,A 
	STL A,i0 
	LD ip1,A					;i1=sign_dn[ip1] 
	STM #sign_dn,pSignDn		 
	ADD *(pSignDn),A 
	STLM A,pSignDn 
	NOP 
	NOP 
	LD *pSignDn,A 
	STL A,i1 
	LD ip2,A					;i2=sign_dn[ip2] 
	STM #sign_dn,pSignDn		 
	ADD *(pSignDn),A 
	STLM A,pSignDn 
	NOP 
	NOP 
	LD *pSignDn,A 
	STL A,i2 
	LD ip3,A					;i3=sign_dn[ip3] 
	STM #sign_dn,pSignDn		 
	ADD *(pSignDn),A 
	STLM A,pSignDn 
	NOP 
	NOP 
	LD *pSignDn,A 
	STL A,i3 
 
	STM #Addr_cn,pCn			;cod[ip0]=shr(i0,2) 
	LD i0,-2,A 
	LD ip0,B 
	ADD *(pCn),B 
	STLM B,pCn 
	LD i1,-2,B					;using circle inteval 
	STL A,*pCn 
 
	STM #Addr_cn,pCn 
	LD ip1,A 
	ADD *(pCn),A 
	STLM A,pCn 
	LD i2,-2,A 
	STL B,*pCn 
	 
	STM #Addr_cn,pCn 
	LD ip2,B 
	ADD *(pCn),B 
	STLM B,pCn 
	LD i3,-2,B 
	STL A,*pCn 
	 
	STM #Addr_cn,pCn 
	LD ip3,A 
	ADD *(pCn),A 
	STLM A,pCn 
	LD ip0,A 
	STLM A,BRC 
	STL B,*pCn 
;find the filterd codeword 
;for(i=0;i0) 
		RPTB Beforei0Else-1 
			MVDD *pH1+,*pYn2+ 
Beforei0Else: 
		ADD #1,B	 
		B i1Begin 
i0Else:				;slse 
	RPTB i1Begin-1 
		LD *pH1+,A 
		NEG A 
		STL A,*pYn2+ 
i1Begin: 
	STM #Addr_h1,pH1 
	STM #Addr_yn2,pYn2 
	LD #L_SUBFR-1,A 
	SUB ip1,A 
	STLM A,BRC 
	LD ip1,A 
	ADD *(pYn2),A 
	STLM A,pYn2 
	LD i1,A	 
	BC i1Else,ALEQ		;if(i1>0) 
		RPTB Beforei1Else-1 
			LD *pYn2,A 
			ADD *pH1+,A 
			STL A,*pYn2+ 
Beforei1Else: 
		ADD #2,B 
		B i2Begin 
i1Else: 
		RPTB i2Begin-1 
			LD *pYn2,A 
			SUB *pH1+,A 
			STL A,*pYn2+ 
i2Begin: 
	STM #Addr_h1,pH1 
	STM #Addr_yn2,pYn2 
	LD #L_SUBFR-1,A 
	SUB ip2,A 
	STLM A,BRC 
	LD ip2,A 
	ADD *(pYn2),A 
	STLM A,pYn2 
	LD i2,A	 
	BC i2Else,ALEQ		;if(i1>0) 
		RPTB Beforei2Else-1 
			LD *pYn2,A 
			ADD *pH1+,A 
			STL A,*pYn2+ 
Beforei2Else: 
		ADD #4,B 
		B i3Begin 
i2Else: 
		RPTB i3Begin-1 
			LD *pYn2,A 
			SUB *pH1+,A 
			STL A,*pYn2+ 
i3Begin: 
	STM #Addr_h1,pH1 
	STM #Addr_yn2,pYn2 
	LD #L_SUBFR-1,A 
	SUB ip3,A 
	STLM A,BRC 
	LD ip3,A 
	ADD *(pYn2),A 
	STLM A,pYn2 
	LD i3,A	 
	BC i3Else,ALEQ		;if(i1>0) 
		RPTB Beforei3Else-1 
			LD *pYn2,A 
			ADD *pH1+,A 
			STL A,*pYn2+ 
Beforei3Else: 
		ADD #8,B 
		B FindEnd 
i3Else: 
		RPTB FindEnd-1 
			LD *pYn2,A 
			SUB *pH1+,A 
			STL A,*pYn2+ 
FindEnd: 
;*sign=i 
	STL B,*(PulseSign) 
	 
	STM #6554,T 
	MPY ip0,A 
	STL A,-16,ip0 
	MPY ip1,A 
	STL A,-16,ip1 
	MPY ip2,A 
	STL A,-16,ip2 
	MPY ip3,A			;A(i)=mult(ip3,6554) 
	LD A,-16 
	LD A,#2,B			;B=shl(i,2) 
	ADD A,B			;B(j)=i+shl(i,2) 
	ADD #3,B 
	STLM A,T			;save shl(i,1) 
	LD ip3,A 
	SUB B,A 
	LDM T,B 
	LD B,1 
	ADD A,B 
	STL B,ip3 
	 
	LD ip0,B 
	LD ip1,3,A 
	ADD A,B 
	LD ip2,6,A 
	ADD A,B 
	LD ip3,9,A 
	ADD A,B 
	STL B,*(PulseIndex)		;return i	 
	RET