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


/*************************************************************************** 
**************************************************************************** 
** 
**   ITU-T 7/14kHz Audio Coder Candidate (G.722.1 Annex C) Source Code 
** 
**   © 2004 Polycom, Inc. 
** 
**   All rights reserved. 
** 
**************************************************************************** 
***************************************************************************/ 
/*************************************************************************** 
  Filename:    decoder.c     
 
  Purpose:     Contains files used to implement the G.722.1 Annex C decoder 
		 
  Design Notes: 
 
***************************************************************************/ 
/*************************************************************************** 
 Include files                                                            
***************************************************************************/ 
#include "defs.h" 
#include "tables.h" 
#include "huff_def.h" 
#include "count.h" 
 
 
/*************************************************************************** 
 Function:    decoder 
 
 Syntax:      void decoder(Bit_Obj *bitobj,                    
                           Rand_Obj *randobj,              
                           Word16 number_of_regions, 
                           Word16 *decoder_mlt_coefs,      
                           Word16 *p_mag_shift,            
                           Word16 *p_old_mag_shift,        
                           Word16 *old_decoder_mlt_coefs,     
                           Word16 frame_error_flag)       
               
              inputs:    Bit_Obj *bitobj 
                         Rand_Obj *randobj 
                         Word16 number_of_regions 
                         Word16 *p_old_mag_shift 
                         Word16 *old_decoder_mlt_coefs 
                         Word16 frame_error_flag 
               
              outputs:   Word16 *decoder_mlt_coefs,     
                         Word16 *p_mag_shift,           
                   
                   
 
 Description: Decodes the out_words into mlt coefs using G.722.1 Annex C 
 
 Design Notes: 
  
 WMOPS:     7kHz |   24kbit    |    32kbit 
          -------|-------------|---------------- 
            AVG  |    0.84     |    0.94 
          -------|-------------|----------------   
            MAX  |    0.90     |    1.00 
          -------|-------------|----------------  
				 
           14kHz |   24kbit    |    32kbit      |     48kbit 
          -------|-------------|----------------|---------------- 
            AVG  |    1.31     |    1.56        |     1.88    
          -------|-------------|----------------|---------------- 
            MAX  |    1.59     |    1.80        |     1.98    
          -------|-------------|----------------|---------------- 
				 
***************************************************************************/ 
void decoder(Bit_Obj *bitobj, 
             Rand_Obj *randobj, 
             Word16 number_of_regions, 
	         Word16 *decoder_mlt_coefs, 
	         Word16 *p_mag_shift, 
             Word16 *p_old_mag_shift, 
             Word16 *old_decoder_mlt_coefs, 
             Word16 frame_error_flag) 
{ 
 
 
    Word16  absolute_region_power_index[MAX_NUMBER_OF_REGIONS]; 
    Word16  decoder_power_categories[MAX_NUMBER_OF_REGIONS]; 
    Word16  decoder_category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1]; 
    UWord16 categorization_control; 
    Word16  decoder_region_standard_deviation[MAX_NUMBER_OF_REGIONS]; 
    Word16  i; 
 
    Word16  num_categorization_control_bits; 
    Word16  num_categorization_control_possibilities; 
    Word16  number_of_coefs; 
    Word16  number_of_valid_coefs; 
     
     
    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(); 
        number_of_coefs = DCT_LENGTH; 
        move16(); 
        number_of_valid_coefs = NUMBER_OF_VALID_COEFS; 
        move16(); 
    } 
    else 
    { 
        num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS; 
        move16(); 
        num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES; 
        move16(); 
        number_of_coefs = MAX_DCT_LENGTH; 
        move16(); 
        number_of_valid_coefs = MAX_NUMBER_OF_VALID_COEFS; 
        move16(); 
    } 
 
    test(); 
    if (frame_error_flag == 0)  
    { 
 
        /* convert the bits to absolute region power index and decoder_region_standard_deviation */ 
         
        decode_envelope(bitobj, 
                        number_of_regions, 
                        decoder_region_standard_deviation, 
		                absolute_region_power_index, 
		                p_mag_shift); 
 
        /* fill the categorization_control with NUM_CATEGORIZATION_CONTROL_BITS */ 
        categorization_control = 0; 
        for (i=0; inext_bit); 
        } 
         
        bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,num_categorization_control_bits); 
 
        /* obtain decoder power categories and category balances */ 
        /* based on the absolute region power index              */ 
        categorize(bitobj->number_of_bits_left, 
	               number_of_regions, 
	               num_categorization_control_possibilities, 
	               absolute_region_power_index, 
	               decoder_power_categories, 
	               decoder_category_balances); 
 
        /* perform adjustmaents to the power categories and category balances based on the cat control */ 
        rate_adjust_categories(categorization_control, 
			                   decoder_power_categories, 
			                   decoder_category_balances); 
 
        /* decode the quantized bits into mlt coefs */ 
        decode_vector_quantized_mlt_indices(bitobj, 
                                            randobj, 
                                            number_of_regions, 
                                            decoder_region_standard_deviation, 
					                        decoder_power_categories, 
					                        decoder_mlt_coefs); 
 
        /* test for frame errors */ 
        test_4_frame_errors(bitobj, 
                            number_of_regions, 
                            num_categorization_control_possibilities, 
                            &frame_error_flag, 
                            categorization_control, 
                            absolute_region_power_index); 
    } 
 
    /* perform error handling operations */ 
    error_handling(number_of_coefs, 
                   number_of_valid_coefs, 
                   &frame_error_flag, 
                   decoder_mlt_coefs, 
                   old_decoder_mlt_coefs, 
                   p_mag_shift, 
                   p_old_mag_shift); 
 
} 
 
/*************************************************************************** 
 Function:    decode_envelope 
 
 Syntax:      void decode_envelope(Bit_Obj *bitobj,                               
                                   Word16  number_of_regions, 
                                   Word16  *decoder_region_standard_deviation,    
                                   Word16  *absolute_region_power_index,          
                                   Word16  *p_mag_shift)                          
               
              inputs:   Bit_Obj *bitobj 
                        Word16  number_of_regions 
                         
                         
              outputs:  Word16  *decoder_region_standard_deviation 
                        Word16  *absolute_region_power_index 
                        Word16  *p_mag_shift 
               
  
 Description: Recover differential_region_power_index from code bits 
 
 Design Notes: 
  
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |     0.04     |    0.04 
          -------|--------------|----------------   
            MAX  |     0.05     |    0.05 
          -------|--------------|----------------  
				 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |     0.08     |    0.08        |     0.08    
          -------|--------------|----------------|---------------- 
            MAX  |     0.10     |    0.10        |     0.10    
          -------|--------------|----------------|---------------- 
				 
***************************************************************************/ 
void decode_envelope(Bit_Obj *bitobj, 
                     Word16  number_of_regions, 
                     Word16  *decoder_region_standard_deviation, 
		             Word16  *absolute_region_power_index, 
		             Word16  *p_mag_shift) 
      
{ 
    Word16 region; 
    Word16 i; 
    Word16 index; 
    Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS]; 
    Word16 max_index; 
     
    Word16 temp; 
    Word16 temp1; 
    Word16 temp2; 
    Word32 acca; 
 
    index = 0; 
    move16(); 
 
    /* get 5 bits from the current code word */ 
    for (i=0; i<5; i++)  
    { 
        get_next_bit(bitobj); 
        index = shl(index,1); 
        index = add(index,bitobj->next_bit); 
    } 
    bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,5); 
 
    /* ESF_ADJUSTMENT_TO_RMS_INDEX compensates for the current (9/30/96) 
        IMLT being scaled to high by the ninth power of sqrt(2). */ 
    differential_region_power_index[0] = sub(index,ESF_ADJUSTMENT_TO_RMS_INDEX); 
    move16(); 
 
    /* obtain differential_region_power_index */ 
    for (region=1; regionnext_bit == 0) 
            { 
	            index = differential_region_power_decoder_tree[region][index][0]; 
                move16(); 
            } 
            else 
            { 
	            index = differential_region_power_decoder_tree[region][index][1]; 
                move16(); 
            } 
            bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1); 
            test(); 
        } while (index > 0); 
         
        differential_region_power_index[region] = negate(index); 
        move16(); 
    } 
 
    /* Reconstruct absolute_region_power_index[] from differential_region_power_index[]. */ 
    absolute_region_power_index[0] = differential_region_power_index[0]; 
    move16(); 
    for (region=1; region 0)  
        { 
            max_index = i; 
            move16(); 
        } 
        temp = add(temp,int_region_standard_deviation_table[i]); 
    } 
    i = 9; 
    move16(); 
 
    temp1 = sub(temp,8); 
    temp2 = sub(max_index,28); 
    test(); 
    test(); 
    logic16(); 
    test(); 
    logic16(); 
    while ((i >= 0) && ((temp1 >= 0) || (temp2 > 0)))  
    { 
        i = sub(i,1); 
        temp = shr(temp,1); 
        max_index = sub(max_index,2); 
        temp1 = sub(temp,8); 
        temp2 = sub(max_index,28); 
        test(); 
        test(); 
        logic16(); 
        test(); 
        logic16(); 
    } 
     
    *p_mag_shift = i; 
    move16(); 
     
    /* pointer arithmetic */ 
    temp = (Word16 )(REGION_POWER_TABLE_NUM_NEGATIVES + (*p_mag_shift * 2)); 
     
    for (region=0; region 0)  
    { 
        region = decoder_category_balances[i++]; 
        move16(); 
        decoder_power_categories[region] = add(decoder_power_categories[region],1); 
        move16(); 
        categorization_control = sub(categorization_control,1); 
    } 
 
} 
 
/*************************************************************************** 
 Function:    decode_vector_quantized_mlt_indices 
 
 Syntax:      void decode_vector_quantized_mlt_indices(Bit_Obj  *bitobj,                                       
                                                       Rand_Obj *randobj,                            
                                                       Word16   number_of_regions, 
                                                       Word16   *decoder_region_standard_deviation,  
                                                       Word16   *decoder_power_categories,           
                                                       Word16   *decoder_mlt_coefs)                  
              inputs:    Bit_Obj  *bitobj                            
                         Rand_Obj *randobj 
                         Word16   number_of_regions 
                         Word16   *decoder_region_standard_deviation 
                         Word16   *decoder_power_categories 
             
             
              outputs:   Word16   *decoder_mlt_coefs 
              
 
 Description: Decode MLT coefficients 
 
 Design Notes: 
  
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |    0.60      |    0.72 
          -------|--------------|----------------   
            MAX  |    0.67      |    0.76 
          -------|--------------|----------------  
				 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    0.77      |    0.98        |     1.28    
          -------|--------------|----------------|---------------- 
            MAX  |    1.05      |    1.18        |     1.36    
          -------|--------------|----------------|---------------- 
				 
***************************************************************************/ 
void decode_vector_quantized_mlt_indices(Bit_Obj  *bitobj, 
                                         Rand_Obj *randobj, 
                                         Word16   number_of_regions, 
                                         Word16   *decoder_region_standard_deviation, 
					                     Word16   *decoder_power_categories, 
					                     Word16   *decoder_mlt_coefs) 
{ 
    Word16 standard_deviation; 
    Word16 *decoder_mlt_ptr; 
    Word16 decoder_mlt_value; 
    Word16 noifillpos; 
    Word16 noifillneg; 
    Word16 noise_fill_factor[3] = {5793,8192,23170}; 
    Word16 region; 
    Word16 category; 
    Word16 j,n; 
    Word16 k[MAX_VECTOR_DIMENSION]; 
    Word16 vec_dim; 
    Word16 num_vecs; 
    Word16 index; 
    Word16 signs_index; 
    Word16 bit; 
    Word16 num_sign_bits; 
    Word16 ran_out_of_bits_flag; 
    Word16 *decoder_table_ptr; 
    Word16 random_word; 
     
    Word16 temp1; 
    Word16 temp; 
    Word32 acca; 
 
    ran_out_of_bits_flag = 0; 
    move16(); 
 
    for (region=0; regionnumber_of_bits_left <= 0)  
                    { 
                        ran_out_of_bits_flag = 1; 
                        move16(); 
    	                break; 
    	            } 
     
    	            get_next_bit(bitobj); 
	                 
                    test(); 
                    if (bitobj->next_bit == 0) 
	                { 
                        temp = shl(index,1); 
                        index = (Word16)*(decoder_table_ptr + temp); 
                        move16(); 
                    } 
	                else 
	                { 
                        temp = shl(index,1); 
                        index = (Word16)*(decoder_table_ptr + temp + 1); 
                        move16(); 
                    } 
	                bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1); 
                    test(); 
	             
                } while (index > 0); 
	   
                test(); 
                if (ran_out_of_bits_flag != 0) 
	                break; 
	   
                index = negate(index); 
	             
                /* convert index into array used to access the centroid table */ 
                /* get the number of sign bits in the index */ 
                num_sign_bits = index_to_array(index,k,category); 
 
	            temp = sub(bitobj->number_of_bits_left,num_sign_bits); 
                test(); 
                if (temp >= 0)  
                { 
	                test(); 
                    if (num_sign_bits != 0)  
                    { 
	                    signs_index = 0; 
	                    move16(); 
                        for (j=0; jnext_bit); 
		                    bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1); 
	                    } 
	                    temp = sub(num_sign_bits,1); 
                        bit = shl(1,(temp)); 
	                } 
	                 
                    for (j=0; jnumber_of_bits_left = sub(bitobj->number_of_bits_left,1); 
} 
/**************************************************************************************** 
 Function:    index_to_array  
 
 Syntax:      number_of_non_zero = index_to_array(Word16 index,  
                                                  Word16 array[MAX_VECTOR_DIMENSION], 
                                                  Word16 category) 
 
                inputs:  Word16 index 
                         Word16 category                      
                        
                outputs: Word16 array[MAX_VECTOR_DIMENSION] - used in decoder to access 
                                                             mlt_quant_centroid table 
                         
                         Word16 number_of_non_zero          - number of non zero elements 
                                                             in the array 
  
 Description: Computes an array of sign bits with the length of the category vector 
              Returns the number of sign bits and the array 
 
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |     0.00     |     0.00 
          -------|--------------|----------------   
            MAX  |     0.00     |     0.00 
          -------|--------------|----------------  
 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |     0.00     |     0.00       |      0.00    
          -------|--------------|----------------|---------------- 
            MAX  |     0.00     |     0.00       |      0.00    
          -------|--------------|----------------|---------------- 
 
****************************************************************************************/ 
Word16 index_to_array(Word16 index,Word16 *array,Word16 category) 
{ 
    Word16 j,q,p; 
    Word16 number_of_non_zero; 
    Word16 max_bin_plus_one; 
    Word16 inverse_of_max_bin_plus_one; 
    Word16 temp; 
 
    number_of_non_zero = 0; 
    move16(); 
 
    p = index; 
    move16(); 
 
    max_bin_plus_one = add(max_bin[category],1); 
    inverse_of_max_bin_plus_one = max_bin_plus_one_inverse[category]; 
    move16(); 
 
    temp = sub(vector_dimension[category],1); 
    for (j=temp; j>=0; j--)  
    { 
        q = mult(p,inverse_of_max_bin_plus_one); 
		temp = extract_l(L_mult0(q,max_bin_plus_one)); 
        array[j] = sub(p,temp); 
        move16(); 
 
        p = q; 
        move16(); 
 
        temp = array[j]; 
        move16(); 
        test(); 
        if (temp != 0)  
            number_of_non_zero = add(number_of_non_zero,1); 
    } 
    return(number_of_non_zero); 
} 
/*************************************************************************** 
 Function:     test_4_frame_errors 
 
 Syntax:       void test_4_frame_errors(Bit_Obj *bitobj,                         
                                        Word16 number_of_regions, 
                                        Word16 num_categorization_control_possibilities, 
                                        Word16 *frame_error_flag,                 
                                        Word16 categorization_control,           
                                        Word16 *absolute_region_power_index)     
         
               inputs:   bit_obj 
                         number_of_regions 
                         num_categorization_control_possibilities 
                         frame_error_flag 
                         categorization_control 
                         absolute_region_power_index 
                
                
               outputs:  frame_error_flag 
                
                
                
         
 Description:  Tests for error conditions and sets the frame_error_flag accordingly  
 
 Design Notes: 
  
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |    0.01      |     0.01 
          -------|--------------|----------------   
            MAX  |    0.04      |     0.08 
          -------|--------------|----------------  
				 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    0.01      |     0.01       |      0.01    
          -------|--------------|----------------|---------------- 
            MAX  |    0.02      |     0.06       |      0.08    
          -------|--------------|----------------|---------------- 
				 
***************************************************************************/ 
void test_4_frame_errors(Bit_Obj *bitobj, 
                         Word16 number_of_regions, 
                         Word16 num_categorization_control_possibilities, 
                         Word16 *frame_error_flag, 
                         Word16 categorization_control, 
                         Word16 *absolute_region_power_index) 
{ 
    Word16 region; 
    Word16 i; 
    Word16 temp; 
    Word32 acca; 
    Word32 accb; 
     
    /* Test for bit stream errors. */ 
 
    test(); 
    if (bitobj->number_of_bits_left > 0)  
    { 
        for (i=0; inumber_of_bits_left; i++)  
        { 
            get_next_bit(bitobj); 
            test(); 
            if (bitobj->next_bit == 0)  
            { 
                *frame_error_flag = 1; 
                move16(); 
            } 
        }	 
    } 
    else  
    { 
        temp = sub(categorization_control,sub(num_categorization_control_possibilities,1)); 
        test(); 
        if (temp < 0)  
        { 
            test(); 
            if (bitobj->number_of_bits_left < 0) 
            { 
                *frame_error_flag |= 2; 
                logic16(); 
            } 
        } 
    } 
 
    /* checks to ensure that abs_region_power_index is within range */ 
    /* the error flag is set if it is out of range */ 
    for (region=0; region 31) || 
            (absolute_region_power_index[region] < -8) */ 
 
        acca = L_add(absolute_region_power_index[region],ESF_ADJUSTMENT_TO_RMS_INDEX); 
        accb = L_sub(acca,31); 
        acca = L_add(acca,8); 
        test(); 
 
        /* the next line was modifed in release 1.2 to 
	   * correct miss typed code and error checking. 
	   */ 
        if ((accb > 0) || (acca < 0)) 
        { 
            *frame_error_flag |= 4; 
            logic16(); 
        } 
    } 
 
} 
/*************************************************************************** 
 Function:    error_handling 
 
 Syntax:      void error_handling(Word16 number_of_coefs, 
                                  Word16 number_of_valid_coefs, 
                                  Word16 *frame_error_flag,      
                                  Word16 *decoder_mlt_coefs,     
                                  Word16 *old_decoder_mlt_coefs, 
                                  Word16 *p_mag_shift,           
                                  Word16 *p_old_mag_shift)       
               
              inputs:  number_of_coefs 
                       number_of_valid_coefs 
                       frame_error_flag 
                       old_decoder_mlt_coefs 
                       p_old_mag_shift 
               
               
              outputs: decoder_mlt_coefs 
                       old_decoder_mlt_coefs 
                       p_mag_shift 
                       p_old_mag_shift 
  
        
 
 Description: If both the current and previous frames are errored,              
              set the mlt coefficients to 0. If only the current frame          
              is errored, then repeat the previous frame's mlt coefficients.    
     
 Design Notes: 
  
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |    0.02      |     0.02 
          -------|--------------|----------------   
            MAX  |    0.03      |     0.03 
          -------|--------------|----------------  
				 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    0.03      |     0.03       |     0.03    
          -------|--------------|----------------|---------------- 
            MAX  |    0.03      |     0.03       |     0.06    
          -------|--------------|----------------|---------------- 
				 
***************************************************************************/ 
void error_handling(Word16 number_of_coefs, 
                    Word16 number_of_valid_coefs, 
                    Word16 *frame_error_flag, 
                    Word16 *decoder_mlt_coefs, 
                    Word16 *old_decoder_mlt_coefs, 
                    Word16 *p_mag_shift, 
                    Word16 *p_old_mag_shift) 
{ 
    Word16 i; 
 
    test(); 
    if (*frame_error_flag != 0)  
    { 
 
        for (i = 0; i < number_of_valid_coefs; i++) 
        { 
            decoder_mlt_coefs[i] = old_decoder_mlt_coefs[i]; 
            move16(); 
        } 
 
        for (i = 0; i < number_of_valid_coefs; i++) 
        { 
            old_decoder_mlt_coefs[i] = 0; 
            move16(); 
        } 
         
        *p_mag_shift = *p_old_mag_shift; 
        move16(); 
 
        *p_old_mag_shift = 0; 
        move16(); 
    } 
    else  
    { 
        /* Store in case next frame is errored. */ 
        for (i = 0; i < number_of_valid_coefs; i++) 
        { 
            old_decoder_mlt_coefs[i] = decoder_mlt_coefs[i]; 
            move16(); 
        } 
   
        *p_old_mag_shift = *p_mag_shift; 
        move16(); 
    } 
 
 
    /* Zero out the upper 1/8 of the spectrum. */ 
    for (i = number_of_valid_coefs; i < number_of_coefs; i++) 
    { 
        decoder_mlt_coefs[i] = 0; 
        move16(); 
    } 
 
} 
/**************************************************************************************** 
 Function:    get_next_bit 
 
 Syntax:      void get_next_bit(Bit_Obj *bitobj) 
  
 Description: Returns the next bit in the current word inside the bit object 
  
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |    0.00      |    0.00 
          -------|--------------|----------------   
            MAX  |    0.00      |    0.00 
          -------|--------------|----------------  
 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    0.00      |    0.00        |     0.00    
          -------|--------------|----------------|---------------- 
            MAX  |    0.00      |    0.00        |     0.00    
          -------|--------------|----------------|---------------- 
 
****************************************************************************************/ 
void get_next_bit(Bit_Obj *bitobj) 
{ 
    Word16 temp; 
 
    test(); 
    if (bitobj->code_bit_count == 0) 
    {                         
        bitobj->current_word = *bitobj->code_word_ptr++;  
        move16(); 
        bitobj->code_bit_count = 16;            
        move16(); 
    } 
    bitobj->code_bit_count = sub(bitobj->code_bit_count,1); 
    temp = shr(bitobj->current_word,bitobj->code_bit_count); 
    logic16(); 
    bitobj->next_bit = (Word16 )(temp & 1); 
 
} 
/**************************************************************************************** 
 Function:    get_rand 
 
 Syntax:      Word16 get_rand(Rand_Obj *randobj) 
  
 Description: Returns a random Word16 based on the seeds inside the rand object   
  
 WMOPS:     7kHz |    24kbit    |    32kbit 
          -------|--------------|---------------- 
            AVG  |    0.00      |    0.00 
          -------|--------------|----------------   
            MAX  |    0.00      |    0.00 
          -------|--------------|----------------  
 
           14kHz |    24kbit    |    32kbit      |     48kbit 
          -------|--------------|----------------|---------------- 
            AVG  |    0.00      |    0.00        |     0.00    
          -------|--------------|----------------|---------------- 
            MAX  |    0.00      |    0.00        |     0.00    
          -------|--------------|----------------|---------------- 
 
****************************************************************************************/ 
Word16 get_rand(Rand_Obj *randobj) 
{ 
    Word16 random_word; 
    Word32 acca; 
 
    acca = L_add(randobj->seed0,randobj->seed3);  
    random_word = extract_l(acca); 
     
    logic16(); 
    test(); 
	if ((random_word & 32768L) != 0) 
        random_word = add(random_word,1); 
     
    randobj->seed3 = randobj->seed2; 
    move16(); 
    randobj->seed2 = randobj->seed1; 
    move16(); 
    randobj->seed1 = randobj->seed0; 
    move16(); 
    randobj->seed0 = random_word; 
    move16(); 
 
    return(random_word); 
}