www.pudn.com > T-REC-G.722.1-200505-I!!SOFT-ZST-E.zip > encoder.c


/*************************************************************************** 
** 
**   ITU-T 7/14kHz Audio Coder Candidate (G.722.1 Annex C) Source Code 
** 
**   © 2004 Polycom, Inc. 
** 
**   All rights reserved. 
** 
***************************************************************************/ 
/*************************************************************************** 
  Filename:    encoder.c     
 
  Purpose:     Contains files used to implement the G.722.1 Annex C encoder 
 
  Design Notes: 
 
***************************************************************************/ 
/*************************************************************************** 
 Include files                                                            
***************************************************************************/ 
 
#include  
#include  
#include "defs.h" 
#include "huff_def.h" 
#include "tables.h" 
#include "count.h" 
 
/*************************************************************************** 
 Function:    encoder                                                      
                                                                          
 Syntax:      void encoder(Word16 number_of_available_bits,                      
                           Word16 number_of_regions, 
                           Word16 mlt_coefs,                                         
                           Word16 mag_shift,                                         
                           Word16 out_words)                                         
               
              inputs:   number_of_available_bits 
                        number_of_regions 
                        mag_shift 
                        mlt_coefs[DCT_LENGTH] 
                         
              outputs:  out_words[MAX_BITS_PER_FRAME/16] 
                                                                          
                                                                          
 Description: Encodes the mlt coefs into out_words using G.722.1 Annex C 
                                                            
                                                                          
 WMOPS:     7kHz |    24kbit    |     32kbit 
          -------|--------------|---------------- 
            AVG  |    0.93      |     1.04 
          -------|--------------|----------------   
            MAX  |    1.20      |     1.28 
          -------|--------------|----------------  
                                                                         
           14kHz |    24kbit    |     32kbit     |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    1.39      |     1.71       |     2.01 
          -------|--------------|----------------|---------------- 
            MAX  |    2.00      |     2.30       |     2.52 
          -------|--------------|----------------|---------------- 
                                                                          
***************************************************************************/ 
 
void encoder(Word16  number_of_available_bits, 
             Word16  number_of_regions, 
             Word16  *mlt_coefs, 
             Word16  mag_shift, 
             Word16  *out_words) 
{ 
 
    Word16  num_categorization_control_bits; 
    Word16  num_categorization_control_possibilities; 
    Word16  number_of_bits_per_frame; 
    Word16  number_of_envelope_bits; 
    Word16  categorization_control; 
    Word16  region; 
    Word16  absolute_region_power_index[MAX_NUMBER_OF_REGIONS]; 
    Word16  power_categories[MAX_NUMBER_OF_REGIONS]; 
    Word16  category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1]; 
    Word16  drp_num_bits[MAX_NUMBER_OF_REGIONS+1]; 
    UWord16 drp_code_bits[MAX_NUMBER_OF_REGIONS+1]; 
    Word16  region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS]; 
    UWord32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS]; 
    Word16  mag_shift_offset; 
 
    Word16 temp; 
 
    /* initialize variables */ 
    test(); 
    if (number_of_regions == NUMBER_OF_REGIONS) 
    { 
        num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS; 
        move16(); 
        num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES; 
        move16(); 
    }  
    else 
    { 
        num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS; 
        move16(); 
        num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES; 
        move16(); 
    } 
 
    number_of_bits_per_frame = number_of_available_bits; 
    move16(); 
 
    for (region=0; region= 0) 
        { 
            temp = extract_l(L_shr(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 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(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(acca,4); 
                acca = L_sub(acca,number_of_bits_per_frame); 
            } 
            accb = L_deposit_l(out_word_index); 
            accb = L_shl(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(acca,4); 
        acca = L_sub(acca,number_of_bits_per_frame); 
    } 
} 
/*************************************************************************** 
 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 0) 
        { 
            temp = extract_l(L_mult0(region,REGION_SIZE)); 
 
            raw_mlt_ptr = &mlt_coefs[temp]; 
 
            for (i=0; i 0) 
        { 
            test(); 
            long_accumulator = L_shr(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(long_accumulator,1); 
            acca = L_sub(long_accumulator,32767); 
            power_shift--; 
            temp = add(power_shift,15); 
        } 
        long_accumulator = L_shr(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(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 0) 
        { 
            absolute_region_power_index[region] = temp1; 
            move16(); 
        } 
    } 
 
    for (region=1; region 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, 
                           ®ion_mlt_bits[shl(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, 
                           ®ion_mlt_bits[shl(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)); 
    } 
} 
 
/*************************************************************************** 
 Function:    vector_huffman 
 
 Syntax:      Word16 vector_huffman(Word16  category,      
                                    Word16  power_index,   
                                    Word16  *raw_mlt_ptr,   
                                    UWord32 *word_ptr)      
                                               
              inputs:     Word16  category 
                          Word16  power_index 
                          Word16  *raw_mlt_ptr 
              
              outputs:    number_of_region_bits 
                          *word_ptr 
                                       
 
 Description: Huffman encoding for each region based on category and power_index   
 
 WMOPS:     7kHz |    24kbit    |     32kbit 
          -------|--------------|---------------- 
            AVG  |    0.03      |     0.03 
          -------|--------------|----------------   
            MAX  |    0.04      |     0.04 
          -------|--------------|----------------  
 
           14kHz |    24kbit    |     32kbit     |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    0.03      |     0.03       |     0.03 
          -------|--------------|----------------|---------------- 
            MAX  |    0.04      |     0.04       |     0.04 
          -------|--------------|----------------|---------------- 
 
***************************************************************************/ 
Word16 vector_huffman(Word16 category, 
                      Word16 power_index, 
                      Word16 *raw_mlt_ptr, 
                      UWord32 *word_ptr) 
{ 
  
 
    Word16  inv_of_step_size_times_std_dev; 
    Word16  j,n; 
    Word16  k; 
    Word16  number_of_region_bits; 
    Word16  number_of_non_zero; 
    Word16  vec_dim; 
    Word16  num_vecs; 
    Word16  kmax, kmax_plus_one; 
    Word16  index,signs_index; 
    Word16  *bitcount_table_ptr; 
    UWord16 *code_table_ptr; 
    Word32  code_bits; 
    Word16  number_of_code_bits; 
    UWord32 current_word; 
    Word16  current_word_bits_free; 
     
    Word32 acca; 
    Word32 accb; 
    Word16 temp; 
 
    Word16 mytemp;			 /* new variable in Release 1.2 */ 
    Word16 myacca;			 /* new variable in Release 1.2 */ 
 
 
    /* initialize variables */ 
    vec_dim = vector_dimension[category]; 
    move16(); 
 
    num_vecs = number_of_vectors[category]; 
    move16(); 
 
    kmax = max_bin[category]; 
    move16(); 
 
    kmax_plus_one = add(kmax,1); 
    move16(); 
 
    current_word = 0L; 
    move16(); 
 
    current_word_bits_free = 32; 
    move16(); 
 
    number_of_region_bits = 0; 
    move16(); 
 
    /* set up table pointers */ 
    bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category]; 
    code_table_ptr = (UWord16 *) table_of_code_tables[category]; 
 
    /* compute inverse of step size * standard deviation */ 
    acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]); 
    acca = L_shr(acca,1); 
    acca = L_add(acca,4096); 
    acca = L_shr(acca,13); 
 
	/* 
	 *  The next two lines are new to Release 1.2  
	 */ 
      
	mytemp = acca & 0x3; 
    acca = L_shr(acca,2); 
 
    inv_of_step_size_times_std_dev = extract_l(acca); 
 
 
    for (n=0; n 0) 
                { 
                    signs_index = add(signs_index,1); 
                } 
                 
                temp = sub(k,kmax); 
                test(); 
                if (temp > 0) 
                { 
                    k = kmax; 
                    move16(); 
                } 
            } 
            acca = L_shr(L_mult(index,(kmax_plus_one)),1); 
            index = extract_l(acca); 
            index = add(index,k); 
            raw_mlt_ptr++; 
        } 
 
        code_bits = *(code_table_ptr+index); 
        number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero); 
        number_of_region_bits = add(number_of_region_bits,number_of_code_bits); 
 
        acca = code_bits << number_of_non_zero; 
        accb = L_deposit_l(signs_index); 
        acca = L_add(acca,accb); 
        code_bits = acca; 
        move32(); 
 
        /* msb of codebits is transmitted first. */ 
        j = sub(current_word_bits_free,number_of_code_bits); 
        test(); 
        if (j >= 0) 
        { 
            test(); 
            acca = code_bits << j; 
            current_word = L_add(current_word,acca); 
            current_word_bits_free = j; 
            move16(); 
        } 
        else 
        { 
            j = negate(j); 
            acca = L_shr(code_bits,j); 
            current_word = L_add(current_word,acca); 
             
            *word_ptr++ = current_word; 
            move16(); 
 
            current_word_bits_free = sub(32,j); 
            test(); 
            current_word = code_bits << current_word_bits_free; 
        } 
    } 
 
    *word_ptr++ = current_word; 
    move16(); 
 
    return (number_of_region_bits); 
}