⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pitchanal.dsp

📁 基于ADSP的G.729语音编解码程序
💻 DSP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
* 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 + -