📄 pitchanal.dsp
字号:
/*-----------------------------------------------------------------*
* Compute correlation of target vector with impulse response. *
*-----------------------------------------------------------------*/
I0=^Dn;
I1=^Enc_xn;
I2=^Enc_h1;
CALL Cor_h_X;
/*-----------------------------------------------------------------*
* Find maximum integer delay. *
*-----------------------------------------------------------------*/
AX0=DM(Enc_T0min);
AY0=DM(Enc_T0max);
AR=AY0-AX0,SR1=AX0;
AR=AR+1;
// CNTR=AR;
AF=PASS AX0;
AY0=H#0000;
AY1=H#8000;
CNTR=AR;
DO find_maxdelay UNTIL CE;
AR=I6;
AR=AR-AF;
I1=AR;
I2=^Dn;
CNTR=SI;
CALL Dot_Product;
DIS AR_SAT;
AR=MR0-AY0,MX0=AY0;
ENA AR_SAT;
AR=MR1-AY1+C-1,AY0=AR;
NONE=PASS AR;
IF LT JUMP find_maxdelay;
NONE=AR OR AY0;
IF EQ JUMP find_maxdelay;
AR=PASS AF,AY1=MR1;
MX0=MR0;
SR1=AR;
find_maxdelay: AF=AF+1,AY0=MX0;
/*-----------------------------------------------------------------*
* Test fractions. *
*-----------------------------------------------------------------*/
/*---------Fraction 0------------*/
SR0=0;
I1=I6;
CNTR=SI;
CALL Pred_lt_3;
I1=^Dn;
I2=I6;
CNTR=SI;
CALL Dot_Product;
/* If first subframe and lag > 84 do not search fractional pitch */
AR=DM(Enc_subfr);
AR=PASS AR,MX1=SR0;
IF NE JUMP not_firstfr;
AY0=84;
AR=SR1-AY0,SR0=AR;
IF GT RTS;
not_firstfr: I1=I6;
// CNTR=SI;
I0=^exc_tmp;
CNTR=SI;
DO copy_exctmp UNTIL CE;
AR=DM(I1,M1);
copy_exctmp: DM(I0,M1)=AR;
AY1=MR0;
MY1=MR1;
/*-------Fraction -1/3------------*/
SR0=-1;
I1=I6;
CNTR=SI;
CALL Pred_lt_3;
I1=^Dn;
I2=I6;
CNTR=SI;
CALL Dot_Product;
DIS AR_SAT;
AR=MR0-AY1,AY0=MY1;
ENA AR_SAT;
AR=MR1-AY0+C-1,AY0=AR;
AR=PASS AR;
IF LT JUMP find_pitch_next;
NONE=AR OR AY0;
IF EQ JUMP find_pitch_next;
MX1=-1;
AY1=MR0;
MY1=MR1;
I1=I6;
// CNTR=SI;
I0=^exc_tmp;
CNTR=SI;
DO copy_tmpexc UNTIL CE;
AR=DM(I1,M1);
copy_tmpexc: DM(I0,M1)=AR;
find_pitch_next:
/*--------Fraction +1/3--------------*/
I1=I6;
SR0=1;
CNTR=SI;
CALL Pred_lt_3;
I2=I6;
I1=^Dn;
CNTR=SI;
CALL Dot_Product;
DIS AR_SAT;
AR=MR0-AY1,AY0=MY1;
ENA AR_SAT;
AR=MR1-AY0+C-1,AY0=AR;
IF LT JUMP restore;
AR=AR OR AY0;
IF NE RTS;
restore: //CNTR=SI;
SR0=MX1;
I1=^exc_tmp;
CNTR=SI;
DO restore_exc UNTIL CE;
AX0=DM(I1,M1);
restore_exc: DM(I6,M4)=AX0;
RTS;
/****************************************************************************
* Function G_pitch: *
* Compute correlations <xn,y1> and <y1,y1> to use in gains quantizer. *
* Also compute the gain of pitch. Result in Q14 *
* if (gain < 0) gain =0 *
* if (gain >1.2) gain =1.2 *
* $$01/10/2000 used only in encoder *
* Calling Parameters *
* I2 : Pitch target. *
* I1 : Filtered adaptive codebook. *
* I0 : Correlations need for gain quantization. *
* SI : Length of subframe. *
* Return Values *
* AR: Gain of pitch lag saturated to 1.2 *
* Altered Registers: MR,MF,SR,AR,AF,AX0,AX1,AY0,AY1,MX0,MY0,I1,I2,I3,I4,I5 *
* Computation Time : 18 cycles *
*****************************************************************************/
.ENTRY G_pitch;
.VAR/DM/RAM/SEG=App_DMbuf scaled_y1[L_SUBFR];
.VAR/DM/RAM/SEG=App_DMtmp xy, yy, exp_xy, exp_yy, gain;
G_pitch: SE=-2;
I3=I1;
// CNTR=SI;
I4=^scaled_y1;
AR=DM(I3,M1);
CNTR=SI;
/*----------divide "y1[]" by 4 to avoid overflow------*/
DO divide_signal UNTIL CE;
SR=ASHIFT AR (LO),AR=DM(I3,M1);
divide_signal: DM(I4,M4)=SR0;
/*----------Compute scalar product <y1[],y1[]>--------*/
MR0=1;
MR1=0;
I3=I1;
// CNTR=SI;
AF=PASS 0;
CNTR=SI;
DO mac_pitch UNTIL CE;
AR=DM(I3,M1);
MR=MR+AR*AR(SS);
IF MV AF=AF+1;
mac_pitch: IF MV SAT MR;
NONE=PASS AF;
IF NE JUMP round_pitch;
SE=EXP MR1(HI);
SE=EXP MR0(LO);
SR=NORM MR0(LO);
SR=SR OR NORM MR1(HI),AY0=SE;
AR=SR0+H#8000;
AR=SR1+C;
DM(yy)=AR;
AR=-AY0;
DM(exp_yy)=AR;
JUMP comp_scalar;
round_pitch: MR =0;
MR0=1;
// CNTR=SI;
I4=^scaled_y1;
CNTR=SI;
DO mac_scaled UNTIL CE;
AR=DM(I4,M4);
mac_scaled: IF NOT MV MR=MR+AR*AR(SS);
IF MV SAT MR;
SE=EXP MR1(HI);
SE=EXP MR0(LO);
SR=NORM MR0(LO),AY0=SE;
SR=SR OR NORM MR1(HI);
AR=SR0+H#8000;
AR=SR1+C;
DM(yy)=AR;
AX0=-4;
AR=AX0-AY0;
DM(exp_yy)=AR;
comp_scalar: MR=0;
I3=I2;
// CNTR=SI;
AF=PASS 0;
CNTR=SI;
/*--------Compute scalar product <xn[],y1[]>----------*/
DO mac_xny1 UNTIL CE;
MX0=DM(I1,M1);
MY0=DM(I3,M1);
MR=MR+MX0*MY0(SS);
IF MV AF=AF+1;
mac_xny1: IF MV SAT MR;
AF=PASS AF,AY0=MR0;
IF NE JUMP round_expxy;
AR=MR1 OR AY0;
IF EQ JUMP special_norm;
SE=EXP MR1(HI);
SE=EXP MR0(LO);
SR=NORM MR0(LO),AY0=SE;
SR=SR OR NORM MR1(HI);
AR=SR0+H#8000;
AR=SR1+C;
special_norm: DM(xy)=AR;
AR=-AY0;
DM(exp_xy)=AR;
JUMP calc_coeff;
round_expxy: MR=0;
// CNTR=SI;
I4=^scaled_y1;
CNTR=SI;
DO mac_xnscal UNTIL CE;
MX0=DM(I2,M1);
MY0=DM(I4,M4);
mac_xnscal: IF NOT MV MR=MR+MX0*MY0(SS);
IF MV SAT MR;
AY0=MR0;
AR=MR1 OR AY0;
IF EQ JUMP extrict_norm;
SE=EXP MR1(HI);
SE=EXP MR0(LO);
SR=NORM MR0(LO),AY0=SE;
SR=NORM MR1(HI);
AR=SR0+H#8000;
AR=SR1+C;
extrict_norm: DM(xy)=AR;
AX0=-2;
AR=AX0-AY0;
DM(exp_xy)=AR;
calc_coeff: AR=DM(yy);
AY0=DM(exp_yy);
AX0=15;
AR=AX0-AY0,DM(I0,M1)=AR;
DM(I0,M1)=AR;
AR=DM(xy);
AY0=DM(exp_xy);
AR=AX0-AY0,DM(I0,M1)=AR;
/*----------If (xy <= 0) gain = 0-------------*/
AX0=DM(xy);
AR=PASS AX0,DM(I0,M0)=AR;
IF GT JUMP compu_gain;
AR=PASS 0;
DM(I0,M1)=-15;
RTS;
/*----------compute gain = xy/yy--------------*/
compu_gain: SR0=DM(xy);
SR=ASHIFT SR0 BY -1(LO); /* Be sure xy < yy */
MR0=SR0;
MR1=SR1;
SR0=DM(yy);
SR=ASHIFT SR0 BY 0(LO);
CALL div_s;
/*----------if(gain >1.2) gain = 1.2 in Q14---------*/
AX0=DM(exp_xy);
AY0=DM(exp_yy);
AR=AY0-AX0,MR0=AR;
IF LE JUMP direc_shift;
NONE=PASS MR0;
IF EQ JUMP direc_shift;
SE=EXP MR0(HI);
AY0=SE;
NONE=AR+AY0;
IF LE JUMP direc_shift;
AR=H#8000;
NONE=PASS MR0;
IF GT AR =-AR;
SR0=AR;
JUMP comm_shift;
direc_shift: SE=AR;
SR=ASHIFT MR0 (LO);
comm_shift: AY0=19661;
AF=SR0-AY0,AR=SR0;
IF GT AR=PASS AY0;
RTS;
/****************************************************************************
* Encoding of fractional pitch lag with 1/3 resolution. *
* The pitch range for the first subframe is divided as follows: *
* 19 1/3 to 84 2/3 resolution 1/3 *
* 85 to 143 resolution 1 *
* The period in the first subframe is encoded with 8 bits. *
* For the range with fractions: *
* index = (T-19)*3 + frac - 1; where T=[19..85] and frac=[-1,0,1] *
* and for the integer only range *
* index = (T - 85) + 197; where T=[86..143] *
* For the second subframe a resolution of 1/3 is always used, and the *
* search range is relative to the lag in the first subframe. *
* If t0 is the lag in the first subframe then *
* t_min=t0-5 and t_max=t0+4 and the range is given by *
* t_min - 2/3 to t_max + 2/3 *
* The period in the 2nd subframe is encoded with 5 bits: *
* index = (T-(t_min-1))*3 + frac - 1; where T[t_min-1 .. t_max+1] *
* $$01/10/2000 used only in encoder *
* Calling Parameters *
* SR0 : Fractional pitch delay *
* SR1 : Pitch delay *
* Enc_T0min: Minimum search delay *
* Enc_T0max: Maximum search delay *
* AY0 : Minimum pitch delay *
* AY1 : Maximum pitch delay *
* AR : Flag for 1st subframe *
* Return Values *
* AR : Return index of encoding *
* Altered Registers: MR,SR,AR,AF,AY0,AY1 *
* Computation Time : 18 cycles *
*****************************************************************************/
.ENTRY Enc_lag3;
Enc_lag3: AR=PASS AR; /* if 1st subframe */
IF NE JUMP sec2_frame;
/*--------find Enc_T0min and Enc_T0max for second subframe---*/
AR=SR1-5;
AF=AR-AY0;
IF LT AR=PASS AY0;
DM(Enc_T0min)=AR;
AR=AR+9;
DM(Enc_T0max)=AR;
AF=AR-AY1,AR=AY1;
IF LE JUMP encode_pitch;
DM(Enc_T0max)=AY1;
AR=AR-9;
DM(Enc_T0min)=AR;
/*---------encode pitch delay (with fraction)-----------*/
encode_pitch: AY0=112;
AR=SR1+AY0;
AY0=85;
AF=SR1-AY0,AY1=SR1;
IF GT RTS;
/*---------index = t0*3 - 58 + t0_frac------------------*/
AY0=58;
AF=SR1+AY1;
AR=SR0+AF;
AR=AR+AY1;
AR=AR-AY0;
RTS;
sec2_frame: AY0=DM(Enc_T0min);/* if second subframe */
/*---------i = t0 - t0_min-----------------------*/
/*---------index = i*3 + 2 + t0_frac-------------*/
AF=SR1-AY0;
AR=SR0+AF;
AR=AR+AF;
AR=AR+AF;
AR=AR+2;
RTS;
/****************************************************************************/
.ENDMOD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -