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