| /* |
| * 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., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, 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 (void) |
| { |
| 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 == 32000) |
| *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; |
| } |