diff options
Diffstat (limited to 'third_party/g7221/common/common.c')
-rw-r--r-- | third_party/g7221/common/common.c | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/third_party/g7221/common/common.c b/third_party/g7221/common/common.c new file mode 100644 index 00000000..66e32ad4 --- /dev/null +++ b/third_party/g7221/common/common.c @@ -0,0 +1,461 @@ +/**************************************************************************************** +** +** 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: common.c + + Purpose: Contains the functions used for both G.722.1 Annex C encoder and decoder + + Design Notes: + +****************************************************************************************/ +/**************************************************************************************** + Include files +****************************************************************************************/ +#include "defs.h" +#include "huff_def.h" +#include "huff_tab.h" +#include "tables.h" +#include "count.h" + +/**************************************************************************************** + Function: categorize + + Syntax: void categorize(Word16 number_of_available_bits, + Word16 number_of_regions, + Word16 num_categorization_control_possibilities, + Word16 rms_index, + Word16 power_categories, + Word16 category_balances) + + inputs: number_of_regions + num_categorization_control_possibilities + number_of_available_bits + rms_index[MAX_NUMBER_OF_REGIONS] + + outputs: power_categories[MAX_NUMBER_OF_REGIONS] + category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1] + + Description: Computes a series of categorizations + + WMOPS: 7kHz | 24kbit | 32kbit + -------|--------------|---------------- + AVG | 0.14 | 0.14 + -------|--------------|---------------- + MAX | 0.15 | 0.15 + -------|--------------|---------------- + + 14kHz | 24kbit | 32kbit | 48kbit + -------|--------------|----------------|---------------- + AVG | 0.42 | 0.45 | 0.48 + -------|--------------|----------------|---------------- + MAX | 0.47 | 0.52 | 0.52 + -------|--------------|----------------|---------------- + +****************************************************************************************/ +void categorize(Word16 number_of_available_bits, + Word16 number_of_regions, + Word16 num_categorization_control_possibilities, + Word16 *rms_index, + Word16 *power_categories, + Word16 *category_balances) +{ + + Word16 offset; + Word16 temp; + Word16 frame_size; + + /* At higher bit rates, there is an increase for most categories in average bit + consumption per region. We compensate for this by pretending we have fewer + available bits. */ + test(); + if (number_of_regions == NUMBER_OF_REGIONS) + { + frame_size = DCT_LENGTH; + } + else + { + frame_size = MAX_DCT_LENGTH; + } + + temp = sub(number_of_available_bits,frame_size); + + test(); + if (temp > 0) + { + number_of_available_bits = sub(number_of_available_bits,frame_size); + number_of_available_bits = extract_l(L_mult0(number_of_available_bits,5)); + number_of_available_bits = shr(number_of_available_bits,3); + number_of_available_bits = add(number_of_available_bits,frame_size); + } + + /* calculate the offset using the original category assignments */ + offset = calc_offset(rms_index,number_of_regions,number_of_available_bits); + + + + /* compute the power categories based on the uniform offset */ + compute_raw_pow_categories(power_categories,rms_index,number_of_regions,offset); + + + /* adjust the category assignments */ + /* compute the new power categories and category balances */ + comp_powercat_and_catbalance(power_categories,category_balances,rms_index,number_of_available_bits,number_of_regions,num_categorization_control_possibilities,offset); + +} + +/*************************************************************************** + Function: comp_powercat_and_catbalance + + Syntax: void comp_powercat_and_catbalance(Word16 *power_categories, + Word16 *category_balances, + Word16 *rms_index, + Word16 number_of_available_bits, + Word16 number_of_regions, + Word16 num_categorization_control_possibilities, + Word16 offset) + + + inputs: *rms_index + number_of_available_bits + number_of_regions + num_categorization_control_possibilities + offset + + outputs: *power_categories + *category_balances + + + Description: Computes the power_categories and the category balances + + WMOPS: 7kHz | 24kbit | 32kbit + -------|--------------|---------------- + AVG | 0.10 | 0.10 + -------|--------------|---------------- + MAX | 0.11 | 0.11 + -------|--------------|---------------- + + 14kHz | 24kbit | 32kbit | 48kbit + -------|--------------|----------------|---------------- + AVG | 0.32 | 0.35 | 0.38 + -------|--------------|----------------|---------------- + MAX | 0.38 | 0.42 | 0.43 + -------|--------------|----------------|---------------- + +***************************************************************************/ +void comp_powercat_and_catbalance(Word16 *power_categories, + Word16 *category_balances, + Word16 *rms_index, + Word16 number_of_available_bits, + Word16 number_of_regions, + Word16 num_categorization_control_possibilities, + Word16 offset) +{ + + Word16 expected_number_of_code_bits; + Word16 region; + Word16 max_region; + Word16 j; + Word16 max_rate_categories[MAX_NUMBER_OF_REGIONS]; + Word16 min_rate_categories[MAX_NUMBER_OF_REGIONS]; + Word16 temp_category_balances[2*MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES]; + Word16 raw_max, raw_min; + Word16 raw_max_index, raw_min_index; + Word16 max_rate_pointer, min_rate_pointer; + Word16 max, min; + Word16 itemp0; + Word16 itemp1; + Word16 min_plus_max; + Word16 two_x_number_of_available_bits; + + Word16 temp; + + expected_number_of_code_bits = 0; + move16(); + + for (region=0; region<number_of_regions; region++) + expected_number_of_code_bits = add(expected_number_of_code_bits,expected_bits_table[power_categories[region]]); + + + for (region=0; region<number_of_regions; region++) + { + max_rate_categories[region] = power_categories[region]; + move16(); + + min_rate_categories[region] = power_categories[region]; + move16(); + } + + max = expected_number_of_code_bits; + move16(); + min = expected_number_of_code_bits; + move16(); + max_rate_pointer = num_categorization_control_possibilities; + move16(); + min_rate_pointer = num_categorization_control_possibilities; + move16(); + + for (j=0; j<num_categorization_control_possibilities-1; j++) + { + min_plus_max = add(max,min); + two_x_number_of_available_bits = shl(number_of_available_bits,1); + + temp = sub(min_plus_max,two_x_number_of_available_bits); + test(); + if (temp <= 0) + { + raw_min = 99; + move16(); + /* Search from lowest freq regions to highest for best */ + /* region to reassign to a higher bit rate category. */ + for (region=0; region<number_of_regions; region++) + { + test(); + if (max_rate_categories[region] > 0) + { + itemp0 = shl(max_rate_categories[region],1); + itemp1 = sub(offset,rms_index[region]); + itemp0 = sub(itemp1,itemp0); + + temp = sub(itemp0,raw_min); + test(); + if (temp < 0) + { + raw_min = itemp0; + raw_min_index = region; + } + } + } + max_rate_pointer = sub(max_rate_pointer,1); + temp_category_balances[max_rate_pointer] = raw_min_index; + move16(); + + max = sub(max,expected_bits_table[max_rate_categories[raw_min_index]]); + max_rate_categories[raw_min_index] = sub(max_rate_categories[raw_min_index],1); + move16(); + + max = add(max,expected_bits_table[max_rate_categories[raw_min_index]]); + } + else + { + raw_max = -99; + move16(); + /* Search from highest freq regions to lowest for best region to reassign to + a lower bit rate category. */ + max_region = sub(number_of_regions,1); + for (region= max_region; region >= 0; region--) + { + temp = sub(min_rate_categories[region],(NUM_CATEGORIES-1)); + test(); + if (temp < 0) + { + itemp0 = shl(min_rate_categories[region],1); + itemp1 = sub(offset,rms_index[region]); + itemp0 = sub(itemp1,itemp0); + + temp = sub(itemp0,raw_max); + test(); + if (temp > 0) + { + raw_max = itemp0; + move16(); + raw_max_index = region; + move16(); + } + } + } + temp_category_balances[min_rate_pointer] = raw_max_index; + move16(); + + min_rate_pointer = add(min_rate_pointer,1); + min = sub(min,expected_bits_table[min_rate_categories[raw_max_index]]); + + min_rate_categories[raw_max_index] = add(min_rate_categories[raw_max_index],1); + move16(); + + min = add(min,expected_bits_table[min_rate_categories[raw_max_index]]); + } + } + + for (region=0; region<number_of_regions; region++) + { + power_categories[region] = max_rate_categories[region]; + move16(); + } + + for (j=0; j<num_categorization_control_possibilities-1; j++) + { + category_balances[j] = temp_category_balances[max_rate_pointer++]; + move16(); + } + +} +/*************************************************************************** + Function: calc_offset + + Syntax: offset=calc_offset(Word16 *rms_index,Word16 number_of_regions,Word16 available_bits) + + input: Word16 *rms_index + Word16 number_of_regions + Word16 available_bits + + output: Word16 offset + + Description: Calculates the the category offset. This is the shift required + To get the most out of the number of available bits. A binary + type search is used to find the offset. + + WMOPS: 7kHz | 24kbit | 32kbit + -------|--------------|---------------- + AVG | 0.04 | 0.04 + -------|--------------|---------------- + MAX | 0.04 | 0.04 + -------|--------------|---------------- + + 14kHz | 24kbit | 32kbit | 48kbit + -------|--------------|----------------|---------------- + AVG | 0.08 | 0.08 | 0.08 + -------|--------------|----------------|---------------- + MAX | 0.09 | 0.09 | 0.09 + -------|--------------|----------------|---------------- + +***************************************************************************/ +Word16 calc_offset(Word16 *rms_index,Word16 number_of_regions,Word16 available_bits) +{ + + Word16 answer; + Word16 delta; + Word16 test_offset; + Word16 region,j; + Word16 power_cats[MAX_NUMBER_OF_REGIONS]; + Word16 bits; + Word16 offset; + Word16 temp; + + /* initialize vars */ + answer = -32; + move16(); + delta = 32; + move16(); + + do + { + test_offset = add(answer,delta); + + /* obtain a category for each region */ + /* using the test offset */ + for (region=0; region<number_of_regions; region++) + { + j = sub(test_offset,rms_index[region]); + j = shr(j,1); + + /* Ensure j is between 0 and NUM_CAT-1 */ + test(); + if (j < 0) + { + j = 0; + move16(); + } + temp = sub(j,NUM_CATEGORIES-1); + test(); + if (temp > 0) + { + j = sub(NUM_CATEGORIES,1); + move16(); + } + power_cats[region] = j; + move16(); + } + bits = 0; + move16(); + + /* compute the number of bits that will be used given the cat assignments */ + for (region=0; region<number_of_regions; region++) + bits = add(bits,expected_bits_table[power_cats[region]]); + + /* if (bits > available_bits - 32) then divide the offset region for the bin search */ + offset = sub(available_bits,32); + temp = sub(bits,offset); + test(); + if (temp >= 0) + { + answer = test_offset; + move16(); + } + delta = shr(delta,1); + test(); /* for the while loop */ + } while (delta > 0); + + return(answer); +} +/*************************************************************************** + Function: compute_raw_pow_categories + + Syntax: void compute_raw_pow_categories(Word16 *power_categories, + Word16 *rms_index, + Word16 number_of_regions, + Word16 offset) + inputs: *rms_index + number_of_regions + offset + + outputs: *power_categories + + + + Description: This function computes the power categories given the offset + This is kind of redundant since they were already computed + in calc_offset to determine the offset. + + WMOPS: | 24kbit | 32kbit + -------|--------------|---------------- + AVG | 0.01 | 0.01 + -------|--------------|---------------- + MAX | 0.01 | 0.01 + -------|--------------|---------------- + + 14kHz | 24kbit | 32kbit | 48kbit + -------|--------------|----------------|---------------- + AVG | 0.01 | 0.01 | 0.01 + -------|--------------|----------------|---------------- + MAX | 0.01 | 0.01 | 0.01 + -------|--------------|----------------|---------------- + +***************************************************************************/ +void compute_raw_pow_categories(Word16 *power_categories,Word16 *rms_index,Word16 number_of_regions,Word16 offset) +{ + Word16 region; + Word16 j; + Word16 temp; + + for (region=0; region<number_of_regions; region++) + { + j = sub(offset,rms_index[region]); + j = shr(j,1); + + /* make sure j is between 0 and NUM_CAT-1 */ + test(); + if (j < 0) + { + j = 0; + move16(); + } + temp = sub(j,(NUM_CATEGORIES-1)); + test(); + if (temp > 0) + j = sub(NUM_CATEGORIES,1); + + power_categories[region] = j; + move16(); + } +} + |