Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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));
}
Ejemplo n.º 3
0
static Word16 compress10 (
       Word16 pos_indxA, /* i : signs of 4 pulses (signs only)             */
       Word16 pos_indxB,  /* i : position index of 8 pulses (pos only)     */
       Word16 pos_indxC) /* i : position and sign of 8 pulses (compressed) */
{
   Word16 indx, ia,ib,ic;

   ia = shr(pos_indxA, 1);
   ib = extract_l(L_shr(L_mult(shr(pos_indxB, 1), 5), 1));
   ic = extract_l(L_shr(L_mult(shr(pos_indxC, 1), 25), 1));            
   indx = shl(add(ia, add(ib, ic)), 3);
   ia = pos_indxA & 1;                                logic16 ();
   ib = shl((pos_indxB & 1), 1);                      logic16 ();
   ic = shl((pos_indxC & 1), 2);                      logic16 ();
   indx = add(indx , add(ia, add(ib, ic)));  
   
   return indx;

}
Ejemplo n.º 4
0
void decode_4i40_17bits(
    Word16 sign,   /* i : signs of 4 pulses.                       */
    Word16 index,  /* i : Positions of the 4 pulses.               */
    Word16 cod[]   /* o : algebraic (fixed) codebook excitation    */
)
{
    Word16 i, j;
    Word16 pos[NB_PULSE];

    /* Decode the positions */

    i = index & 7;                                       logic16 ();
    i = dgray[i];                                        move16 ();

    pos[0] = add(i, shl(i, 2));   /* pos0 =i*5 */        move16 ();

    index = shr(index, 3);
    i = index & 7;                                       logic16 ();
    i = dgray[i];                                        move16 ();

    i = add(i, shl(i, 2));        /* pos1 =i*5+1 */
    pos[1] = add(i, 1);                                  move16 ();

    index = shr(index, 3);
    i = index & 7;                                       logic16 ();
    i = dgray[i];                                        move16 ();

    i = add(i, shl(i, 2));        /* pos2 =i*5+1 */
    pos[2] = add(i, 2);                                  move16 ();

    index = shr(index, 3);
    j = index & 1;                                       logic16 ();
    index = shr(index, 1);
    i = index & 7;                                       logic16 ();
    i = dgray[i];                                        move16 ();

    i = add(i, shl(i, 2));        /* pos3 =i*5+3+j */
    i = add(i, 3);
    pos[3] = add(i, j);                                  move16 ();

    /* decode the signs  and build the codeword */

    for (i = 0; i < L_SUBFR; i++) {
        cod[i] = 0;                                      move16 ();
    }

    for (j = 0; j < NB_PULSE; j++) {
        i = sign & 1;                                    logic16 ();
        sign = shr(sign, 1);

        test ();
        if (i != 0) {
            cod[pos[j]] = 8191;                          move16 ();
        } else {
            cod[pos[j]] = -8192;                         move16 ();
        }
    }

    return;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
static void build_code (
    Word16 codvec[],    /* i : position of pulses                           */
    Word16 sign[],      /* i : sign of d[n]                                 */
    Word16 cod[],       /* o : innovative code vector                       */
    Word16 h[],         /* i : impulse response of weighted synthesis filter*/
    Word16 y[],         /* o : filtered innovative code                     */
    Word16 sign_indx[], /* o : signs of 4  pulses (signs only)              */
    Word16 pos_indx[]   /* o : position index of 8 pulses(position only)    */
)
{
    Word16 i, j, k, track, sign_index, pos_index, _sign[NB_PULSE];
    Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
    Word32 s;

    for (i = 0; i < L_CODE; i++)
    {
        cod[i] = 0;                              move16 (); 
    }
    for (i = 0; i < NB_TRACK_MR102; i++)
    {
        pos_indx[i] = -1;                            move16 (); 
        sign_indx[i] = -1;                            move16 (); 
    }
    
    for (k = 0; k < NB_PULSE; k++)
    {
       /* read pulse position */            
       i = codvec[k];                           move16 ();
       /* read sign           */        
       j = sign[i];                             move16 (); 
       
       pos_index = shr(i, 2);                      /* index = pos/4 */
       track = i & 3;             logic16 ();      /* track = pos%4 */
       
       test (); 
       if (j > 0)
       {
          cod[i] = add (cod[i], POS_CODE);         move16 ();
          _sign[k] = POS_SIGN;                     move16 (); 
          sign_index = 0;  /* bit=0 -> positive pulse */  move16 (); 
       }
       else
       {
          cod[i] = sub (cod[i], NEG_CODE);         move16 ();
          _sign[k] = NEG_SIGN;                     move16 (); 
          sign_index = 1;     move16 (); /* bit=1 => negative pulse */ 
          /* index = add (index, 8); 1 = negative  old code */
       }
       
       test (); move16 ();
       if (pos_indx[track] < 0)
       {   /* first set first NB_TRACK pulses  */
          pos_indx[track] = pos_index;                 move16 (); 
          sign_indx[track] = sign_index;              move16 (); 
       }
       else
       {   /* 2nd row of pulses , test if positions needs to be switched */
          test (); logic16 (); logic16 (); 
          if (((sign_index ^ sign_indx[track]) & 1) == 0)
          {
             /* sign of 1st pulse == sign of 2nd pulse */
             
             test (); 
             if (sub (pos_indx[track], pos_index) <= 0)
             {   /* no swap */
                pos_indx[track + NB_TRACK_MR102] = pos_index;     move16 (); 
             }
             else
             {   /* swap*/
                pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
                move16 (); 
                
                pos_indx[track] = pos_index;         move16 ();
                sign_indx[track] = sign_index;       move16 ();
             }
          }
          else
          {
             /* sign of 1st pulse != sign of 2nd pulse */
             
             test (); 
             if (sub (pos_indx[track], pos_index) <= 0)
             {  /*swap*/
                pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
                move16 (); 
                
                pos_indx[track] = pos_index;         move16 (); 
                sign_indx[track] = sign_index;       move16 (); 
             }
             else
             {   /*no swap */
                pos_indx[track + NB_TRACK_MR102] = pos_index;     move16 (); 
             }
          }
       }
    }
    
    p0 = h - codvec[0];                          move16 (); 
    p1 = h - codvec[1];                          move16 (); 
    p2 = h - codvec[2];                          move16 (); 
    p3 = h - codvec[3];                          move16 (); 
    p4 = h - codvec[4];                          move16 (); 
    p5 = h - codvec[5];                          move16 (); 
    p6 = h - codvec[6];                          move16 (); 
    p7 = h - codvec[7];                          move16 (); 
    
    for (i = 0; i < L_CODE; i++)
    {
       s = 0;                                   move32 (); 
       s = L_mac (s, *p0++, _sign[0]);
       s = L_mac (s, *p1++, _sign[1]);
       s = L_mac (s, *p2++, _sign[2]);
       s = L_mac (s, *p3++, _sign[3]);
       s = L_mac (s, *p4++, _sign[4]);
       s = L_mac (s, *p5++, _sign[5]);
       s = L_mac (s, *p6++, _sign[6]);
       s = L_mac (s, *p7++, _sign[7]);
       y[i] = round (s);                        move16 (); 
    }
}
Ejemplo n.º 7
0
void vector_quantize_mlts(Word16 number_of_available_bits,
                          Word16 number_of_regions,
                          Word16 num_categorization_control_possibilities,
                          Word16 *mlt_coefs,
                          Word16 *absolute_region_power_index,
                          Word16 *power_categories,
                          Word16 *category_balances,
                          Word16 *p_categorization_control,
                          Word16 *region_mlt_bit_counts,
                          UWord32 *region_mlt_bits)
{

    Word16 *raw_mlt_ptr;
    Word16 region;
    Word16 category;
    Word16 total_mlt_bits = 0;

    Word16 temp;
    Word16 temp1;
    Word16 temp2;

    /* Start in the middle of the categorization control range. */
    temp = shr_nocheck(num_categorization_control_possibilities,1);
    temp = sub(temp,1);
    for (*p_categorization_control = 0; *p_categorization_control < temp; (*p_categorization_control)++)
    {
        region = category_balances[*p_categorization_control];
        move16();
        power_categories[region] = add(power_categories[region],1);
        move16();
    }

    for (region=0; region<number_of_regions; region++)
    {
        category = power_categories[region];
        move16();
        temp = extract_l(L_mult0(region,REGION_SIZE));
        raw_mlt_ptr = &mlt_coefs[temp];
        move16();
        temp = sub(category,(NUM_CATEGORIES-1));
        test();
        if (temp < 0)
        {
            region_mlt_bit_counts[region] =
            vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
                           &region_mlt_bits[shl_nocheck(region,2)]);
        }
        else
        {
            region_mlt_bit_counts[region] = 0;
            move16();
        }
        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
    }


    /* If too few bits... */
    temp = sub(total_mlt_bits,number_of_available_bits);
    test();
    test();
    logic16();
    while ((temp < 0) && (*p_categorization_control > 0))
    {
        test();
        test();
        logic16();
        (*p_categorization_control)--;
        region = category_balances[*p_categorization_control];
        move16();
        
        power_categories[region] = sub(power_categories[region],1);
        move16();

        total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
        category = power_categories[region];
        move16();
        
        raw_mlt_ptr = &mlt_coefs[region*REGION_SIZE];
        move16();
        
        temp = sub(category,(NUM_CATEGORIES-1));
        test();
        if (temp < 0)
        {
            region_mlt_bit_counts[region] =
                vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
                           &region_mlt_bits[shl_nocheck(region,2)]);
        }
        else
        {
            region_mlt_bit_counts[region] = 0;
            move16();
        }
        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
        temp = sub(total_mlt_bits,number_of_available_bits);
    }

    /* If too many bits... */
    /* Set up for while loop test */
    temp1 = sub(total_mlt_bits,number_of_available_bits);
    temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
    test();
    test();
    logic16();
    
    while ((temp1 > 0) && (temp2 < 0))
    {
        /* operations for while contitions */
        test();
        test();
        logic16();
        
        region = category_balances[*p_categorization_control];
        move16();
        
        power_categories[region] = add(power_categories[region],1);
        move16();

        total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
        category = power_categories[region];
        move16();
        
        temp = extract_l(L_mult0(region,REGION_SIZE));
        raw_mlt_ptr = &mlt_coefs[temp];
        move16();
        
        temp = sub(category,(NUM_CATEGORIES-1));
        test();
        if (temp < 0)
        {
            region_mlt_bit_counts[region] =
                vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
                           &region_mlt_bits[shl_nocheck(region,2)]);
        }
        else
        {
            region_mlt_bit_counts[region] = 0;
            move16();
        }
        total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
        (*p_categorization_control)++;
        
        temp1 = sub(total_mlt_bits,number_of_available_bits);
        temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
    }
}
Ejemplo n.º 8
0
Word16 compute_region_powers(Word16  *mlt_coefs,
                             Word16  mag_shift,
                             Word16  *drp_num_bits,
                             UWord16 *drp_code_bits,
                             Word16  *absolute_region_power_index,
                             Word16  number_of_regions)
{

    Word16 *input_ptr;
    Word32 long_accumulator;
    Word16 itemp1;
    Word16 power_shift;
    Word16 region;
    Word16 j;
    Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];
    Word16 number_of_bits;
    
    Word32 acca;
    Word16 temp;
    Word16 temp1;
    Word16 temp2;


    input_ptr = mlt_coefs;
    for (region=0; region<number_of_regions; region++)
    {
        long_accumulator = L_deposit_l(0);

        for (j=0; j<REGION_SIZE; j++)
        {
            itemp1 = *input_ptr++;
            move16();
            long_accumulator = L_mac0(long_accumulator,itemp1,itemp1);
        }

        power_shift = 0;
        move16();

        acca = (long_accumulator & 0x7fff0000L);
        logic32();

        test();
        while (acca > 0)
        {
            test();
            long_accumulator = L_shr_nocheck(long_accumulator,1);
            
            acca = (long_accumulator & 0x7fff0000L);
            logic32();

            power_shift = add(power_shift,1);
        }
        
        acca = L_sub(long_accumulator,32767);
        
        temp = add(power_shift,15);
        test();
        test();
        logic16();
        while ((acca <= 0) && (temp >= 0))
        {
            test();
            test();
            logic16();
            
            long_accumulator = L_shl_nocheck(long_accumulator,1);
            acca = L_sub(long_accumulator,32767);
            power_shift--;
            temp = add(power_shift,15);
        }
        long_accumulator = L_shr_nocheck(long_accumulator,1);
        /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */
        acca = L_sub(long_accumulator,28963);
        
        test();
        if (acca >= 0)
            power_shift = add(power_shift,1);
        
        acca = L_deposit_l(mag_shift);
        acca = L_shl_nocheck(acca,1);
        acca = L_sub(power_shift,acca);
        acca = L_add(35,acca);
        acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES);
        absolute_region_power_index[region] = extract_l(acca);
    }


    /* Before we differentially encode the quantized region powers, adjust upward the
    valleys to make sure all the peaks can be accurately represented. */
    temp = sub(number_of_regions,2);

    for (region = temp; region >= 0; region--)
    {
        temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX);
        temp2 = sub(absolute_region_power_index[region],temp1);
        test();
        if (temp2 < 0)
        {
            absolute_region_power_index[region] = temp1;
            move16();
        }
    }

    /* The MLT is currently scaled too low by the factor
       ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160).
       This is the ninth power of 1 over the square root of 2.
       So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9)
       to drp_code_bits[0]. */

    /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */
    temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX);
    temp2 = sub(absolute_region_power_index[0],temp1);
    test();
    if (temp2 < 0)
    {
        absolute_region_power_index[0] = temp1;
        move16();
    }
    
    temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);

	/*
	 * The next line was corrected in Release 1.2 
	 */

    temp2 = sub(absolute_region_power_index[0], temp1);  
    test();
    if (temp2 > 0)
    {
        absolute_region_power_index[0] = temp1;
        move16();
    }

    differential_region_power_index[0] = absolute_region_power_index[0];
    move16();
    
    number_of_bits = 5;
    move16();
    
    drp_num_bits[0] = 5;
    move16();
    
    drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX);
    move16();

    /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes
     may be mathematically impossible anyway.*/
    for (region=1; region<number_of_regions; region++)
    {
        temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX);
        temp2 = sub(absolute_region_power_index[region],temp1);
        test();
        if (temp2 < 0)
        {
            absolute_region_power_index[region] = temp1;
            move16();
        }

        temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
        temp2 = sub(absolute_region_power_index[region],temp1);
        test();
        if (temp2 > 0)
        {
            absolute_region_power_index[region] = temp1;
            move16();
        }
    }

    for (region=1; region<number_of_regions; region++)
    {
        j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]);
        temp = sub(j,DRP_DIFF_MIN);
        test();
        if (temp < 0)
        {
            j = DRP_DIFF_MIN;
        }
        j = sub(j,DRP_DIFF_MIN);
        move16();
        differential_region_power_index[region] = j;
        move16();
        
        temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]);
        temp = add(temp,DRP_DIFF_MIN);
        absolute_region_power_index[region] = temp;
        move16();

        number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]);
        drp_num_bits[region] = differential_region_power_bits[region][j];
        move16();
        drp_code_bits[region] = differential_region_power_codes[region][j];
        move16();
    }

    return (number_of_bits);
}
Ejemplo n.º 9
0
/***************************************************************************
 Function:    bits_to_words

 Syntax:      bits_to_words(UWord32 *region_mlt_bits,              
                            Word16  *region_mlt_bit_counts,                                                             
                            Word16  *drp_num_bits,                                                                      
                            UWord16 *drp_code_bits,                                                                     
                            Word16  *out_words,                                                                         
                            Word16  categorization_control,                                                                         
                            Word16  number_of_regions,
                            Word16  num_categorization_control_bits,
                            Word16  number_of_bits_per_frame)                                                           
                                                                   
                                                                   
 Description: Stuffs the bits into words for output

 WMOPS:     7kHz |    24kbit    |      32kbit
          -------|--------------|----------------
            AVG  |    0.09      |     0.12
          -------|--------------|----------------  
            MAX  |    0.10      |     0.13
          -------|--------------|---------------- 
          
           14kHz |    24kbit    |     32kbit     |     48kbit
          -------|--------------|----------------|----------------
            AVG  |    0.12      |     0.15       |     0.19
          -------|--------------|----------------|----------------
            MAX  |    0.14      |     0.17       |     0.21
          -------|--------------|----------------|----------------

***************************************************************************/
void bits_to_words(UWord32 *region_mlt_bits,
                   Word16  *region_mlt_bit_counts,
                   Word16  *drp_num_bits,
                   UWord16 *drp_code_bits,
                   Word16  *out_words,
                   Word16  categorization_control,
                   Word16  number_of_regions,
                   Word16  num_categorization_control_bits,
                   Word16  number_of_bits_per_frame)
{
    Word16  out_word_index = 0;
    Word16  j;
    Word16  region;
    Word16  out_word;
    Word16  region_bit_count;
    Word16  current_word_bits_left;
    UWord16 slice;
    Word16  out_word_bits_free = 16;
    UWord32 *in_word_ptr;
    UWord32 current_word;
    
    Word32  acca = 0;
    Word32  accb;
    Word16  temp;

    /* First set up the categorization control bits to look like one more set of region power bits. */
    out_word = 0;
    move16();

    drp_num_bits[number_of_regions] = num_categorization_control_bits;
    move16();
    
    drp_code_bits[number_of_regions] = (UWord16)categorization_control;
    move16();

    /* These code bits are right justified. */
    for (region=0; region <= number_of_regions; region++)
    {
        current_word_bits_left = drp_num_bits[region];
        move16();
        
        current_word = (UWord32)drp_code_bits[region];
        move16();
        
        j = sub(current_word_bits_left,out_word_bits_free);

        test();
        if (j >= 0)
        {
            temp = extract_l(L_shr_nocheck(current_word,j));
            out_word = add(out_word,temp);

            out_words[out_word_index++] = out_word;
            move16();
            
            out_word_bits_free = 16;
            move16();
            
            out_word_bits_free = sub(out_word_bits_free,j);
            
            acca = (current_word << out_word_bits_free);
            out_word = extract_l(acca);
        }
        else
        {
            j = negate(j);

            acca = (current_word << j);
            accb = L_deposit_l(out_word);
            acca = L_add(accb,acca);
            out_word = extract_l(acca);
            
            out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
        }
    }

    /* These code bits are left justified. */
    
    for (region=0;region<number_of_regions; region++)
    {
        accb = L_deposit_l(out_word_index);
        accb = L_shl_nocheck(accb,4);
        accb = L_sub(accb,number_of_bits_per_frame);
        test();
        if(accb < 0)        
        {
            temp = shl_nocheck(region,2);
            in_word_ptr = &region_mlt_bits[temp];
            region_bit_count = region_mlt_bit_counts[region];
            move16();

            temp = sub(32,region_bit_count);
            test();
            if(temp > 0)
                current_word_bits_left = region_bit_count;
            else
                current_word_bits_left = 32;

            current_word = *in_word_ptr++;
    
            acca = L_deposit_l(out_word_index);
            acca = L_shl_nocheck(acca,4);
            acca = L_sub(acca,number_of_bits_per_frame);
            
            /* from while loop */
            test();
            test();
            logic16(); 
            while ((region_bit_count > 0) && (acca < 0))
            {
                /* from while loop */
                test();
                test();
                logic16(); 
                
                temp = sub(current_word_bits_left,out_word_bits_free);
                test();
                if (temp >= 0)
                {
                    temp = sub(32,out_word_bits_free);
                    accb = LU_shr(current_word,temp);
                    slice = (UWord16)extract_l(accb);
                    
                    out_word = add(out_word,slice);
    
                    test();
                    current_word <<= out_word_bits_free;

                    current_word_bits_left = sub(current_word_bits_left,out_word_bits_free);
                    out_words[out_word_index++] = extract_l(out_word);
                    move16();

                    out_word = 0;
                    move16();

                    out_word_bits_free = 16;
                    move16();
                }
                else
                {
                    temp = sub(32,current_word_bits_left);
                    accb = LU_shr(current_word,temp);
                    slice = (UWord16)extract_l(accb);
                    
                    temp = sub(out_word_bits_free,current_word_bits_left);
                    test();
                    accb = slice << temp;
                    acca = L_deposit_l(out_word);
                    acca = L_add(acca,accb);
                    out_word = extract_l(acca);
                    out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
                    
                    current_word_bits_left = 0;
                    move16();
                }
    
                test();
                if (current_word_bits_left == 0)
                {
                    current_word = *in_word_ptr++;
                    region_bit_count = sub(region_bit_count,32);
                    
                    /* current_word_bits_left = MIN(32,region_bit_count); */
                    temp = sub(32,region_bit_count);
                    test();
                    if(temp > 0)
                        current_word_bits_left = region_bit_count;
                    else
                        current_word_bits_left = 32;
                    
                }
                acca = L_deposit_l(out_word_index);
                acca = L_shl_nocheck(acca,4);
                acca = L_sub(acca,number_of_bits_per_frame);
            }
            accb = L_deposit_l(out_word_index);
            accb = L_shl_nocheck(accb,4);
            accb = L_sub(accb,number_of_bits_per_frame);
        }
    }

    /* Fill out with 1's. */

    test();
    while (acca < 0)
    {
        test();
        current_word = 0x0000ffff;
        move32();

        temp = sub(16,out_word_bits_free);
        acca = LU_shr(current_word,temp);
        slice = (UWord16)extract_l(acca);

        out_word = add(out_word,slice);
        out_words[out_word_index++] = out_word;
        move16();

        out_word = 0;
        move16();
        
        out_word_bits_free = 16;
        move16();
        
        acca = L_deposit_l(out_word_index);
        acca = L_shl_nocheck(acca,4);
        acca = L_sub(acca,number_of_bits_per_frame);
    }
}
Ejemplo n.º 10
0
Word16 vad2 (Word16 * farray_ptr, vadState2 * st)
{

	/*
	 * The channel table is defined below.  In this table, the
	 * lower and higher frequency coefficients for each of the 16
	 * channels are specified.  The table excludes the coefficients
	 * with numbers 0 (DC), 1, and 64 (Foldover frequency).
	 */

	const static Word16 ch_tbl[NUM_CHAN][2] =
	{

		{2, 3},
		{4, 5},
		{6, 7},
		{8, 9},
		{10, 11},
		{12, 13},
		{14, 16},
		{17, 19},
		{20, 22},
		{23, 26},
		{27, 30},
		{31, 35},
		{36, 41},
		{42, 48},
		{49, 55},
		{56, 63}

	};

	/* channel energy scaling table - allows efficient division by number
         * of DFT bins in the channel: 1/2, 1/3, 1/4, etc.
	 */

	const static Word16 ch_tbl_sh[NUM_CHAN] =
	{
		16384, 16384, 16384, 16384, 16384, 16384, 10923, 10923,
		10923, 8192, 8192, 6554, 5461, 4681, 4681, 4096
	};

	/*
	 * The voice metric table is defined below.  It is a non-
	 * linear table with a deadband near zero.  It maps the SNR
	 * index (quantized SNR value) to a number that is a measure
	 * of voice quality.
	 */

	const static Word16 vm_tbl[90] =
	{
		2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
		8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15,
		15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24,
		24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34,
		35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45,
		46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50,
		50, 50
	};

	/* hangover as a function of peak SNR (3 dB steps) */
	const static Word16 hangover_table[20] =
	{
		30, 30, 30, 30, 30, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 8, 8, 8
	};

	/* burst sensitivity as a function of peak SNR (3 dB steps) */
	const static Word16 burstcount_table[20] =
	{
		8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4
	};

	/* voice metric sensitivity as a function of peak SNR (3 dB steps) */
	const static Word16 vm_threshold_table[20] =
	{
                34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 40, 51, 71, 100, 139, 191, 257, 337, 432
	};


	/* State tables that use 22,9 or 27,4 scaling for ch_enrg[] */

   const static Word16 noise_floor_chan[2] =	{NOISE_FLOOR_CHAN_0, NOISE_FLOOR_CHAN_1};
	const  static Word16 min_chan_enrg[2] =	{MIN_CHAN_ENRG_0, MIN_CHAN_ENRG_1};
	const static Word16 ine_noise[2] = 		{INE_NOISE_0, INE_NOISE_1};
	const static Word16 fbits[2] = 		{FRACTIONAL_BITS_0, FRACTIONAL_BITS_1};
	const static Word16 state_change_shift_r[2] = {STATE_1_TO_0_SHIFT_R, STATE_0_TO_1_SHIFT_R};

	/* Energy scale table given 30,1 input scaling (also account for -6 dB shift on input) */
	const static Word16 enrg_norm_shift[2] = 	{(FRACTIONAL_BITS_0-1+2), (FRACTIONAL_BITS_1-1+2)};


	/* Automatic variables */

	Word32 Lenrg;				/* scaled as 30,1 */
	Word32 Ltne;				/* scaled as 22,9 */
	Word32 Ltce;				/* scaled as 22,9 or 27,4 */

	Word16 tne_db;				/* scaled as 7,8 */
	Word16 tce_db;				/* scaled as 7,8 */

	Word16 input_buffer[FRM_LEN];		/* used for block normalising input data */
	Word16 data_buffer[FFT_LEN];		/* used for in-place FFT */

	Word16 ch_snr[NUM_CHAN];		/* scaled as 7,8 */
	Word16 ch_snrq;				/* scaled as 15,0 (in 0.375 dB steps) */
	Word16 vm_sum;				/* scaled as 15,0 */
	Word16 ch_enrg_dev;			/* scaled as 7,8 */

	Word32 Lpeak;				/* maximum channel energy */
	Word16 p2a_flag;			/* flag to indicate spectral peak-to-average ratio > 10 dB */

	Word16 ch_enrg_db[NUM_CHAN];		/* scaled as 7,8 */
	Word16 ch_noise_db;			/* scaled as 7,8 */

	Word16 alpha;				/* scaled as 0,15 */
	Word16 one_m_alpha;			/* scaled as 0,15 */
	Word16 update_flag;			/* set to indicate a background noise estimate update */

	Word16 i, j, j1, j2;			/* Scratch variables */
	Word16 hi1, lo1;

	Word32 Ltmp, Ltmp1, Ltmp2;
	Word16 tmp;

	Word16 normb_shift;		/* block norm shift count */

	Word16 ivad;			/* intermediate VAD decision (return value) */
	Word16 tsnrq;			/* total signal-to-noise ratio (quantized 3 dB steps) scaled as 15,0 */
	Word16 xt;			/* instantaneous frame SNR in dB, scaled as 7,8 */

	Word16 state_change;


	/* Increment frame counter */
	st->Lframe_cnt = L_add(st->Lframe_cnt, 1);

	/* Block normalize the input */
	normb_shift = block_norm(farray_ptr, input_buffer, FRM_LEN, FFT_HEADROOM);

	/* Pre-emphasize the input data and store in the data buffer with the appropriate offset */
	for (i = 0; i < DELAY; i++)
	{
		data_buffer[i] = 0;									move16();
	}

	st->pre_emp_mem = shr_r(st->pre_emp_mem, sub(st->last_normb_shift, normb_shift));
	st->last_normb_shift = normb_shift;								move16();

	data_buffer[DELAY] = add(input_buffer[0], mult(PRE_EMP_FAC, st->pre_emp_mem));			move16();

	for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++)
	{
		data_buffer[i] = add(input_buffer[j], mult(PRE_EMP_FAC, input_buffer[j-1]));		move16();
	}
	st->pre_emp_mem = input_buffer[FRM_LEN-1];							move16();

	for (i = DELAY + FRM_LEN; i < FFT_LEN; i++)
	{
		data_buffer[i] = 0;									move16();
	}


	/* Perform FFT on the data buffer */
	r_fft(data_buffer);


	/* Use normb_shift factor to determine the scaling of the energy estimates */
	state_change = 0;										move16();
													test();
	if (st->shift_state == 0)
	{												test();
		if (sub(normb_shift, -FFT_HEADROOM+2) <= 0)
		{
			state_change = 1;								move16();
			st->shift_state = 1;								move16();
		}
	}
	else
	{												test();
		if (sub(normb_shift, -FFT_HEADROOM+5) >= 0)
		{
			state_change = 1;								move16();
			st->shift_state = 0;								move16();
		}
	}

	/* Scale channel energy estimate */								test();
	if (state_change)
	{
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			st->Lch_enrg[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[st->shift_state]);	move32();
		}
	}


	/* Estimate the energy in each channel */
													test();
	if (L_sub(st->Lframe_cnt, 1) == 0)
	{
		alpha = 32767;										move16();
		one_m_alpha = 0;									move16();
	}
	else
	{
		alpha = CEE_SM_FAC;									move16();
		one_m_alpha = ONE_MINUS_CEE_SM_FAC;							move16();
	}

	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		Lenrg = 0;										move16();
		j1 = ch_tbl[i][0];									move16();
		j2 = ch_tbl[i][1];									move16();

		for (j = j1; j <= j2; j++)
		{
			Lenrg = L_mac(Lenrg, data_buffer[2 * j], data_buffer[2 * j]);
			Lenrg = L_mac(Lenrg, data_buffer[2 * j + 1], data_buffer[2 * j + 1]);
		}

		/* Denorm energy & scale 30,1 according to the state */
		Lenrg = L_shr_r(Lenrg, sub(shl(normb_shift, 1), enrg_norm_shift[st->shift_state]));

		/* integrate over time: e[i] = (1-alpha)*e[i] + alpha*enrg/num_bins_in_chan */
		tmp = mult(alpha, ch_tbl_sh[i]);
		L_Extract (Lenrg, &hi1, &lo1);
		Ltmp = Mpy_32_16(hi1, lo1, tmp);

		L_Extract (st->Lch_enrg[i], &hi1, &lo1);
		st->Lch_enrg[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, one_m_alpha));			move32();
													test();
		if (L_sub(st->Lch_enrg[i], min_chan_enrg[st->shift_state]) < 0)
		{
			st->Lch_enrg[i] = min_chan_enrg[st->shift_state];				move32();
		}

	}


	/* Compute the total channel energy estimate (Ltce) */
	Ltce = 0;											move16();
	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		Ltce = L_add(Ltce, st->Lch_enrg[i]);
	}


	/* Calculate spectral peak-to-average ratio, set flag if p2a > 10 dB */
	Lpeak = 0;											move32();
	for (i = LO_CHAN+2; i <= HI_CHAN; i++)	/* Sine waves not valid for low frequencies */
	{												test();
		if (L_sub(st->Lch_enrg [i], Lpeak) > 0)
		{
			Lpeak = st->Lch_enrg [i];							move32();
		}
	}

	/* Set p2a_flag if peak (dB) > average channel energy (dB) + 10 dB */
	/*   Lpeak > Ltce/num_channels * 10^(10/10)                        */
	/*   Lpeak > (10/16)*Ltce                                          */

	L_Extract (Ltce, &hi1, &lo1);
	Ltmp = Mpy_32_16(hi1, lo1, 20480);
													test();
	if (L_sub(Lpeak, Ltmp) > 0)
	{
		p2a_flag = TRUE;									move16();
	}
	else
	{
		p2a_flag = FALSE;									move16();
	}


	/* Initialize channel noise estimate to either the channel energy or fixed level  */
	/*   Scale the energy appropriately to yield state 0 (22,9) scaling for noise */
													test();
	if (L_sub(st->Lframe_cnt, 4) <= 0)
	{												test();
		if (p2a_flag == TRUE)
		{
			for (i = LO_CHAN; i <= HI_CHAN; i++)
			{
				st->Lch_noise[i] = INE_NOISE_0;						move32();
			}
		}
		else
		{
			for (i = LO_CHAN; i <= HI_CHAN; i++)
			{										test();
				if (L_sub(st->Lch_enrg[i], ine_noise[st->shift_state]) < 0)
				{
					st->Lch_noise[i] = INE_NOISE_0;					move32();
				}
				else
				{									test();
					if (st->shift_state == 1)
					{
						st->Lch_noise[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[0]);
													move32();
					}
					else
					{
						st->Lch_noise[i] = st->Lch_enrg[i];			move32();
					}
				}
			}
		}
	}


	/* Compute the channel energy (in dB), the channel SNRs, and the sum of voice metrics */
	vm_sum = 0;											move16();
	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		ch_enrg_db[i] = fn10Log10(st->Lch_enrg[i], fbits[st->shift_state]);			move16();
		ch_noise_db = fn10Log10(st->Lch_noise[i], FRACTIONAL_BITS_0);

		ch_snr[i] = sub(ch_enrg_db[i], ch_noise_db);						move16();

		/* quantize channel SNR in 3/8 dB steps (scaled 7,8 => 15,0) */
		/*   ch_snr = round((snr/(3/8))>>8)                          */
		/*          = round(((0.6667*snr)<<2)>>8)                    */
		/*          = round((0.6667*snr)>>6)                         */

		ch_snrq = shr_r(mult(21845, ch_snr[i]), 6);

		/* Accumulate the sum of voice metrics	*/						test();
		if (sub(ch_snrq, 89) < 0)
		{											test();
			if (ch_snrq > 0)
			{
				j = ch_snrq;								move16();
			}
			else
			{
				j = 0;									move16();
			}
		}
		else
		{
			j = 89;										move16();
		}
		vm_sum = add(vm_sum, vm_tbl[j]);
	}


	/* Initialize NOMINAL peak voice energy and average noise energy, calculate instantaneous SNR */ 
												test(),test(),logic16();
	if (L_sub(st->Lframe_cnt, 4) <= 0 || st->fupdate_flag == TRUE)
	{
		/* tce_db = (96 - 22 - 10*log10(64) (due to FFT)) scaled as 7,8 */
		tce_db = 14320;										move16();
		st->negSNRvar = 0;									move16();
		st->negSNRbias = 0;									move16();

		/* Compute the total noise estimate (Ltne) */
		Ltne = 0;										move32();
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			Ltne = L_add(Ltne, st->Lch_noise[i]);
		}

		/* Get total noise in dB */
		tne_db = fn10Log10(Ltne, FRACTIONAL_BITS_0);

		/* Initialise instantaneous and long-term peak signal-to-noise ratios */
		xt = sub(tce_db, tne_db);
		st->tsnr = xt;										move16();
	}
	else
	{
		/* Calculate instantaneous frame signal-to-noise ratio */
		/* xt = 10*log10( sum(2.^(ch_snr*0.1*log2(10)))/length(ch_snr) ) */
		Ltmp1 = 0;										move32();
		for (i=LO_CHAN; i<=HI_CHAN; i++) {
			/* Ltmp2 = ch_snr[i] * 0.1 * log2(10); (ch_snr scaled as 7,8) */
			Ltmp2 = L_shr(L_mult(ch_snr[i], 10885), 8);
			L_Extract(Ltmp2, &hi1, &lo1);
			hi1 = add(hi1, 3);			/* 2^3 to compensate for negative SNR */
			Ltmp1 = L_add(Ltmp1, Pow2(hi1, lo1));
		}
		xt = fn10Log10(Ltmp1, 4+3);			/* average by 16, inverse compensation 2^3 */

		/* Estimate long-term "peak" SNR */							test(),test();
		if (sub(xt, st->tsnr) > 0)
		{
			/* tsnr = 0.9*tsnr + 0.1*xt; */
			st->tsnr = round(L_add(L_mult(29491, st->tsnr), L_mult(3277, xt)));
		}
		/* else if (xt > 0.625*tsnr) */	
		else if (sub(xt, mult(20480, st->tsnr)) > 0)
		{
			/* tsnr = 0.998*tsnr + 0.002*xt; */
			st->tsnr = round(L_add(L_mult(32702, st->tsnr), L_mult(66, xt)));
		}
	}

	/* Quantize the long-term SNR in 3 dB steps, limit to 0 <= tsnrq <= 19 */
	tsnrq = shr(mult(st->tsnr, 10923), 8);

	/* tsnrq = min(19, max(0, tsnrq)); */								test(),test();
	if (sub(tsnrq, 19) > 0)
	{
		tsnrq = 19;										move16();
	}
	else if (tsnrq < 0)
	{
		tsnrq = 0;										move16();
	}

	/* Calculate the negative SNR sensitivity bias */
													test();
	if (xt < 0)
	{
		/* negSNRvar = 0.99*negSNRvar + 0.01*xt*xt; */
		/*   xt scaled as 7,8 => xt*xt scaled as 14,17, shift to 7,8 and round */
		tmp = round(L_shl(L_mult(xt, xt), 7));
		st->negSNRvar = round(L_add(L_mult(32440, st->negSNRvar), L_mult(328, tmp)));

		/* if (negSNRvar > 4.0) negSNRvar = 4.0;  */						test();
		if (sub(st->negSNRvar, 1024) > 0)
		{
			st->negSNRvar = 1024;								move16();
		}

		/* negSNRbias = max(12.0*(negSNRvar - 0.65), 0.0); */
		tmp = mult_r(shl(sub(st->negSNRvar, 166), 4), 24576);					test();

		if (tmp < 0)
		{
			st->negSNRbias = 0;								move16();
		}
		else
		{
			st->negSNRbias = shr(tmp, 8);
		}
	}


	/* Determine VAD as a function of the voice metric sum and quantized SNR */

	tmp = add(vm_threshold_table[tsnrq], st->negSNRbias);						test();
	if (sub(vm_sum, tmp) > 0)
	{
		ivad = 1;										move16();
		st->burstcount = add(st->burstcount, 1);						test();
		if (sub(st->burstcount, burstcount_table[tsnrq]) > 0)
		{
			st->hangover = hangover_table[tsnrq];						move16();
		}
	}
	else
	{
		st->burstcount = 0;									move16();
		st->hangover = sub(st->hangover, 1);							test();
		if (st->hangover <= 0)
		{
			ivad = 0;									move16();
			st->hangover = 0;								move16();
		}
		else
		{
			ivad = 1;									move16();
		}
	}


	/* Calculate log spectral deviation */
	ch_enrg_dev = 0;										move16();
													test();
	if (L_sub(st->Lframe_cnt, 1) == 0)
	{
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			st->ch_enrg_long_db[i] = ch_enrg_db[i];						move16();
		}
	}
	else
	{
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			tmp = abs_s(sub(st->ch_enrg_long_db[i], ch_enrg_db[i]));
			ch_enrg_dev = add(ch_enrg_dev, tmp);
		}
	}

	/*
	 * Calculate long term integration constant as a function of instantaneous SNR
	 * (i.e., high SNR (tsnr dB) -> slower integration (alpha = HIGH_ALPHA),
	 *         low SNR (0 dB) -> faster integration (alpha = LOW_ALPHA)
	 */

	/* alpha = HIGH_ALPHA - ALPHA_RANGE * (tsnr - xt) / tsnr, low <= alpha <= high */
	tmp = sub(st->tsnr, xt);						test(),logic16(),test(),test();
	if (tmp <= 0 || st->tsnr <= 0)
	{
		alpha = HIGH_ALPHA;								move16();
		one_m_alpha = 32768L-HIGH_ALPHA;						move16();
	}
	else if (sub(tmp, st->tsnr) > 0)
	{
		alpha = LOW_ALPHA;								move16();
		one_m_alpha = 32768L-LOW_ALPHA;							move16();
	}
	else
	{
		tmp = div_s(tmp, st->tsnr);
		alpha = sub(HIGH_ALPHA, mult(ALPHA_RANGE, tmp));
		one_m_alpha = sub(32767, alpha);
	}

	/* Calc long term log spectral energy */
	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		Ltmp1 = L_mult(one_m_alpha, ch_enrg_db[i]);
		Ltmp2 = L_mult(alpha, st->ch_enrg_long_db[i]);
		st->ch_enrg_long_db[i] = round(L_add(Ltmp1, Ltmp2));
	}


	/* Set or clear the noise update flags */
	update_flag = FALSE;										move16();
	st->fupdate_flag = FALSE;									move16();
													test(),test();
	if (sub(vm_sum, UPDATE_THLD) <= 0)
	{												test();
		if (st->burstcount == 0)
		{
			update_flag = TRUE;								move16();
			st->update_cnt = 0;								move16();
		}
	}
	else if (L_sub(Ltce, noise_floor_chan[st->shift_state]) > 0)
	{												test();
		if (sub(ch_enrg_dev, DEV_THLD) < 0)
		{											test();
			if (p2a_flag == FALSE)
			{										test();
				if (st->LTP_flag == FALSE)
				{
					st->update_cnt = add(st->update_cnt, 1);			test();
					if (sub(st->update_cnt, UPDATE_CNT_THLD) >= 0)
					{
						update_flag = TRUE;					move16();
						st->fupdate_flag = TRUE;				move16();
					}
				}
			}
		}
	}
													test();
	if (sub(st->update_cnt, st->last_update_cnt) == 0)
	{
		st->hyster_cnt = add(st->hyster_cnt, 1);
	}
	else
	{
		st->hyster_cnt = 0;									move16();
	}

	st->last_update_cnt = st->update_cnt;								move16();
													test();
	if (sub(st->hyster_cnt, HYSTER_CNT_THLD) > 0)
	{
		st->update_cnt = 0;									move16();
	}


	/* Conditionally update the channel noise estimates */
													test();
	if (update_flag == TRUE)
	{
		/* Check shift state */									test();
		if (st->shift_state == 1)
		{
			/* get factor to shift ch_enrg[] from state 1 to 0 (noise always state 0) */
			tmp = state_change_shift_r[0];							move16();
		}
		else
		{
			/* No shift if already state 0 */
			tmp = 0;									move16();
		}

		/* Update noise energy estimate */
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{											test();
			/* integrate over time: en[i] = (1-alpha)*en[i] + alpha*e[n] */
			/* (extract with shift compensation for state 1) */
			L_Extract (L_shr(st->Lch_enrg[i], tmp), &hi1, &lo1);
			Ltmp = Mpy_32_16(hi1, lo1, CNE_SM_FAC);

			L_Extract (st->Lch_noise[i], &hi1, &lo1);
			st->Lch_noise[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, ONE_MINUS_CNE_SM_FAC));	move32();

			/* Limit low level noise */							test();
			if (L_sub(st->Lch_noise[i], MIN_NOISE_ENRG_0) < 0)
			{
				st->Lch_noise[i] = MIN_NOISE_ENRG_0;					move32();
			}
		}
	}

	return(ivad);
}								/* end of vad2 () */
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
/*************************************************************************
 *
 *  FUNCTION:  G_pitch
 *
 *  PURPOSE:  Compute the pitch (adaptive codebook) gain.
 *            Result in Q14 (NOTE: 12.2 bit exact using Q12) 
 *
 *  DESCRIPTION:
 *      The adaptive codebook gain is given by
 *
 *              g = <x[], y[]> / <y[], y[]>
 *
 *      where x[] is the target vector, y[] is the filtered adaptive
 *      codevector, and <> denotes dot product.
 *      The gain is limited to the range [0,1.2] (=0..19661 Q14)
 *
 *************************************************************************/
Word16 G_pitch     (    /* o : Gain of pitch lag saturated to 1.2       */
    enum Mode mode,     /* i : AMR mode                                 */
    Word16 xn[],        /* i : Pitch target.                            */
    Word16 y1[],        /* i : Filtered adaptive codebook.              */
    Word16 g_coeff[],   /* i : Correlations need for gain quantization  */
    Word16 L_subfr      /* i : Length of subframe.                      */
)
{
    Word16 i;
    Word16 xy, yy, exp_xy, exp_yy, gain;
    Word32 s;

    Word16 scaled_y1[L_SUBFR];   /* Usually dynamic allocation of (L_subfr) */

    /* divide "y1[]" by 4 to avoid overflow */

    for (i = 0; i < L_subfr; i++)
    {
        scaled_y1[i] = shr (y1[i], 2); move16 (); 
    }

    /* Compute scalar product <y1[],y1[]> */

    /* Q12 scaling / MR122 */
    Overflow = 0;                   move16 ();
    s = 1L;                         move32 (); /* Avoid case of all zeros */
    for (i = 0; i < L_subfr; i++)
    {
        s = L_mac (s, y1[i], y1[i]);
    }
    test (); 
    if (Overflow == 0)       /* Test for overflow */
    {
        exp_yy = norm_l (s);
        yy = round (L_shl (s, exp_yy));
    }
    else
    {
        s = 1L;                     move32 (); /* Avoid case of all zeros */
        for (i = 0; i < L_subfr; i++)
        {
            s = L_mac (s, scaled_y1[i], scaled_y1[i]);
        }
        exp_yy = norm_l (s);
        yy = round (L_shl (s, exp_yy));
        exp_yy = sub (exp_yy, 4);
    }
        
    /* Compute scalar product <xn[],y1[]> */
        
    Overflow = 0;                   move16 (); 
    s = 1L;                         move32 (); /* Avoid case of all zeros */
        
    for (i = 0; i < L_subfr; i++)
    {
        s = L_mac(s, xn[i], y1[i]);
    }
    test (); 
    if (Overflow == 0)
    {
        exp_xy = norm_l (s);
        xy = round (L_shl (s, exp_xy));
    }
    else
    {
        s = 1L;                     move32 (); /* Avoid case of all zeros */
        for (i = 0; i < L_subfr; i++)
        {
            s = L_mac (s, xn[i], scaled_y1[i]);
        }
        exp_xy = norm_l (s);
        xy = round (L_shl (s, exp_xy));
        exp_xy = sub (exp_xy, 2);
    }

    g_coeff[0] = yy;                 move16 ();
    g_coeff[1] = sub (15, exp_yy);   move16 ();
    g_coeff[2] = xy;                 move16 ();
    g_coeff[3] = sub (15, exp_xy);   move16 ();
    
    /* If (xy < 4) gain = 0 */

    i = sub (xy, 4);

    test (); 
    if (i < 0)
        return ((Word16) 0);

    /* compute gain = xy/yy */

    xy = shr (xy, 1);                  /* Be sure xy < yy */
    gain = div_s (xy, yy);

    i = sub (exp_xy, exp_yy);      /* Denormalization of division */        
    gain = shr (gain, i);
    
    /* if(gain >1.2) gain = 1.2 */
    
    test (); 
    if (sub (gain, 19661) > 0)
    {
        gain = 19661;                   move16 (); 
    }

    test ();
    if (sub(mode, MR122) == 0)
    {
       /* clear 2 LSBits */
       gain = gain & 0xfffC;            logic16 ();
    }
    
    return (gain);
}
Ejemplo n.º 13
0
enum DTXStateType rx_dtx_handler(
                      dtx_decState *st,           /* i/o : State struct     */
                      enum RXFrameType frame_type /* i   : Frame type       */ 
                      )
{
   enum DTXStateType newState;
   enum DTXStateType encState;

   /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
   test(); test(); test();
   test(); test(); test();
   test(); test();   
   if ((sub(frame_type, RX_SID_FIRST) == 0)   ||
       (sub(frame_type, RX_SID_UPDATE) == 0)  ||
       (sub(frame_type, RX_SID_BAD) == 0)     ||
       (((sub(st->dtxGlobalState, DTX) == 0) ||
         (sub(st->dtxGlobalState, DTX_MUTE) == 0)) && 
        ((sub(frame_type, RX_NO_DATA) == 0) ||
         (sub(frame_type, RX_SPEECH_BAD) == 0) || 
         (sub(frame_type, RX_ONSET) == 0))))
   {
      newState = DTX;                                              move16();

      /* stay in mute for these input types */
      test(); test(); test(); test(); test();
      if ((sub(st->dtxGlobalState, DTX_MUTE) == 0) &&
          ((sub(frame_type, RX_SID_BAD) == 0) ||
           (sub(frame_type, RX_SID_FIRST) ==  0) ||
           (sub(frame_type, RX_ONSET) ==  0) ||
           (sub(frame_type, RX_NO_DATA) == 0)))
      {
         newState = DTX_MUTE;                                      move16();
      }

      /* evaluate if noise parameters are too old                     */
      /* since_last_sid is reset when CN parameters have been updated */
      st->since_last_sid = add(st->since_last_sid, 1);             move16();

      /* no update of sid parameters in DTX for a long while */
      /* Due to the delayed update of  st->since_last_sid counter
         SID_UPDATE frames need to be handled separately to avoid
         entering DTX_MUTE for late SID_UPDATE frames
         */
      test(); test(); logic16();
      if((sub(frame_type, RX_SID_UPDATE) != 0) &&
         (sub(st->since_last_sid, DTX_MAX_EMPTY_THRESH) > 0))
      {
         newState = DTX_MUTE;                                      move16();
      }
   }
   else 
   {
      newState = SPEECH;                                           move16();
      st->since_last_sid = 0;                                      move16();
   }
   
   /* 
      reset the decAnaElapsed Counter when receiving CNI data the first  
      time, to robustify counter missmatch after handover
      this might delay the bwd CNI analysis in the new decoder slightly.
   */    
   test(); test();
   if ((st->data_updated == 0) &&
       (sub(frame_type, RX_SID_UPDATE) == 0))
   {
      st->decAnaElapsedCount = 0;                                  move16();
   }

   /* update the SPE-SPD DTX hangover synchronization */
   /* to know when SPE has added dtx hangover         */
   st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);        move16();
   st->dtxHangoverAdded = 0;                                       move16();
   
   test(); test(); test(); test(); test();
   if ((sub(frame_type, RX_SID_FIRST) == 0)  ||
       (sub(frame_type, RX_SID_UPDATE) == 0) ||
       (sub(frame_type, RX_SID_BAD) == 0)    ||
       (sub(frame_type, RX_ONSET) == 0)      ||
       (sub(frame_type, RX_NO_DATA) == 0))
   {
      encState = DTX;                                              move16();
      
      /*         
         In frame errors simulations RX_NO_DATA may occasionally mean that
         a speech packet was probably sent by the encoder,
         the assumed _encoder_ state should be SPEECH in such cases.
      */
      
      test(); logic16(); 
      if((sub(frame_type, RX_NO_DATA) == 0) &&
         (sub(newState, SPEECH) == 0)) 
      {
         encState = SPEECH;                                       move16();
      }
      
      
      /* Note on RX_ONSET operation differing from RX_NO_DATA operation:
         If a  RX_ONSET is received in the decoder (by "accident")
         it is still most likely that the encoder  state
         for the "ONSET frame" was DTX.
      */      
   }
   else 
   {
      encState = SPEECH;                                           move16();
   }
 
   test();
   if (sub(encState, SPEECH) == 0)
   {
      st->dtxHangoverCount = DTX_HANG_CONST;                       move16();
   }
   else
   {
      test();
      if (sub(st->decAnaElapsedCount, DTX_ELAPSED_FRAMES_THRESH) > 0)
      {
         st->dtxHangoverAdded = 1;                                 move16();
         st->decAnaElapsedCount = 0;                               move16();
         st->dtxHangoverCount = 0;                                 move16();
      }
      else if (test(), st->dtxHangoverCount == 0)
      {
         st->decAnaElapsedCount = 0;                               move16();
      }
      else
      {
         st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);      move16();
      }
   }
   
   if (sub(newState, SPEECH) != 0)
   {
      /* DTX or DTX_MUTE
       * CN data is not in a first SID, first SIDs are marked as SID_BAD 
       *  but will do backwards analysis if a hangover period has been added
       *  according to the state machine above 
       */
      
      st->sid_frame = 0;                                           move16();
      st->valid_data = 0;                                          move16();
            
      test(); 
      if (sub(frame_type, RX_SID_FIRST) == 0)
      {
         st->sid_frame = 1;                                        move16();
      }
      else if (test(), sub(frame_type, RX_SID_UPDATE) == 0)
      {
         st->sid_frame = 1;                                        move16();
         st->valid_data = 1;                                       move16();
      }
      else if (test(), sub(frame_type, RX_SID_BAD) == 0)
      {
         st->sid_frame = 1;                                        move16();
         st->dtxHangoverAdded = 0; /* use old data */              move16();
      } 
   }

   return newState; 
   /* newState is used by both SPEECH AND DTX synthesis routines */ 
}
Ejemplo n.º 14
0
/*
**************************************************************************
*
*  Function    : D_plsf_5
*  Purpose     : Decodes the 2 sets of LSP parameters in a frame 
*                using the received quantization indices.
*
**************************************************************************
*/
int D_plsf_5 (
    D_plsfState *st,    /* i/o: State variables                            */
    Word16 bfi,         /* i  : bad frame indicator (set to 1 if a bad    
                                frame is received)                         */  
    Word16 *indice,     /* i  : quantization indices of 5 submatrices, Q0  */
    Word16 *lsp1_q,     /* o  : quantized 1st LSP vector (M),          Q15 */
    Word16 *lsp2_q      /* o  : quantized 2nd LSP vector (M),          Q15 */
)
{
    Word16 i;
    const Word16 *p_dico;
    Word16 temp, sign;
    Word16 lsf1_r[M], lsf2_r[M];
    Word16 lsf1_q[M], lsf2_q[M];

    test (); 
    if (bfi != 0)                               /* if bad frame */
    {
        /* use the past LSFs slightly shifted towards their mean */

        for (i = 0; i < M; i++)
        {
            /* lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*mean_lsf[i]; */

            lsf1_q[i] = add (mult (st->past_lsf_q[i], ALPHA),
                             mult (mean_lsf[i], ONE_ALPHA));
                                                move16 (); 

            lsf2_q[i] = lsf1_q[i];              move16 (); 
        }

        /* estimate past quantized residual to be used in next frame */

        for (i = 0; i < M; i++)
        {
            /* temp  = mean_lsf[i] +  st->past_r_q[i] * LSP_PRED_FAC_MR122; */

            temp = add (mean_lsf[i], mult (st->past_r_q[i],
                                           LSP_PRED_FAC_MR122));

            st->past_r_q[i] = sub (lsf2_q[i], temp);
                                                move16 (); 
        }
    }
    else
        /* if good LSFs received */
    {
        /* decode prediction residuals from 5 received indices */

        p_dico = &dico1_lsf[shl (indice[0], 2)];move16 ();
        lsf1_r[0] = *p_dico++;                  move16 (); 
        lsf1_r[1] = *p_dico++;                  move16 (); 
        lsf2_r[0] = *p_dico++;                  move16 (); 
        lsf2_r[1] = *p_dico++;                  move16 (); 

        p_dico = &dico2_lsf[shl (indice[1], 2)];move16 ();
        lsf1_r[2] = *p_dico++;                  move16 (); 
        lsf1_r[3] = *p_dico++;                  move16 (); 
        lsf2_r[2] = *p_dico++;                  move16 (); 
        lsf2_r[3] = *p_dico++;                  move16 (); 

        sign = indice[2] & 1;                   logic16 (); 
        i = shr (indice[2], 1);
        p_dico = &dico3_lsf[shl (i, 2)];        move16 (); 

        test (); 
        if (sign == 0)
        {
            lsf1_r[4] = *p_dico++;              move16 (); 
            lsf1_r[5] = *p_dico++;              move16 (); 
            lsf2_r[4] = *p_dico++;              move16 (); 
            lsf2_r[5] = *p_dico++;              move16 (); 
        }
        else
        {
            lsf1_r[4] = negate (*p_dico++);     move16 (); 
            lsf1_r[5] = negate (*p_dico++);     move16 (); 
            lsf2_r[4] = negate (*p_dico++);     move16 (); 
            lsf2_r[5] = negate (*p_dico++);     move16 (); 
        }

        p_dico = &dico4_lsf[shl (indice[3], 2)];move16 (); 
        lsf1_r[6] = *p_dico++;                  move16 (); 
        lsf1_r[7] = *p_dico++;                  move16 (); 
        lsf2_r[6] = *p_dico++;                  move16 (); 
        lsf2_r[7] = *p_dico++;                  move16 (); 

        p_dico = &dico5_lsf[shl (indice[4], 2)];move16 (); 
        lsf1_r[8] = *p_dico++;                  move16 (); 
        lsf1_r[9] = *p_dico++;                  move16 (); 
        lsf2_r[8] = *p_dico++;                  move16 (); 
        lsf2_r[9] = *p_dico++;                  move16 (); 

        /* Compute quantized LSFs and update the past quantized residual */
        for (i = 0; i < M; i++)
        {
            temp = add (mean_lsf[i], mult (st->past_r_q[i],
                                           LSP_PRED_FAC_MR122));
            lsf1_q[i] = add (lsf1_r[i], temp);
                                                move16 (); 
            lsf2_q[i] = add (lsf2_r[i], temp);
                                                move16 (); 
            st->past_r_q[i] = lsf2_r[i];        move16 (); 
        }
    }

    /* verification that LSFs have minimum distance of LSF_GAP Hz */

    Reorder_lsf (lsf1_q, LSF_GAP, M);
    Reorder_lsf (lsf2_q, LSF_GAP, M);

    Copy (lsf2_q, st->past_lsf_q, M);

    /*  convert LSFs to the cosine domain */

    Lsf_lsp (lsf1_q, lsp1_q, M);
    Lsf_lsp (lsf2_q, lsp2_q, M);

    return 0;
}
Ejemplo n.º 15
0
/*************************************************************************
 *
 *  FUNCTION:   dec_10i40_35bits()
 *
 *  PURPOSE:  Builds the innovative codevector from the received
 *            index of algebraic codebook.
 *
 *   See  c1035pf.c  for more details about the algebraic codebook structure.
 *
 *************************************************************************/
void dec_10i40_35bits (
    Word16 index[],    /* (i)     : index of 10 pulses (sign+position)       */
    Word16 cod[]       /* (o)     : algebraic (fixed) codebook excitation    */
)
{
    Word16 i, j, pos1, pos2, sign, tmp;

    for (i = 0; i < L_CODE; i++)
    {
        cod[i] = 0;
        move16 ();
    }

    /* decode the positions and signs of pulses and build the codeword */

    for (j = 0; j < NB_TRACK; j++)
    {
        /* compute index i */

        tmp = index[j];
        move16 ();
        i = tmp & 7;
        logic16 ();
        i = dgray[i];
        move16 ();

        i = extract_l (L_shr (L_mult (i, 5), 1));
        pos1 = add (i, j); /* position of pulse "j" */

        i = shr (tmp, 3) & 1;
        logic16 ();
        test ();
        if (i == 0)
        {
            sign = 4096;
            move16 (); /* +1.0 */
        }
        else
        {
            sign = -4096;
            move16 (); /* -1.0 */
        }

        cod[pos1] = sign;
        move16 ();

        /* compute index i */

        i = index[add (j, 5)] & 7;
        logic16 ();
        i = dgray[i];
        move16 ();
        i = extract_l (L_shr (L_mult (i, 5), 1));

        pos2 = add (i, j);      /* position of pulse "j+5" */

        test ();
        if (sub (pos2, pos1) < 0)
        {
            sign = negate (sign);
        }
        cod[pos2] = add (cod[pos2], sign);
        move16 ();
    }

    return;
}