Пример #1
0
/***************************************************************************
 *   FUNCTION: cod_amr
 *
 *   PURPOSE:  Main encoder routine.
 *
 *   DESCRIPTION: This function is called every 20 ms speech frame,
 *       operating on the newly read 160 speech samples. It performs the
 *       principle encoding functions to produce the set of encoded parameters
 *       which include the LSP, adaptive codebook, and fixed codebook
 *       quantization indices (addresses and gains).
 *
 *   INPUTS:
 *       No input argument are passed to this function. However, before
 *       calling this function, 160 new speech data should be copied to the
 *       vector new_speech[]. This is a global pointer which is declared in
 *       this file (it points to the end of speech buffer minus 160).
 *
 *   OUTPUTS:
 *
 *       ana[]:     vector of analysis parameters.
 *       synth[]:   Local synthesis speech (for debugging purposes)
 *
 ***************************************************************************/
int cod_amr(
    cod_amrState *st,          /* i/o : State struct                   */
    enum Mode mode,            /* i   : AMR mode                       */
    Word16 new_speech[],       /* i   : speech input (L_FRAME)         */
    Word16 ana[],              /* o   : Analysis parameters            */
    enum Mode *usedMode,       /* o   : used mode                    */
    Word16 synth[]             /* o   : Local synthesis                */
)
{
   /* LPC coefficients */
   Word16 A_t[(MP1) * 4];      /* A(z) unquantized for the 4 subframes */
   Word16 Aq_t[(MP1) * 4];     /* A(z)   quantized for the 4 subframes */
   Word16 *A, *Aq;             /* Pointer on A_t and Aq_t              */
   Word16 lsp_new[M];
   
   /* Other vectors */
   Word16 xn[L_SUBFR];         /* Target vector for pitch search       */
   Word16 xn2[L_SUBFR];        /* Target vector for codebook search    */
   Word16 code[L_SUBFR];       /* Fixed codebook excitation            */
   Word16 y1[L_SUBFR];         /* Filtered adaptive excitation         */
   Word16 y2[L_SUBFR];         /* Filtered fixed codebook excitation   */
   Word16 gCoeff[6];           /* Correlations between xn, y1, & y2:   */
   Word16 res[L_SUBFR];        /* Short term (LPC) prediction residual */
   Word16 res2[L_SUBFR];       /* Long term (LTP) prediction residual  */

   /* Vector and scalars needed for the MR475 */
   Word16 xn_sf0[L_SUBFR];     /* Target vector for pitch search       */
   Word16 y2_sf0[L_SUBFR];     /* Filtered codebook innovation         */   
   Word16 code_sf0[L_SUBFR];   /* Fixed codebook excitation            */
   Word16 h1_sf0[L_SUBFR];     /* The impulse response of sf0          */
   Word16 mem_syn_save[M];     /* Filter memory                        */
   Word16 mem_w0_save[M];      /* Filter memory                        */
   Word16 mem_err_save[M];     /* Filter memory                        */
   Word16 sharp_save;          /* Sharpening                           */
   Word16 evenSubfr;           /* Even subframe indicator              */ 
   Word16 T0_sf0 = 0;          /* Integer pitch lag of sf0             */  
   Word16 T0_frac_sf0 = 0;     /* Fractional pitch lag of sf0          */  
   Word16 i_subfr_sf0 = 0;     /* Position in exc[] for sf0            */
   Word16 gain_pit_sf0;        /* Quantized pitch gain for sf0         */
   Word16 gain_code_sf0;       /* Quantized codebook gain for sf0      */
    
   /* Scalars */
   Word16 i_subfr, subfrNr;
   Word16 T_op[L_FRAME/L_FRAME_BY2];
   Word16 T0, T0_frac;
   Word16 gain_pit, gain_code;

   /* Flags */
   Word16 lsp_flag = 0;        /* indicates resonance in LPC filter */   
   Word16 gp_limit;            /* pitch gain limit value            */
   Word16 vad_flag;            /* VAD decision flag                 */
   Word16 compute_sid_flag;    /* SID analysis  flag                 */

   Copy(new_speech, st->new_speech, L_FRAME);

   *usedMode = mode;                     move16 ();

   /* DTX processing */
   if (st->dtx)
   {  /* no test() call since this if is only in simulation env */
      /* Find VAD decision */

#ifdef  VAD2
      vad_flag = vad2 (st->new_speech,    st->vadSt);
      vad_flag = vad2 (st->new_speech+80, st->vadSt) || vad_flag;      logic16();
#else
      vad_flag = vad1(st->vadSt, st->new_speech);     
#endif
      fwc ();                 /* function worst case */

      /* NB! usedMode may change here */
      compute_sid_flag = tx_dtx_handler(st->dtx_encSt,
                                        vad_flag, 
                                        usedMode);
   }
   else 
   {
      compute_sid_flag = 0;              move16 ();
   }
   
   /*------------------------------------------------------------------------*
    *  - Perform LPC analysis:                                               *
    *       * autocorrelation + lag windowing                                *
    *       * Levinson-durbin algorithm to find a[]                          *
    *       * convert a[] to lsp[]                                           *
    *       * quantize and code the LSPs                                     *
    *       * find the interpolated LSPs and convert to a[] for all          *
    *         subframes (both quantized and unquantized)                     *
    *------------------------------------------------------------------------*/
   
   /* LP analysis */
   lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t);

   fwc ();                 /* function worst case */

   /* From A(z) to lsp. LSP quantization and interpolation */
   lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana);
   
   fwc ();                 /* function worst case */

   /* Buffer lsp's and energy */
   dtx_buffer(st->dtx_encSt,
	      lsp_new,
	      st->new_speech);

   /* Check if in DTX mode */
   test();
   if (sub(*usedMode, MRDTX) == 0)
   {
      dtx_enc(st->dtx_encSt,
              compute_sid_flag,
              st->lspSt->qSt, 
              st->gainQuantSt->gc_predSt,
              &ana);
      
      Set_zero(st->old_exc,    PIT_MAX + L_INTERPOL);
      Set_zero(st->mem_w0,     M);
      Set_zero(st->mem_err,    M);
      Set_zero(st->zero,       L_SUBFR);
      Set_zero(st->hvec,       L_SUBFR);    /* set to zero "h1[-L_SUBFR..-1]" */
      /* Reset lsp states */
      lsp_reset(st->lspSt);
      Copy(lsp_new, st->lspSt->lsp_old, M);
      Copy(lsp_new, st->lspSt->lsp_old_q, M);
      
      /* Reset clLtp states */
      cl_ltp_reset(st->clLtpSt);
      st->sharp = SHARPMIN;       move16 ();
   }
   else
   {
       /* check resonance in the filter */
      lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old);  move16 ();
   }
   
   /*----------------------------------------------------------------------*
    * - Find the weighted input speech w_sp[] for the whole speech frame   *
    * - Find the open-loop pitch delay for first 2 subframes               *
    * - Set the range for searching closed-loop pitch in 1st subframe      *
    * - Find the open-loop pitch delay for last 2 subframes                *
    *----------------------------------------------------------------------*/

#ifdef VAD2
   if (st->dtx)
   {  /* no test() call since this if is only in simulation env */
       st->vadSt->L_Rmax = 0;			move32 ();
       st->vadSt->L_R0 = 0;			move32 ();
   }
#endif
   for(subfrNr = 0, i_subfr = 0; 
       subfrNr < L_FRAME/L_FRAME_BY2; 
       subfrNr++, i_subfr += L_FRAME_BY2)
   {
      /* Pre-processing on 80 samples */
      pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech,
              st->mem_w, st->wsp);
    
      test (); test ();
      if ((sub(mode, MR475) != 0) && (sub(mode, MR515) != 0))
      {
         /* Find open loop pitch lag for two subframes */
         ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr],
                &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr,
                st->dtx);
      }
   }
   fwc ();                 /* function worst case */

   test (); test();
   if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0))
   {
      /* Find open loop pitch lag for ONE FRAME ONLY */
      /* search on 160 samples */
      
      ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0],
             st->old_lags, st->ol_gain_flg, 1, st->dtx);
      T_op[1] = T_op[0];                                     move16 ();
   }         
   fwc ();                 /* function worst case */
   
#ifdef VAD2
   if (st->dtx)
   {  /* no test() call since this if is only in simulation env */
      LTP_flag_update(st->vadSt, mode);
   }
#endif

#ifndef VAD2
   /* run VAD pitch detection */
   if (st->dtx)
   {  /* no test() call since this if is only in simulation env */
      vad_pitch_detection(st->vadSt, T_op);
   } 
#endif
   fwc ();                 /* function worst case */

   if (sub(*usedMode, MRDTX) == 0)
   {
      goto the_end;
   }
   
   /*------------------------------------------------------------------------*
    *          Loop for every subframe in the analysis frame                 *
    *------------------------------------------------------------------------*
    *  To find the pitch and innovation parameters. The subframe size is     *
    *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
    *     - find the weighted LPC coefficients                               *
    *     - find the LPC residual signal res[]                               *
    *     - compute the target signal for pitch search                       *
    *     - compute impulse response of weighted synthesis filter (h1[])     *
    *     - find the closed-loop pitch parameters                            *
    *     - encode the pitch dealy                                           *
    *     - update the impulse response h1[] by including fixed-gain pitch   *
    *     - find target vector for codebook search                           *
    *     - codebook search                                                  *
    *     - encode codebook address                                          *
    *     - VQ of pitch and codebook gains                                   *
    *     - find synthesis speech                                            *
    *     - update states of weighting filter                                *
    *------------------------------------------------------------------------*/

   A = A_t;      /* pointer to interpolated LPC parameters */
   Aq = Aq_t;    /* pointer to interpolated quantized LPC parameters */

   evenSubfr = 0;                                                  move16 ();
   subfrNr = -1;                                                   move16 ();
   for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
   {
      subfrNr = add(subfrNr, 1);
      evenSubfr = sub(1, evenSubfr);

      /* Save states for the MR475 mode */
      test(); test();
      if ((evenSubfr != 0) && (sub(*usedMode, MR475) == 0))
      {
         Copy(st->mem_syn, mem_syn_save, M);
         Copy(st->mem_w0, mem_w0_save, M);         
         Copy(st->mem_err, mem_err_save, M);         
         sharp_save = st->sharp;
      }
      
      /*-----------------------------------------------------------------*
       * - Preprocessing of subframe                                     *
       *-----------------------------------------------------------------*/
      test();
      if (sub(*usedMode, MR475) != 0)
      {
         subframePreProc(*usedMode, gamma1, gamma1_12k2,
                         gamma2, A, Aq, &st->speech[i_subfr],
                         st->mem_err, st->mem_w0, st->zero,
                         st->ai_zero, &st->exc[i_subfr],
                         st->h1, xn, res, st->error);
      }
      else
      { /* MR475 */
         subframePreProc(*usedMode, gamma1, gamma1_12k2, 
                         gamma2, A, Aq, &st->speech[i_subfr],
                         st->mem_err, mem_w0_save, st->zero,
                         st->ai_zero, &st->exc[i_subfr],
                         st->h1, xn, res, st->error);

         /* save impulse response (modified in cbsearch) */
         test ();
         if (evenSubfr != 0)
         {
             Copy (st->h1, h1_sf0, L_SUBFR);
         }
      }
      
      /* copy the LP residual (res2 is modified in the CL LTP search)    */
      Copy (res, res2, L_SUBFR);

      fwc ();                 /* function worst case */
    
      /*-----------------------------------------------------------------*
       * - Closed-loop LTP search                                        *
       *-----------------------------------------------------------------*/
      cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, 
             &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, 
             &T0, &T0_frac, &gain_pit, gCoeff, &ana,
             &gp_limit);

      /* update LTP lag history */
      move16 (); test(); test ();
      if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0))
      {
         st->old_lags[1] = T0;     move16 ();
      }
      
      move16 (); test(); test ();
      if ((sub(subfrNr, 3) == 0) && (st->ol_gain_flg[1] > 0))
      {
         st->old_lags[0] = T0;     move16 ();
      }      

      fwc ();                 /* function worst case */
      
      /*-----------------------------------------------------------------*
       * - Inovative codebook search (find index and gain)               *
       *-----------------------------------------------------------------*/
      cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, 
               code, y2, &ana, *usedMode, subfrNr);
      
      fwc ();                 /* function worst case */
    
      /*------------------------------------------------------*
       * - Quantization of gains.                             *
       *------------------------------------------------------*/
      gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code,
                xn, xn2,  y1, y2, gCoeff, evenSubfr, gp_limit,
                &gain_pit_sf0, &gain_code_sf0,
                &gain_pit, &gain_code, &ana);
      
      fwc ();                 /* function worst case */

      /* update gain history */
      update_gp_clipping(st->tonStabSt, gain_pit);
      
      test(); 
      if (sub(*usedMode, MR475) != 0)
      {
         /* Subframe Post Porcessing */
         subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                          gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn,
                          st->mem_err, st->mem_w0, st->exc, &st->sharp);
      }
      else
      {
         test();
         if (evenSubfr != 0)
         {
            i_subfr_sf0 = i_subfr;             move16 ();
            Copy(xn, xn_sf0, L_SUBFR);
            Copy(y2, y2_sf0, L_SUBFR);          
            Copy(code, code_sf0, L_SUBFR);
            T0_sf0 = T0;                       move16 ();
            T0_frac_sf0 = T0_frac;             move16 ();
            
            /* Subframe Post Porcessing */
            subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                             gain_code, Aq, synth, xn, code, y1, y2,
                             mem_syn_save, st->mem_err, mem_w0_save,
                             st->exc, &st->sharp);
            st->sharp = sharp_save;                         move16();
         }
         else
         {
            /* update both subframes for the MR475 */
            
            /* Restore states for the MR475 mode */
            Copy(mem_err_save, st->mem_err, M);         
            
            /* re-build excitation for sf 0 */
            Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0,
                         L_SUBFR, 1);
            Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR);
            
            Aq -= MP1;
            subframePostProc(st->speech, *usedMode, i_subfr_sf0,
                             gain_pit_sf0, gain_code_sf0, Aq,
                             synth, xn_sf0, code_sf0, y1, y2_sf0,
                             st->mem_syn, st->mem_err, st->mem_w0, st->exc,
                             &sharp_save); /* overwrites sharp_save */
            Aq += MP1;
            
            /* re-run pre-processing to get xn right (needed by postproc) */
            /* (this also reconstructs the unsharpened h1 for sf 1)       */
            subframePreProc(*usedMode, gamma1, gamma1_12k2,
                            gamma2, A, Aq, &st->speech[i_subfr],
                            st->mem_err, st->mem_w0, st->zero,
                            st->ai_zero, &st->exc[i_subfr],
                            st->h1, xn, res, st->error);
            
            /* re-build excitation sf 1 (changed if lag < L_SUBFR) */
            Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1);
            Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR);
            
            subframePostProc(st->speech, *usedMode, i_subfr, gain_pit,
                             gain_code, Aq, synth, xn, code, y1, y2,
                             st->mem_syn, st->mem_err, st->mem_w0,
                             st->exc, &st->sharp);
         }
      }      
               
      fwc ();                 /* function worst case */
          
      A += MP1;    /* interpolated LPC parameters for next subframe */
      Aq += MP1;
   }

   Copy(&st->old_exc[L_FRAME], &st->old_exc[0], PIT_MAX + L_INTERPOL);
   
the_end:
   
   /*--------------------------------------------------*
    * Update signal for next frame.                    *
    *--------------------------------------------------*/
   Copy(&st->old_wsp[L_FRAME], &st->old_wsp[0], PIT_MAX);
   
   Copy(&st->old_speech[L_FRAME], &st->old_speech[0], L_TOTAL - L_FRAME);

   fwc ();                 /* function worst case */
       
   return 0;
}
Пример #2
0
//*****************************************************************************
//transmition loop: grab 8KHz speech samples from Mike,
//resample, collect frame (540 in 67.5 mS), encode
//encrypt, modulate, play 48KHz baseband signal into Line
int tx(int job)
{
 int i,j;

 //loop 1: try to play unplayed samples
 job+=_playjit(); //the first try to play a tail of samples in buffer

 //loop 2: try to grab next 180 samples
 //check for number of grabbed samples
 if(spcnt<540) //we haven't enought samples for melpe encoder
 {
  i=soundgrab((char*)spraw, 180); //grab up to 180 samples
  if((i>0)&&(i<=180)) //if some samles was grabbed
  {
   //Since we are using different audio devices
   //on headset and line sides, the sampling rates of grabbing
   // and playing devices can slightly differ then 48/8 depends HW
   //so we must adjusts one of rates for synchronizing grabbing and playing processes
   //The line side is more sensitive (requirements for baseband is more hard)
   //That why we resamples grabbed stream (slave) for matching rate with playing stream as a master
   //The adjusting process doing approximation in iterative way
   //and requires several seconds for adaptation during possible loss of some speech 67.5mS frames

   //computes estimated rate depends recording delay obtained in moment of last block was modulated
   j=8000-(_fdelay-27000)/50; //computes samplerate using optimal delay and adjusting sensitivity
   if(j>9000) j=9000; //restrict resulting samplerate
   if(j<7000) j=7000;

   //change rate of grabbed samples for synchronizing grabbing and playing loops
   i=_resample(spraw, spbuf+spcnt, i, j); //resample and collect speech samples
   spcnt+=i; //the number of samples in buffer for processing
   tgrab+=i; //the total difference between grabbed speech and played baseband samples
                //this is actually recording delay and must be near 270 sample in average
                //for jitter protecting (due PC multi threading etc.)

   job+=32; //set job
  }
 }
 //check for we have enough grabbed samples for processing
 if(spcnt>=540) //we have enough samples for melpe encoder
 {
  if(Mute(0)>0)
  {
   i=vad2(spbuf+10, &vad);  //check frame is speech (by VAD)
   i+=vad2(spbuf+100,&vad);
   i+=vad2(spbuf+190,&vad);
   i+=vad2(spbuf+280,&vad);
   i+=vad2(spbuf+370,&vad);
   i+=vad2(spbuf+460,&vad);
  }
  else i=0;
  
  txbuf[11]=0xFF;   //set defaults flag for voiced frame
  if(i) //frame is voices: compress it
  {
   melpe_a(txbuf, spbuf); //encode the speech frame
   i=State(1); //set VAD flag
  }
  else //unvoiced frame: sync packet will be send
  {
   txbuf[11]=0xFE; //or set silence flag for control blocks
   i=State(-1); //clears VAD flag
  }

  spcnt-=540; //samples rest
  if(spcnt) memcpy((char*)spbuf, (char*)(spbuf+540), 2*spcnt);  //move tail to start of buffer
  job+=64;
 }

 //Loop 3: playing
//get number of unplayed samples in buffer 
 i=_getdelay();
//preventing of freezing audio output after underrun or overrun 
 if(i>540*3*6)
 {
  _soundflush1();
  i=_getdelay();
 }   
//check for delay is acceptable for playing next portion of samples 
 if(i<720*6) 
 {
  if(l__jit_buf) return job; //we have some unplayed samples in local buffer, not play now.
  MakePkt(txbuf); //encrypt voice or get actual control packet
  l__jit_buf=Modulate(txbuf, _jit_buf); //modulate block
  txbuf[11]=0; //clear tx buffer (processed)
  _playjit();  //immediately play baseband into Line
 
  //estimate rate changing for grabbed samples for synchronizing grabbing and playing
  _fdelay*=0.99; //smooth coefficient
  _fdelay+=tgrab;   //averages recording delay
  tgrab-=540;  //decrease counter of grabbed samples

  job+=128;
 }

 return job;
}