Exemplo n.º 1
0
void LTP_flag_update (vadState2 * st, Word16 mode)
{
	Word16 thresh;
	Word16 hi1;
	Word16 lo1;
	Word32 Ltmp;

									test(); test();
	if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0))
	{
		thresh = (Word16)(32768.0*0.55);			move16();
	}
	else if (sub(mode, MR102) == 0)
	{
		thresh = (Word16)(32768.0*0.60);			move16();
	}
	else
	{
		thresh = (Word16)(32768.0*0.65);			move16();
	}

	L_Extract (st->L_R0, &hi1, &lo1);
	Ltmp = Mpy_32_16(hi1, lo1, thresh);				test();
	if (L_sub(st->L_Rmax, Ltmp) > 0)
	{
		st->LTP_flag = TRUE;					move16();
	}
	else
	{
		st->LTP_flag = FALSE;					move16();
	}

	return;
}
Exemplo n.º 2
0
Arquivo: common.c Projeto: VVer/opal
/***************************************************************************
 Function:    compute_raw_pow_categories

 Syntax:      void compute_raw_pow_categories(Word16 *power_categories,
                                              Word16 *rms_index,
                                              Word16 number_of_regions,
                                              Word16 offset)
              inputs:  *rms_index
                       number_of_regions
                       offset
                    
              outputs: *power_categories                    



 Description: This function computes the power categories given the offset
              This is kind of redundant since they were already computed
              in calc_offset to determine the offset.

 WMOPS:          |    24kbit    |     32kbit
          -------|--------------|----------------
            AVG  |    0.01      |     0.01
          -------|--------------|----------------  
            MAX  |    0.01      |     0.01
          -------|--------------|---------------- 

           14kHz |    24kbit    |     32kbit     |     48kbit
          -------|--------------|----------------|----------------
            AVG  |    0.01      |     0.01       |     0.01   
          -------|--------------|----------------|----------------
            MAX  |    0.01      |     0.01       |     0.01   
          -------|--------------|----------------|----------------

***************************************************************************/
void compute_raw_pow_categories(Word16 *power_categories,Word16 *rms_index,Word16 number_of_regions,Word16 offset)
{
    Word16 region;
    Word16 j;
    Word16 temp;

    for (region=0; region<number_of_regions; region++) 
    {
        j = sub(offset,rms_index[region]);
        j = shr(j,1);
        
        /* make sure j is between 0 and NUM_CAT-1 */
        test();
        if (j < 0) 
        {
            j = 0;
            move16();
        }
        temp = sub(j,(NUM_CATEGORIES-1));
        test();
        if (temp > 0) 
            j = sub(NUM_CATEGORIES,1);
        
        power_categories[region] = j;
        move16();
    }
}
Exemplo n.º 3
0
Word16 block_norm (Word16 * in, Word16 * out, Word16 length, Word16 headroom)
{

	Word16 i, max, scnt, adata;

        max = abs_s(in[0]);
	for (i = 1; i < length; i++)
	{
                adata = abs_s(in[i]);                           test();
		if (sub(adata, max) > 0)
		{
			max = adata;				move16();
		}
	}
	test();
	if (max != 0)
	{
		scnt = sub(norm_s(max), headroom);
		for (i = 0; i < length; i++)
		{
			out[i] = shl(in[i], scnt);	       	move16();
		}
	}
	else
	{
		scnt = sub(16, headroom);
		for (i = 0; i < length; i++)
		{
			out[i] = 0;                             move16();
		}
	}
	return (scnt);
}
Exemplo n.º 4
0
/*************************************************************************
 *
 *  FUNCTION  set_sign()
 *
 *  PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]".
 *           Also finds the position of maximum of correlation in each track
 *           and the starting position for each pulse.
 *
 *************************************************************************/
void set_sign(Word16 dn[],   /* i/o : correlation between target and h[]    */
              Word16 sign[], /* o   : sign of dn[]                          */
              Word16 dn2[],  /* o   : maximum of correlation in each track. */
              Word16 n       /* i   : # of maximum correlations in dn2[]    */
)
{
   Word16 i, j, k;
   Word16 val, min;
   Word16 pos = 0; /* initialization only needed to keep gcc silent */
   
   /* set sign according to dn[] */
   
   for (i = 0; i < L_CODE; i++) {
      val = dn[i];                                 move16 ();
      
      test ();
      if (val >= 0) {
         sign[i] = 32767;                          move16 ();
      } else {
         sign[i] = -32767;                         move16 ();
         val = negate(val);
      }
      dn[i] = val;    move16 (); /* modify dn[] according to the fixed sign */
      dn2[i] = val;   move16 ();
   }
   
   /* keep 8-n maximum positions/8 of each track and store it in dn2[] */
   
   for (i = 0; i < NB_TRACK; i++)
   {
      for (k = 0; k < (8-n); k++)
      {
         min = 0x7fff;                             move16 ();
         for (j = i; j < L_CODE; j += STEP)
         {
            test ();                               move16 ();
            if (dn2[j] >= 0)
            {
               val = sub(dn2[j], min);
               test ();
               if (val < 0)
               {
                  min = dn2[j];                    move16 ();
                  pos = j;                         move16 ();
               }
            }
         }
         dn2[pos] = -1;                            move16 ();
      }
   }
   
   return;
}
Exemplo n.º 5
0
/*
********************************************************************************
*                         PUBLIC PROGRAM CODE
********************************************************************************
*/
int pre_big(
    enum Mode mode,            /* i  : coder mode                             */
    const Word16 gamma1[],     /* i  : spectral exp. factor 1                 */
    const Word16 gamma1_12k2[],/* i  : spectral exp. factor 1 for EFR         */
    const Word16 gamma2[],     /* i  : spectral exp. factor 2                 */
    Word16 A_t[],              /* i  : A(z) unquantized, for 4 subframes, Q12 */
    Word16 frameOffset,        /* i  : Start position in speech vector,   Q0  */
    Word16 speech[],           /* i  : speech,                            Q0  */
    Word16 mem_w[],            /* i/o: synthesis filter memory state,     Q0  */
    Word16 wsp[]               /* o  : weighted speech                    Q0  */
)
{
   Word16 Ap1[MP1];            /* A(z) with spectral expansion         */
   Word16 Ap2[MP1];            /* A(z) with spectral expansion         */
   const Word16 *g1;           /* Pointer to correct gammma1 vector    */
   Word16 aOffset;
   Word16 i;
   
   test ();
   if (sub (mode, MR795) <= 0 )
   {
       g1 = gamma1;                          move16 ();
   }
   else
   {
       g1 = gamma1_12k2;                     move16 ();
   }

   test ();
   if (frameOffset > 0) {
      aOffset = 2*MP1;                       move16 ();
   }
   else {
      aOffset = 0;                           move16 ();
   }

   /* process two subframes (which form the "big" subframe) */
   for (i = 0; i < 2; i++)
   {
       Weight_Ai(&A_t[aOffset], g1, Ap1);
       Weight_Ai(&A_t[aOffset], gamma2, Ap2);
       Residu(Ap1, &speech[frameOffset], &wsp[frameOffset], L_SUBFR);
       
       Syn_filt(Ap2, &wsp[frameOffset], &wsp[frameOffset], L_SUBFR, mem_w, 1);
       aOffset = add (aOffset, MP1);
       frameOffset = add (frameOffset, L_SUBFR);
   }   

   return 0;
}
Exemplo n.º 6
0
/*
********************************************************************************
*                         PUBLIC PROGRAM CODE
********************************************************************************
*/
void Weight_Ai (
    Word16 a[],         /* (i)     : a[M+1]  LPC coefficients   (M=10)    */
    const Word16 fac[], /* (i)     : Spectral expansion factors.          */
    Word16 a_exp[]      /* (o)     : Spectral expanded LPC coefficients   */
)
{
    Word16 i;

    a_exp[0] = a[0];                                    move16 (); 
    for (i = 1; i <= M; i++)
    {
        a_exp[i] = round (L_mult (a[i], fac[i - 1]));   move16 (); 
    }

    return;
}
Exemplo n.º 7
0
int Speech_Encode_Frame_First (
    Speech_Encode_FrameState *st,  /* i/o : post filter states       */
    Word16 *new_speech)            /* i   : speech input             */
{
#if !defined(NO13BIT)
   Word16 i;
#endif

   setCounter(st->complexityCounter);

#if !defined(NO13BIT)
  /* Delete the 3 LSBs (13-bit input) */
  for (i = 0; i < L_NEXT; i++) 
  {
     new_speech[i] = new_speech[i] & 0xfff8;    move16 (); logic16 ();
  }
#endif

  /* filter + downscaling */
  Pre_Process (st->pre_state, new_speech, L_NEXT);

  cod_amr_first(st->cod_amr_state, new_speech);

  Init_WMOPS_counter (); /* reset WMOPS counter for the new frame */

  return 0;
}
Exemplo n.º 8
0
static void compress_code (
    Word16 sign_indx[], /* i : signs of 4 pulses (signs only)             */
    Word16 pos_indx[],  /* i : position index of 8 pulses (position only) */
    Word16 indx[])      /* o : position and sign of 8 pulses (compressed) */
{
   Word16 i, ia, ib, ic;

   for (i = 0; i < NB_TRACK_MR102; i++)
   {
      indx[i] = sign_indx[i];                            move16 (); 
   }
    
    /* First index 
      indx[NB_TRACK] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
   move16 (); 
   indx[NB_TRACK_MR102] = compress10(pos_indx[0],pos_indx[4],pos_indx[1]);

    /* Second index       
      indx[NB_TRACK+1] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
    
   move16 (); 
   indx[NB_TRACK_MR102+1]= compress10(pos_indx[2],pos_indx[6],pos_indx[5]);
    
    /*
      Third index      
      if ((ib/2)%2 == 1)
        indx[NB_TRACK+2] = ((((4-ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
      else   
        indx[NB_TRACK+2] = ((((ia/2) +   (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
        */
    
    ib = shr(pos_indx[7], 1) & 1;                        logic16 ();
    test ();
    if (sub(ib, 1) == 0)
       ia = sub(4, shr(pos_indx[3], 1));
    else
       ia = shr(pos_indx[3], 1);

    ib = extract_l(L_shr(L_mult(shr(pos_indx[7], 1), 5), 1));       
    ib = add(shl(add(ia, ib), 5), 12);
    ic = shl(mult(ib, 1311), 2);
    ia = pos_indx[3] & 1;                             logic16 ();
    ib = shl((pos_indx[7] & 1), 1);                   logic16 ();
    indx[NB_TRACK_MR102+2] = add(ia, add(ib, ic));
}
Exemplo n.º 9
0
int vad2_reset (vadState2 * st)
{
	Word16	i;
	Word16	*ptr;

	if (st == (vadState2 *) NULL){
		fprintf(stderr, "vad2_reset: invalid parameter\n");
		return -1;
	}
	ptr = (Word16 *)st;				move16();

	for (i = 0; i < sizeof(vadState2)/2; i++)
	{
		*ptr++ = 0;				move16();
	}

	return 0;
}						/* end of vad2_reset () */
Exemplo n.º 10
0
/*
**************************************************************************
*
*  Function    : Bin2int
*  Purpose     : Read "no_of_bits" bits from the array bitstream[] 
*                and convert to integer.
*
**************************************************************************
*/
static Word16 Bin2int ( /* Reconstructed parameter                      */
    Word16 no_of_bits,  /* input : number of bits associated with value */
    Word16 *bitstream   /* output: address where bits are written       */
)
{
    Word16 value, i, bit;

    value = 0;                                  move16 (); 
    for (i = 0; i < no_of_bits; i++)
    {
        value = shl (value, 1);
        bit = *bitstream++;                     move16 (); 
        test (); 
        if (sub (bit, BIT_1) == 0)
            value = add (value, 1);
    }
    return (value);
}
Exemplo n.º 11
0
void dtx_dec_activity_update(dtx_decState *st,
                             Word16 lsf[],
                             Word16 frame[])
{
   Word16 i;

   Word32 L_frame_en;
   Word16 log_en_e, log_en_m, log_en;

   /* update lsp history */
   st->lsf_hist_ptr = add(st->lsf_hist_ptr,M);                     move16();
   test();
   if (sub(st->lsf_hist_ptr, 80) == 0)
   {
      st->lsf_hist_ptr = 0;                                        move16();
   }
   Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M); 

   /* compute log energy based on frame energy */
   L_frame_en = 0;     /* Q0 */                                    move32();
   for (i=0; i < L_FRAME; i++)
   {
      L_frame_en = L_mac(L_frame_en, frame[i], frame[i]); 
   }
   Log2(L_frame_en, &log_en_e, &log_en_m);
   
   /* convert exponent and mantissa to Word16 Q10 */
   log_en = shl(log_en_e, 10);  /* Q10 */                          
   log_en = add(log_en, shr(log_en_m, 15-10));                      
   
   /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
   log_en = sub(log_en, 7497+1024);                                
   
   /* insert into log energy buffer, no division by two as  *
    * log_en in decoder is Q11                              */
   st->log_en_hist_ptr = add(st->log_en_hist_ptr, 1);
   test();
   if (sub(st->log_en_hist_ptr, DTX_HIST_SIZE) == 0)
   {
      st->log_en_hist_ptr = 0;                                     move16();
   }
   st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */        move16();
}
Exemplo n.º 12
0
/*
**************************************************************************
*
*  Function    : Int_lsf
*  Purpose     : Interpolates the LSFs for selected subframe
*  Description : The 20 ms speech frame is divided into 4 subframes.
*                The LSFs are interpolated at the 1st, 2nd and 3rd
*                subframe and only forwarded at the 4th subframe.
*
*                      |------|------|------|------|
*                         sf1    sf2    sf3    sf4
*                   F0                          F1
*      
*                 sf1:   3/4 F0 + 1/4 F1         sf3:   1/4 F0 + 3/4 F1
*                 sf2:   1/2 F0 + 1/2 F1         sf4:       F1
*  Returns     : void
*
**************************************************************************
*/
void Int_lsf(
    Word16 lsf_old[], /* i : LSF vector at the 4th SF of past frame          */
    Word16 lsf_new[], /* i : LSF vector at the 4th SF of present frame       */
    Word16 i_subfr,   /* i : Pointer to current sf (equal to 0,40,80 or 120) */
    Word16 lsf_out[]  /* o : interpolated LSF parameters for current sf      */
)
{
    Word16 i;

    if ( i_subfr == 0 )
    {
       test ();          
       for (i = 0; i < M; i++) {
          lsf_out[i] = add(sub(lsf_old[i], shr(lsf_old[i], 2)), shr(lsf_new[i], 2));
          move16 ();
       }
    }
    else if ( sub(i_subfr, 40) == 0 )
    {
       test (); test ();
       for (i = 0; i < M; i++) {
          lsf_out[i] = add(shr(lsf_old[i],1), shr(lsf_new[i], 1) );
          move16 ();
       }
    }
    else if ( sub(i_subfr, 80) == 0 )
    {
       test (); test (); test ();
       for (i = 0; i < M; i++) {
          lsf_out[i] = add(shr(lsf_old[i], 2), sub(lsf_new[i], shr(lsf_new[i], 2)));
          move16 ();
       }
    }
    else if ( sub(i_subfr, 120) == 0 )
    {
       test (); test (); test (); test ();                    
       for (i = 0; i < M; i++) {
          lsf_out[i] = lsf_new[i];                        move16 ();
       }
    }

    return;
}
Exemplo n.º 13
0
int Speech_Encode_Frame (
    Speech_Encode_FrameState *st, /* i/o : post filter states          */
    enum Mode mode,               /* i   : speech coder mode           */
    Word16 *new_speech,           /* i   : speech input                */
    Word16 *serial,               /* o   : serial bit stream           */
    enum Mode *usedMode           /* o   : used speech coder mode */
    )
{
  Word16 prm[MAX_PRM_SIZE];   /* Analysis parameters.                  */
  Word16 syn[L_FRAME];        /* Buffer for synthesis speech           */
  Word16 i;

  setCounter(st->complexityCounter);
  Reset_WMOPS_counter (); /* reset WMOPS counter for the new frame */

  /* initialize the serial output frame to zero */
  for (i = 0; i < MAX_SERIAL_SIZE; i++)   
  {
    serial[i] = 0;                                           move16 ();
  }

#if !defined(NO13BIT)
  /* Delete the 3 LSBs (13-bit input) */
  for (i = 0; i < L_FRAME; i++)   
  {
     new_speech[i] = new_speech[i] & 0xfff8;    move16 (); logic16 ();
  }
#endif

  /* filter + downscaling */
  Pre_Process (st->pre_state, new_speech, L_FRAME);           
  
  /* Call the speech encoder */
  cod_amr(st->cod_amr_state, mode, new_speech, prm, usedMode, syn);
  
  /* Parameters to serial bits */
  Prm2bits (*usedMode, prm, &serial[0]); 

  fwc();
  setCounter(0); /* set counter to global counter */

  return 0;
}
Exemplo n.º 14
0
/*
**************************************************************************
*
*  Function    : Bits2prm
*  Purpose     : Retrieves the vector of encoder parameters from 
*                the received serial bits in a frame.
*
**************************************************************************
*/
void Bits2prm (
    enum Mode mode,     /* i : AMR mode                                    */
    Word16 bits[],      /* i : serial bits       (size <= MAX_SERIAL_SIZE) */
    Word16 prm[]        /* o : analysis parameters  (size <= MAX_PRM_SIZE) */
)
{
    Word16 i;

    move16();           /* account for pointer init (bitno[mode])  */
    
    for (i = 0; i < prmno[mode]; i++)
    {
        prm[i] = Bin2int (bitno[mode][i], bits);      move16 (); 
        bits += bitno[mode][i];
        add(0,0);       /* account for above pointer update  */
    }
    
   return;
}
Exemplo n.º 15
0
/*************************************************************************
 *
 *  FUNCTION:  Reorder_lsf()
 *
 *  PURPOSE: To make sure that the LSFs are properly ordered and to keep a
 *           certain minimum distance between adjacent LSFs.
 *
 *           The LSFs are in the frequency range 0-0.5 and represented in Q15
 *
 *************************************************************************/
void Reorder_lsf (
    Word16 *lsf,        /* (i/o)     : vector of LSFs   (range: 0<=val<=0.5) */
    Word16 min_dist,    /* (i)       : minimum required distance             */
    Word16 n            /* (i)       : LPC order                             */
)
{
    Word16 i;
    Word16 lsf_min;

    lsf_min = min_dist;         move16 (); 
    for (i = 0; i < n; i++)
    {
        test (); 
        if (sub (lsf[i], lsf_min) < 0)
        {
            lsf[i] = lsf_min;   move16 (); 
        }
        lsf_min = add (lsf[i], min_dist);
    }
}
Exemplo n.º 16
0
/*************************************************************************
 *
 * FUNCTION:  gc_pred_update()
 *
 * PURPOSE: update MA predictor with last quantized energy
 *
 *************************************************************************/
void gc_pred_update(
    gc_predState *st,      /* i/o: State struct                     */
    Word16 qua_ener_MR122, /* i  : quantized energy for update, Q10 */
                           /*      (log2(qua_err))                  */
    Word16 qua_ener        /* i  : quantized energy for update, Q10 */
                           /*      (20*log10(qua_err))              */
)
{
    Word16 i;

    for (i = 3; i > 0; i--)
    {
        st->past_qua_en[i] = st->past_qua_en[i - 1];             move16 ();
        st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1]; move16 ();
    }

    st->past_qua_en_MR122[0] = qua_ener_MR122;  /*    log2 (qua_err), Q10 */
	                                                             move16 ();
    st->past_qua_en[0] = qua_ener;              /* 20*log10(qua_err), Q10 */
	                                                             move16 ();
}
Exemplo n.º 17
0
void Lsf_wt (
    Word16 *lsf,         /* input : LSF vector                  */
    Word16 *wf)          /* output: square of weighting factors */
{
    Word16 temp;
    Word16 i;
    /* wf[0] = lsf[1] - 0  */
    wf[0] = lsf[1];                                     move16 (); 
    for (i = 1; i < 9; i++)
    {
        wf[i] = sub (lsf[i + 1], lsf[i - 1]);           move16 (); 
    }
    /* wf[9] = 0.5 - lsf[8] */    
    wf[9] = sub (16384, lsf[8]);move16 ();      

    for (i = 0; i < 10; i++)
    {
        temp = sub (wf[i], 1843);
        test (); 
        if (temp < 0)
        {
            wf[i] = sub (3427, mult (wf[i], 28160));    move16 (); 
        }
        else
        {
            wf[i] = sub (1843, mult (temp, 6242));      move16 (); 
        }

        wf[i] = shl (wf[i], 3); move16 (); 
    }
    return;
}
Exemplo n.º 18
0
static Word16 Vq_subvec (/* o : quantization index,            Q0  */
    Word16 *lsf_r1,      /* i : 1st LSF residual vector,       Q15 */
    Word16 *lsf_r2,      /* i : 2nd LSF residual vector,       Q15 */
    const Word16 *dico,  /* i : quantization codebook,         Q15 */
    Word16 *wf1,         /* i : 1st LSF weighting factors      Q13 */
    Word16 *wf2,         /* i : 2nd LSF weighting factors      Q13 */  
    Word16 dico_size     /* i : size of quantization codebook, Q0  */
)
{
    Word16 index = 0; /* initialization only needed to keep gcc silent */
    Word16 i, temp;
    const Word16 *p_dico;
    Word32 dist_min, dist;

    dist_min = MAX_32;                                  move32 (); 
    p_dico = dico;                                      move16 (); 

    for (i = 0; i < dico_size; i++)
    {
        temp = sub (lsf_r1[0], *p_dico++);
        temp = mult (wf1[0], temp);
        dist = L_mult (temp, temp);

        temp = sub (lsf_r1[1], *p_dico++);
        temp = mult (wf1[1], temp);
        dist = L_mac (dist, temp, temp);

        temp = sub (lsf_r2[0], *p_dico++);
        temp = mult (wf2[0], temp);
        dist = L_mac (dist, temp, temp);

        temp = sub (lsf_r2[1], *p_dico++);
        temp = mult (wf2[1], temp);
        dist = L_mac (dist, temp, temp);

        test (); 
        if (L_sub (dist, dist_min) < (Word32) 0)
        {
            dist_min = dist;                            move32 (); 
            index = i;                                  move16 (); 
        }
    }

    /* Reading the selected vector */

    p_dico = &dico[shl (index, 2)];                     move16 (); 
    lsf_r1[0] = *p_dico++;                              move16 (); 
    lsf_r1[1] = *p_dico++;                              move16 (); 
    lsf_r2[0] = *p_dico++;                              move16 (); 
    lsf_r2[1] = *p_dico++;                              move16 (); 

    return index;

}
Exemplo n.º 19
0
/*************************************************************************
 *
 * FUNCTION:  gc_pred_average_limited()
 *
 * PURPOSE: get average of MA predictor state values (with a lower limit)
 *          [used in error concealment]
 *
 *************************************************************************/
void gc_pred_average_limited(
    gc_predState *st,       /* i: State struct                    */
    Word16 *ener_avg_MR122, /* o: everaged quantized energy,  Q10 */
    /*    (log2(qua_err))                 */
    Word16 *ener_avg        /* o: averaged quantized energy,  Q10 */
    /*    (20*log10(qua_err))             */
)
{
    Word16 av_pred_en;
    Word16 i;

    /* do average in MR122 mode (log2() domain) */
    av_pred_en = 0;
    move16 ();
    for (i = 0; i < NPRED; i++)
    {
        av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]);
    }

    /* av_pred_en = 0.25*av_pred_en */
    av_pred_en = mult (av_pred_en, 8192);

    /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
    test ();
    if (sub (av_pred_en, MIN_ENERGY_MR122) < 0)
    {
        av_pred_en = MIN_ENERGY_MR122;
        move16 ();
    }
    *ener_avg_MR122 = av_pred_en;
    move16 ();

    /* do average for other modes (20*log10() domain) */
    av_pred_en = 0;
    move16 ();
    for (i = 0; i < NPRED; i++)
    {
        av_pred_en = add (av_pred_en, st->past_qua_en[i]);
    }

    /* av_pred_en = 0.25*av_pred_en */
    av_pred_en = mult (av_pred_en, 8192);

    /* if (av_pred_en < -14) av_pred_en = .. */
    test ();
    if (sub (av_pred_en, MIN_ENERGY) < 0)
    {
        av_pred_en = MIN_ENERGY;
        move16 ();
    }
    *ener_avg = av_pred_en;
    move16 ();
}
Exemplo n.º 20
0
Word16 gmed_n (   /* o : index of the median value (0...N-1)      */
    Word16 ind[], /* i : Past gain values                         */
    Word16 n      /* i : The number of gains; this routine        */
    /*     is only valid for a odd number of gains  */
    /*     (n <= NMAX)                              */
)
{
    Word16 i, j, ix = 0;
    Word16 max;
    Word16 medianIndex;
    Word16 tmp[NMAX];
    Word16 tmp2[NMAX];

    for (i = 0; i < n; i++)
    {
        tmp2[i] = ind[i];
        move16 ();
    }

    for (i = 0; i < n; i++)
    {
        max = -32767;
        move16 ();
        for (j = 0; j < n; j++)
        {
            test ();
            if (sub (tmp2[j], max) >= 0)
            {
                max = tmp2[j];
                move16 ();
                ix = j;
                move16 ();
            }
        }
        tmp2[ix] = -32768;
        move16 ();
        tmp[i] = ix;
        move16 ();
    }

    medianIndex=tmp[ shr(n,1) ];
    move16 (); /* account for complex addressing */
    return (ind[medianIndex]);
}
Exemplo n.º 21
0
/*************************************************************************
 *
 * FUNCTION: calc_target_energy
 *
 * PURPOSE:  calculation of target energy
 *
 *      en = <xn, xn>
 *
 *************************************************************************/
void
calc_target_energy(
    Word16 xn[],     /* i: LTP target vector,                       Q0  */
    Word16 *en_exp,  /* o: optimum codebook gain (exponent part),   Q0  */
    Word16 *en_frac  /* o: optimum codebook gain (fraction part),   Q15 */
)
{
    Word32 s;
    Word16 i, exp;

    /* Compute scalar product <xn[], xn[]> */
    s = L_mac(0L, xn[0], xn[0]);
    for (i = 1; i < L_SUBFR; i++)
        s = L_mac(s, xn[i], xn[i]);

    /* s = SUM 2*xn(i) * xn(i) = <xn xn> * 2 */
    exp = norm_l(s);
    *en_frac = extract_h(L_shl(s, exp));
    *en_exp = sub(16, exp);    move16();
}
Exemplo n.º 22
0
/***************************************************************************
 Function:    adjust_abs_region_power_index

 Syntax:      adjust_abs_region_power_index(Word16 *absolute_region_power_index,
                                            Word16 *mlt_coefs,
                                            Word16 number_of_regions)

              inputs:   *mlt_coefs
                        *absolute_region_power_index
                        number_of_regions
            
              outputs:  *absolute_region_power_index
 
 Description: Adjusts the absolute power index
 
 
 WMOPS:     7kHz |    24kbit    |      32kbit
          -------|--------------|----------------
            AVG  |    0.03      |      0.03
          -------|--------------|----------------  
            MAX  |    0.12      |      0.12
          -------|--------------|---------------- 

           14kHz |    24kbit    |     32kbit     |     48kbit
          -------|--------------|----------------|----------------
            AVG  |    0.03      |     0.03       |     0.03
          -------|--------------|----------------|----------------
            MAX  |    0.14      |     0.14       |     0.14
          -------|--------------|----------------|----------------

***************************************************************************/
void adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions)
{
    Word16 n,i;
    Word16 region;
    Word16 *raw_mlt_ptr;
    
    Word32 acca;
    Word16 temp;

    for (region=0; region<number_of_regions; region++)
    {
        n = sub(absolute_region_power_index[region],39);
        n = shr_nocheck(n,1);
        
        test();
        if (n > 0)
        {
            temp = extract_l(L_mult0(region,REGION_SIZE));

            raw_mlt_ptr = &mlt_coefs[temp];

            for (i=0; i<REGION_SIZE; i++)
            {
                acca = L_shl_nocheck(*raw_mlt_ptr,16);
                acca = L_add(acca,32768L);
                acca = L_shr_nocheck(acca,n);
                acca = L_shr_nocheck(acca,16);
                *raw_mlt_ptr++ = extract_l(acca);
            }

            temp = shl_nocheck(n,1);
            temp = sub(absolute_region_power_index[region],temp);
            absolute_region_power_index[region] = temp;
            move16();
        }
    }
}
Exemplo n.º 23
0
/*
**************************************************************************
*
*  Function    : Chebps
*  Purpose     : Evaluates the Chebyshev polynomial series
*  Description : - The polynomial order is   n = m/2 = 5
*                - The polynomial F(z) (F1(z) or F2(z)) is given by
*                   F(w) = 2 exp(-j5w) C(x)
*                  where
*                   C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2
*                  and T_m(x) = cos(mw) is the mth order Chebyshev
*                  polynomial ( x=cos(w) )
*  Returns     : C(x) for the input x.
*
**************************************************************************
*/
static Word16 Chebps (Word16 x,
                      Word16 f[], /* (n) */
                      Word16 n)
{
    Word16 i, cheb;
    Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
    Word32 t0;

    b2_h = 256;                    move16 (); /* b2 = 1.0 */
    b2_l = 0;                      move16 (); 

    t0 = L_mult (x, 512);          /* 2*x                 */
    t0 = L_mac (t0, f[1], 8192);   /* + f[1]              */
    L_Extract (t0, &b1_h, &b1_l);  /* b1 = 2*x + f[1]     */

    for (i = 2; i < n; i++)
    {
        t0 = Mpy_32_16 (b1_h, b1_l, x);         /* t0 = 2.0*x*b1        */
        t0 = L_shl (t0, 1);
        t0 = L_mac (t0, b2_h, (Word16) 0x8000); /* t0 = 2.0*x*b1 - b2   */
        t0 = L_msu (t0, b2_l, 1);
        t0 = L_mac (t0, f[i], 8192);            /* t0 = 2.0*x*b1 - b2 + f[i] */

        L_Extract (t0, &b0_h, &b0_l);           /* b0 = 2.0*x*b1 - b2 + f[i]*/

        b2_l = b1_l;               move16 ();   /* b2 = b1; */
        b2_h = b1_h;               move16 (); 
        b1_l = b0_l;               move16 ();   /* b1 = b0; */
        b1_h = b0_h;               move16 (); 
    }

    t0 = Mpy_32_16 (b1_h, b1_l, x);             /* t0 = x*b1; */
    t0 = L_mac (t0, b2_h, (Word16) 0x8000);     /* t0 = x*b1 - b2   */
    t0 = L_msu (t0, b2_l, 1);
    t0 = L_mac (t0, f[i], 4096);                /* t0 = x*b1 - b2 + f[i]/2 */

    t0 = L_shl (t0, 6);

    cheb = extract_h (t0);

    return (cheb);
}
Exemplo n.º 24
0
/*************************************************************************
 *
 *  FUNCTION:  Post_Process()
 *
 *  PURPOSE: Postprocessing of input speech.
 *
 *  DESCRIPTION:
 *     - 2nd order high pass filtering with cut off frequency at 60 Hz.
 *     - Multiplication of output by two.
 *                                                                        
 * Algorithm:                                                             
 *                                                                        
 *  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b[2]*x[i-2]*2
 *                     + a[1]*y[i-1]   + a[2]*y[i-2];                     
 *                                                                        
 *                                                                        
 *************************************************************************/
int Post_Process (
    Post_ProcessState *st,  /* i/o : post process state                   */
    Word16 signal[],        /* i/o : signal                               */
    Word16 lg               /* i   : length of signal                     */
    )
{
    Word16 i, x2;
    Word32 L_tmp;

    test (); test ();
    for (i = 0; i < lg; i++)
    {
        x2 = st->x1;                             move16 (); 
        st->x1 = st->x0;                         move16 (); 
        st->x0 = signal[i];                      move16 (); 
        
        /*  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2  */
        /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
        
        L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
        L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
        L_tmp = L_mac (L_tmp, st->x0, b[0]);
        L_tmp = L_mac (L_tmp, st->x1, b[1]);
        L_tmp = L_mac (L_tmp, x2, b[2]);
        L_tmp = L_shl (L_tmp, 2);
        
        /* Multiplication by two of output speech with saturation. */
        signal[i] = round(L_shl(L_tmp, 1));   move16 (); 
        
        st->y2_hi = st->y1_hi;                   move16 (); 
        st->y2_lo = st->y1_lo;                   move16 (); 
        L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
    }

    return 0;    
}
Exemplo n.º 25
0
/*************************************************************************
 *
 *   FUNCTION:  Dec_gain()
 *
 *   PURPOSE: Decode the pitch and codebook gains
 *
 ************************************************************************/
void Dec_gain(
    gc_predState *pred_state, /* i/o: MA predictor state           */
    enum Mode mode,           /* i  : AMR mode                     */
    Word16 index,             /* i  : index of quantization.       */
    Word16 code[],            /* i  : Innovative vector.           */
    Word16 evenSubfr,         /* i  : Flag for even subframes      */     
    Word16 * gain_pit,        /* o  : Pitch gain.                  */
    Word16 * gain_cod         /* o  : Code gain.                   */
)
{
    const Word16 *p;
    Word16 frac, gcode0, exp, qua_ener, qua_ener_MR122;
    Word16 g_code;
    Word32 L_tmp;
    
    /* Read the quantized gains (table depends on mode) */
    index = shl (index, 2);
    
    test(); test(); test();
    if (    sub (mode, MR102) == 0
         || sub (mode, MR74) == 0
         || sub (mode, MR67) == 0)
    {
        p = &table_gain_highrates[index];                  move16 ();
        
        *gain_pit = *p++;                                  move16 ();
        g_code = *p++;                                     move16 ();
        qua_ener_MR122 = *p++;                             move16 ();
        qua_ener = *p;                                     move16 ();
    }
    else
    {
        test();
        if (sub (mode, MR475) == 0)
        {
            index = add (index, shl(sub(1, evenSubfr), 1));
            p = &table_gain_MR475[index];                  move16 ();
            
            *gain_pit = *p++;                              move16 ();
            g_code = *p++;                                 move16 ();
            
            /*---------------------------------------------------------*
             *  calculate predictor update values (not stored in 4.75  *
             *  quantizer table to save space):                        *
             *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
             *                                                         *
             *   qua_ener       = log2(g)                              *
             *   qua_ener_MR122 = 20*log10(g)                          *
             *---------------------------------------------------------*/

            /* Log2(x Q12) = log2(x) + 12 */
            Log2 (L_deposit_l (g_code), &exp, &frac); 
            exp = sub(exp, 12);
    
            qua_ener_MR122 = add (shr_r (frac, 5), shl (exp, 10));
    
            /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
            L_tmp = Mpy_32_16(exp, frac, 24660);
            qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */
        }
        else
        {
            p = &table_gain_lowrates[index];                move16 ();
            
            *gain_pit = *p++;                               move16 ();
            g_code = *p++;                                  move16 ();
            qua_ener_MR122 = *p++;                          move16 ();
            qua_ener = *p;                                  move16 ();
        }
    }
    
    /*-------------------------------------------------------------------*
     *  predict codebook gain                                            *
     *  ~~~~~~~~~~~~~~~~~~~~~                                            *
     *  gc0     = Pow2(int(d)+frac(d))                                   *
     *          = 2^exp + 2^frac                                         *
     *                                                                   *
     *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
     *-------------------------------------------------------------------*/

    gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL);

    gcode0 = extract_l(Pow2(14, frac));

    /*------------------------------------------------------------------*
     *  read quantized gains, update table of past quantized energies   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
     *                       = Log2(g_fac)                              *
     *                       = qua_ener                                 *
     *                                           constant = 20*Log10(2) *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0);
    L_tmp = L_shr(L_tmp, sub(10, exp));
    *gain_cod = extract_h(L_tmp);

    /* update table of past quantized energies */

    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);

    return;
}
Exemplo n.º 26
0
/*
**************************************************************************
*
*  Function    : Az_lsp
*  Purpose     : Compute the LSPs from  the LP coefficients
*
**************************************************************************
*/
void Az_lsp (
    Word16 a[],         /* (i)  : predictor coefficients (MP1)               */
    Word16 lsp[],       /* (o)  : line spectral pairs (M)                    */
    Word16 old_lsp[]    /* (i)  : old lsp[] (in case not found 10 roots) (M) */
)
{
    Word16 i, j, nf, ip;
    Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
    Word16 x, y, sign, exp;
    Word16 *coef;
    Word16 f1[M / 2 + 1], f2[M / 2 + 1];
    Word32 t0;

    /*-------------------------------------------------------------*
     *  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] ;                       *
     * }                                                           *
     *-------------------------------------------------------------*/

    f1[0] = 1024;                  move16 (); /* f1[0] = 1.0 */
    f2[0] = 1024;                  move16 (); /* f2[0] = 1.0 */

    for (i = 0; i < NC; i++)
    {
        t0 = L_mult (a[i + 1], 8192);   /* x = (a[i+1] + a[M-i]) >> 2  */
        t0 = L_mac (t0, a[M - i], 8192);
        x = extract_h (t0);
        /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
        f1[i + 1] = sub (x, f1[i]);move16 (); 

        t0 = L_mult (a[i + 1], 8192);   /* x = (a[i+1] - a[M-i]) >> 2 */
        t0 = L_msu (t0, a[M - i], 8192);
        x = extract_h (t0);
        /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
        f2[i + 1] = add (x, f2[i]);move16 (); 
    }

    /*-------------------------------------------------------------*
     * find the LSPs using the Chebychev pol. evaluation           *
     *-------------------------------------------------------------*/

    nf = 0;                        move16 (); /* number of found frequencies */
    ip = 0;                        move16 (); /* indicator for f1 or f2      */

    coef = f1;                     move16 (); 

    xlow = grid[0];                move16 (); 
    ylow = Chebps (xlow, coef, NC);move16 (); 

    j = 0;
    test (); test (); 
    /* while ( (nf < M) && (j < grid_points) ) */
    while ((sub (nf, M) < 0) && (sub (j, grid_points) < 0))
    {
        j++;
        xhigh = xlow;              move16 (); 
        yhigh = ylow;              move16 (); 
        xlow = grid[j];            move16 (); 
        ylow = Chebps (xlow, coef, NC);
                                   move16 (); 

        test (); 
        if (L_mult (ylow, yhigh) <= (Word32) 0L)
        {

            /* divide 4 times the interval */

            for (i = 0; i < 4; i++)
            {
                /* xmid = (xlow + xhigh)/2 */
                xmid = add (shr (xlow, 1), shr (xhigh, 1));
                ymid = Chebps (xmid, coef, NC);
                                   move16 (); 

                test (); 
                if (L_mult (ylow, ymid) <= (Word32) 0L)
                {
                    yhigh = ymid;  move16 (); 
                    xhigh = xmid;  move16 (); 
                }
                else
                {
                    ylow = ymid;   move16 (); 
                    xlow = xmid;   move16 (); 
                }
            }

            /*-------------------------------------------------------------*
             * Linear interpolation                                        *
             *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
             *-------------------------------------------------------------*/

            x = sub (xhigh, xlow);
            y = sub (yhigh, ylow);

            test (); 
            if (y == 0)
            {
                xint = xlow;       move16 (); 
            }
            else
            {
                sign = y;          move16 (); 
                y = abs_s (y);
                exp = norm_s (y);
                y = shl (y, exp);
                y = div_s ((Word16) 16383, y);
                t0 = L_mult (x, y);
                t0 = L_shr (t0, sub (20, exp));
                y = extract_l (t0);     /* y= (xhigh-xlow)/(yhigh-ylow) */

                test (); 
                if (sign < 0)
                    y = negate (y);

                t0 = L_mult (ylow, y);
                t0 = L_shr (t0, 11);
                xint = sub (xlow, extract_l (t0)); /* xint = xlow - ylow*y */
            }

            lsp[nf] = xint;        move16 (); 
            xlow = xint;           move16 (); 
            nf++;

            test (); 
            if (ip == 0)
            {
                ip = 1;            move16 (); 
                coef = f2;         move16 (); 
            }
            else
            {
                ip = 0;            move16 (); 
                coef = f1;         move16 (); 
            }
            ylow = Chebps (xlow, coef, NC);
                                   move16 (); 

        }
        test (); test (); 
    }

    /* Check if M roots found */

    test (); 
    if (sub (nf, M) < 0)
    {
        for (i = 0; i < M; i++)
        {
            lsp[i] = old_lsp[i];   move16 (); 
        }

    }
    return;
}
Exemplo n.º 27
0
/*
**************************************************************************
*
*  Function    : Bgn_scd
*  Purpose     : Charaterice synthesis speech and detect background noise
*  Returns     : background noise decision; 0 = no bgn, 1 = bgn
*
**************************************************************************
*/
Word16 Bgn_scd (Bgn_scdState *st,      /* i : State variables for bgn SCD */
                Word16 ltpGainHist[],  /* i : LTP gain history            */
                Word16 speech[],       /* o : synthesis speech frame      */
                Word16 *voicedHangover /* o : # of frames after last 
                                              voiced frame                */
                )
{
   Word16 i;
   Word16 prevVoiced, inbgNoise;
   Word16 temp;
   Word16 ltpLimit, frameEnergyMin;
   Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart;
   Word32 s;
   
   /* Update the inBackgroundNoise flag (valid for use in next frame if BFI) */
   /* it now works as a energy detector floating on top                      */ 
   /* not as good as a VAD.                                                  */

   currEnergy = 0;                                   move16 ();
   s = (Word32) 0;                                   move32 ();

   for (i = 0; i < L_FRAME; i++)
   {
       s = L_mac (s, speech[i], speech[i]);
   }

   s = L_shl(s, 2);  

   currEnergy = extract_h (s);

   frameEnergyMin = 32767;                     move16 ();

   for (i = 0; i < L_ENERGYHIST; i++)
   {
      test ();
      if (sub(st->frameEnergyHist[i], frameEnergyMin) < 0)
         frameEnergyMin = st->frameEnergyHist[i];           move16 ();
   }

   noiseFloor = shl (frameEnergyMin, 4); /* Frame Energy Margin of 16 */

   maxEnergy = st->frameEnergyHist[0];               move16 ();
   for (i = 1; i < L_ENERGYHIST-4; i++)
   {
      test ();
      if ( sub (maxEnergy, st->frameEnergyHist[i]) < 0)
      {
         maxEnergy = st->frameEnergyHist[i];         move16 ();
      }
   }
   
   maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; move16 ();
   for (i = 2*L_ENERGYHIST/3+1; i < L_ENERGYHIST; i++)
   {
      test ();
      if ( sub (maxEnergyLastPart, st->frameEnergyHist[i] ) < 0)
      {
         maxEnergyLastPart = st->frameEnergyHist[i]; move16 ();     
      }
   }

   inbgNoise = 0;        /* false */                 move16 (); 

   /* Do not consider silence as noise */
   /* Do not consider continuous high volume as noise */
   /* Or if the current noise level is very low */
   /* Mark as noise if under current noise limit */
   /* OR if the maximum energy is below the upper limit */

   test (); test (); test (); test (); test (); 
   if ( (sub(maxEnergy, LOWERNOISELIMIT) > 0) &&
        (sub(currEnergy, FRAMEENERGYLIMIT) < 0) &&
        (sub(currEnergy, LOWERNOISELIMIT) > 0) &&
        ( (sub(currEnergy, noiseFloor) < 0) ||
          (sub(maxEnergyLastPart, UPPERNOISELIMIT) < 0)))
   {
      test ();
      if (sub(add(st->bgHangover, 1), 30) > 0)
      {
         st->bgHangover = 30;                         move16 ();
      } else
      {
         st->bgHangover = add(st->bgHangover, 1);
      }
   }
   else
   {
      st->bgHangover = 0;                             move16 ();    
   }
   
   /* make final decision about frame state , act somewhat cautiosly */
   test ();
   if (sub(st->bgHangover,1) > 0)
      inbgNoise = 1;       /* true  */               move16 ();  

   for (i = 0; i < L_ENERGYHIST-1; i++)
   {
      st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; move16 ();
   }
   st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy;              move16 ();
   
   /* prepare for voicing decision; tighten the threshold after some 
      time in noise */
   ltpLimit = 13926;             /* 0.85  Q14 */     move16 (); 
   test ();
   if (sub(st->bgHangover, 8) > 0)
   {
      ltpLimit = 15565;          /* 0.95  Q14 */     move16 ();
   }
   test ();
   if (sub(st->bgHangover, 15) > 0)
   {
      ltpLimit = 16383;          /* 1.00  Q14 */     move16 ();
   }

   /* weak sort of voicing indication. */
   prevVoiced = 0;        /* false */                move16 ();
   test ();

   if (sub(gmed_n(&ltpGainHist[4], 5), ltpLimit) > 0)
   {
      prevVoiced = 1;     /* true  */                move16 ();
   }
   test ();   
   if (sub(st->bgHangover, 20) > 0) {
      if (sub(gmed_n(ltpGainHist, 9), ltpLimit) > 0)
      {
         prevVoiced = 1;  /* true  */                move16 ();
      }
      else
      {
         prevVoiced = 0;  /* false  */                move16 ();
      }
   }
   
   test ();
   if (prevVoiced)
   {
      *voicedHangover = 0;                        move16 ();
   }
   else
   {
      temp = add(*voicedHangover, 1);
      test ();
      if (sub(temp, 10) > 0)
      {
         *voicedHangover = 10;                    move16 ();
      }
      else
      {
         *voicedHangover = temp;                  move16 ();
      }
   }

   return inbgNoise;
}
Exemplo n.º 28
0
/*************************************************************************
 *
 *  FUNCTION  set_sign12k2()
 *
 *  PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]", and modifies
 *           dn[] to include the sign information (dn[i]=sign[i]*dn[i]).
 *           Also finds the position of maximum of correlation in each track
 *           and the starting position for each pulse.
 *
 *************************************************************************/
void set_sign12k2 (
    Word16 dn[],      /* i/o : correlation between target and h[]         */
    Word16 cn[],      /* i   : residual after long term prediction        */
    Word16 sign[],    /* o   : sign of d[n]                               */
    Word16 pos_max[], /* o   : position of maximum correlation            */
    Word16 nb_track,  /* i   : number of tracks tracks                    */        
    Word16 ipos[],    /* o   : starting position for each pulse           */
    Word16 step       /* i   : the step size in the tracks                */        
)
{
    Word16 i, j;
    Word16 val, cor, k_cn, k_dn, max, max_of_all;
    Word16 pos = 0; /* initialization only needed to keep gcc silent */
    Word16 en[L_CODE];                  /* correlation vector */
    Word32 s;
 
    /* calculate energy for normalization of cn[] and dn[] */
 
    s = 256;                                     move32 (); 
    for (i = 0; i < L_CODE; i++)
    {
        s = L_mac (s, cn[i], cn[i]);
    }
    s = Inv_sqrt (s);                            move32 (); 
    k_cn = extract_h (L_shl (s, 5));
    
    s = 256;                                     move32 (); 
    for (i = 0; i < L_CODE; i++)
    {
        s = L_mac (s, dn[i], dn[i]);
    }
    s = Inv_sqrt (s);                            move32 (); 
    k_dn = extract_h (L_shl (s, 5));
    
    for (i = 0; i < L_CODE; i++)
    {
        val = dn[i];                             move16 (); 
        cor = round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10));
 
        test (); 
        if (cor >= 0)
        {
            sign[i] = 32767;                     move16 (); /* sign = +1 */
        }
        else
        {
            sign[i] = -32767;                    move16 (); /* sign = -1 */
            cor = negate (cor);
            val = negate (val);
        }
        /* modify dn[] according to the fixed sign */        
        dn[i] = val;                             move16 (); 
        en[i] = cor;                             move16 (); 
    }
    
    max_of_all = -1;                             move16 (); 
    for (i = 0; i < nb_track; i++)
    {
        max = -1;                                move16 (); 
        
        for (j = i; j < L_CODE; j += step)
        {
            cor = en[j];                         move16 (); 
            val = sub (cor, max);
            test (); 
            if (val > 0)
            {
                max = cor;                       move16 (); 
                pos = j;                         move16 (); 
            }
        }
        /* store maximum correlation position */
        pos_max[i] = pos;                        move16 (); 
        val = sub (max, max_of_all);
        test (); 
        if (val > 0)
        {
            max_of_all = max;                    move16 ();
            /* starting position for i0 */            
            ipos[0] = i;                         move16 (); 
        }
    }
    
    /*----------------------------------------------------------------*
     *     Set starting position of each pulse.                       *
     *----------------------------------------------------------------*/
    
    pos = ipos[0];                               move16 (); 
    ipos[nb_track] = pos;                        move16 (); 
    
    for (i = 1; i < nb_track; i++)
    {
        pos = add (pos, 1);
        test ();
        if (sub (pos, nb_track) >= 0)
        {
           pos = 0;                              move16 (); 
        }
        ipos[i] = pos;                           move16 (); 
        ipos[add(i, nb_track)] = pos;            move16 (); 
    }
}
Exemplo n.º 29
0
/*
**************************************************************************
*  Function:  Post_Filter
*  Purpose:   postfiltering of synthesis speech.
*  Description:
*      The postfiltering process is described as follows:
*
*          - inverse filtering of syn[] through A(z/0.7) to get res2[]
*          - tilt compensation filtering; 1 - MU*k*z^-1
*          - synthesis filtering through 1/A(z/0.75)
*          - adaptive gain control
*
**************************************************************************
*/
int Post_Filter (
    Post_FilterState *st, /* i/o : post filter states                        */
    enum Mode mode,       /* i   : AMR mode                                  */
    Word16 *syn,          /* i/o : synthesis speech (postfiltered is output) */
    Word16 *Az_4          /* i   : interpolated LPC parameters in all subfr. */
)
{
    /*-------------------------------------------------------------------*
     *           Declaration of parameters                               *
     *-------------------------------------------------------------------*/

    Word16 Ap3[MP1], Ap4[MP1];  /* bandwidth expanded LP parameters */
    Word16 *Az;                 /* pointer to Az_4:                 */
    /*  LPC parameters in each subframe */
    Word16 i_subfr;             /* index for beginning of subframe  */
    Word16 h[L_H];

    Word16 i;
    Word16 temp1, temp2;
    Word32 L_tmp;
    Word16 *syn_work = &st->synth_buf[M];
    move16 ();


    /*-----------------------------------------------------*
     * Post filtering                                      *
     *-----------------------------------------------------*/

    Copy (syn, syn_work , L_FRAME);

    Az = Az_4;

    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
    {
        /* Find weighted filter coefficients Ap3[] and ap[4] */

        test ();
        test ();
        if (sub(mode, MR122) == 0 || sub(mode, MR102) == 0)
        {
            Weight_Ai (Az, gamma3_MR122, Ap3);
            Weight_Ai (Az, gamma4_MR122, Ap4);
        }
        else
        {
            Weight_Ai (Az, gamma3, Ap3);
            Weight_Ai (Az, gamma4, Ap4);
        }

        /* filtering of synthesis speech by A(z/0.7) to find res2[] */

        Residu (Ap3, &syn_work[i_subfr], st->res2, L_SUBFR);

        /* tilt compensation filter */

        /* impulse response of A(z/0.7)/A(z/0.75) */

        Copy (Ap3, h, M + 1);
        Set_zero (&h[M + 1], L_H - M - 1);
        Syn_filt (Ap4, h, h, L_H, &h[M + 1], 0);

        /* 1st correlation of h[] */

        L_tmp = L_mult (h[0], h[0]);
        for (i = 1; i < L_H; i++)
        {
            L_tmp = L_mac (L_tmp, h[i], h[i]);
        }
        temp1 = extract_h (L_tmp);

        L_tmp = L_mult (h[0], h[1]);
        for (i = 1; i < L_H - 1; i++)
        {
            L_tmp = L_mac (L_tmp, h[i], h[i + 1]);
        }
        temp2 = extract_h (L_tmp);

        test ();
        if (temp2 <= 0)
        {
            temp2 = 0;
            move16 ();
        }
        else
        {
            temp2 = mult (temp2, MU);
            temp2 = div_s (temp2, temp1);
        }

        preemphasis (st->preemph_state, st->res2, temp2, L_SUBFR);

        /* filtering through  1/A(z/0.75) */

        Syn_filt (Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1);

        /* scale output to input */

        agc (st->agc_state, &syn_work[i_subfr], &syn[i_subfr],
             AGC_FAC, L_SUBFR);

        Az += MP1;
    }

    /* update syn_work[] buffer */

    Copy (&syn_work[L_FRAME - M], &syn_work[-M], M);

    return 0;
}
Exemplo n.º 30
0
void dct_type_iv_a (Word16 *input,Word16 *output,Word16 dct_length)
{
    Word16   buffer_a[MAX_DCT_LENGTH], buffer_b[MAX_DCT_LENGTH], buffer_c[MAX_DCT_LENGTH];
    Word16   *in_ptr, *in_ptr_low, *in_ptr_high, *next_in_base;
    Word16   *out_ptr_low, *out_ptr_high, *next_out_base;
    Word16   *out_buffer, *in_buffer, *buffer_swap;
    Word16   in_val_low, in_val_high;
    Word16   out_val_low, out_val_high;
    Word16   in_low_even, in_low_odd;
    Word16   in_high_even, in_high_odd;
    Word16   out_low_even, out_low_odd;
    Word16   out_high_even, out_high_odd;
    Word16   *pair_ptr;
    Word16   cos_even, cos_odd, msin_even, msin_odd;
    Word16   neg_cos_odd;
    Word16   neg_msin_even;
    Word32   sum;
    Word16   set_span, set_count, set_count_log, pairs_left, sets_left;
    Word16   i,k;
    Word16   index;
    cos_msin_t  **table_ptr_ptr, *cos_msin_ptr;
    
    Word16   temp;
    Word32   acca;

    Word16   dct_length_log;


    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    /* Do the sum/difference butterflies, the first part of */
    /* converting one N-point transform into N/2 two-point  */
    /* transforms, where N = 1 << DCT_LENGTH_LOG. = 64/128  */
    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    test();
    if (dct_length==DCT_LENGTH)
    {
        dct_length_log = DCT_LENGTH_LOG;

        /* Add bias offsets */
        for (i=0;i<dct_length;i++)
        {
            input[i] = add(input[i],anal_bias[i]);
            move16();
        }
    }
    else
        dct_length_log = MAX_DCT_LENGTH_LOG;

    index = 0L;
    move16();

    in_buffer  = input;
    move16();

    out_buffer = buffer_a;
    move16();

    temp = sub(dct_length_log,2);
    for (set_count_log=0;set_count_log<=temp;set_count_log++)
    {

        /*===========================================================*/
        /* Initialization for the loop over sets at the current size */
        /*===========================================================*/

        /*    set_span      = 1 << (DCT_LENGTH_LOG - set_count_log); */
        set_span = shr_nocheck(dct_length,set_count_log);

        set_count     = shl_nocheck(1,set_count_log);

        in_ptr        = in_buffer;
        move16();

        next_out_base = out_buffer;
        move16();

        /*=====================================*/
        /* Loop over all the sets of this size */
        /*=====================================*/

        for (sets_left=set_count;sets_left>0;sets_left--)
        {

            /*||||||||||||||||||||||||||||||||||||||||||||*/
            /* Set up output pointers for the current set */
            /*||||||||||||||||||||||||||||||||||||||||||||*/

            out_ptr_low    = next_out_base;
            next_out_base  = next_out_base + set_span;
            out_ptr_high   = next_out_base;

            /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
            /* Loop over all the butterflies in the current set */
            /*||||||||||||||||||||||||||||||||||||||||||||||||||*/

            do 
            {
                in_val_low      = *in_ptr++;
                in_val_high     = *in_ptr++;
		// blp: addition of two 16bits vars, there's no way
		//      they'll overflow a 32bit var
                //acca            = L_add(in_val_low,in_val_high);
		acca = (in_val_low + in_val_high);
		acca            = L_shr_nocheck(acca,1);
                out_val_low     = extract_l(acca);

                acca            = L_sub(in_val_low,in_val_high);
                acca            = L_shr_nocheck(acca,1);
                out_val_high    = extract_l(acca);

                *out_ptr_low++  = out_val_low;
                *--out_ptr_high = out_val_high;

                test();
            } while (out_ptr_low < out_ptr_high);

        } /* End of loop over sets of the current size */

        /*============================================================*/
        /* Decide which buffers to use as input and output next time. */
        /* Except for the first time (when the input buffer is the    */
        /* subroutine input) we just alternate the local buffers.     */
        /*============================================================*/

        in_buffer = out_buffer;
        move16();
        if (out_buffer == buffer_a)
            out_buffer = buffer_b;
        else
            out_buffer = buffer_a;
        index = add(index,1);

    } /* End of loop over set sizes */


    /*++++++++++++++++++++++++++++++++*/
    /* Do N/2 two-point transforms,   */
    /* where N =  1 << DCT_LENGTH_LOG */
    /*++++++++++++++++++++++++++++++++*/

    pair_ptr = in_buffer;
    move16();

    buffer_swap = buffer_c;
    move16();

    temp = sub(dct_length_log,1);
    temp = shl_nocheck(1,temp);

    for (pairs_left=temp; pairs_left > 0; pairs_left--)
    {
        for ( k=0; k<CORE_SIZE; k++ )
        {
#if PJ_HAS_INT64
	    /* blp: danger danger! not really compatible but faster */
	    pj_int64_t sum64=0;
            move32();
            
            for ( i=0; i<CORE_SIZE; i++ )
            {
                sum64 += L_mult(pair_ptr[i], dct_core_a[i][k]);
            }
	    sum = L_saturate(sum64);
#else
            sum=0L;
            move32();
            for ( i=0; i<CORE_SIZE; i++ )
            {
                sum = L_mac(sum, pair_ptr[i],dct_core_a[i][k]);
            }
#endif
            buffer_swap[k] = itu_round(sum);
        }
        /* address arithmetic */
        pair_ptr   += CORE_SIZE;
        buffer_swap += CORE_SIZE;
    }

    for (i=0;i<dct_length;i++)
    {
        in_buffer[i] = buffer_c[i];
        move16();
    }
    
    table_ptr_ptr = a_cos_msin_table;

    /*++++++++++++++++++++++++++++++*/
    /* Perform rotation butterflies */
    /*++++++++++++++++++++++++++++++*/
    temp = sub(dct_length_log,2);
    for (set_count_log = temp; set_count_log >= 0;    set_count_log--)
    {
        /*===========================================================*/
        /* Initialization for the loop over sets at the current size */
        /*===========================================================*/
        /*    set_span      = 1 << (DCT_LENGTH_LOG - set_count_log); */
        set_span = shr_nocheck(dct_length,set_count_log);

        set_count     = shl_nocheck(1,set_count_log);
        next_in_base  = in_buffer;
        move16();

        test();
        if (set_count_log == 0)
        {
            next_out_base = output;
        }
        else
        {
            next_out_base = out_buffer;
        }


        /*=====================================*/
        /* Loop over all the sets of this size */
        /*=====================================*/
        for (sets_left = set_count; sets_left > 0;sets_left--)
        {
            /*|||||||||||||||||||||||||||||||||||||||||*/
            /* Set up the pointers for the current set */
            /*|||||||||||||||||||||||||||||||||||||||||*/
            in_ptr_low     = next_in_base;
            move16();
            temp           = shr_nocheck(set_span,1);

            /* address arithmetic */
            in_ptr_high    = in_ptr_low + temp;
            next_in_base  += set_span;
            out_ptr_low    = next_out_base;
            next_out_base += set_span;
            out_ptr_high   = next_out_base;
            cos_msin_ptr   = *table_ptr_ptr;

            /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
            /* Loop over all the butterfly pairs in the current set */
            /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

            do 
            {
                /* address arithmetic */
                in_low_even     = *in_ptr_low++;
                in_low_odd      = *in_ptr_low++;
                in_high_even    = *in_ptr_high++;
                in_high_odd     = *in_ptr_high++;
                cos_even        = cos_msin_ptr[0].cosine;
                move16();
                msin_even       = cos_msin_ptr[0].minus_sine;
                move16();
                cos_odd         = cos_msin_ptr[1].cosine;
                move16();
                msin_odd        = cos_msin_ptr[1].minus_sine;
                move16();
                cos_msin_ptr   += 2;

                sum = 0L;
                sum=L_mac(sum,cos_even,in_low_even);
                neg_msin_even = negate(msin_even);
                sum=L_mac(sum,neg_msin_even,in_high_even);
                out_low_even = itu_round(sum);

                sum = 0L;
                sum=L_mac(sum,msin_even,in_low_even);
                sum=L_mac(sum,cos_even,in_high_even);
                out_high_even= itu_round(sum);

                sum = 0L;
                sum=L_mac(sum,cos_odd,in_low_odd);
                sum=L_mac(sum,msin_odd,in_high_odd);
                out_low_odd= itu_round(sum);

                sum = 0L;
                sum=L_mac(sum,msin_odd,in_low_odd);
                neg_cos_odd = negate(cos_odd);
                sum=L_mac(sum,neg_cos_odd,in_high_odd);
                out_high_odd= itu_round(sum);

                *out_ptr_low++  = out_low_even;
                *--out_ptr_high = out_high_even;
                *out_ptr_low++  = out_low_odd;
                *--out_ptr_high = out_high_odd;
                test();
            } while (out_ptr_low < out_ptr_high);

        } /* End of loop over sets of the current size */

        /*=============================================*/
        /* Swap input and output buffers for next time */
        /*=============================================*/

        buffer_swap = in_buffer;
        in_buffer   = out_buffer;
        out_buffer  = buffer_swap;
        table_ptr_ptr++;
    }
}