diff options
Diffstat (limited to 'gst/siren/common.c')
-rw-r--r-- | gst/siren/common.c | 505 |
1 files changed, 505 insertions, 0 deletions
diff --git a/gst/siren/common.c b/gst/siren/common.c new file mode 100644 index 00000000..a85e6726 --- /dev/null +++ b/gst/siren/common.c @@ -0,0 +1,505 @@ +/* + * Siren Encoder/Decoder library + * + * @author: Youness Alaoui <kakaroto@kakaroto.homelinux.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "siren7.h" + +int region_size; +float region_size_inverse; + +float standard_deviation[64]; +float deviation_inverse[64]; +float region_power_table_boundary[63]; + +int expected_bits_table[8] = {52, 47, 43, 37, 29, 22, 16, 0}; +int vector_dimension[8] = {2, 2, 2, 4, 4, 5, 5, 1}; +int number_of_vectors[8] = {10, 10, 10, 5, 5, 4, 4, 20}; +float dead_zone[8] = {0.3f, 0.33f, 0.36f, 0.39f, 0.42f, 0.45f, 0.5f, 0.5f}; + +int max_bin[8] = { + 13, + 9, + 6, + 4, + 3, + 2, + 1, + 1}; + +float step_size[8] = { + 0.3536f, + 0.5f, + 0.70709997f, + 1.0f, + 1.4141999f, + 2.0f, + 2.8283999f, + 2.8283999f}; + +float step_size_inverse[8]; + +static int siren_initialized = 0; + +/* + STEPSIZE = 2.0 * log(sqrt(2)); +*/ +#define STEPSIZE 0.3010299957 + +void siren_init() { + int i; + float region_power; + + if (siren_initialized == 1) + return; + + region_size = 20; + region_size_inverse = 1.0f/region_size; + + for (i = 0; i < 64; i++) { + region_power = (float) pow(10, (i-24) * STEPSIZE); + standard_deviation[i] = (float) sqrt(region_power); + deviation_inverse[i] = (float) 1.0 / standard_deviation[i]; + } + + for (i = 0; i < 63; i++) + region_power_table_boundary[i] = (float) pow(10, (i-24 + 0.5) * STEPSIZE); + + for (i = 0; i < 8; i++) + step_size_inverse[i] = (float) 1.0 / step_size[i]; + + siren_dct4_init(); + siren_rmlt_init(); + + siren_initialized = 1; +} + + +int categorize_regions(int number_of_regions, int number_of_available_bits, int *absolute_region_power_index, int *power_categories, int *category_balance) { + int region, delta, i, temp; + int expected_number_of_code_bits; + int min, max; + int offset, + num_rate_control_possibilities, + raw_value, + raw_max_idx = 0, + raw_min_idx = 0; + int max_rate_categories[28]; + int min_rate_categories[28]; + int temp_category_balances[64]; + int *min_rate_ptr = NULL; + int *max_rate_ptr = NULL; + + if (number_of_regions == 14) { + num_rate_control_possibilities = 16; + if ( number_of_available_bits > 320) + number_of_available_bits = ((number_of_available_bits - 320) * 5/8) + 320; + } else { + num_rate_control_possibilities = 32; + if (number_of_regions == 28 && number_of_available_bits > 640) + number_of_available_bits = ((number_of_available_bits - 640) * 5/8) + 640; + } + + offset = -32; + for (delta = 32; number_of_regions > 0 && delta > 0; delta /= 2) { + expected_number_of_code_bits = 0; + for (region = 0; region < number_of_regions; region++) { + i = (delta + offset - absolute_region_power_index[region]) >> 1; + if (i > 7) + i = 7; + else if (i < 0) + i = 0; + + power_categories[region] = i; + expected_number_of_code_bits += expected_bits_table[i]; + + } + if (expected_number_of_code_bits >= number_of_available_bits-32) + offset += delta; + } + + expected_number_of_code_bits = 0; + for (region = 0; region < number_of_regions; region++) { + i = (offset - absolute_region_power_index[region]) >> 1; + if (i > 7) + i = 7; + else if (i < 0) + i = 0; + max_rate_categories[region] = min_rate_categories[region] = power_categories[region] = i; + expected_number_of_code_bits += expected_bits_table[i]; + } + + + min = max = expected_number_of_code_bits; + min_rate_ptr = max_rate_ptr = temp_category_balances + num_rate_control_possibilities; + for (i = 0; i < num_rate_control_possibilities -1; i++) { + if (min + max > number_of_available_bits * 2) { + raw_value = -99; + for (region = number_of_regions-1; region >= 0; region--) { + if (min_rate_categories[region] < 7) { + temp = offset - absolute_region_power_index[region] - 2*min_rate_categories[region]; + if (temp > raw_value) { + raw_value = temp; + raw_min_idx = region; + } + } + } + *min_rate_ptr++ = raw_min_idx; + min += expected_bits_table[min_rate_categories[raw_min_idx] + 1] - expected_bits_table[min_rate_categories[raw_min_idx]]; + min_rate_categories[raw_min_idx]++; + } else { + raw_value = 99; + for (region = 0; region < number_of_regions; region++) { + if (max_rate_categories[region] > 0 ) { + temp = offset - absolute_region_power_index[region] - 2*max_rate_categories[region]; + if (temp < raw_value) { + raw_value = temp; + raw_max_idx = region; + } + } + } + + *--max_rate_ptr = raw_max_idx; + max += expected_bits_table[max_rate_categories[raw_max_idx] - 1] - expected_bits_table[max_rate_categories[raw_max_idx]]; + max_rate_categories[raw_max_idx]--; + } + } + + for (region = 0; region < number_of_regions; region++) + power_categories[region] = max_rate_categories[region]; + + for (i = 0; i < num_rate_control_possibilities-1; i++) + category_balance[i] = *max_rate_ptr++; + + + return 0; +} + + + +/* + Looks like the flag means what kind of encoding is used + for now, it looks like : + 0 : the sample rate is not encoded in the frame + 1 - 2 : the sample rate is fixed in the frame + 3 : sample rate is variable and there is one for each frame +*/ + +int GetSirenCodecInfo(int flag, int sample_rate, int *number_of_coefs, int *sample_rate_bits, int *rate_control_bits, int *rate_control_possibilities, int *checksum_bits, int *esf_adjustment, int *scale_factor, int *number_of_regions, int *sample_rate_code, int *bits_per_frame ) { + switch (flag) { + case 0: + *number_of_coefs = 320; + *sample_rate_bits = 0; + *rate_control_bits = 4; + *rate_control_possibilities = 16; + *checksum_bits = 0; + *esf_adjustment = 7; + *number_of_regions = 14; + *sample_rate_code = 0; + *scale_factor = 22; + break; + case 1: + *number_of_coefs = 320; + *sample_rate_bits = 2; + *rate_control_bits = 4; + *rate_control_possibilities = 16; + *checksum_bits = 4; + *esf_adjustment = -2; + *number_of_regions = 14; + *scale_factor = 1; + if (sample_rate == 16000) + *sample_rate_code = 1; + else if (sample_rate == 24000) + *sample_rate_code = 2; + else if (sample_rate == 32000) + *sample_rate_code = 3; + else + return 3; + break; + case 2: + *number_of_coefs = 640; + *sample_rate_bits = 2; + *rate_control_bits = 5; + *rate_control_possibilities = 32; + *checksum_bits = 4; + *esf_adjustment = 7; + *number_of_regions = 28; + *scale_factor = 33; + + if (sample_rate == 24000) + *sample_rate_code = 1; + else if (sample_rate == 24000) + *sample_rate_code = 2; + else if (sample_rate == 48000) + *sample_rate_code = 3; + else + return 3; + + break; + case 3: + *number_of_coefs = 640; + *sample_rate_bits = 6; + *rate_control_bits = 5; + *rate_control_possibilities = 32; + *checksum_bits = 4; + *esf_adjustment = 7; + *scale_factor = 33; + + switch (sample_rate) { + case 8800: + *number_of_regions = 12; + *sample_rate_code = 59; + break; + case 9600: + *number_of_regions = 12; + *sample_rate_code = 1; + break; + case 10400: + *number_of_regions = 12; + *sample_rate_code = 13; + break; + case 10800: + *number_of_regions = 12; + *sample_rate_code = 14; + break; + case 11200: + *number_of_regions = 12; + *sample_rate_code = 15; + break; + case 11600: + *number_of_regions = 12; + *sample_rate_code = 16; + break; + case 12000: + *number_of_regions = 12; + *sample_rate_code = 2; + break; + case 12400: + *number_of_regions = 12; + *sample_rate_code = 17; + break; + case 12800: + *number_of_regions = 12; + *sample_rate_code = 18; + break; + case 13200: + *number_of_regions = 12; + *sample_rate_code = 19; + break; + case 13600: + *number_of_regions = 12; + *sample_rate_code = 20; + break; + case 14000: + *number_of_regions = 12; + *sample_rate_code = 21; + break; + case 14400: + *number_of_regions = 16; + *sample_rate_code = 3; + break; + case 14800: + *number_of_regions = 16; + *sample_rate_code = 22; + break; + case 15200: + *number_of_regions = 16; + *sample_rate_code = 23; + break; + case 15600: + *number_of_regions = 16; + *sample_rate_code = 24; + break; + case 16000: + *number_of_regions = 16; + *sample_rate_code = 25; + break; + case 16400: + *number_of_regions = 16; + *sample_rate_code = 26; + break; + case 16800: + *number_of_regions = 18; + *sample_rate_code = 4; + break; + case 17200: + *number_of_regions = 18; + *sample_rate_code = 27; + break; + case 17600: + *number_of_regions = 18; + *sample_rate_code = 28; + break; + case 18000: + *number_of_regions = 18; + *sample_rate_code = 29; + break; + case 18400: + *number_of_regions = 18; + *sample_rate_code = 30; + break; + case 18800: + *number_of_regions = 18; + *sample_rate_code = 31; + break; + case 19200: + *number_of_regions = 20; + *sample_rate_code = 5; + break; + case 19600: + *number_of_regions = 20; + *sample_rate_code = 32; + break; + case 20000: + *number_of_regions = 20; + *sample_rate_code = 33; + break; + case 20400: + *number_of_regions = 20; + *sample_rate_code = 34; + break; + case 20800: + *number_of_regions = 20; + *sample_rate_code = 35; + break; + case 21200: + *number_of_regions = 20; + *sample_rate_code = 36; + break; + case 21600: + *number_of_regions = 22; + *sample_rate_code = 6; + break; + case 22000: + *number_of_regions = 22; + *sample_rate_code = 37; + break; + case 22400: + *number_of_regions = 22; + *sample_rate_code = 38; + break; + case 22800: + *number_of_regions = 22; + *sample_rate_code = 39; + break; + case 23200: + *number_of_regions = 22; + *sample_rate_code = 40; + break; + case 23600: + *number_of_regions = 22; + *sample_rate_code = 41; + break; + case 24000: + *number_of_regions = 24; + *sample_rate_code = 7; + break; + case 24400: + *number_of_regions = 24; + *sample_rate_code = 42; + break; + case 24800: + *number_of_regions = 24; + *sample_rate_code = 43; + break; + case 25200: + *number_of_regions = 24; + *sample_rate_code = 44; + break; + case 25600: + *number_of_regions = 24; + *sample_rate_code = 45; + break; + case 26000: + *number_of_regions = 24; + *sample_rate_code = 46; + break; + case 26400: + *number_of_regions = 26; + *sample_rate_code = 8; + break; + case 26800: + *number_of_regions = 26; + *sample_rate_code = 47; + break; + case 27200: + *number_of_regions = 26; + *sample_rate_code = 48; + break; + case 27600: + *number_of_regions = 26; + *sample_rate_code = 49; + break; + case 28000: + *number_of_regions = 26; + *sample_rate_code = 50; + break; + case 28400: + *number_of_regions = 26; + *sample_rate_code = 51; + break; + case 28800: + *number_of_regions = 28; + *sample_rate_code = 9; + break; + case 29200: + *number_of_regions = 28; + *sample_rate_code = 52; + break; + case 29600: + *number_of_regions = 28; + *sample_rate_code = 53; + break; + case 30000: + *number_of_regions = 28; + *sample_rate_code = 54; + break; + case 30400: + *number_of_regions = 28; + *sample_rate_code = 55; + break; + case 30800: + *number_of_regions = 28; + *sample_rate_code = 56; + break; + case 31200: + *number_of_regions = 28; + *sample_rate_code = 10; + break; + case 31600: + *number_of_regions = 28; + *sample_rate_code = 57; + break; + case 32000: + *number_of_regions = 28; + *sample_rate_code = 58; + break; + default: + return 3; + break; + } + break; + default: + return 6; + } + + *bits_per_frame = sample_rate / 50; + return 0; +} + |