/**************************************************************************************** ** ** 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 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 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 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 0) j = sub(NUM_CATEGORIES,1); power_categories[region] = j; move16(); } }