123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /****************************************************************************************
- **
- ** 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_nocheck(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=0, raw_min_index=0;
- 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_nocheck(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_nocheck(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_nocheck(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_nocheck(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_nocheck(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_nocheck(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();
- }
- }
|