diff options
Diffstat (limited to 'third_party/g7221/decode/decoder.c')
-rw-r--r-- | third_party/g7221/decode/decoder.c | 1112 |
1 files changed, 1112 insertions, 0 deletions
diff --git a/third_party/g7221/decode/decoder.c b/third_party/g7221/decode/decoder.c new file mode 100644 index 00000000..c6b8c065 --- /dev/null +++ b/third_party/g7221/decode/decoder.c @@ -0,0 +1,1112 @@ +/*************************************************************************** +** +** 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(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(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(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 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; 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(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; j<num_sign_bits; j++) + { + get_next_bit(bitobj); + signs_index = shl(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(1,(temp)); + } + + for (j=0; j<vec_dim; j++) + { + acca = L_mult0(standard_deviation,mlt_quant_centroid[category][k[j]]); + acca = L_shr(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(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(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(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(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(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(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); +} |