📄 lpc.asm
字号:
;==========================================================================
; File Name
; ----------
; LPC.ASM
;
; Brief Description of the Code:
; ------------------------------
; Find LPC coefficients.
;
; Ref
; ------
; LPC.C
;==========================================================================
.mmregs
.include ..\include\const.h
.include ..\include\ld8amem.h
.text
.def AutoCorr
.def LagWindow
.def Levinson
.ref HamWindow ; tab_ld8a.asm
.ref CorrLoop1 ; tab_ld8a.asm
.ref LagWin_l ; tab_ld8a.asm
.ref LagWin_h ; tab_ld8a.asm
.ref MPY32 ; math.asm
;------------------------------------------------------------------------
; Function : AutoCorr
;-----------------------------------------------------------------------
; void Autocorr(
; Word16 x[], /* (i) : Input signal */
; Word16 m, /* (i) : LPC order */
; Word16 r_h[], /* (o) : Autocorrelations (msb) */
; Word16 r_l[] /* (o) : Autocorrelations (lsb) */
; )
;-----------------------------------------------------------------------
; Input Registers :
; AR3 -> signal[]
;
; Modified Registers : BRC
; A, B
; AR0, AR1, AR2, AR3, AR4, AR5
;-----------------------------------------------------------------------
.asg "AR0", pNumCoef
.asg "AR0", pLoopNum
.asg "AR0", pTemp
.asg "AR1", pCoef
.asg "AR2", pWSigBase
.asg "AR3", pWSigOffset
.asg "AR3", pSignal
.asg "AR4", pWSig1
.asg "AR5", pWSig2
.asg "AR5", pHamWindow
AutoCorr:
RSBX 0, 10
STM #Addr_wsig_buf, pWSigBase
STM #L_TOTAL - 1, BRC
MVMM pWSigBase, pWSig1
LD #1, 15, B
RPTBD #WinSig - 1
STM #HamWindow, pHamWindow
MAC *pHamWindow+, *pSignal+, B, A
STL A, -16, *pWSig1+
WinSig:
MVMM pWSigBase, pWSig1
LD #1, A ; avoid case of all zero
RPT #L_TOTAL - 1
SQURA *pWSig1+, A ; find r[0]
BC No_AOV, ANOV ; if overflow, make justfy, otherwise, go ahead
MVMM pWSigBase, pWSig1 ; pWsig1 point to y[0]
STM #L_WINDOW - 1, BRC ; Repeat 240 times
RPTB #Un_Jmp - 1 ; Two ins.
LD *pWSig1, -2, A ; (y[i] >> 2) -> A
STL A, *pWSig1+ ; A -> y[i]
Un_Jmp:
B #WinSig ; Unconditionally jumping, repeat more
No_AOV:
STM #Addr_CorrCoef1, pCoef
EXP A
STM #10 - 1, BRC
NORM A
;.........for store with bit-exact with c
LD A, -1, A
LD A, 1, A
;.........
DST A, *pCoef+
MVMM pWSigBase, pWSigOffset
LDM T, B
MAR *pWSigOffset+
RPTBD #AutoCorrCoef - 1 ; find r[1] .. r[10]
STM #CorrLoop1, pLoopNum
MVMM pWSigBase, pWSig1
MVMM pWSigOffset, pWSig2
MPY *pWSig1+, *pWSig2+, A
RPT *pLoopNum+
MAC *pWSig1+, *pWSig2+, A
STLM B, T
MAR *pWSigOffset+
NORM A
;............for store with bit-exact with c
LD A, -1, A
LD A, 1, A
;............
DST A, *pCoef+
AutoCorrCoef:
RET
;-----------------------------------------------------------------------
; Function LagWindow(
; Word16 m, /* (i) : LPC order */
; Word32 r[], /* (i/o) : Autocorrelations */
; )
;
; Lag_window on autocorrelations.
;
; r[i] *= LagWin[i]
;
;
;-----------------------------------------------------------------------
; Input Registers :
; AR5 -> &r[1]_hi
;
; Modified Registers : BRC
; A, B
; AR0, AR4, AR5
;-----------------------------------------------------------------------
.asg "AR3", pLagWin_h
.asg "AR4", pLagWin_l
.asg "AR5", pWCoef
LagWindow:
STM #M - 1, BRC
STM #LagWin_l, pLagWin_l
LD #0ffffh, 16, B ; to be bit-exact with C code
RPTBD #WinCoef - 1
STM #LagWin_h, pLagWin_h
MPY *pLagWin_l+, *pWCoef+, A ; LagWin_l * WCoef_h
AND B, A
LD A, 1, A
MACSU *pWCoef-, *pLagWin_h, A
LD A, -16, A
MAC *pLagWin_h+, *pWCoef, A
LD A, -1, A
LD A, 1, A
DST A, *pWCoef+
WinCoef:
RET
;-----------------------------------------------------------------------
;
; LEVINSON-DURBIN algorithm in double precision
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;--------------------------------------------------------------------------
; void Levinson(
; Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */
; Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */
; Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 10) */
; Word16 rc[] /* (o) Q15 : rc[M] Reflection coefficients. */
; )
;--------------------------------------------------------------------------
;
; Algorithm
;
; R[i] autocorrelations.
; A[i] filter coefficients.
; K reflection coefficients.
; Alpha prediction gain.
;
; Initialization:
; A[0] = 1
; K = -R[1]/R[0]
; A[1] = K
; Alpha = R[0] * (1-K**2)
;
; Do for i = 2 to M
;
; S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i]
;
; K = -S / Alpha
;
; An[j] = A[j] + K*A[i-j] for j=1 to i-1
; where An[i] = new A[i]
; An[i]=K
;
; Alpha = Alpha * (1-K**2)
;
; END
;
;-----------------------------------------------------------------------
; Constants : Addr_CorrCoef1 -> R
; Addr_LPCoefQ27 -> A
; Addr_RCoef -> rc
;
; Modified Registers : A, B, ST0(DP), AR0 -- AR5
;
; Return Value : if successfully find LPC coefficients
; A = 0
; else
; A != 0
;-----------------------------------------------------------------------
.asg "AR0", AR_Counter
.asg "AR1", AR_LPC_Index
.asg "AR2", AR_Sign
.asg "AR2", pLPC1Q27
.asg "AR3", pLPCQ12
.asg "AR3", pLPC2Q27
.asg "AR3", pAutoCorr
.asg "AR4", pRCoef
.asg "AR5", pAlpha
xOne .set 0x60
Levinson:
STM #Addr_CorrCoef1 + 2, pAlpha ; pAlpha -> R[1]_hi
STM #Addr_RCoef, pRCoef ; pRCoef -> K[]
LD #0, DP
; K = -R[1]/R[0]
; A[1] = K
DLD *pAlpha-, B ; pAlpha -> R[0]
STL B, -16, AR_Sign
CALLD DIV32B
ABS B
DST B, *pRCoef ; *pRCoef = numerator
LD AR_Sign, B
STM #Addr_LPCoefQ27, AR_LPC_Index ; AR_LPC_Index -> A[1]_hi
XC 1, BGEQ
NEG A
MVMM AR_LPC_Index, pLPC2Q27 ; pLPC1Q27 -> A[1]_hi
DST A, *pRCoef ; RCoef[0] = K
SFTA A, -4 ; Q31 -> Q27
ld A, -1, A
ld A, 1, A
DST A, *pLPC2Q27 ; A[1] = K
STM #M-2, AR_Counter
LD #0, ASM
UpdateLPCoef:
; Alpha=Alpha * (1-K**2)
MAR *pRCoef+ ; pRCoef -> K_lo
LDU *pRCoef-, A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -