📄 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;i1<L_SUBFR;i0+=STEP)
STM #NB_POS-1,BRC
LD *p0,T
MPY *pSign+,A
STL A,-16,*p0+ ;*p0++=nult(*p0,psign[i1]);
LD *p1,T
MPY *pSign+,A
STL A,-16,*p1+ ;*p1++=nult(*p1,psign[i1+1]);
LD *p2,T
MPY *pSign+,A
STL A,-16,*p2+ ;*p2++=nult(*p2,psign[i1+2]);
LD *p3,T
MPY *pSign+,A
STL A,-16,*p3+ ;*p3++=nult(*p3,psign[i1+2]);
MAR *pSign+
InnerLoopOfRi0End:
BANZD LoopRi0,*AR_INDEX2-
MAR *+pSignDn2(STEP)
STM #rri1i2,p0 ;p0=rri1i2
STM #rri1i3,p1 ;p1=rri1i3
STM #rri1i4,p2 ;p2=rri1i4
STM #NB_POS-1,AR_INDEX2 ;AR_INDEX2=AR6
STM #sign_dn+1,pSignDn2 ;pSignDn2=AR7
LoopRi1:
; STM #sign_dn,pSign ;pSignDn=AR4.psign=sign_dn
LD *pSignDn2,A ;pSignDn2 point at psign[i1].
BCD LoopRi1Next,AGEQ ;if(psign[i1]<0) psign=sign_dn_inv
STM #sign_dn,pSign ;pSignDn=AR4.psign=sign_dn
;Use delay circle
STM #sign_dn_inv,pSign
LoopRi1Next:
; STM #NB_POS-1,BRC
MAR *+pSign(2)
RPTBD InnerLoopOfRi1End-1 ;for(i1=1;i1<L_SUBFR;i0+=STEP)
STM #NB_POS-1,BRC ;Use delay circle
LD *p0,T
MPY *pSign+,A
STL A,-16,*p0+ ;*p0++=nult(*p0,psign[i2]);
LD *p1,T
MPY *pSign+,A
STL A,-16,*p1+ ;*p1++=nult(*p1,psign[i2+1]);
LD *p2,T
MPY *pSign+,A
STL A,-16,*p2+ ;*p2++=nult(*p2,psign[i2+1]);
MAR *+pSign(2) ;pSign+=STEP(2=STEP-3(increment)
InnerLoopOfRi1End:
BANZD LoopRi1,*AR_INDEX2-
MAR *+pSignDn2(STEP)
STM #rri2i3,p0 ;p0=rri2i3
STM #rri2i4,p1 ;p1=rri2i4
STM #NB_POS-1,AR_INDEX2
STM #sign_dn+2,pSignDn2 ;pSignDn2=AR7
LoopRi2:
; STM #sign_dn,pSign ;pSignDn=AR4.psign=sign_dn
LD *pSignDn2,A ;pSignDn2 point at psign[i1].
BCD LoopRi2Next,AGEQ ;if(psign[i1]<0) psign=sign_dn_inv
STM #sign_dn,pSign ;pSignDn=AR4.psign=sign_dn
;Use delay circle
STM #sign_dn_inv,pSign
LoopRi2Next:
; STM #NB_POS-1,BRC
MAR *+pSign(#3)
RPTBD InnerLoopOfRi2End-1 ;for(i1=1;i1<L_SUBFR;i0+=STEP)
STM #NB_POS-1,BRC ;Use delay circle
LD *p0,T
MPY *pSign+,A
STL A,-16,*p0+ ;*p0++=nult(*p0,psign[i2]);
LD *p1,T
MPY *pSign+,A
STL A,-16,*p1+ ;*p1++=nult(*p1,psign[i2+1]);
MAR *+pSign(3)
InnerLoopOfRi2End:
BANZD LoopRi2,*AR_INDEX2-
MAR *+pSignDn2(STEP)
;----------------------------------------------------------------------------
;Search the optimum position of the four pulses which maximize
; square(correlation)/energy
;----------------------------------------------------------------------------
LD #Addr_local_buf3,DP
;initialize the pointer of rrixiy.
ST #rri0i3,ptr_rri0i3_i4
ST #rri1i3,ptr_rri1i3_i4
ST #rri2i3,ptr_rri2i3_i4
ST #rri3i3,ptr_rri3i3_i4
ST #-1,psk
ST #1,alpk
ST #0,ip0
ST #1,ip1
ST #2,ip2
ST #3,ip3
ST #0,ix
ST #0,iy
ST #0,ps
;the outter loop
STM #2-1,AR_INDEX ;for(track=3,trk=0;track<5;track++,trk++)
SearchPosLoop:
ST #-1,sq ;sq=-1
ST #1,alp ;alp=1;
;i0 loop:2 positions in track 2
ST #-1,prev_i0
STM #2-1,AR_INDEX2 ;for(i=0;i<2;i++)
Loopi0:
STM #Addr_Dn+2,pDn
ST #-1,max
STM #2,AR0 ;index counter :j
;search "dn[]" maximum posiition in track 2
STM #NB_POS-1,BRC
RPTB SearchMaxDnEnd-1
LD *pDn,A
LD max,B
MAX A
STLM A,T ;T for the temp result
BCD BeforeSearchMaxDnEnd,C ;if A<B (dn[j]<max) goto ...
MAR *+pDn(STEP) ;use the delate circle
LD prev_i0,A
SUB *(AR0),A
BC BeforeSearchMaxDnEnd,AEQ ;if prev_i0==j goto ...
LDM T,A ;else all above
STL A,max
MVMD AR0,i0
BeforeSearchMaxDnEnd:
MAR *+AR0(STEP) ;j+=STEP
SearchMaxDnEnd:
LD i0,B ;prev_i0=i0
STL B,prev_i0
STM #6554,T
MPY i0,A
LD A,-16 ;j(A)=mult(i0,6554)
STLM A,BRC ;save j into BRC for temp
STM #rri2i2,p0
ADD *(p0),A
STLM A,p0 ;p0=ri2i2+j
STM #8192,T
MPY *p0,A
DST A,alp1 ;alp1=L_mult(*p0,_1_4)
STM #Addr_Dn,pDn ;ps1=dn[i0]
LD i0,A
ADD *(pDn),A
STLM A,pDn
NOP
NOP
LD *pDn,A
STL A,ps1
LD *(BRC),A
MVDM ptr_rri2i3_i4,p0 ;p0=ptr_rri2i3_i4
LD A,3
Add *(p0),A
; STLM A,p0
MVDM ptr_rri3i3_i4,p1 ;p1=ptr_rri3i3_i4
STLM A,p0
;initianlize pDn point at dn[i1]
STM #Addr_Dn+4,pDn ;dn[i1]=pDn+4-AR_INDEX(it belong to 1~0)
LDM pDn,A ;track=4-AR_INDEX
LDM AR_INDEX,B
SUB B,A ;A=dn[i1]
STLM A,pDn
LD #4,A
SUB *(AR_INDEX),A
STM #NB_POS-1,BRC
STL A,i1 ;i1=track
;for(i1=track;i1<L_SUBFR;i1+=STEP)
RPTB LoopTrackEnd-1
STM #16384, T ;alp2=L_mac(alp1,*p0++,_1_2);
MPY *p0+,B ;alp2=L_mac(alp2,*p1++,_1_2);
DADD alp1, B ;apl2=B
STM #8192,T
MPY *p1+,A
ADD B,A ;alp2=A
ADD #1,15,A ;apl_16=round(alp2)
STL A,-16,alp_16
LD ps1,A
ADD *pDn,A
STL A,ps2
SQUR *(AL),B
STL B,-16,sq2
;s=L_msu(L_mult(alp,sq2),sq,alp_16)
LD alp,T
MPY sq2,A
LD sq,T
MPY alp_16,B
SUB B,A ;A=A-B
BC BeforLoopTrackEnd,ALEQ ;if(s>0)
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;i3<L_SUBFR;i3+=STEP)
STM #NB_POS-1,BRC
RPTB Loopi2End-1
STM #8192,T ;s=L_mult(*p0,_1_4)
MPY *p0,A
MAR *+p0(NB_POS) ;p0+=NB_POS
MPY *p1,B ;s=L_mac(s,*p1,_1_4)
ADD B,A
MAR *+p1(NB_POS) ;p1+=NB_POS
STM #4096,T ;s=L_mac(s,*p2++,_1_8)
MPY *p2+,B
ADD B,A
ADD #1,15,A ;*p3++=round(s)
STL A,-16,*p3+
Loopi2End:
STM #6554,T
STM #rri0i2,p0 ;p0=rri0i2+mult(i0,6554)
MPY i0,A
LD A,-16
ADD *(p0),A
STLM A,p0
MVDM ptr_rri0i3_i4,p1 ;p1=ptr_rri0i3_i4+mult(ii1,6554)
MPY i1,A
LD A,-16
ADD *(p1),A
STLM A,p1
STM #rri0i0,p2 ;p2=rri0i0
STM #rri0i1,p3 ;p3=rri0i1
STM #NB_POS-1,AR_INDEX2 ;AR_INDEX2(AR7) is the loop counter.
STM #Addr_Dn,pDn
ST #0,i2
Loopi2:
LD ps0,A
ADD *pDn,A
MAR *+pDn(STEP)
STL A,ps1
MVMD pDn,addr_dn ;save the pointer into addr_dn
;alp1=alp0+rr[i0][i2]+rr[i1][i2]+0.5*rr[i2][i2]
STM #4096,T
DLD alp0,A
MPY *p0,B
ADD B,A
MAR *+p0(NB_POS)
MPY *p1,B
ADD B,A
MAR *+p1(NB_POS)
STM #2048,T
MPY *p2+,B
ADD B,A
DST A,alp1
STM #tmp_vect,p4
STM #Addr_Dn+1,pDn ;pDn=dn[i3]
STM #NB_POS-1,BRC
ST #1,i3 ;for (i3=1; i3<L_SUBFR; i3+=STEP)
RPTB Loopi3End-1
LD ps1,A ;ps2=add(ps1,dn[i3])
ADD *pDn,A
STL A,ps2
SQUR *(AL),B ;sq2=mult(ps2,ps2)
STL B,-16,sq2
STM #4096,T
DLD alp1,A ;alp2=L_mac(alp1,*p3++,_1_8)
MPY *p3+,B
ADD B,A
STM #16384,T ;alp2=L_mac(alp2,*p4++,_1_2)
MPY *p4+,B
ADD B,A
DST A,alp2
ADD #1,15,A ;alp_16=round(alp2)
LD A,-16
STL A,alp_16
;s=L_msu(L_mult(alp,sq2),sq,alp_16)
LD alp,T
MPY sq2,A
LD sq,T
MPY alp_16,B
SUB B,A
BC BeforeLoopi3End,ALEQ ;if(s>0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -