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


;============================================================= 
;  File Name 
;  ---------- 
;  ENCODER.ASM 
; 
;  Brief Description of the Code: 
;  ------------------------------ 
;  Main encoder for G.729A. 
; 
;  Reference 
;  ---------- 
;  cod_ld8a.C 
;============================================================= 
 
        .mmregs 
 
        .include  ..\include\const.h 
        .include  ..\include\tab_ld8a.h 
        .include  ..\include\ld8amem.h 
 
        .ref   	G729A_encoder 
 
        .ref    Pre_Process          ; pre_proc.asm 
        .ref    AutoCorr             ; autocorr.asm 
        .ref    LagWindow            ; lag_win.asm 
        .ref    Levinson             ; levinson.asm 
        .ref    lpc_lsp              ; lpc_lsp.asm 
        .ref    QUA_LSP              ; qua_lsp.asm 
        .ref    Int_qlpc             ; int_qlpc.asm 
        .ref    Weight_Az            ; wegt_az.asm 
        .ref    Residu               ; residu.asm 
        .ref    Syn_ap1              ; syn_ap1.asm    
        .ref    Syn_filt1            ; syn_filt.asm first 40 
        .ref    Syn_filt2            ; syn_filt.asm second 40 
        .ref    Syn_filt3            ; syn_filt.asm Updata = 0   
 
        .ref    Pitch_ol_fast        ; pit_ol_f.asm 
 
        .ref    Pitch_fr3_fast       ; pit_fr3.asm 
        .ref    Enc_lag3             ; Enc_lag3.asm 
        .ref    Parity_Pitch         ; P_Parity.asm 
        .ref    G_pitch              ; G_pitch.asm 
        .ref    test_err             ; Test_err.asm 
        .ref    ACELP_Codebook       ; ACELP_CA.asm 
        .ref    Corr_xy2             ; Corr_xy2.asm 
        .ref    Qua_gain             ; Qua_gain.asm 
        .ref    update_exc_err       ; Updt_err.asm 
 
 
;----------------------------------------------------------------------- 
;  G729A_encoder 
;----------------------------------------------------------------------- 
G729A_encoder: 
        PSHM    ST1 
        RSBX    CPL 
        SSBX    FRCT 
 
        NOP                             ; 3 cycles latencies for changing CPL 
        LD      #ptr_codeword, DP 
        ST      #CodeWord, ptr_codeword 
 
        LD      #0, DP 
        ORM     #020h, PMST                ; set DARAM 
 
        MVDM    ptr_new_speech, AR3 
        CALLD   Pre_Process 
        STM     #L_FRAME - 1, BRC 
 
        CALLD   AutoCorr 
        MVDM    ptr_old_speech, AR3            ; init input pointer 
 
        CALLD   LagWindow 
        STM     #Addr_CorrCoef1 + 2, AR5       ; init input pointer 
 
        CALL    Levinson 
 
   ; if (!NewCoef) 
   ;   skip lpc_lsp, QUA_LSP, lar(in perc_var) 
 
        BCD     FailToFindNewCoef, ANEQ 
        LD      #bOldCoef, DP 
        STL     A, bOldCoef 
 
 
; lsp coefficients are found successfully 
        CALL    lpc_lsp 
        BC     LSP_Quantization, AEQ            
 
   ; unable to find coefficients 
   ; use old lsp coefficients and skip QUA_LSP 
 
FailToFindNewCoef: 
        STM     #M - 1, BRC 
        MVDM    ptr_lsp_old, AR2 
        MVDM    ptr_qlsp_old, AR4 
        STM     #Addr_lsp_coef, AR3 
 
        RPTBD   EndOldLsp - 1 
        STM     #Addr_lspq_coef, AR5 
 
		MVDD    *AR2+, *AR3+       ; lsp_new[i]  = lsp_old[i] 
		MVDD    *AR4+, *AR5+       ; lspq_new[i] = lspq_old[i] 
EndOldLsp: 
 
        B       LPC_Intp 
LSP_Quantization: 
 
        CALL    QUA_LSP 
 
LPC_Intp: 
 
        LD      #ptr_lsp_new, DP 
        ST      #Addr_lspq_coef, ptr_lsp_new     ;lsp_new_q 
        CALLD   Int_qlpc 
        ST      #Addr_qlpc_intp, ptr_Az          ;Aq_t 
 
 
   ; update lsp coefficients 
 
        STM     #M - 1, BRC 
        STM     #Addr_lsp_coef, AR2 
        MVDM    ptr_lsp_old, AR3 
        MVDM    ptr_qlsp_old, AR5 
 
        RPTBD   EndUpdateLsp - 1 
        STM     #Addr_lspq_coef, AR4 
 
		MVDD    *AR2+, *AR3+       ; lsp_old[i] = lsp_new[i] 
		MVDD    *AR4+, *AR5+       ; lspq_old[i] = lspq_new[i] 
EndUpdateLsp: 
 
 
;        STM     #24576, AR1                ; AR1 -> gamma=0.75 
	LD	#24576, 16, A 
 
        STM     #Addr_qlpc_intp, AR4 
        STM     #Addr_Ap1_1, AR5 
;        LD      AR1, 16, A                 ; AR1 -> gamma=0.75 
        CALLD   Weight_Az 
        STM     #M - 1, BRC 
 
 
	LD	#24576, 16, A 
        STM     #Addr_qlpc_intp+16, AR4 
        STM     #Addr_Ap1_2, AR5 
;        LD      AR1, 16, A                 ; AR1 -> gamma=0.75 
        CALLD   Weight_Az 
        STM     #M - 1, BRC 
 
 
        MVDM    ptr_new_speech, AR3 ;(i) AR3 -> ptr_new_speech 
        NOP 
        MAR     *+AR3(#-40) 
        MVDM    ptr_exc, AR4           ; (o) AR4 --> ptr_exc 
        STM     #Addr_qlpc_intp, AR2   ; (i) AR2 --> Aq_t[0] 
        CALLD   Residu 
        STM     #L_SUBFR-1,BRC         ; (i) lg --> L_SUBFR 
                                       
 
        MAR     *+AR2(#16) 
        CALLD   Residu 
        STM     #L_SUBFR-1,BRC         ; (i) lg --> LSUBFR 
 
;------------------------------------------------------------- 
        STM     #Addr_Ap1_1 - 1, AR3 
        STM     #Addr_Ap_1, AR4 
        CALLD   Syn_ap1 
        STM     #M-1, BRC              ; BRC = #M - 1 
 
 
        STM     #Addr_Ap_1 + 1, AR2        ; AR2 --> ptr_bi 
        MVDM    ptr_exc, AR3           ; AR3 --> ptr_xn 
        MVDM    ptr_wsp, AR5           ; AR5 --> ptr_yn 
        MVDM    ptr_mem_w, AR4         ; AR4 --> ptr_un 
        CALLD   Syn_filt1 
        LD      #L_SUBFR, 0, A         ; A --> lg 
        NOP 
 
;------------------------------------ 
 
        STM     #Addr_Ap1_2 - 1, AR3 
        STM     #Addr_Ap_1, AR4 
        CALLD   Syn_ap1 
        STM     #M-1, BRC                ;BRC = #M - 1 
        NOP 
 
        STM    #Addr_Ap_1+1, AR2       ;AR2 --> ptr_bi 
        MVDM   ptr_exc, AR3            ;AR3 --> ptr_xn 
        NOP 
        MAR     *+AR3(#40) 
        MVDM   ptr_wsp, AR5            ;AR5 --> ptr_yn 
        NOP 
        MAR     *+AR5(#40) 
        MVDM   ptr_mem_w, AR4          ;AR4 --> ptr_un 
        CALLD   Syn_filt2 
        LD      #L_SUBFR, A            ;A --> lg 
        NOP 
 
        CALL    Pitch_ol_fast 
 
        LD      #Addr_T0, DP 
        STL     A, Addr_T0 
 
;------------------------------------------------------------- 
; T0_min = sub(T_op - 3); 
; if(sub(T0_min,PIT_MIN)<0) T0_min = PIT_MIN  
 
        SUB     #3, A, B        ; T0_min = T0 - 3 
        LD      #PIT_MIN, A 
        MAX     B               ; T0_min = MIN(T0_min, PIT_MIN) 
 
; T0_max = add(T0_min + 6); 
; if(sub(T0_max,PIT_MAX)>0){ 
;   T0_max = PIT_MAX; 
;   T0_min = sub(T0_max,6)} 
 
        ADD     #6, B           ; T0_max = T0_min + 6 
        LD      #PIT_MAX, A 
        MIN     B               ; B = min(T0_max, PIT_MAX) 
        SUB     #6, B, A        ; A = T0_min 
        LD      #Addr_T0_min, DP 
        STL     B, Addr_T0_max 
        STL     A, Addr_T0_min 
 
;----------------------------------------------- 
; Loop for every subframe in the analysis frame 
;----------------------------------------------- 
 
        LD      #Addr_i_subfr, DP 
        ST      #0, Addr_i_subfr        ; i = 0 
 
 
 
SubFrameBegin: 
 
        STM     #Addr_h1, AR5 
        LD      #4096, A 
        STL     A,*AR5+ 
        RPTZ    A, L_SUBFR - 2       ; for(i=1;i ptr_bi 
H1_First_40_Next: 
        STM     #Addr_h1, AR3               ; AR3 --> ptr_xn 
        STM     #Addr_h1, AR5               ; AR5 --> ptr_yn 
        STM     #Addr_h1+1, AR4             ; AR4 --> ptr_un 
        CALLD   Syn_filt3 
        LD      #L_SUBFR, 0, A         ; A -->lg 
        NOP 
         
        LD      #Addr_i_subfr, DP 
        LD      Addr_i_subfr, A 
        BC      Xn_Second_40, ANEQ 
 
        STM     #Addr_Ap1_1, AR2    ; AR2 --> ptr_bi 
        MVDM    ptr_exc, AR3           ; AR3 --> ptr_xn 
        STM     #Addr_xn1, AR5         ; AR5 --> ptr_yn 
        MVDM    ptr_mem_w0, AR4        ; AR4 --> ptr_un 
        CALLD   Syn_filt3 
        LD      #L_SUBFR, 0, A         ; A --> lg 
        NOP 
        B       Xn_End_80 
Xn_Second_40: 
        LD      #ptr_ai, DP 
        STM     #Addr_Ap1_2, AR2    ; AR2 --> ptr_bi 
        MVDM    ptr_exc, AR3           ; AR3 --> ptr_xn 
        NOP 
        MAR     *+AR3(#40) 
        STM     #Addr_xn1, AR5         ; AR5 --> ptr_yn 
;        MAR     *+AR5(#40) 
        MVDM    ptr_mem_w0, AR4        ; AR4 --> ptr_un 
        CALLD   Syn_filt3 
        LD      #L_SUBFR, 0, A         ; A --> lg 
        NOP 
Xn_End_80: 
;------------------------------------ 
; Closed-loop fractional pitch search 
;------------------------------------ 
;T0 = Pitch_fr3_fast(&exc[i_subfr] 
;     xn, h1, L_SUBFR, T0_min, 
;     T0_max, i_subfr, &T0_frac) 
;------------------------------------ 
	LD #ptr_exc,DP 
	PSHD ptr_exc 
	LD ptr_exc,A 
	ADD *(Addr_i_subfr),A 
	NOP 
	STL A,ptr_exc 
    CALL    Pitch_fr3_fast 
	LD #ptr_exc,DP 
	POPD  ptr_exc 
 
;------------------------------------ 
; index = Enc_lag3(T0, T0_frac. 
;         &T0_min, &T0_max, 
;         PIT_MIN, PIT_MAX, 
;         i_subfr) 
;------------------------------------ 
 
        CALLD   Enc_lag3 
        	LD      #Addr_i_subfr, DP 
        	LD      Addr_i_subfr, A 
 
        MVDM    ptr_codeword, AR3 
        LD      #Addr_i_subfr, DP 
        LD      Addr_i_subfr, A 
        STL     B, *AR3+		;save the index 
 
; if(i_subfr==0)Parity_Pitch() 
        BC      SkipP0, ANEQ         
                CALL    Parity_Pitch 
                STL     A, *AR3+ 
 
SkipP0: 
        MVMD    AR3, ptr_codeword 
 
;------------------------------------- 
; Syn_filt(Ap, &exc[i_subfr], y1, 
;          L_SUBFR, mem_zero, 0) 
;------------------------------------- 
        LD      #Addr_i_subfr, DP 
        LD      Addr_i_subfr, A 
        BC      Y1_Second_40, ANEQ 
 
        STM     #Addr_Ap1_1, AR2    ; AR2 --> ptr_bi 
        MVDM    ptr_exc, AR3        ; AR3 --> ptr_xn 
        STM     #Addr_yn1, AR5      ; AR5 --> ptr_yn 
        MVDM    ptr_mem_zero, AR4   ; AR4 --> ptr_un 
        CALLD   Syn_filt3 
        LD      #L_SUBFR, A         ; A --> lg 
        NOP 
        B       Y1_End_80 
 
Y1_Second_40: 
 
        LD      #ptr_ai, DP 
        STM     #Addr_Ap1_2, AR2    ; AR2 --> ptr_bi 
        MVDM    ptr_exc, AR3        ; AR3 --> ptr_xn 
        NOP 
        MAR     *+AR3(#40) 
        STM     #Addr_yn1, AR5      ; AR5 --> ptr_yn 
;	MAR     *+AR5(#40) 
        MVDM    ptr_mem_zero, AR4   ; AR4 --> ptr_un 
        CALLD   Syn_filt3 
        LD      #L_SUBFR, A         ; A --> lg 
        NOP 
 
         
Y1_End_80: 
        CALL    G_pitch 
 
        CALL    test_err 
        BCD     EndTestErr, AEQ 
        LD      #Addr_TempFlag, DP 
        STL     A, Addr_TempFlag 
 
                LD      #Addr_gain_pit, DP 
                LD      #GPCLIP, B 
                LD      Addr_gain_pit, A 
                MIN     A 
                STL     A, Addr_gain_pit 
EndTestErr: 
 
;------------------------------------ 
; xn2[i] = xn[i] - y1[i] * gain_pit 
;------------------------------------ 
 
        STM     #L_SUBFR - 1, BRC 
        STM     #Addr_xn1, AR2 
        STM     #Addr_yn1, AR3 
        MVDM    Addr_gain_pit, T 
 
        RPTBD   EndXn2 - 1 
        STM     #Addr_xn2, AR4 
		LD *AR2+, A			;xn[i] 
		MPY *AR3+, B			;L_temp = L_mult(y1[i], gain_pit); 
		LD B, 1				;L_temp = L_shl(L_temp, 1); 
		LD B,-16 
		SUB B, A				;sub(xn[i], extract_h(L_temp)); 
		SAT A 
		STL A, *AR4+		 
EndXn2: 
 
;----------------------------------- 
; Innovative codebook serach. 
;----------------------------------- 
        CALL    ACELP_Codebook 
 
        MVDM    ptr_codeword, AR3 
        STM     #PulseIndex, AR2 
 
        MVDD    *AR2-, *AR3+ 
        MVDD    *AR2, *AR3+ 
 
        MVMD    AR3, ptr_codeword 
 
;------------------------------------ 
; Quantization of gains. 
;------------------------------------ 
; g_coeff_cs[0]     = g_coeff[0];          
; exp_g_coeff_cs[0] = negate(g_coeff[1]);  
; g_coeff_cs[1]     = negate(g_coeff[2]);  
; exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1)); 
 
 
        STM     #Addr_g_coeff, AR2 
        STM     #Addr_g_coeff_cs, AR3 
        STM     #Addr_exp_g_coeff_cs, AR4 
 
; g_coeff_cs[0] = g_coeff[0] 
        MVDD    *AR2+, *AR3+    
        LD      #0, ASM 
        LD      *AR2+, 16, A 
        NEG     A, B 
 
; exp_g_coeff_cs[0] = negate(g_coeff[1]); 
        ST      B, *AR4+        
        ||LD      *AR2+, A 
 
        NEG     A, B 
; g_coeff_cs[1] = negate(g_coeff[2]) 
        ST      B, *AR3         
        ||LD      *AR2, A 
 
        ADD     #1, 16, A      
; Corr_xy2( xn, y1, y2, g_coeff_cs, exp_g_coeff_cs ) 
        NEG     A 
        CALLD   Corr_xy2 
; exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1))		(use delay) 
        STL     A, -16, *AR4      
 
        CALL    Qua_gain 
 
        MVDM    ptr_codeword, AR3 
        MVDM    ptr_sharp, AR4 
        STL     A, *AR3+              ; Al = Qua_gain(xxx) 
        MVMD    AR3, ptr_codeword 
 
 
; sharp = gain_pit; 
; if (sub(sharp, SHARPMAX) > 0) { sharp = SHARPMAX;  } 
; if (sub(sharp, SHARPMIN) < 0) { sharp = SHARPMIN;  } 
         
        LD      #Addr_gain_pit, DP 
        LD      Addr_gain_pit, B 
        LD      #SHARPMAX, A 
        MIN     B 
        LD      #SHARPMIN, A 
        MAX     B 
 
        STL     B, *AR4               ; update sharp 
 
; --- Find the total excitation --- 
; --- find synthesis speech corresponding to exc[] --- 
; --- update filters memories for finding the target --- 
; --- vector in the next subframe --- 
; --- (update error[-m..-1] and mem_w_err[]) --- 
; --- update error function for taming process --- 
 
;  exc[i] = gain_pit*exc[i] + gain_code*code[i] 
         
        STM     #L_SUBFR - 1, BRC 
        MVDM    ptr_exc_subfrm, AR2 
        STM     #Addr_gain_pit, AR3 
        STM     #Addr_cn, AR4 
        LD      #1, 14, B                  ; rounding 
        RPTBD   EndTotalExc - 1 
        STM     #Addr_gain_code, AR5 
                 
                MAC     *AR2, *AR3, B, A ;A = gain_pit*exc[i] 
                MAC     *AR4+, *AR5, A   ;A += gain_code*code[i] 
                STL     A, -15, *AR2+ 
EndTotalExc: 
 
; update_exc_err(gain_pit, T0); 
 
        CALL    update_exc_err 
 
; for (i = L_SUBFR-M, j = 0; i < L_SUBFR; i++, j++) 
; { 
;    temp       = extract_h(L_shl( L_mult(y1[i], gain_pit),  1) ); 
;    k          = extract_h(L_shl( L_mult(y2[i], gain_code), 2) ); 
;    mem_w0[j]  = sub(xn[i], add(temp, k)); 
; } 
         
        STM     #M - 1, BRC 
        MVDM    ptr_mem_w0, AR1 
        MVDM    ptr_speech_subfrm, AR2 
 
        LD      #Addr_gain_pit, DP 
        STM     #Addr_yn1+(L_SUBFR - M), AR4  ;AR4 -> &y1[L_SUBFR-M] 
        STM     #Addr_yn2+(L_SUBFR - M), AR5  ;AR5 -> &y2[L_SUBFR-M] 
        RPTBD   EndUpdateMemErr - 1 
        STM     #Addr_xn1+(L_SUBFR - M), AR6  ;AR6 -> &xn[L_SUBFR-M] 
                 
                LD      Addr_gain_pit, T 
                MPY     *AR4+, A             
				LD A,1 
				LD A,-16			               ;¡ÙLD A,-14   ! ! 
                LD      Addr_gain_code, T 
                MPY     *AR5+, B 
				LD B,2 
				LD B,-16 
                ADD     B,A 
                SAT A			;saturate A 
                LD      *AR6+, B 
                SUB     A,B 
                SAT B			;saturate B 
                STL     B, *AR1+                ; update mem_w0 
 
EndUpdateMemErr: 
 
         
 
        LD      #Addr_i_subfr, DP 
        LD      Addr_i_subfr, A 
 
SubFrameEnd: 
 
        BCD     SubFrameBegin, AEQ      ; if(i==0)loop; 
        ADDM    #L_SUBFR, Addr_i_subfr  ; i += L_SUBFR 
 
        CALL    UpdateSignals 
        POPM    ST1 
        RET 
 
 
;------------------------------------------------------------- 
;  UpdateSignals 
;------------------------------------------------------------- 
UpdateSignals: 
 
        MVDM    ptr_old_speech, AR2 
        MVDM    ptr_wsp, AR4 
        MVMM    AR2, AR3 
        MAR     *+AR2(L_FRAME) 
        RPT     #L_TOTAL-L_FRAME-1 
; Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME); 
                MVDD    *AR2+, *AR3+        
 
        MVDM    ptr_exc, AR2 
 
        MVMM    AR4, AR3 
        MAR     *+AR4(-PIT_MAX)          ;AR4 -> &old_wsp[0] 
        MAR     *+AR3(L_FRAME - PIT_MAX) ;AR3 -> &old_wsp[L_FRAME] 
 
        RPT     #PIT_MAX - 1 
; Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX); 
                MVDD    *AR3+, *AR4+        
 
        MVMM    AR2, AR3 
 
        MAR     *+AR2(L_FRAME - PIT_MAX - L_INTERPOL) ;AR2 -> &old_exc[L_FRAME] 
        MAR     *+AR3(-(PIT_MAX + L_INTERPOL))        ;AR2 -> &old_exc[0] 
 
        RPT     #(PIT_MAX + L_INTERPOL - 1) 
; Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); 
                MVDD    *AR2+, *AR3+                    
 
        RET