summaryrefslogtreecommitdiff
path: root/third_party/g7221/decode/decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/g7221/decode/decoder.c')
-rw-r--r--third_party/g7221/decode/decoder.c1112
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);
+}