| /*************************************************************************** |
| ** |
| ** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C |
| ** > Software Release 2.1 (2008-06) |
| ** (Simple repackaging; no change from 2005-05 Release 2.0 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; i<num_categorization_control_bits; i++) |
| { |
| get_next_bit(bitobj); |
| categorization_control = shl_nocheck(categorization_control,1); |
| categorization_control = add(categorization_control,bitobj->next_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_nocheck(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; region<number_of_regions; region++) |
| { |
| index = 0; |
| move16(); |
| do |
| { |
| get_next_bit(bitobj); |
| test(); |
| if (bitobj->next_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<number_of_regions; region++) |
| { |
| acca = L_add(absolute_region_power_index[region-1],differential_region_power_index[region]); |
| acca = L_add(acca,DRP_DIFF_MIN); |
| absolute_region_power_index[region] = extract_l(acca); |
| } |
| |
| /* Reconstruct decoder_region_standard_deviation[] from absolute_region_power_index[]. */ |
| /* DEBUG!!!! - This integer method jointly computes the mag_shift |
| and the standard deviations already mag_shift compensated. It |
| relies on REGION_POWER_STEPSIZE_DB being exactly 3.010299957 db |
| or a square root of 2 chnage in standard deviation. If |
| REGION_POWER_STEPSIZE_DB changes, this software must be |
| reworked. */ |
| |
| temp = 0; |
| move16(); |
| max_index = 0; |
| move16(); |
| for (region=0; region<number_of_regions; region++) |
| { |
| acca = L_add(absolute_region_power_index[region],REGION_POWER_TABLE_NUM_NEGATIVES); |
| i = extract_l(acca); |
| |
| temp1 = sub(i,max_index); |
| test(); |
| if (temp1 > 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_nocheck(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<number_of_regions; region++) |
| { |
| acca = L_add(absolute_region_power_index[region],temp); |
| i = extract_l(acca); |
| decoder_region_standard_deviation[region] = int_region_standard_deviation_table[i]; |
| move16(); |
| } |
| |
| } |
| |
| /*************************************************************************** |
| Function: rate_adjust_categories |
| |
| Syntax: void rate_adjust_categories(Word16 categorization_control, |
| Word16 *decoder_power_categories, |
| Word16 *decoder_category_balances) |
| |
| inputs: Word16 categorization_control, |
| Word16 *decoder_power_categories, |
| Word16 *decoder_category_balances |
| |
| outputs: Word16 categorization_control, |
| Word16 *decoder_power_categories, |
| |
| Description: Adjust the power categories based on the categorization control |
| |
| Design Notes: |
| |
| 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.01 | 0.01 | 0.01 |
| -------|--------------|----------------|---------------- |
| |
| ***************************************************************************/ |
| void rate_adjust_categories(Word16 categorization_control, |
| Word16 *decoder_power_categories, |
| Word16 *decoder_category_balances) |
| { |
| Word16 i; |
| Word16 region; |
| |
| i = 0; |
| move16(); |
| |
| test(); |
| while (categorization_control > 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 bit=0; |
| Word16 signs_index=0; |
| 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; region<number_of_regions; region++) |
| { |
| category = (Word16)decoder_power_categories[region]; |
| move16(); |
| acca = L_mult0(region,REGION_SIZE); |
| index = extract_l(acca); |
| decoder_mlt_ptr = &decoder_mlt_coefs[index]; |
| move16(); |
| standard_deviation = decoder_region_standard_deviation[region]; |
| move16(); |
| |
| temp = sub(category,7); |
| test(); |
| if (temp < 0) |
| { |
| /* Get the proper table of decoder tables, vec_dim, and num_vecs for the cat */ |
| decoder_table_ptr = (Word16 *) table_of_decoder_tables[category]; |
| move16(); |
| vec_dim = vector_dimension[category]; |
| move16(); |
| num_vecs = number_of_vectors[category]; |
| move16(); |
| |
| for (n=0; n<num_vecs; n++) |
| { |
| index = 0; |
| move16(); |
| |
| /* get index */ |
| do |
| { |
| test(); |
| if (bitobj->number_of_bits_left <= 0) |
| { |
| ran_out_of_bits_flag = 1; |
| move16(); |
| break; |
| } |
| |
| get_next_bit(bitobj); |
| |
| test(); |
| if (bitobj->next_bit == 0) |
| { |
| temp = shl_nocheck(index,1); |
| index = (Word16)*(decoder_table_ptr + temp); |
| move16(); |
| } |
| else |
| { |
| temp = shl_nocheck(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; j<num_sign_bits; j++) |
| { |
| get_next_bit(bitobj); |
| signs_index = shl_nocheck(signs_index,1); |
| signs_index = add(signs_index,bitobj->next_bit); |
| bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1); |
| } |
| temp = sub(num_sign_bits,1); |
| bit = shl_nocheck(1,(temp)); |
| } |
| |
| for (j=0; j<vec_dim; j++) |
| { |
| acca = L_mult0(standard_deviation,mlt_quant_centroid[category][k[j]]); |
| acca = L_shr_nocheck(acca,12); |
| decoder_mlt_value = extract_l(acca); |
| |
| test(); |
| if (decoder_mlt_value != 0) |
| { |
| test(); |
| if ((signs_index & bit) == 0) |
| decoder_mlt_value = negate(decoder_mlt_value); |
| bit = shr_nocheck(bit,1); |
| } |
| *decoder_mlt_ptr++ = decoder_mlt_value; |
| move16(); |
| } |
| } |
| else |
| { |
| ran_out_of_bits_flag = 1; |
| move16(); |
| break; |
| } |
| } |
| /* If ran out of bits during decoding do noise fill for remaining regions. */ |
| /* DEBUG!! - For now also redo all of last region with all noise fill. */ |
| test(); |
| if (ran_out_of_bits_flag != 0) |
| { |
| temp = add(region,1); |
| for (j=temp; j<number_of_regions; j++) |
| { |
| decoder_power_categories[j] = 7; |
| move16(); |
| } |
| category = 7; |
| move16(); |
| decoder_mlt_ptr = &decoder_mlt_coefs[region*REGION_SIZE]; |
| move16(); |
| } |
| } |
| |
| temp = sub(category,5); |
| temp1 = sub(category,6); |
| test(); |
| test(); |
| logic16(); |
| if ((temp == 0) || (temp1 == 0)) |
| { |
| |
| decoder_mlt_ptr = &decoder_mlt_coefs[region*REGION_SIZE]; |
| move16(); |
| noifillpos = mult(standard_deviation,noise_fill_factor[category - 5]); |
| noifillneg = negate(noifillpos); |
| |
| random_word = get_rand(randobj); |
| |
| for (j=0; j<10; j++) |
| { |
| test(); |
| if (*decoder_mlt_ptr == 0) |
| { |
| logic16(); |
| test(); |
| if ((random_word & 1) == 0) |
| { |
| temp1 = noifillneg; |
| move16(); |
| } |
| else |
| { |
| temp1 = noifillpos; |
| move16(); |
| } |
| *decoder_mlt_ptr = temp1; |
| move16(); |
| random_word = shr_nocheck(random_word,1); |
| } |
| /* pointer arithmetic */ |
| decoder_mlt_ptr++; |
| } |
| random_word = get_rand(randobj); |
| for (j=0; j<10; j++) |
| { |
| test(); |
| if (*decoder_mlt_ptr == 0) |
| { |
| logic16(); |
| test(); |
| if ((random_word & 1) == 0) |
| { |
| temp1 = noifillneg; |
| move16(); |
| } |
| else |
| { |
| temp1 = noifillpos; |
| move16(); |
| } |
| *decoder_mlt_ptr = temp1; |
| move16(); |
| random_word = shr_nocheck(random_word,1); |
| } |
| /* pointer arithmetic */ |
| decoder_mlt_ptr++; |
| } |
| } |
| |
| /* if (category == 7) */ |
| temp1 = sub(category,7); |
| test(); |
| if (temp1 == 0) |
| { |
| index = sub(category,5); |
| noifillpos = mult(standard_deviation,noise_fill_factor[index]); |
| noifillneg = negate(noifillpos); |
| |
| random_word = get_rand(randobj); |
| for (j=0; j<10; j++) |
| { |
| logic16(); |
| test(); |
| if ((random_word & 1) == 0) |
| { |
| temp1 = noifillneg; |
| move16(); |
| } |
| else |
| { |
| temp1 = noifillpos; |
| move16(); |
| } |
| *decoder_mlt_ptr++ = temp1; |
| move16(); |
| random_word = shr_nocheck(random_word,1); |
| } |
| random_word = get_rand(randobj); |
| for (j=0; j<10; j++) |
| { |
| logic16(); |
| test(); |
| if ((random_word & 1) == 0) |
| { |
| temp1 = noifillneg; |
| move16(); |
| } |
| else |
| { |
| temp1 = noifillpos; |
| move16(); |
| } |
| |
| *decoder_mlt_ptr++ = temp1; |
| move16(); |
| random_word = shr_nocheck(random_word,1); |
| } |
| } |
| } |
| |
| test(); |
| if (ran_out_of_bits_flag) |
| bitobj->number_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; i<bitobj->number_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<number_of_regions; region++) |
| { |
| /* the next two lines of comments were modified in release 1.2 |
| * to correct the description of the range of |
| * absolute_region_power_index[] to be tested in the next |
| * 9 lines of code. |
| */ |
| /* if ((absolute_region_power_index[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_nocheck(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); |
| } |