freeswitch/libs/libg722_1/src/commonf.c

196 lines
6.5 KiB
C

/*
* g722_1 - a library for the G.722.1 and Annex C codecs
*
* commonf.c
*
* Adapted by Steve Underwood <steveu@coppice.org> 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 <config.h>
#endif
#include <inttypes.h>
#include <stdlib.h>
#include <math.h>
#include "g722_1/g722_1.h"
#include "defs.h"
#include "tables.h"
#include "huff_tab.h"
#if !defined(G722_1_USE_FIXED_POINT)
/* Compute a series of categorizations */
void categorize(int number_of_regions,
int number_of_available_bits,
int rms_index[MAX_NUMBER_OF_REGIONS],
int power_categories[MAX_NUMBER_OF_REGIONS],
int category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES - 1])
{
int region;
int i;
int expected_number_of_code_bits;
int delta;
int offset;
int test_offset;
int num_categorization_control_possibilities;
int max_rate_categories[MAX_NUMBER_OF_REGIONS];
int min_rate_categories[MAX_NUMBER_OF_REGIONS];
int temp_category_balances[2*MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES];
int raw_max;
int raw_min;
int raw_max_index;
int raw_min_index;
int max_rate_pointer;
int min_rate_pointer;
int max;
int min;
int itemp0;
if (number_of_regions == NUMBER_OF_REGIONS)
num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
else
num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
/* 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.
*/
if (number_of_regions == NUMBER_OF_REGIONS)
{
if (number_of_available_bits > FRAME_SIZE)
number_of_available_bits = FRAME_SIZE + (((number_of_available_bits - FRAME_SIZE)*5) >> 3);
}
else if (number_of_regions == MAX_NUMBER_OF_REGIONS)
{
if (number_of_available_bits > MAX_FRAME_SIZE)
number_of_available_bits = MAX_FRAME_SIZE + (((number_of_available_bits - MAX_FRAME_SIZE)*5) >> 3);
}
offset = -32;
delta = 32;
do
{
test_offset = offset + delta;
for (region = 0; region < number_of_regions; region++)
{
i = (test_offset - rms_index[region]) >> 1;
if (i < 0)
i = 0;
else if (i > NUM_CATEGORIES - 1)
i = NUM_CATEGORIES - 1;
power_categories[region] = i;
}
expected_number_of_code_bits = 0;
for (region = 0; region < number_of_regions; region++)
expected_number_of_code_bits += expected_bits_table[power_categories[region]];
if (expected_number_of_code_bits >= number_of_available_bits - 32)
offset = test_offset;
delta >>= 1;
}
while (delta > 0);
for (region = 0; region < number_of_regions; region++)
{
i = (offset - rms_index[region]) >> 1;
if (i < 0)
i = 0;
else if (i > NUM_CATEGORIES - 1)
i = NUM_CATEGORIES - 1;
power_categories[region] = i;
}
expected_number_of_code_bits = 0;
for (region = 0; region < number_of_regions; region++)
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;
raw_min_index = 0;
raw_max_index = 0;
for (i = 0; i < num_categorization_control_possibilities - 1; i++)
{
if (max + min <= 2*number_of_available_bits)
{
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 = offset - rms_index[region] - 2*max_rate_categories[region];
if (itemp0 < raw_min)
{
raw_min = itemp0;
raw_min_index = region;
}
}
}
max_rate_pointer--;
temp_category_balances[max_rate_pointer] = raw_min_index;
max -= expected_bits_table[max_rate_categories[raw_min_index]];
max_rate_categories[raw_min_index] -= 1;
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. */
for (region = number_of_regions - 1; region >= 0; region--)
{
if (min_rate_categories[region] < NUM_CATEGORIES - 1)
{
itemp0 = offset - rms_index[region] - 2*min_rate_categories[region];
if (itemp0 > raw_max)
{
raw_max = itemp0;
raw_max_index = region;
}
}
}
temp_category_balances[min_rate_pointer] = raw_max_index;
min_rate_pointer++;
min -= expected_bits_table[min_rate_categories[raw_max_index]];
min_rate_categories[raw_max_index]++;
min += expected_bits_table[min_rate_categories[raw_max_index]];
}
}
for (i = 0; i < number_of_regions; i++)
power_categories[i] = max_rate_categories[i];
for (i = 0; i < num_categorization_control_possibilities - 1; i++)
category_balances[i] = temp_category_balances[max_rate_pointer++];
}
/*- End of function --------------------------------------------------------*/
#endif
/*- End of file ------------------------------------------------------------*/