📄 pitchanal.dsp
字号:
/***************************************************************************
* Pitch related functions *
* $$01/10/2000 checked pitch coder 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 PitchAnal;
/***************************************************************************/
#include "ld8a.inc"
#include "tab_ld8a.inc"
/***************************************************************************/
.EXTERNAL Enc_xn,Enc_h1,Enc_subfr;
.EXTERNAL Enc_T0min,Enc_T0max;
.EXTERNAL div_s;
.EXTERNAL Inv_sqrt;
.EXTERNAL Pred_lt_3;
.EXTERNAL Cor_h_X;
/****************************************************************************
* Function Pitch_ol_fast *
* Compute the open loop pitch lag. (fast version) *
* $$01/10/2000 used only in encoder *
* Calling Parameters *
* I1 : signal used to compute the open loop pitch (-pit_max) *
* AY1 : maximum pitch lag *
* AX1 : length of frame to compute pitch (L_frame/2) *
* SI : maximum pitch lag (L_frame+pit_max) *
* Return Values *
* AR : open loop pitch lag *
* Altered Registers: MR,SR,SE,AR,I0,I1,I2,I3,AY0,MY0 *
* Computation Time : 18 cycles *
*****************************************************************************/
.ENTRY Pitch_ol_fast;
.VAR/DM/RAM/SEG=App_DMbuf scaled_signal[L_FRAME+PIT_MAX];
.VAR/DM/RAM/SEG=App_DMtmp Enc_T1,Enc_T2,Enc_T3,max1,max2;
Pitch_ol_fast: MR=0;
M3=2;
I2=I1;
I0=^scaled_signal;
AR=^scaled_signal;
AR=AR+AY1;
I3=AR;
AF=PASS 0;
SR=ASHIFT SI BY -1(HI);
AR=SR0+H#8000;
AR=SR1+C;
CNTR=AR;
/*--------------------------------------------------------*
* Verification for risk of overflow. *
*--------------------------------------------------------*/
DO energy_sig UNTIL CE;
AR=DM(I2,M3);
MR=MR+AR*AR(SS);
IF MV AF=AF+1;
energy_sig: IF MV SAT MR;
/*--------------------------------------------------------*
* Scaling of input signal. *
* *
* if Overflow -> scal_sig[i] = signal[i]>>3 *
* else if sum < 1^20 -> scal_sig[i] = signal[i]<<3 *
* else -> scal_sig[i] = signal[i] *
*--------------------------------------------------------*/
NONE=PASS AF;
IF EQ JUMP normal_pitch;
CNTR=SI;
DO shr_scalsig UNTIL CE;
AR=DM(I1,M1);
SR=ASHIFT AR BY -3(LO);
shr_scalsig: DM(I0,M1)=SR0;
JUMP pitch_comm;
normal_pitch: AY0=H#0000;
AY1=H#0010;
AF=MR0-AY0;
AF=MR1-AY1+C-1;
NONE=PASS AF;
IF GE JUMP scalsig_lt;
CNTR=SI;
DO shl_signal UNTIL CE;
AR=DM(I1,M1);
SR=ASHIFT AR BY 3(LO);
shl_signal: DM(I0,M1)=SR0;
JUMP pitch_comm;
scalsig_lt: CNTR=SI;
DO shift_signal UNTIL CE;
AR=DM(I1,M1);
shift_signal: DM(I0,M1)=AR;
/*--------------------------------------------------------------------*
* The pitch lag search is divided in three sections. *
* Each section cannot have a pitch multiple. *
* We find a maximum for each section. *
* We compare the maxima of each section by favoring small lag. *
* First section: lag delay = 20 to 39 *
* Second section: lag delay = 40 to 79 *
* Third section: lag delay = 80 to 143 *
*--------------------------------------------------------------------*/
pitch_comm:
/*-------First section----------------*/
SR1=1;
AR=20;
CNTR=20;
CALL search_section;
DM(Enc_T1)=AX0;
DM(max1)=MR0;
/*-------Second section----------------*/
SR1=1;
AR=40;
CNTR=40;
CALL search_section;
DM(Enc_T2)=AX0;
DM(max2)=MR0;
/*------Third section----------------*/
SR1=2;
AR=80;
CNTR=32;
CALL search_section;
DM(Enc_T3)=AX0;
/*-------Test around max3-----------*/
M3=2;
MR=0;
AR=I3;
AF=AX0+1;
AR=AR-AF;
I2=AR;
I1=I3;
CNTR=AX1;
DO round_energy1 UNTIL CE;
MX0=DM(I1,M3);
MY0=DM(I2,M3);
round_energy1: IF NOT MV MR=MR+MX0*MY0(SS);
IF MV SAT MR;
DIS AR_SAT;
AR=MR0-AY0,SR0=AY0;
ENA AR_SAT;
AY0=AR,AR=MR1-AY1+C-1;
AR=PASS AR;
IF LT JUMP round_max1;
NONE=AR OR AY0;
IF EQ JUMP round_max1;
AR=PASS AF,AY1=MR1;
SR0=MR0;
DM(Enc_T3)=AR;
round_max1: MR=0,AY0=SR0;
AR=I3;
AF=AX0-1;
AR=AR-AF;
I2=AR;
I1=I3;
CNTR=AX1;
DO round_energy2 UNTIL CE;
MX0=DM(I1,M3);
MY0=DM(I2,M3);
round_energy2: IF NOT MV MR=MR+MX0*MY0(SS);
IF MV SAT MR;
DIS AR_SAT;
AR=MR0-AY0,SR0=AY0;
ENA AR_SAT;
AY0=AR,AR=MR1-AY1+C-1;
AR=PASS AR;
IF LT JUMP round_max2;
NONE=AR OR AY0;
IF EQ JUMP round_max2;
AR=PASS AF,AY1=MR1;
SR0=MR0;
DM(Enc_T3)=AR;
/*----------compute energy of maximum-----------*/
round_max2: SR=LSHIFT SR0 BY -1(LO);
AX0=DM(Enc_T3);
MR=0,MX0=SR0;
AF=PASS AX0;
MR0=1;
AR=I3;
AR=AR-AF,MY1=AY1;
I2=AR;
CNTR=AX1;
DO round_energy3 UNTIL CE;
AR=DM(I2,M3);
round_energy3: IF NOT MV MR=MR+AR*AR(SS);
IF MV SAT MR;
/*---------max1 = max/sqrt(energy)------------------*/
/*---------This result will always be on 16 bits----*/
CALL Inv_sqrt;
AR=PASS 1,MY0=MX0;
MR=SR1 * MY1(SS);
MF=SR1 * MY0(SS);
MR=MR+AR*MF(SS);
SR=LSHIFT SR0 BY -1(LO);
MF=SR0 * MY1(SS);
MR=MR+AR * MF(SS);
/*------------------------------------*
* Test for multiple. *
*------------------------------------*/
SR=ASHIFT MR0 BY -2(LO);
AX1=DM(max1);
AY1=DM(max2);
AX0=DM(Enc_T3);
AY0=DM(Enc_T2);
AR=AY0-AX0,MY1=AX0;
AR=AR+AY0,AX0=AY0;
AR=ABS AR,AY0=AR;
AR=AR-5;
IF GE JUMP judge_T2;
AR=SR0+AY1;
AY1=AR;
judge_T2: AR=AX0+AY0,MX1=MR0;
AR=ABS AR;
AY0=7;
AR=AR-AY0,AY0=AX0;
IF GE JUMP judge_T1;
AR=SR0+AY1;
AY1=AR;
judge_T1: AX0=DM(Enc_T1);
AF=AX0-AY0,SR1=AX0;
AR=AX0+AF,MX0=AY1;
AR=ABS AR,AY0=AR;
AR=AR-5;
MY0=6554;
IF GE JUMP judge_T0;
AF=PASS AX1;
MR=MX0 * MY0(SS);
AR=MR1+AF;
AX1=AR;
judge_T0: AR=AX0+AY0;
AR=ABS AR,MX0=AY1;
AY0=7;
AR=AR-AY0;
IF GE JUMP calc_maxima;
AF=PASS AX1;
MR=MX0 * MY0(SS);
AR=MR1+AF;
AX1=AR;
/*--------------------------------------------------------------------*
* Compare the 3 sections maxima. *
*--------------------------------------------------------------------*/
calc_maxima: AF=AX1-AY1,AR=SR1;
IF GE JUMP comp_maxima;
AX1=AY1;
AR=DM(Enc_T2);
comp_maxima: AF=PASS AX1,AX0=MX1;
AF=AF-AX0,AX1=MY1;
IF LT AR=PASS AX1;
RTS;
/*****************************************************************************
* Function search_section() *
* one of three section to search codebook *
* $$01/10/2000 used only in encoder *
* Calling Parameters *
* AX1 : search loop count *
* AR : start serach section *
* SR1 : control of sum energy *
* CNTR : Number of points in one section *
* Return Values *
* MR0 = searched maximum impose *
* AX0 = searched pitch period *
* Altered Registers: MR,SR,AR,AF,MX0,MY0,AX0,AX1,AY0,AY1,I1,I2,M1 *
* Computation Time : 18 cycles *
******************************************************************************/
search_section:
AY0=H#0000;
AY1=H#8000;
AF=PASS AR,AX0=AR;
DO find_max1 UNTIL CE;
AR=I3;
AR=AR-AF,MY1=AY1;
MR=0;
I2=AR;
I1=I3;
CNTR=AX1;
DO mac_energy1 UNTIL CE;
MX0=DM(I1,M3);
MY0=DM(I2,M3);
mac_energy1: IF NOT MV MR=MR+MX0*MY0(SS);
IF MV SAT MR;
DIS AR_SAT;
AR=MR0-AY0,SR0=AY0;
ENA AR_SAT;
AY0=AR,AR=MR1-AY1+C-1;
AR=PASS AR;
IF LT JUMP find_max1;
AR=AR OR AY0;
IF EQ JUMP find_max1;
AR=PASS AF,AY1=MR1;
SR0=MR0;
AX0=AR;
find_max1: AF=SR1+AF,AY0=SR0;
AR=SR1-1;
IF NE RTS;
/*---------compute energy of maximum---------*/
SR=LSHIFT SR0 BY -1(LO);
MR=0,MX0=SR0;
MR0=1;
AY0=I3;
AR=AY0-AX0,MY1=AY1;
I2=AR;
CNTR=AX1;
DO calc_energy1 UNTIL CE;
AR=DM(I2,M3);
calc_energy1: IF NOT MV MR=MR+AR*AR(SS);
IF MV SAT MR;
/*---------max1 = max/sqrt(energy)-----------------------*/
/*---------This result will always be on 16 bits !!------*/
CALL Inv_sqrt;
AR=PASS 1,MY0=MX0;
MR=SR1 * MY1(SS);
MF=SR1 * MY0(SS);
MR=MR+AR*MF(SS);
SR=LSHIFT SR0 BY -1(LO);
MF=SR0 * MY1(SS);
MR=MR+AR * MF(SS);
RTS;
/*****************************************************************************
* Function Dot_Product() *
* $$01/10/2000 used only in encoder *
* Calling Parameters *
* I1 : First vector. *
* I2 : Second vector. *
* CNTR : Number of point. *
* Return Values *
* MR0 = LSW of scalar product *
* MR1 = MSW of scalar product *
* Altered Registers: MR,AR,MY0,I1,I2,M1 *
* Computation Time : 18 cycles *
******************************************************************************/
Dot_Product: MR=0;
DO mac_dotproc UNTIL CE;
AR=DM(I1,M1);
MY0=DM(I2,M1);
mac_dotproc: IF NOT MV MR=MR+AR*MY0(SS);
IF MV SAT MR;
RTS;
/****************************************************************************
* Function Pitch_fr3_fast() *
* Fast version of the pitch close loop. *
* $$01/10/2000 used only in encoder *
* Calling Parameters *
* I6 : excitation buffer *
* Enc_xn : target vector *
* Enc_h1 : Q12 : impulse response of filters. *
* SI : Length of subframe *
* Enc_T0min: minimum value in the searched range. *
* Enc_T0max: maximum value in the searched range. *
* Enc_subfr: indicator for first subframe. *
* Return Values *
* SR0 : chosen fraction. *
* SR1 : pitch period. *
* Altered Registers: MR,AR,MY0,I1,I2,M1 *
* Computation Time : 18 cycles *
*****************************************************************************/
.ENTRY Pitch_fr3_fast;
.VAR/DM/RAM/SEG=App_DMtmp t0_eval;
.VAR/DM/RAM/SEG=App_DMbuf Dn[L_SUBFR];
.VAR/DM/RAM/SEG=App_DMbuf exc_tmp[L_SUBFR];
Pitch_fr3_fast:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -