/* * g722_1 - a library for the G.722.1 and Annex C codecs * * common.c * * Adapted by Steve Underwood from the reference * code supplied with ITU G.722.1, which is: * * (C) 2004 Polycom, Inc. * All rights reserved. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /*! \file */ #if defined(HAVE_CONFIG_H) #include #endif #include #include #include "g722_1/g722_1.h" #include "defs.h" #include "huff_tab.h" #include "tables.h" #if defined(G722_1_USE_FIXED_POINT) static void compute_raw_pow_categories(int16_t *power_categories, int16_t *rms_index, int16_t number_of_regions, int16_t offset); /* Compute a series of categorizations */ void categorize(int16_t number_of_available_bits, int16_t number_of_regions, int16_t num_categorization_control_possibilities, int16_t *rms_index, int16_t *power_categories, int16_t *category_balances) { int16_t offset; int16_t temp; int16_t 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. */ frame_size = (number_of_regions == NUMBER_OF_REGIONS) ? DCT_LENGTH : MAX_DCT_LENGTH; temp = sub(number_of_available_bits, frame_size); if (temp > 0) { number_of_available_bits = sub(number_of_available_bits, frame_size); number_of_available_bits = (int16_t) 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); } /*- End of function --------------------------------------------------------*/ /* Compute the power_categories and the category balances */ void comp_powercat_and_catbalance(int16_t *power_categories, int16_t *category_balances, int16_t *rms_index, int16_t number_of_available_bits, int16_t number_of_regions, int16_t num_categorization_control_possibilities, int16_t offset) { int16_t expected_number_of_code_bits; int16_t region; int16_t max_region; int16_t j; int16_t max_rate_categories[MAX_NUMBER_OF_REGIONS]; int16_t min_rate_categories[MAX_NUMBER_OF_REGIONS]; int16_t temp_category_balances[2*MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES]; int16_t raw_max; int16_t raw_min; int16_t raw_max_index; int16_t raw_min_index; int16_t max_rate_pointer; int16_t min_rate_pointer; int16_t max; int16_t min; int16_t itemp0; int16_t itemp1; int16_t min_plus_max; int16_t two_x_number_of_available_bits; int16_t temp; expected_number_of_code_bits = 0; raw_max_index = 0; raw_min_index = 0; 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]; min_rate_categories[region] = power_categories[region]; } max = expected_number_of_code_bits; min = expected_number_of_code_bits; max_rate_pointer = num_categorization_control_possibilities; min_rate_pointer = num_categorization_control_possibilities; 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); if (temp <= 0) { raw_min = 99; /* 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++) { 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); 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; 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); max = add(max,expected_bits_table[max_rate_categories[raw_min_index]]); } else { raw_max = -99; /* 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)); 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); if (temp > 0) { raw_max = itemp0; raw_max_index = region; } } } temp_category_balances[min_rate_pointer] = raw_max_index; 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); 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]; for (j = 0; j < num_categorization_control_possibilities - 1; j++) category_balances[j] = temp_category_balances[max_rate_pointer++]; } /*- End of function --------------------------------------------------------*/ /* Calculate 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. */ int16_t calc_offset(int16_t *rms_index, int16_t number_of_regions, int16_t available_bits) { int16_t answer; int16_t delta; int16_t test_offset; int16_t region; int16_t j; int16_t power_cats[MAX_NUMBER_OF_REGIONS]; int16_t bits; int16_t offset; int16_t temp; /* initialize vars */ answer = -32; delta = 32; 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 */ if (j < 0) j = 0; temp = sub(j, NUM_CATEGORIES - 1); if (temp > 0) j = sub(NUM_CATEGORIES, 1); power_cats[region] = j; } bits = 0; /* 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); if (temp >= 0) answer = test_offset; delta = shr(delta, 1); } while (delta > 0); return answer; } /*- End of function --------------------------------------------------------*/ /* Compute the power categories given the offset This is kind of redundant since they were already computed in calc_offset to determine the offset. */ static void compute_raw_pow_categories(int16_t *power_categories, int16_t *rms_index, int16_t number_of_regions, int16_t offset) { int16_t region; int16_t j; int16_t 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 */ if (j < 0) j = 0; temp = sub(j, (NUM_CATEGORIES - 1)); if (temp > 0) j = sub(NUM_CATEGORIES, 1); power_categories[region] = j; } } /*- End of function --------------------------------------------------------*/ #endif /*- End of file ------------------------------------------------------------*/