D-Modem/pjproject-2.11.1/third_party/g7221/decode/decoder.c
2021-10-29 14:41:03 -04:00

1113 lines
38 KiB
C

/***************************************************************************
**
** 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);
}