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