📄 lpc.dsp
字号:
/************************************************************************/
/* $$01/10/2000 checked LpcMod module data variables and function */
/* $$01/16/2001 modified and printed,Author: Jason.wang (zhigang wang) */
/* $$01/16/2001 Email: wzg119@yeah.net, BP: 86+02195950-161452 */
/* $$01/16/2001 This modlue is not optimized! should be test on Emulator*/
/************************************************************************/
.MODULE/SEG=App_PM LpcMod;
/************************************************************************/
#include "ld8a.inc"
#include "tab_ld8a.inc"
/************************************************************************/
/* Last A(z) for case of unstable filter */
/* $$01/10/2000 static memory and pointer */
/************************************************************************/
.VAR/DM/RAM/SEG=App_DMmem old_A[M+1],old_rc[2];
/************************************************************************/
.EXTERNAL Div_32;
.EXTERNAL div_s;
/************************************************************************
* Initialize the LPC filter static memory *
* $$01/10/2000 used both in encoder and decoder *
* Calling Parameters *
* Return Values *
* Altered Registers: I1,M1 *
* Computation Time : 18 cycles *
*************************************************************************/
.ENTRY Init_LPCFilt;
Init_LPCFilt: I1=^old_A;
// CNTR=M;
DM(I1,M1)=4096;
CNTR=M;
DO zero_LPCfilt UNTIL CE;
zero_LPCfilt: DM(I1,M1)=0;
I1=^old_rc;
DM(I1,M1)=0;
DM(I1,M1)=0;
RTS;
/************************************************************************
* LEVINSON-DURBIN algorithm in double precision *
* $$01/10/2000 used both in encoder and decoder *
* $$01/11/2000 modify pointer and varaibles to adapt table change *
* Calling Parameters *
* I3 : Rh[M+1] Vector of autocorrelations (msb) *
* I2 : Rl[M+1] Vector of autocorrelations (lsb) *
* Return Values *
* I0 : Q12 A[M] LPC coefficients (m = 10) *
* I1 : Q15 rc[M] Reflection coefficients. *
* SR0 : R0 exponent value *
* Altered Registers: MR,SR,AR,I0,I1,I2,I3,AX0,MY0 *
* Computation Time : 18 cycles *
*************************************************************************/
.ENTRY Levinson;
.VAR/DM/RAM/SEG=App_DMbuf Ah[M+1], Al[M+1]; /* LPC coef. in double prec. */
.VAR/DM/RAM/SEG=App_DMbuf Anh[M+1], Anl[M+1]; /* LPC coef.for next iteration in double prec. */
.VAR/DM/RAM/SEG=App_DMtmp alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent*/
.VAR/DM/RAM/SEG=App_DMtmp rc, t0hi_save, t0lo_save;
Levinson: DM(rc)=I1;
MY0=DM(I2,M1);
MY1=DM(I3,M1);
MR0=DM(I2,M2);
MR1=DM(I3,M2);
SR=LSHIFT MR0 BY 1(LO);
{---------K = A[1] = -R[1] / R[0] ---------------}
AR=PASS MR1,MR0=SR0;
IF GT JUMP abs_rhl;
DIS AR_SAT;
AR=-MR0;
ENA AR_SAT;
MR0=AR,AR=-MR1+C-1;
abs_rhl: MX0=MR0;
MX1=AR;
AX0=MR0;
AX1=MR1;
CALL Div_32;
AF=PASS AX1,AR=SR1;
IF LE JUMP abs_t0;
DIS AR_SAT;
AR=-SR0;
ENA AR_SAT;
SR0=AR,AR=-SR1+C-1;
abs_t0: SE=-4;
I4=^Al+1;
I5=^Ah+1;
MR0=SR0;
SR=LSHIFT SR0 BY -1(LO);
SR=LSHIFT MR0 (LO),MY0=SR0;
SR=SR OR ASHIFT AR (HI),MX1=AR;
{---------Alpha = R[0] * (1-K**2)------------}
AR=PASS 1,DM(I1,M1)=MX1;
MR=MX1 * MX1(SS);
MF=MX1 * MY0(SS),DM(I5,M4)=SR1;
SR=LSHIFT SR0 BY -1(LO);
MR=MR+AR*MF(SS),DM(I4,M4)=SR0;
MF=MX1 * MY0(SS),AY0=DM(I5,M7);
MR=MR+AR * MF(SS),AY0=DM(I4,M7);
AR=PASS MR1;
IF GE JUMP abs_t00;
DIS AR_SAT;
AR=-MR0;
ENA AR_SAT;
MR0=AR,AR=-MR1+C-1;
abs_t00: AY0=H#FFFF;
DIS AR_SAT;
AR=AY0-MR0,MR1=AR;
ENA AR_SAT;
SR=LSHIFT AR BY -1(LO);
AY0=H#7FFF;
AR=AY0-MR1+C-1,MY1=DM(I3,M1);
AR=PASS 1,MX1=AR;
MR=MX1 * MY1(SS),MY0=DM(I2,M1);
MF=MX1 * MY0(SS);
MR=MR+AR*MF(SS);
MF=SR0 * MY1(SS);
MR=MR+AR * MF(SS);
{---------Normalize Alpha-------------}
SE=EXP MR1 (HI);
SE=EXP MR0 (LO);
SR=NORM MR0 (LO),AR=SE;
SR=SR OR NORM MR1 (HI);
DM(alp_h)=SR1;
SR=LSHIFT SR0 BY -1(LO);
DM(alp_l)=SR0;
AR=-AR;
DM(alp_exp)=AR;
/*--------------------------------------*
* ITERATIONS I=2 to M *
*--------------------------------------*/
SI= 1;
CNTR=M-1;
DO levinson_loop UNTIL CE;
{-------------t0 = SUM(R[j]*A[i-j],j=1,i-1)+R[i]-------------}
AX0=I2;
AX1=I3;
AY0=I4;
AY1=I5;
// CNTR=SI;
AR=PASS 1,MX1=DM(I5,M7);
MR=0,MY1=DM(I3,M1);
CNTR=SI;
DO long_add UNTIL CE;
MR=MR+MX1 * MY1(SS),MY0=DM(I2,M1);
MF=MX1 * MY0(SS),MX0=DM(I4,M7);
MR=MR+AR*MF(SS);
MF=MX0 * MY1(SS),MY1=DM(I3,M1);
MR=MR+AR * MF(SS),MX1=DM(I5,M7);
long_add: IF MV SAT MR;
I4=AY0;
I5=AY1;
AR=DM(I2,M1);
SR=LSHIFT AR BY 1(LO);
AY0=SR0;
SR=LSHIFT MR0 BY 4(LO);
SR=SR OR ASHIFT MR1 BY 4(HI);
DIS AR_SAT;
AR=SR0+AY0,AY1=MY1;
ENA AR_SAT;
I2=AX0;
I3=AX1;
AX0=AR,AR=SR1+AY1+C;
DM(t0lo_save)=AX0;
DM(t0hi_save)=AR;
{---------K = -t0 / Alpha---------------}
IF GE JUMP abs_t0t0;
AR=-AX0,AX1=AR;
AX0=AR,AR=-AX1+C-1;
abs_t0t0: MX0=AX0;
MX1=AR;
MY0=DM(alp_l);
MY1=DM(alp_h);
CALL Div_32;
AX0=DM(t0hi_save);
AY0=DM(t0lo_save);
AF=PASS AX0,AR=SR1;
IF LT JUMP abs_t2;
NONE=AX0 OR AY0;
IF EQ JUMP abs_t2;
DIS AR_SAT;
AR=-SR0;
ENA AR_SAT;
SR0=AR,AR=-SR1+C-1;
abs_t2: AY0=32750;
SE=DM(alp_exp);
SR=lSHIFT SR0 (LO);
SR=SR OR ASHIFT AR (HI);
{-------------Test for unstable filter. If unstable keep old A(z)--------}
AR=ABS SR1,DM(I1,M0)=SR1;
SR=LSHIFT SR0 BY -1(LO);
AF=AR-AY0,SR1=DM(I1,M1);
IF LE JUMP stable_filter;
// CNTR=M;
I1=^old_A;
CNTR=M;
DO copy_oldA UNTIL CE;
AR=DM(I1,M1);
copy_oldA: DM(I0,M1)=AR;
I1=DM(rc);
I2=^old_rc;
AR=DM(I2,M1);
DM(I1,M1)=AR;
AR=DM(I2,M1);
DM(I1,M1)=AR;
RTS;
/*------------------------------------------*
* Compute new LPC coeff. -> An[i] *
* An[j]= A[j] + K*A[i-j] , j=1 to i-1 *
* An[i]= K *
*------------------------------------------*/
stable_filter: //CNTR=SI;
MX0=I0;
MX1=I1;
AX0=I2;
AX1=I3;
I0=^Al+1;
I1=^Ah+1;
I2=^Anl+1;
I3=^Anh+1;
CNTR=SI;
DO extra_khkl UNTIL CE;
AR=PASS 1,MY1=DM(I5,M7);
MR=SR1 * MY1(SS),MY0=DM(I4,M7);
MF=SR1 * MY0(SS),MY0=SR0;
MR=MR+AR*MF(SS),AY1=DM(I1,M1);
MF=SR0 * MY1(SS),MY1=SR1;
MR=MR+AR * MF(SS),AR=DM(I0,M1);
SR=LSHIFT AR BY 1(LO);
AY0=SR0;
DIS AR_SAT;
AR=MR0+AY0;
ENA AR_SAT;
SR=LSHIFT AR BY -1(LO);
AR=MR1+AY1+C,DM(I2,M1)=SR0;
SR0=MY0;
SR1=MY1;
extra_khkl: DM(I3,M1)=AR;
I0=MX0;
I1=MX1;
AR=PASS 1,MY0=SR0;
MR=SR1 * SR1(SS);
MF=SR1 * MY0(SS);
MR=MR+AR*MF(SS);
MF=SR1 * MY0(SS);
MR=MR+AR * MF(SS),AR=SR1;
SR=LSHIFT SR0 BY -3(LO);
SR=SR OR ASHIFT AR BY -4(HI);
{-----------Alpha = Alpha * (1-K**2)-------------}
DM(I3,M1)=SR1;
SR=LSHIFT SR0 BY -1(LO);
AR=PASS MR1,DM(I2,M1)=SR0;
IF GE JUMP abs_t02;
DIS AR_SAT;
AR=-MR0;
ENA AR_SAT;
MR0=AR,AR=-MR1+C-1;
abs_t02: AY0=H#FFFF;
DIS AR_SAT;
AR=AY0-MR0,MR1=AR;
ENA AR_SAT;
AY0=H#7FFF;
SR=LSHIFT AR BY -1(LO);
AR=AY0-MR1+C-1;
MY0=DM(alp_l);
MY1=DM(alp_h);
AR=PASS 1,MX0=AR;
MR=MX0 * MY1(SS);
MF=MX0 * MY0(SS);
MR=MR+AR*MF(SS);
MF=SR0 * MY1(SS);
MR=MR+AR * MF(SS);
{------------Normalize Alpha----------------}
SE=EXP MR1 (HI),AR=SI;
SE=EXP MR0 (LO);
SR=NORM MR0 (LO),AY0=SE;
SR=SR OR NORM MR1 (HI);
DM(alp_h)=SR1;
SR=LSHIFT SR0 BY -1(LO);
DM(alp_l)=SR0;
AR=AR+1;
SR0=DM(alp_exp);
AR=SR0-AY0,SI=AR;
DM(alp_exp)=AR;
{-----------A[j] = An[j]---------------}
// CNTR=SI;
I4=^Al+1;
I5=^Ah+1;
I2=^Anl+1;
I3=^Anh+1;
CNTR=SI;
DO copy_anhl UNTIL CE;
AR=DM(I2,M1);
DM(I4,M4)=AR;
AR=DM(I3,M1);
copy_anhl: DM(I5,M4)=AR;
I2=AX0;
I3=AX1;
MODIFY(I4,M7);
levinson_loop: MODIFY(I5,M7);
{---------Truncate A[i] in Q27 to Q12 with rounding----------}
I4=^Al+1;
I5=^Ah+1;
// CNTR=M;
I1=^old_A+1;
DM(I0,M1)=4096;
SR0=DM(I4,M4);
CNTR=M;
DO calc_A UNTIL CE;
AR=DM(I5,M4);
SR=LSHIFT SR0 BY 2(LO);
SR=SR OR ASHIFT AR BY 1(HI);
AR=SR0+H#8000;
AR=SR1+C,SR0=DM(I4,M4);
DM(I0,M1)=AR;
calc_A: DM(I1,M1)=AR;
I1=DM(rc);
I2=^old_rc;
AR=DM(I1,M1);
DM(I2,M1)=AR;
AR=DM(I1,M1);
AX0=DM(alp_exp);
AR=-AX0,DM(I2,M1)=AR;
SE=AR;
SR0=DM(alp_h);
SR=ASHIFT SR0 (LO);
RTS;
/**************************************************************************
* procedure Az_lsp: *
* Compute the LSPs from the LPC coefficients (order=10) *
* $$01/10/2000 used only in encoder and decoder *
* $$01/11/2000 modify pointer and varaibles to adapt table change *
* Calling Parameters *
* I1 : Q12 predictor coefficients (+1) *
* I2 : Q12 predictor coefficients (+M) *
* I3 : old lsp[] (in case not found 10 roots) *
* Return Values *
* I0 : Q15 line spectral pairs *
* Altered Registers: MR,SR,AR,AF,AX0,AX1,AY0,AY1,MX0,MX1,MY0,MY1 *
* Computation Time : 18 cycles *
***************************************************************************/
.ENTRY Az_lsp;
.VAR/DM/RAM/SEG=App_DMbuf f1[M_2+1], f2[M_2+1];
.VAR/DM/RAM/SEG=App_DMtmp nf, ip, ylow, xhigh, yhigh;
/*-------------------------------------------------------------*
* find the sum and diff. pol. F1(z) and F2(z) *
* F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) *
* f1[0] = 1.0; *
* f2[0] = 1.0; *
* for (i = 0; i< NC; i++) *
* f1[i+1] = a[i+1] + a[M-i] - f1[i] ; *
* f2[i+1] = a[i+1] - a[M-i] + f2[i] ; *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -