summaryrefslogtreecommitdiffstats
path: root/gst/siren/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/siren/common.c')
-rw-r--r--gst/siren/common.c505
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;
+}
+