summaryrefslogtreecommitdiff
path: root/third_party/g7221/encode
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2009-04-01 12:05:34 +0000
committerNanang Izzuddin <nanang@teluu.com>2009-04-01 12:05:34 +0000
commitd35a8221a34a562a88bdb7c947a7018080539c59 (patch)
treeaa5a5abd2d4421426668329a193d079d2d0b293d /third_party/g7221/encode
parent5c2400ce2b6ca229272457be1ff383df1d9c6139 (diff)
Ticket #774:
- Initial source of G.722.1/Annex C integration. - Disabled some "odd" modes of L16 codec (11kHz & 22kHz mono & stereo) while releasing some payload types. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2563 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'third_party/g7221/encode')
-rw-r--r--third_party/g7221/encode/dct4_a.c352
-rw-r--r--third_party/g7221/encode/dct4_a.h728
-rw-r--r--third_party/g7221/encode/encoder.c1125
-rw-r--r--third_party/g7221/encode/sam2coef.c270
4 files changed, 2475 insertions, 0 deletions
diff --git a/third_party/g7221/encode/dct4_a.c b/third_party/g7221/encode/dct4_a.c
new file mode 100644
index 00000000..24f4f5e0
--- /dev/null
+++ b/third_party/g7221/encode/dct4_a.c
@@ -0,0 +1,352 @@
+/*********************************************************************************
+** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
+** > Software Release 2.1 (2008-06)
+** (Simple repackaging; no change from 2005-05 Release 2.0 code)
+**
+** © 2004 Polycom, Inc.
+**
+** All rights reserved.
+**
+*********************************************************************************/
+
+/*********************************************************************************
+* Filename: dct_type_iv_a.c
+*
+* Purpose: Discrete Cosine Transform, Type IV used for MLT
+*
+* The basis functions are
+*
+* cos(PI*(t+0.5)*(k+0.5)/block_length)
+*
+* for time t and basis function number k. Due to the symmetry of the expression
+* in t and k, it is clear that the forward and inverse transforms are the same.
+*
+*********************************************************************************/
+
+/*********************************************************************************
+ Include files
+*********************************************************************************/
+#include "defs.h"
+#include "count.h"
+#include "dct4_a.h"
+
+/*********************************************************************************
+ External variable declarations
+*********************************************************************************/
+extern Word16 anal_bias[DCT_LENGTH];
+extern Word16 dct_core_a[DCT_LENGTH_DIV_32][DCT_LENGTH_DIV_32];
+extern cos_msin_t a_cos_msin_2 [DCT_LENGTH_DIV_32];
+extern cos_msin_t a_cos_msin_4 [DCT_LENGTH_DIV_16];
+extern cos_msin_t a_cos_msin_8 [DCT_LENGTH_DIV_8];
+extern cos_msin_t a_cos_msin_16[DCT_LENGTH_DIV_4];
+extern cos_msin_t a_cos_msin_32[DCT_LENGTH_DIV_2];
+extern cos_msin_t a_cos_msin_64[DCT_LENGTH];
+extern cos_msin_t *a_cos_msin_table[];
+
+/*********************************************************************************
+ Function: dct_type_iv_a
+
+ Syntax: void dct_type_iv_a (input, output, dct_length)
+ Word16 input[], output[], dct_length;
+
+ Description: Discrete Cosine Transform, Type IV used for MLT
+
+ Design Notes:
+
+ WMOPS: | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 1.14 | 1.14
+ -------|--------------|----------------
+ MAX | 1.14 | 1.14
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 2.57 | 2.57 | 2.57
+ -------|--------------|----------------|----------------
+ MAX | 2.57 | 2.57 | 2.57
+ -------|--------------|----------------|----------------
+
+*********************************************************************************/
+
+void dct_type_iv_a (Word16 *input,Word16 *output,Word16 dct_length)
+{
+ Word16 buffer_a[MAX_DCT_LENGTH], buffer_b[MAX_DCT_LENGTH], buffer_c[MAX_DCT_LENGTH];
+ Word16 *in_ptr, *in_ptr_low, *in_ptr_high, *next_in_base;
+ Word16 *out_ptr_low, *out_ptr_high, *next_out_base;
+ Word16 *out_buffer, *in_buffer, *buffer_swap;
+ Word16 in_val_low, in_val_high;
+ Word16 out_val_low, out_val_high;
+ Word16 in_low_even, in_low_odd;
+ Word16 in_high_even, in_high_odd;
+ Word16 out_low_even, out_low_odd;
+ Word16 out_high_even, out_high_odd;
+ Word16 *pair_ptr;
+ Word16 cos_even, cos_odd, msin_even, msin_odd;
+ Word16 neg_cos_odd;
+ Word16 neg_msin_even;
+ Word32 sum;
+ Word16 set_span, set_count, set_count_log, pairs_left, sets_left;
+ Word16 i,k;
+ Word16 index;
+ cos_msin_t **table_ptr_ptr, *cos_msin_ptr;
+
+ Word16 temp;
+ Word32 acca;
+
+ Word16 dct_length_log;
+
+
+ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Do the sum/difference butterflies, the first part of */
+ /* converting one N-point transform into N/2 two-point */
+ /* transforms, where N = 1 << DCT_LENGTH_LOG. = 64/128 */
+ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ test();
+ if (dct_length==DCT_LENGTH)
+ {
+ dct_length_log = DCT_LENGTH_LOG;
+
+ /* Add bias offsets */
+ for (i=0;i<dct_length;i++)
+ {
+ input[i] = add(input[i],anal_bias[i]);
+ move16();
+ }
+ }
+ else
+ dct_length_log = MAX_DCT_LENGTH_LOG;
+
+ index = 0L;
+ move16();
+
+ in_buffer = input;
+ move16();
+
+ out_buffer = buffer_a;
+ move16();
+
+ temp = sub(dct_length_log,2);
+ for (set_count_log=0;set_count_log<=temp;set_count_log++)
+ {
+
+ /*===========================================================*/
+ /* Initialization for the loop over sets at the current size */
+ /*===========================================================*/
+
+ /* set_span = 1 << (DCT_LENGTH_LOG - set_count_log); */
+ set_span = shr(dct_length,set_count_log);
+
+ set_count = shl(1,set_count_log);
+
+ in_ptr = in_buffer;
+ move16();
+
+ next_out_base = out_buffer;
+ move16();
+
+ /*=====================================*/
+ /* Loop over all the sets of this size */
+ /*=====================================*/
+
+ for (sets_left=set_count;sets_left>0;sets_left--)
+ {
+
+ /*||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Set up output pointers for the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||*/
+
+ out_ptr_low = next_out_base;
+ next_out_base = next_out_base + set_span;
+ out_ptr_high = next_out_base;
+
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Loop over all the butterflies in the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
+
+ do
+ {
+ in_val_low = *in_ptr++;
+ in_val_high = *in_ptr++;
+ acca = L_add(in_val_low,in_val_high);
+ acca = L_shr(acca,1);
+ out_val_low = extract_l(acca);
+
+ acca = L_sub(in_val_low,in_val_high);
+ acca = L_shr(acca,1);
+ out_val_high = extract_l(acca);
+
+ *out_ptr_low++ = out_val_low;
+ *--out_ptr_high = out_val_high;
+
+ test();
+ } while (out_ptr_low < out_ptr_high);
+
+ } /* End of loop over sets of the current size */
+
+ /*============================================================*/
+ /* Decide which buffers to use as input and output next time. */
+ /* Except for the first time (when the input buffer is the */
+ /* subroutine input) we just alternate the local buffers. */
+ /*============================================================*/
+
+ in_buffer = out_buffer;
+ move16();
+ if (out_buffer == buffer_a)
+ out_buffer = buffer_b;
+ else
+ out_buffer = buffer_a;
+ index = add(index,1);
+
+ } /* End of loop over set sizes */
+
+
+ /*++++++++++++++++++++++++++++++++*/
+ /* Do N/2 two-point transforms, */
+ /* where N = 1 << DCT_LENGTH_LOG */
+ /*++++++++++++++++++++++++++++++++*/
+
+ pair_ptr = in_buffer;
+ move16();
+
+ buffer_swap = buffer_c;
+ move16();
+
+ temp = sub(dct_length_log,1);
+ temp = shl(1,temp);
+
+ for (pairs_left=temp; pairs_left > 0; pairs_left--)
+ {
+ for ( k=0; k<CORE_SIZE; k++ )
+ {
+ sum=0L;
+ move32();
+ for ( i=0; i<CORE_SIZE; i++ )
+ {
+ sum = L_mac(sum, pair_ptr[i],dct_core_a[i][k]);
+ }
+ buffer_swap[k] = round(sum);
+ }
+ /* address arithmetic */
+ pair_ptr += CORE_SIZE;
+ buffer_swap += CORE_SIZE;
+ }
+
+ for (i=0;i<dct_length;i++)
+ {
+ in_buffer[i] = buffer_c[i];
+ move16();
+ }
+
+ table_ptr_ptr = a_cos_msin_table;
+
+ /*++++++++++++++++++++++++++++++*/
+ /* Perform rotation butterflies */
+ /*++++++++++++++++++++++++++++++*/
+ temp = sub(dct_length_log,2);
+ for (set_count_log = temp; set_count_log >= 0; set_count_log--)
+ {
+ /*===========================================================*/
+ /* Initialization for the loop over sets at the current size */
+ /*===========================================================*/
+ /* set_span = 1 << (DCT_LENGTH_LOG - set_count_log); */
+ set_span = shr(dct_length,set_count_log);
+
+ set_count = shl(1,set_count_log);
+ next_in_base = in_buffer;
+ move16();
+
+ test();
+ if (set_count_log == 0)
+ {
+ next_out_base = output;
+ }
+ else
+ {
+ next_out_base = out_buffer;
+ }
+
+
+ /*=====================================*/
+ /* Loop over all the sets of this size */
+ /*=====================================*/
+ for (sets_left = set_count; sets_left > 0;sets_left--)
+ {
+ /*|||||||||||||||||||||||||||||||||||||||||*/
+ /* Set up the pointers for the current set */
+ /*|||||||||||||||||||||||||||||||||||||||||*/
+ in_ptr_low = next_in_base;
+ move16();
+ temp = shr(set_span,1);
+
+ /* address arithmetic */
+ in_ptr_high = in_ptr_low + temp;
+ next_in_base += set_span;
+ out_ptr_low = next_out_base;
+ next_out_base += set_span;
+ out_ptr_high = next_out_base;
+ cos_msin_ptr = *table_ptr_ptr;
+
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Loop over all the butterfly pairs in the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
+
+ do
+ {
+ /* address arithmetic */
+ in_low_even = *in_ptr_low++;
+ in_low_odd = *in_ptr_low++;
+ in_high_even = *in_ptr_high++;
+ in_high_odd = *in_ptr_high++;
+ cos_even = cos_msin_ptr[0].cosine;
+ move16();
+ msin_even = cos_msin_ptr[0].minus_sine;
+ move16();
+ cos_odd = cos_msin_ptr[1].cosine;
+ move16();
+ msin_odd = cos_msin_ptr[1].minus_sine;
+ move16();
+ cos_msin_ptr += 2;
+
+ sum = 0L;
+ sum=L_mac(sum,cos_even,in_low_even);
+ neg_msin_even = negate(msin_even);
+ sum=L_mac(sum,neg_msin_even,in_high_even);
+ out_low_even = round(sum);
+
+ sum = 0L;
+ sum=L_mac(sum,msin_even,in_low_even);
+ sum=L_mac(sum,cos_even,in_high_even);
+ out_high_even= round(sum);
+
+ sum = 0L;
+ sum=L_mac(sum,cos_odd,in_low_odd);
+ sum=L_mac(sum,msin_odd,in_high_odd);
+ out_low_odd= round(sum);
+
+ sum = 0L;
+ sum=L_mac(sum,msin_odd,in_low_odd);
+ neg_cos_odd = negate(cos_odd);
+ sum=L_mac(sum,neg_cos_odd,in_high_odd);
+ out_high_odd= round(sum);
+
+ *out_ptr_low++ = out_low_even;
+ *--out_ptr_high = out_high_even;
+ *out_ptr_low++ = out_low_odd;
+ *--out_ptr_high = out_high_odd;
+ test();
+ } while (out_ptr_low < out_ptr_high);
+
+ } /* End of loop over sets of the current size */
+
+ /*=============================================*/
+ /* Swap input and output buffers for next time */
+ /*=============================================*/
+
+ buffer_swap = in_buffer;
+ in_buffer = out_buffer;
+ out_buffer = buffer_swap;
+ table_ptr_ptr++;
+ }
+}
+
diff --git a/third_party/g7221/encode/dct4_a.h b/third_party/g7221/encode/dct4_a.h
new file mode 100644
index 00000000..74f3d939
--- /dev/null
+++ b/third_party/g7221/encode/dct4_a.h
@@ -0,0 +1,728 @@
+/****************************************************************************
+**
+** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
+** > Software Release 2.1 (2008-06)
+** (Simple repackaging; no change from 2005-05 Release 2.0 code)
+**
+** © 2004 Polycom, Inc.
+**
+** All rights reserved.
+**
+****************************************************************************/
+
+/****************************************************************************
+ Filename: dct4_a.h
+
+ Purpose: Contains tables used by dct4_a.c
+
+ Design Notes:
+
+****************************************************************************/
+
+/***************************************************************************
+ Include files
+***************************************************************************/
+#include <stdio.h>
+#include <math.h>
+
+typedef struct
+{
+ Word16 cosine;
+ Word16 minus_sine;
+} cos_msin_t;
+
+cos_msin_t a_cos_msin_2[10] = {
+ { 29805 , -1171 } ,
+ { 29621 , -3506 } ,
+ { 29255 , -5819 } ,
+ { 28708 , -8097 } ,
+ { 27984 , -10324 } ,
+ { 27088 , -12488 } ,
+ { 26025 , -14575 } ,
+ { 24801 , -16572 } ,
+ { 23425 , -18466 } ,
+ { 21903 , -20247 }
+ };
+cos_msin_t a_cos_msin_4[20] = {
+ { 29822 , -586 } ,
+ { 29776 , -1756 } ,
+ { 29684 , -2924 } ,
+ { 29547 , -4087 } ,
+ { 29364 , -5244 } ,
+ { 29135 , -6392 } ,
+ { 28862 , -7531 } ,
+ { 28544 , -8659 } ,
+ { 28182 , -9773 } ,
+ { 27776 , -10871 } ,
+ { 27328 , -11954 } ,
+ { 26838 , -13017 } ,
+ { 26306 , -14061 } ,
+ { 25734 , -15083 } ,
+ { 25122 , -16081 } ,
+ { 24471 , -17055 } ,
+ { 23783 , -18003 } ,
+ { 23057 , -18923 } ,
+ { 22297 , -19813 } ,
+ { 21502 , -20673 }
+ };
+cos_msin_t a_cos_msin_8[40] = {
+ { 29827 , -293 } ,
+ { 29815 , -878 } ,
+ { 29792 , -1464 } ,
+ { 29758 , -2048 } ,
+ { 29712 , -2632 } ,
+ { 29654 , -3215 } ,
+ { 29586 , -3797 } ,
+ { 29505 , -4377 } ,
+ { 29414 , -4955 } ,
+ { 29311 , -5532 } ,
+ { 29196 , -6106 } ,
+ { 29071 , -6678 } ,
+ { 28934 , -7248 } ,
+ { 28786 , -7814 } ,
+ { 28627 , -8378 } ,
+ { 28457 , -8938 } ,
+ { 28276 , -9495 } ,
+ { 28084 , -10049 } ,
+ { 27882 , -10598 } ,
+ { 27668 , -11144 } ,
+ { 27444 , -11685 } ,
+ { 27209 , -12221 } ,
+ { 26964 , -12753 } ,
+ { 26709 , -13280 } ,
+ { 26443 , -13802 } ,
+ { 26167 , -14318 } ,
+ { 25881 , -14829 } ,
+ { 25584 , -15335 } ,
+ { 25278 , -15834 } ,
+ { 24963 , -16327 } ,
+ { 24637 , -16814 } ,
+ { 24302 , -17295 } ,
+ { 23958 , -17769 } ,
+ { 23605 , -18236 } ,
+ { 23242 , -18695 } ,
+ { 22871 , -19148 } ,
+ { 22490 , -19594 } ,
+ { 22101 , -20031 } ,
+ { 21704 , -20461 } ,
+ { 21298 , -20884 }
+ };
+cos_msin_t a_cos_msin_16[80] = {
+ { 29828 , -146 } ,
+ { 29825 , -439 } ,
+ { 29819 , -732 } ,
+ { 29811 , -1025 } ,
+ { 29799 , -1317 } ,
+ { 29785 , -1610 } ,
+ { 29767 , -1902 } ,
+ { 29747 , -2194 } ,
+ { 29724 , -2486 } ,
+ { 29698 , -2778 } ,
+ { 29670 , -3069 } ,
+ { 29638 , -3360 } ,
+ { 29604 , -3651 } ,
+ { 29567 , -3942 } ,
+ { 29526 , -4232 } ,
+ { 29483 , -4521 } ,
+ { 29438 , -4811 } ,
+ { 29389 , -5099 } ,
+ { 29338 , -5388 } ,
+ { 29283 , -5676 } ,
+ { 29226 , -5963 } ,
+ { 29166 , -6249 } ,
+ { 29103 , -6535 } ,
+ { 29038 , -6821 } ,
+ { 28969 , -7106 } ,
+ { 28898 , -7390 } ,
+ { 28824 , -7673 } ,
+ { 28748 , -7956 } ,
+ { 28668 , -8237 } ,
+ { 28586 , -8518 } ,
+ { 28501 , -8799 } ,
+ { 28413 , -9078 } ,
+ { 28323 , -9357 } ,
+ { 28229 , -9634 } ,
+ { 28133 , -9911 } ,
+ { 28035 , -10187 } ,
+ { 27933 , -10461 } ,
+ { 27829 , -10735 } ,
+ { 27723 , -11008 } ,
+ { 27613 , -11279 } ,
+ { 27501 , -11550 } ,
+ { 27387 , -11819 } ,
+ { 27269 , -12088 } ,
+ { 27149 , -12355 } ,
+ { 27027 , -12621 } ,
+ { 26901 , -12885 } ,
+ { 26774 , -13149 } ,
+ { 26643 , -13411 } ,
+ { 26510 , -13672 } ,
+ { 26375 , -13932 } ,
+ { 26237 , -14190 } ,
+ { 26096 , -14447 } ,
+ { 25953 , -14702 } ,
+ { 25807 , -14956 } ,
+ { 25659 , -15209 } ,
+ { 25509 , -15460 } ,
+ { 25356 , -15710 } ,
+ { 25200 , -15958 } ,
+ { 25043 , -16205 } ,
+ { 24882 , -16450 } ,
+ { 24720 , -16693 } ,
+ { 24554 , -16935 } ,
+ { 24387 , -17175 } ,
+ { 24217 , -17414 } ,
+ { 24045 , -17651 } ,
+ { 23871 , -17886 } ,
+ { 23694 , -18119 } ,
+ { 23515 , -18351 } ,
+ { 23334 , -18581 } ,
+ { 23150 , -18809 } ,
+ { 22964 , -19036 } ,
+ { 22776 , -19260 } ,
+ { 22586 , -19483 } ,
+ { 22394 , -19704 } ,
+ { 22199 , -19923 } ,
+ { 22003 , -20140 } ,
+ { 21804 , -20355 } ,
+ { 21603 , -20568 } ,
+ { 21400 , -20779 } ,
+ { 21195 , -20988 }
+ };
+cos_msin_t a_cos_msin_32[160]= {
+ { 29828 , -73 } ,
+ { 29827 , -220 } ,
+ { 29826 , -366 } ,
+ { 29824 , -512 } ,
+ { 29821 , -659 } ,
+ { 29817 , -805 } ,
+ { 29813 , -952 } ,
+ { 29808 , -1098 } ,
+ { 29802 , -1244 } ,
+ { 29796 , -1390 } ,
+ { 29789 , -1537 } ,
+ { 29781 , -1683 } ,
+ { 29772 , -1829 } ,
+ { 29763 , -1975 } ,
+ { 29753 , -2121 } ,
+ { 29742 , -2267 } ,
+ { 29730 , -2413 } ,
+ { 29718 , -2559 } ,
+ { 29705 , -2705 } ,
+ { 29692 , -2851 } ,
+ { 29677 , -2997 } ,
+ { 29662 , -3142 } ,
+ { 29646 , -3288 } ,
+ { 29630 , -3433 } ,
+ { 29613 , -3579 } ,
+ { 29595 , -3724 } ,
+ { 29576 , -3869 } ,
+ { 29557 , -4014 } ,
+ { 29537 , -4159 } ,
+ { 29516 , -4304 } ,
+ { 29494 , -4449 } ,
+ { 29472 , -4594 } ,
+ { 29449 , -4738 } ,
+ { 29426 , -4883 } ,
+ { 29401 , -5027 } ,
+ { 29376 , -5172 } ,
+ { 29351 , -5316 } ,
+ { 29324 , -5460 } ,
+ { 29297 , -5604 } ,
+ { 29269 , -5747 } ,
+ { 29241 , -5891 } ,
+ { 29211 , -6034 } ,
+ { 29181 , -6178 } ,
+ { 29151 , -6321 } ,
+ { 29119 , -6464 } ,
+ { 29087 , -6607 } ,
+ { 29054 , -6749 } ,
+ { 29021 , -6892 } ,
+ { 28987 , -7034 } ,
+ { 28952 , -7177 } ,
+ { 28916 , -7319 } ,
+ { 28880 , -7460 } ,
+ { 28843 , -7602 } ,
+ { 28805 , -7744 } ,
+ { 28767 , -7885 } ,
+ { 28728 , -8026 } ,
+ { 28688 , -8167 } ,
+ { 28648 , -8308 } ,
+ { 28607 , -8448 } ,
+ { 28565 , -8589 } ,
+ { 28522 , -8729 } ,
+ { 28479 , -8869 } ,
+ { 28435 , -9008 } ,
+ { 28391 , -9148 } ,
+ { 28346 , -9287 } ,
+ { 28300 , -9426 } ,
+ { 28253 , -9565 } ,
+ { 28206 , -9703 } ,
+ { 28158 , -9842 } ,
+ { 28109 , -9980 } ,
+ { 28060 , -10118 } ,
+ { 28010 , -10255 } ,
+ { 27959 , -10393 } ,
+ { 27908 , -10530 } ,
+ { 27856 , -10667 } ,
+ { 27803 , -10803 } ,
+ { 27750 , -10940 } ,
+ { 27696 , -11076 } ,
+ { 27641 , -11212 } ,
+ { 27586 , -11347 } ,
+ { 27529 , -11482 } ,
+ { 27473 , -11617 } ,
+ { 27415 , -11752 } ,
+ { 27357 , -11886 } ,
+ { 27299 , -12021 } ,
+ { 27239 , -12154 } ,
+ { 27179 , -12288 } ,
+ { 27119 , -12421 } ,
+ { 27057 , -12554 } ,
+ { 26996 , -12687 } ,
+ { 26933 , -12819 } ,
+ { 26870 , -12951 } ,
+ { 26806 , -13083 } ,
+ { 26741 , -13215 } ,
+ { 26676 , -13346 } ,
+ { 26610 , -13476 } ,
+ { 26544 , -13607 } ,
+ { 26477 , -13737 } ,
+ { 26409 , -13867 } ,
+ { 26340 , -13996 } ,
+ { 26271 , -14125 } ,
+ { 26202 , -14254 } ,
+ { 26132 , -14383 } ,
+ { 26061 , -14511 } ,
+ { 25989 , -14638 } ,
+ { 25917 , -14766 } ,
+ { 25844 , -14893 } ,
+ { 25771 , -15020 } ,
+ { 25697 , -15146 } ,
+ { 25622 , -15272 } ,
+ { 25547 , -15397 } ,
+ { 25471 , -15523 } ,
+ { 25394 , -15648 } ,
+ { 25317 , -15772 } ,
+ { 25239 , -15896 } ,
+ { 25161 , -16020 } ,
+ { 25082 , -16143 } ,
+ { 25003 , -16266 } ,
+ { 24923 , -16389 } ,
+ { 24842 , -16511 } ,
+ { 24760 , -16632 } ,
+ { 24678 , -16754 } ,
+ { 24596 , -16875 } ,
+ { 24513 , -16995 } ,
+ { 24429 , -17115 } ,
+ { 24345 , -17235 } ,
+ { 24260 , -17354 } ,
+ { 24174 , -17473 } ,
+ { 24088 , -17592 } ,
+ { 24002 , -17710 } ,
+ { 23914 , -17827 } ,
+ { 23827 , -17945 } ,
+ { 23738 , -18061 } ,
+ { 23649 , -18178 } ,
+ { 23560 , -18293 } ,
+ { 23470 , -18409 } ,
+ { 23379 , -18524 } ,
+ { 23288 , -18638 } ,
+ { 23196 , -18752 } ,
+ { 23104 , -18866 } ,
+ { 23011 , -18979 } ,
+ { 22917 , -19092 } ,
+ { 22824 , -19204 } ,
+ { 22729 , -19316 } ,
+ { 22634 , -19427 } ,
+ { 22538 , -19538 } ,
+ { 22442 , -19649 } ,
+ { 22345 , -19759 } ,
+ { 22248 , -19868 } ,
+ { 22150 , -19977 } ,
+ { 22052 , -20086 } ,
+ { 21953 , -20194 } ,
+ { 21854 , -20301 } ,
+ { 21754 , -20408 } ,
+ { 21653 , -20515 } ,
+ { 21552 , -20621 } ,
+ { 21451 , -20726 } ,
+ { 21349 , -20831 } ,
+ { 21246 , -20936 } ,
+ { 21143 , -21040 }
+ };
+cos_msin_t a_cos_msin_64[320] = {
+{29827, -34},
+{29827, -106},
+{29827, -177},
+{29827, -249},
+{29826, -320},
+{29825, -392},
+{29824, -463},
+{29823, -535},
+{29821, -606},
+{29819, -678},
+{29818, -750},
+{29816, -821},
+{29814, -893},
+{29812, -964},
+{29809, -1035},
+{29807, -1106},
+{29804, -1177},
+{29801, -1249},
+{29797, -1320},
+{29795, -1392},
+{29791, -1463},
+{29787, -1535},
+{29784, -1606},
+{29780, -1678},
+{29776, -1749},
+{29771, -1820},
+{29767, -1892},
+{29763, -1963},
+{29758, -2035},
+{29753, -2106},
+{29748, -2177},
+{29742, -2249},
+{29737, -2320},
+{29731, -2391},
+{29726, -2462},
+{29719, -2534},
+{29713, -2605},
+{29707, -2676},
+{29701, -2747},
+{29694, -2819},
+{29686, -2890},
+{29680, -2961},
+{29673, -3032},
+{29665, -3103},
+{29658, -3174},
+{29650, -3245},
+{29643, -3316},
+{29635, -3387},
+{29626, -3459},
+{29618, -3529},
+{29610, -3600},
+{29601, -3671},
+{29592, -3742},
+{29583, -3813},
+{29574, -3884},
+{29564, -3955},
+{29554, -4026},
+{29544, -4097},
+{29535, -4167},
+{29525, -4238},
+{29514, -4309},
+{29504, -4380},
+{29493, -4450},
+{29483, -4521},
+{29472, -4591},
+{29461, -4662},
+{29450, -4733},
+{29439, -4803},
+{29427, -4874},
+{29415, -4944},
+{29403, -5015},
+{29391, -5085},
+{29379, -5155},
+{29366, -5226},
+{29353, -5296},
+{29341, -5367},
+{29328, -5438},
+{29314, -5508},
+{29301, -5578},
+{29289, -5648},
+{29274, -5718},
+{29260, -5788},
+{29247, -5858},
+{29232, -5928},
+{29218, -5998},
+{29204, -6068},
+{29188, -6139},
+{29175, -6209},
+{29159, -6279},
+{29145, -6348},
+{29128, -6418},
+{29114, -6488},
+{29097, -6557},
+{29082, -6627},
+{29066, -6697},
+{29050, -6767},
+{29034, -6837},
+{29017, -6906},
+{29001, -6975},
+{28984, -7045},
+{28966, -7114},
+{28950, -7184},
+{28933, -7254},
+{28915, -7323},
+{28897, -7392},
+{28880, -7461},
+{28862, -7530},
+{28843, -7600},
+{28825, -7669},
+{28807, -7738},
+{28788, -7806},
+{28769, -7875},
+{28751, -7944},
+{28732, -8014},
+{28712, -8082},
+{28692, -8151},
+{28672, -8219},
+{28653, -8289},
+{28633, -8357},
+{28613, -8425},
+{28593, -8494},
+{28572, -8563},
+{28551, -8632},
+{28531, -8700},
+{28510, -8768},
+{28488, -8837},
+{28468, -8905},
+{28447, -8973},
+{28425, -9041},
+{28403, -9109},
+{28381, -9177},
+{28359, -9245},
+{28336, -9313},
+{28315, -9381},
+{28292, -9448},
+{28269, -9517},
+{28246, -9584},
+{28223, -9652},
+{28200, -9720},
+{28176, -9787},
+{28153, -9854},
+{28129, -9922},
+{28105, -9990},
+{28082, -10056},
+{28057, -10124},
+{28032, -10191},
+{28009, -10258},
+{27984, -10326},
+{27959, -10392},
+{27934, -10460},
+{27909, -10526},
+{27883, -10593},
+{27858, -10661},
+{27832, -10727},
+{27807, -10794},
+{27780, -10860},
+{27754, -10927},
+{27728, -10993},
+{27701, -11059},
+{27676, -11126},
+{27648, -11192},
+{27622, -11259},
+{27595, -11324},
+{27567, -11391},
+{27540, -11456},
+{27512, -11523},
+{27484, -11588},
+{27456, -11655},
+{27429, -11720},
+{27401, -11786},
+{27372, -11852},
+{27344, -11917},
+{27315, -11982},
+{27286, -12049},
+{27257, -12114},
+{27229, -12179},
+{27199, -12244},
+{27169, -12309},
+{27140, -12375},
+{27110, -12439},
+{27080, -12505},
+{27050, -12570},
+{27019, -12634},
+{26990, -12699},
+{26958, -12764},
+{26928, -12828},
+{26897, -12892},
+{26866, -12956},
+{26835, -13021},
+{26804, -13086},
+{26773, -13149},
+{26741, -13214},
+{26709, -13278},
+{26677, -13342},
+{26645, -13406},
+{26613, -13470},
+{26581, -13534},
+{26549, -13597},
+{26515, -13661},
+{26483, -13725},
+{26450, -13788},
+{26417, -13851},
+{26384, -13915},
+{26350, -13978},
+{26316, -14041},
+{26283, -14103},
+{26248, -14166},
+{26215, -14229},
+{26180, -14292},
+{26146, -14355},
+{26112, -14417},
+{26077, -14480},
+{26042, -14543},
+{26008, -14605},
+{25972, -14667},
+{25937, -14730},
+{25901, -14792},
+{25866, -14854},
+{25830, -14916},
+{25794, -14977},
+{25759, -15039},
+{25723, -15101},
+{25687, -15162},
+{25650, -15224},
+{25613, -15286},
+{25577, -15347},
+{25540, -15408},
+{25503, -15470},
+{25465, -15531},
+{25428, -15592},
+{25391, -15653},
+{25353, -15714},
+{25315, -15774},
+{25277, -15834},
+{25240, -15895},
+{25201, -15956},
+{25162, -16016},
+{25124, -16076},
+{25086, -16136},
+{25047, -16196},
+{25008, -16256},
+{24969, -16316},
+{24930, -16375},
+{24891, -16436},
+{24851, -16496},
+{24811, -16555},
+{24772, -16615},
+{24732, -16674},
+{24692, -16732},
+{24652, -16791},
+{24612, -16852},
+{24572, -16911},
+{24531, -16969},
+{24490, -17027},
+{24449, -17086},
+{24408, -17145},
+{24367, -17203},
+{24325, -17261},
+{24284, -17320},
+{24242, -17379},
+{24200, -17436},
+{24158, -17494},
+{24116, -17552},
+{24075, -17610},
+{24032, -17668},
+{23990, -17725},
+{23947, -17782},
+{23904, -17840},
+{23862, -17897},
+{23819, -17954},
+{23775, -18011},
+{23732, -18068},
+{23689, -18125},
+{23645, -18181},
+{23602, -18238},
+{23558, -18294},
+{23514, -18351},
+{23470, -18407},
+{23426, -18464},
+{23381, -18520},
+{23337, -18576},
+{23293, -18632},
+{23248, -18688},
+{23202, -18743},
+{23158, -18799},
+{23112, -18854},
+{23068, -18910},
+{23022, -18964},
+{22977, -19020},
+{22931, -19074},
+{22885, -19129},
+{22839, -19185},
+{22793, -19239},
+{22747, -19294},
+{22700, -19348},
+{22655, -19403},
+{22607, -19457},
+{22561, -19511},
+{22514, -19565},
+{22467, -19619},
+{22421, -19673},
+{22373, -19726},
+{22326, -19780},
+{22279, -19834},
+{22230, -19887},
+{22183, -19940},
+{22135, -19993},
+{22087, -20047},
+{22039, -20099},
+{21991, -20152},
+{21942, -20205},
+{21894, -20257},
+{21845, -20309},
+{21797, -20362},
+{21748, -20413},
+{21699, -20466},
+{21650, -20518},
+{21601, -20570},
+{21551, -20621},
+{21502, -20674}
+};
+
+cos_msin_t *a_cos_msin_table[] = {a_cos_msin_2, a_cos_msin_4,
+ a_cos_msin_8, a_cos_msin_16,
+ a_cos_msin_32,a_cos_msin_64
+ };
+
+Word16 dct_core_a[10][10] = {
+
+{ 10453, 10196, 9688, 8941, 7973, 6810, 5479, 4013, 2448, 823 },
+{ 10196, 7973, 4013, -823, -5479, -8941, -10453, -9688, -6810, -2448 },
+{ 9688 , 4013, -4013, -9688, -9688, -4013, 4013, 9688, 9688, 4013 },
+{ 8941 , -823, -9688, -7973, 2448, 10196, 6810, -4013, -10453, -5479 },
+{ 7973 , -5479, -9688, 2448, 10453, 823, -10196, -4013, 8941, 6810 },
+{ 6810 , -8941, -4013, 10196, 823, -10453, 2448, 9688, -5479, -7973 },
+{ 5479 , -10453, 4013, 6810, -10196, 2448, 7973, -9688, 823, 8941 },
+{ 4013 , -9688, 9688, -4013, -4013, 9688, -9688, 4013, 4013, -9688 },
+{ 2448 , -6810, 9688, -10453, 8941, -5479, 823, 4013, -7973, 10196 },
+{ 823 , -2448, 4013, -5479, 6810, -7973, 8941, -9688, 10196, -10453 }};
+
+Word16 anal_bias[320] = {
+ 1, 1, 3, 1, 4, 1, 3, -2, 4, 3,
+ 4, 1, 3, 0, 2, -3, 0, 0, 2, 2,
+ 4, 1, 1, -5, 4, 1, 2, -1, 0, -1,
+ 1, -2, 0, 2, 2, 2, 4, 1, 3, 0,
+ 5, 3, 2, 0, 3, 0, 1, -4, 1, 1,
+ 2, 0, 4, 0, 1, -4, 6, 1, 3, -1,
+ 1, 0, 0, -4, 1, 1, 3, 1, 3, 2,
+ 4, -2, 4, 3, 5, 1, 3, 0, 1, -3,
+ 1, 1, 2, 0, 4, 1, 2, -4, 4, 2,
+ 2, -1, 1, -1, 1, -4, 0, 0, 3, 0,
+ 5, 2, 3, -1, 6, 2, 5, 0, 4, 0,
+ 1, -3, 1, 0, 3, 0, 4, 0, 1, -3,
+ 4, 1, 3, -1, 1, -2, 1, -4, 0, 1,
+ 2, 1, 3, 2, 2, -2, 4, 3, 3, 0,
+ 3, 0, 0, -2, 1, 0, 2, 0, 5, -1,
+ 1, -3, 4, 2, 2, 0, 2, -3, 1, -4,
+ -1, 1, 2, 2, 4, 1, 3, -1, 5, 2,
+ 2, 0, 3, -1, 2, -3, 0, 1, 2, 2,
+ 4, 0, 1, -5, 5, 1, 3, 0, 2, -1,
+ 0, -2, 1, 2, 2, 2, 4, 1, 0, 0,
+ 4, 2, 4, 1, 4, -1, 1, -4, 0, 1,
+ 3, 1, 5, 1, 1, -2, 4, 0, 2, 0,
+ 2, -1, 0, -2, 0, 1, 1, 1, 4, 2,
+ 3, -2, 5, 4, 4, 0, 3, 0, 3, -4,
+ 1, 2, 2, 0, 4, 1, 0, -3, 4, 2,
+ 3, -1, 1, -1, 1, -4, 0, 2, 3, 1,
+ 4, 1, 3, 0, 3, 3, 4, 1, 2, 0,
+ 1, -3, 2, 2, 2, 1, 5, 0, 1, -4,
+ 4, 1, 3, -2, 3, -1, 0, -2, 0, 2,
+ 2, 0, 5, 1, 4, -1, 4, 3, 4, 1,
+ 3, 0, 1, -4, 2, 0, 3, 1, 5, 0,
+ 1, -5, 5, 2, 2, 0, 0, 0, 0, -4};
+
diff --git a/third_party/g7221/encode/encoder.c b/third_party/g7221/encode/encoder.c
new file mode 100644
index 00000000..0ec8cf85
--- /dev/null
+++ b/third_party/g7221/encode/encoder.c
@@ -0,0 +1,1125 @@
+/***************************************************************************
+**
+** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
+** > Software Release 2.1 (2008-06)
+** (Simple repackaging; no change from 2005-05 Release 2.0 code)
+**
+** © 2004 Polycom, Inc.
+**
+** All rights reserved.
+**
+***************************************************************************/
+
+/***************************************************************************
+ Filename: encoder.c
+
+ Purpose: Contains files used to implement the G.722.1 Annex C encoder
+
+ Design Notes:
+
+***************************************************************************/
+
+/***************************************************************************
+ Include files
+***************************************************************************/
+
+#include <stdio.h>
+#include <math.h>
+#include "defs.h"
+#include "huff_def.h"
+#include "tables.h"
+#include "count.h"
+
+/***************************************************************************
+ Function: encoder
+
+ Syntax: void encoder(Word16 number_of_available_bits,
+ Word16 number_of_regions,
+ Word16 mlt_coefs,
+ Word16 mag_shift,
+ Word16 out_words)
+
+ inputs: number_of_available_bits
+ number_of_regions
+ mag_shift
+ mlt_coefs[DCT_LENGTH]
+
+ outputs: out_words[MAX_BITS_PER_FRAME/16]
+
+
+ Description: Encodes the mlt coefs into out_words using G.722.1 Annex C
+
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.93 | 1.04
+ -------|--------------|----------------
+ MAX | 1.20 | 1.28
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 1.39 | 1.71 | 2.01
+ -------|--------------|----------------|----------------
+ MAX | 2.00 | 2.30 | 2.52
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+void encoder(Word16 number_of_available_bits,
+ Word16 number_of_regions,
+ Word16 *mlt_coefs,
+ Word16 mag_shift,
+ Word16 *out_words)
+{
+
+ Word16 num_categorization_control_bits;
+ Word16 num_categorization_control_possibilities;
+ Word16 number_of_bits_per_frame;
+ Word16 number_of_envelope_bits;
+ Word16 categorization_control;
+ Word16 region;
+ Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
+ Word16 power_categories[MAX_NUMBER_OF_REGIONS];
+ Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];
+ Word16 drp_num_bits[MAX_NUMBER_OF_REGIONS+1];
+ UWord16 drp_code_bits[MAX_NUMBER_OF_REGIONS+1];
+ Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];
+ UWord32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];
+ Word16 mag_shift_offset;
+
+ Word16 temp;
+
+ /* initialize variables */
+ test();
+ if (number_of_regions == NUMBER_OF_REGIONS)
+ {
+ num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS;
+ move16();
+ num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
+ move16();
+ }
+ else
+ {
+ num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS;
+ move16();
+ num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
+ move16();
+ }
+
+ number_of_bits_per_frame = number_of_available_bits;
+ move16();
+
+ for (region=0; region<number_of_regions; region++)
+ {
+ region_mlt_bit_counts[region] = 0;
+ move16();
+ }
+
+ /* Estimate power envelope. */
+ number_of_envelope_bits = compute_region_powers(mlt_coefs,
+ mag_shift,
+ drp_num_bits,
+ drp_code_bits,
+ absolute_region_power_index,
+ number_of_regions);
+
+ /* Adjust number of available bits based on power envelope estimate */
+ temp = sub(number_of_available_bits,number_of_envelope_bits);
+ number_of_available_bits = sub(temp,num_categorization_control_bits);
+
+ /* get categorizations */
+ categorize(number_of_available_bits,
+ number_of_regions,
+ num_categorization_control_possibilities,
+ absolute_region_power_index,
+ power_categories,
+ category_balances);
+
+ /* Adjust absolute_region_category_index[] for mag_shift.
+ This assumes that REGION_POWER_STEPSIZE_DB is defined
+ to be exactly 3.010299957 or 20.0 times log base 10
+ of square root of 2. */
+ temp = shl(mag_shift,1);
+ mag_shift_offset = add(temp,REGION_POWER_TABLE_NUM_NEGATIVES);
+
+ for (region=0; region<number_of_regions; region++)
+ {
+ absolute_region_power_index[region] = add(absolute_region_power_index[region],mag_shift_offset);
+ move16();
+ }
+
+ /* adjust the absolute power region index based on the mlt coefs */
+ adjust_abs_region_power_index(absolute_region_power_index,mlt_coefs,number_of_regions);
+
+
+ /* quantize and code the mlt coefficients based on categorizations */
+ vector_quantize_mlts(number_of_available_bits,
+ number_of_regions,
+ num_categorization_control_possibilities,
+ mlt_coefs,
+ absolute_region_power_index,
+ power_categories,
+ category_balances,
+ &categorization_control,
+ region_mlt_bit_counts,
+ region_mlt_bits);
+
+ /* stuff bits into words */
+ bits_to_words(region_mlt_bits,
+ region_mlt_bit_counts,
+ drp_num_bits,
+ drp_code_bits,
+ out_words,
+ categorization_control,
+ number_of_regions,
+ num_categorization_control_bits,
+ number_of_bits_per_frame);
+
+}
+
+/***************************************************************************
+ Function: bits_to_words
+
+ Syntax: bits_to_words(UWord32 *region_mlt_bits,
+ Word16 *region_mlt_bit_counts,
+ Word16 *drp_num_bits,
+ UWord16 *drp_code_bits,
+ Word16 *out_words,
+ Word16 categorization_control,
+ Word16 number_of_regions,
+ Word16 num_categorization_control_bits,
+ Word16 number_of_bits_per_frame)
+
+
+ Description: Stuffs the bits into words for output
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.09 | 0.12
+ -------|--------------|----------------
+ MAX | 0.10 | 0.13
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.12 | 0.15 | 0.19
+ -------|--------------|----------------|----------------
+ MAX | 0.14 | 0.17 | 0.21
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void bits_to_words(UWord32 *region_mlt_bits,
+ Word16 *region_mlt_bit_counts,
+ Word16 *drp_num_bits,
+ UWord16 *drp_code_bits,
+ Word16 *out_words,
+ Word16 categorization_control,
+ Word16 number_of_regions,
+ Word16 num_categorization_control_bits,
+ Word16 number_of_bits_per_frame)
+{
+ Word16 out_word_index = 0;
+ Word16 j;
+ Word16 region;
+ Word16 out_word;
+ Word16 region_bit_count;
+ Word16 current_word_bits_left;
+ UWord16 slice;
+ Word16 out_word_bits_free = 16;
+ UWord32 *in_word_ptr;
+ UWord32 current_word;
+
+ Word32 acca;
+ Word32 accb;
+ Word16 temp;
+
+ /* First set up the categorization control bits to look like one more set of region power bits. */
+ out_word = 0;
+ move16();
+
+ drp_num_bits[number_of_regions] = num_categorization_control_bits;
+ move16();
+
+ drp_code_bits[number_of_regions] = (UWord16)categorization_control;
+ move16();
+
+ /* These code bits are right justified. */
+ for (region=0; region <= number_of_regions; region++)
+ {
+ current_word_bits_left = drp_num_bits[region];
+ move16();
+
+ current_word = (UWord32)drp_code_bits[region];
+ move16();
+
+ j = sub(current_word_bits_left,out_word_bits_free);
+
+ test();
+ if (j >= 0)
+ {
+ temp = extract_l(L_shr(current_word,j));
+ out_word = add(out_word,temp);
+
+ out_words[out_word_index++] = out_word;
+ move16();
+
+ out_word_bits_free = 16;
+ move16();
+
+ out_word_bits_free = sub(out_word_bits_free,j);
+
+ acca = (current_word << out_word_bits_free);
+ out_word = extract_l(acca);
+ }
+ else
+ {
+ j = negate(j);
+
+ acca = (current_word << j);
+ accb = L_deposit_l(out_word);
+ acca = L_add(accb,acca);
+ out_word = extract_l(acca);
+
+ out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
+ }
+ }
+
+ /* These code bits are left justified. */
+
+ for (region=0;region<number_of_regions; region++)
+ {
+ accb = L_deposit_l(out_word_index);
+ accb = L_shl(accb,4);
+ accb = L_sub(accb,number_of_bits_per_frame);
+ test();
+ if(accb < 0)
+ {
+ temp = shl(region,2);
+ in_word_ptr = &region_mlt_bits[temp];
+ region_bit_count = region_mlt_bit_counts[region];
+ move16();
+
+ temp = sub(32,region_bit_count);
+ test();
+ if(temp > 0)
+ current_word_bits_left = region_bit_count;
+ else
+ current_word_bits_left = 32;
+
+ current_word = *in_word_ptr++;
+
+ acca = L_deposit_l(out_word_index);
+ acca = L_shl(acca,4);
+ acca = L_sub(acca,number_of_bits_per_frame);
+
+ /* from while loop */
+ test();
+ test();
+ logic16();
+ while ((region_bit_count > 0) && (acca < 0))
+ {
+ /* from while loop */
+ test();
+ test();
+ logic16();
+
+ temp = sub(current_word_bits_left,out_word_bits_free);
+ test();
+ if (temp >= 0)
+ {
+ temp = sub(32,out_word_bits_free);
+ accb = LU_shr(current_word,temp);
+ slice = (UWord16)extract_l(accb);
+
+ out_word = add(out_word,slice);
+
+ test();
+ current_word <<= out_word_bits_free;
+
+ current_word_bits_left = sub(current_word_bits_left,out_word_bits_free);
+ out_words[out_word_index++] = extract_l(out_word);
+ move16();
+
+ out_word = 0;
+ move16();
+
+ out_word_bits_free = 16;
+ move16();
+ }
+ else
+ {
+ temp = sub(32,current_word_bits_left);
+ accb = LU_shr(current_word,temp);
+ slice = (UWord16)extract_l(accb);
+
+ temp = sub(out_word_bits_free,current_word_bits_left);
+ test();
+ accb = slice << temp;
+ acca = L_deposit_l(out_word);
+ acca = L_add(acca,accb);
+ out_word = extract_l(acca);
+ out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
+
+ current_word_bits_left = 0;
+ move16();
+ }
+
+ test();
+ if (current_word_bits_left == 0)
+ {
+ current_word = *in_word_ptr++;
+ region_bit_count = sub(region_bit_count,32);
+
+ /* current_word_bits_left = MIN(32,region_bit_count); */
+ temp = sub(32,region_bit_count);
+ test();
+ if(temp > 0)
+ current_word_bits_left = region_bit_count;
+ else
+ current_word_bits_left = 32;
+
+ }
+ acca = L_deposit_l(out_word_index);
+ acca = L_shl(acca,4);
+ acca = L_sub(acca,number_of_bits_per_frame);
+ }
+ accb = L_deposit_l(out_word_index);
+ accb = L_shl(accb,4);
+ accb = L_sub(accb,number_of_bits_per_frame);
+ }
+ }
+
+ /* Fill out with 1's. */
+
+ test();
+ while (acca < 0)
+ {
+ test();
+ current_word = 0x0000ffff;
+ move32();
+
+ temp = sub(16,out_word_bits_free);
+ acca = LU_shr(current_word,temp);
+ slice = (UWord16)extract_l(acca);
+
+ out_word = add(out_word,slice);
+ out_words[out_word_index++] = out_word;
+ move16();
+
+ out_word = 0;
+ move16();
+
+ out_word_bits_free = 16;
+ move16();
+
+ acca = L_deposit_l(out_word_index);
+ acca = L_shl(acca,4);
+ acca = L_sub(acca,number_of_bits_per_frame);
+ }
+}
+/***************************************************************************
+ Function: adjust_abs_region_power_index
+
+ Syntax: adjust_abs_region_power_index(Word16 *absolute_region_power_index,
+ Word16 *mlt_coefs,
+ Word16 number_of_regions)
+
+ inputs: *mlt_coefs
+ *absolute_region_power_index
+ number_of_regions
+
+ outputs: *absolute_region_power_index
+
+ Description: Adjusts the absolute power index
+
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.03 | 0.03
+ -------|--------------|----------------
+ MAX | 0.12 | 0.12
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.03 | 0.03 | 0.03
+ -------|--------------|----------------|----------------
+ MAX | 0.14 | 0.14 | 0.14
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions)
+{
+ Word16 n,i;
+ Word16 region;
+ Word16 *raw_mlt_ptr;
+
+ Word32 acca;
+ Word16 temp;
+
+ for (region=0; region<number_of_regions; region++)
+ {
+ n = sub(absolute_region_power_index[region],39);
+ n = shr(n,1);
+
+ test();
+ if (n > 0)
+ {
+ temp = extract_l(L_mult0(region,REGION_SIZE));
+
+ raw_mlt_ptr = &mlt_coefs[temp];
+
+ for (i=0; i<REGION_SIZE; i++)
+ {
+ acca = L_shl(*raw_mlt_ptr,16);
+ acca = L_add(acca,32768L);
+ acca = L_shr(acca,n);
+ acca = L_shr(acca,16);
+ *raw_mlt_ptr++ = extract_l(acca);
+ }
+
+ temp = shl(n,1);
+ temp = sub(absolute_region_power_index[region],temp);
+ absolute_region_power_index[region] = temp;
+ move16();
+ }
+ }
+}
+
+/***************************************************************************
+ Function: compute_region_powers
+
+ Syntax: Word16 compute_region_powers(Word16 *mlt_coefs,
+ Word16 mag_shift,
+ Word16 *drp_num_bits,
+ UWord16 *drp_code_bits,
+ Word16 *absolute_region_power_index,
+ Word16 number_of_regions)
+ mlt_coefs[DCT_LENGTH];
+ mag_shift;
+ drp_num_bits[MAX_NUMBER_OF_REGIONS];
+ drp_code_bits[MAX_NUMBER_OF_REGIONS];
+ absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
+ number_of_regions;
+
+ Description: Computes the power for each of the regions
+
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.09 | 0.09
+ -------|--------------|----------------
+ MAX | 0.13 | 0.13
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.20 | 0.20 | 0.20
+ -------|--------------|----------------|----------------
+ MAX | 0.29 | 0.29 | 0.29
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+Word16 compute_region_powers(Word16 *mlt_coefs,
+ Word16 mag_shift,
+ Word16 *drp_num_bits,
+ UWord16 *drp_code_bits,
+ Word16 *absolute_region_power_index,
+ Word16 number_of_regions)
+{
+
+ Word16 *input_ptr;
+ Word32 long_accumulator;
+ Word16 itemp1;
+ Word16 power_shift;
+ Word16 region;
+ Word16 j;
+ Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];
+ Word16 number_of_bits;
+
+ Word32 acca;
+ Word16 temp;
+ Word16 temp1;
+ Word16 temp2;
+
+
+ input_ptr = mlt_coefs;
+ for (region=0; region<number_of_regions; region++)
+ {
+ long_accumulator = L_deposit_l(0);
+
+ for (j=0; j<REGION_SIZE; j++)
+ {
+ itemp1 = *input_ptr++;
+ move16();
+ long_accumulator = L_mac0(long_accumulator,itemp1,itemp1);
+ }
+
+ power_shift = 0;
+ move16();
+
+ acca = (long_accumulator & 0x7fff0000L);
+ logic32();
+
+ test();
+ while (acca > 0)
+ {
+ test();
+ long_accumulator = L_shr(long_accumulator,1);
+
+ acca = (long_accumulator & 0x7fff0000L);
+ logic32();
+
+ power_shift = add(power_shift,1);
+ }
+
+ acca = L_sub(long_accumulator,32767);
+
+ temp = add(power_shift,15);
+ test();
+ test();
+ logic16();
+ while ((acca <= 0) && (temp >= 0))
+ {
+ test();
+ test();
+ logic16();
+
+ long_accumulator = L_shl(long_accumulator,1);
+ acca = L_sub(long_accumulator,32767);
+ power_shift--;
+ temp = add(power_shift,15);
+ }
+ long_accumulator = L_shr(long_accumulator,1);
+ /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */
+ acca = L_sub(long_accumulator,28963);
+
+ test();
+ if (acca >= 0)
+ power_shift = add(power_shift,1);
+
+ acca = L_deposit_l(mag_shift);
+ acca = L_shl(acca,1);
+ acca = L_sub(power_shift,acca);
+ acca = L_add(35,acca);
+ acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES);
+ absolute_region_power_index[region] = extract_l(acca);
+ }
+
+
+ /* Before we differentially encode the quantized region powers, adjust upward the
+ valleys to make sure all the peaks can be accurately represented. */
+ temp = sub(number_of_regions,2);
+
+ for (region = temp; region >= 0; region--)
+ {
+ temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX);
+ temp2 = sub(absolute_region_power_index[region],temp1);
+ test();
+ if (temp2 < 0)
+ {
+ absolute_region_power_index[region] = temp1;
+ move16();
+ }
+ }
+
+ /* The MLT is currently scaled too low by the factor
+ ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160).
+ This is the ninth power of 1 over the square root of 2.
+ So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9)
+ to drp_code_bits[0]. */
+
+ /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */
+ temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX);
+ temp2 = sub(absolute_region_power_index[0],temp1);
+ test();
+ if (temp2 < 0)
+ {
+ absolute_region_power_index[0] = temp1;
+ move16();
+ }
+
+ temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
+
+ /*
+ * The next line was corrected in Release 1.2
+ */
+
+ temp2 = sub(absolute_region_power_index[0], temp1);
+ test();
+ if (temp2 > 0)
+ {
+ absolute_region_power_index[0] = temp1;
+ move16();
+ }
+
+ differential_region_power_index[0] = absolute_region_power_index[0];
+ move16();
+
+ number_of_bits = 5;
+ move16();
+
+ drp_num_bits[0] = 5;
+ move16();
+
+ drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX);
+ move16();
+
+ /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes
+ may be mathematically impossible anyway.*/
+ for (region=1; region<number_of_regions; region++)
+ {
+ temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX);
+ temp2 = sub(absolute_region_power_index[region],temp1);
+ test();
+ if (temp2 < 0)
+ {
+ absolute_region_power_index[region] = temp1;
+ move16();
+ }
+
+ temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
+ temp2 = sub(absolute_region_power_index[region],temp1);
+ test();
+ if (temp2 > 0)
+ {
+ absolute_region_power_index[region] = temp1;
+ move16();
+ }
+ }
+
+ for (region=1; region<number_of_regions; region++)
+ {
+ j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]);
+ temp = sub(j,DRP_DIFF_MIN);
+ test();
+ if (temp < 0)
+ {
+ j = DRP_DIFF_MIN;
+ }
+ j = sub(j,DRP_DIFF_MIN);
+ move16();
+ differential_region_power_index[region] = j;
+ move16();
+
+ temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]);
+ temp = add(temp,DRP_DIFF_MIN);
+ absolute_region_power_index[region] = temp;
+ move16();
+
+ number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]);
+ drp_num_bits[region] = differential_region_power_bits[region][j];
+ move16();
+ drp_code_bits[region] = differential_region_power_codes[region][j];
+ move16();
+ }
+
+ return (number_of_bits);
+}
+
+/***************************************************************************
+ Function: vector_quantize_mlts
+
+ Syntax: void vector_quantize_mlts(number_of_available_bits,
+ number_of_regions,
+ num_categorization_control_possibilities,
+ mlt_coefs,
+ absolute_region_power_index,
+ power_categories,
+ category_balances,
+ p_categorization_control,
+ region_mlt_bit_counts,
+ region_mlt_bits)
+
+ Word16 number_of_available_bits;
+ Word16 number_of_regions;
+ Word16 num_categorization_control_possibilities;
+ Word16 mlt_coefs[DCT_LENGTH];
+ Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
+ Word16 power_categories[MAX_NUMBER_OF_REGIONS];
+ Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];
+ Word16 *p_categorization_control;
+ Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];
+ Word32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];
+
+ Description: Scalar quantized vector Huffman coding (SQVH)
+
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.57 | 0.65
+ -------|--------------|----------------
+ MAX | 0.78 | 0.83
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.62 | 0.90 | 1.11
+ -------|--------------|----------------|----------------
+ MAX | 1.16 | 1.39 | 1.54
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+void vector_quantize_mlts(Word16 number_of_available_bits,
+ Word16 number_of_regions,
+ Word16 num_categorization_control_possibilities,
+ Word16 *mlt_coefs,
+ Word16 *absolute_region_power_index,
+ Word16 *power_categories,
+ Word16 *category_balances,
+ Word16 *p_categorization_control,
+ Word16 *region_mlt_bit_counts,
+ UWord32 *region_mlt_bits)
+{
+
+ Word16 *raw_mlt_ptr;
+ Word16 region;
+ Word16 category;
+ Word16 total_mlt_bits = 0;
+
+ Word16 temp;
+ Word16 temp1;
+ Word16 temp2;
+
+ /* Start in the middle of the categorization control range. */
+ temp = shr(num_categorization_control_possibilities,1);
+ temp = sub(temp,1);
+ for (*p_categorization_control = 0; *p_categorization_control < temp; (*p_categorization_control)++)
+ {
+ region = category_balances[*p_categorization_control];
+ move16();
+ power_categories[region] = add(power_categories[region],1);
+ move16();
+ }
+
+ for (region=0; region<number_of_regions; region++)
+ {
+ category = power_categories[region];
+ move16();
+ temp = extract_l(L_mult0(region,REGION_SIZE));
+ raw_mlt_ptr = &mlt_coefs[temp];
+ move16();
+ temp = sub(category,(NUM_CATEGORIES-1));
+ test();
+ if (temp < 0)
+ {
+ region_mlt_bit_counts[region] =
+ vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
+ &region_mlt_bits[shl(region,2)]);
+ }
+ else
+ {
+ region_mlt_bit_counts[region] = 0;
+ move16();
+ }
+ total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
+ }
+
+
+ /* If too few bits... */
+ temp = sub(total_mlt_bits,number_of_available_bits);
+ test();
+ test();
+ logic16();
+ while ((temp < 0) && (*p_categorization_control > 0))
+ {
+ test();
+ test();
+ logic16();
+ (*p_categorization_control)--;
+ region = category_balances[*p_categorization_control];
+ move16();
+
+ power_categories[region] = sub(power_categories[region],1);
+ move16();
+
+ total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
+ category = power_categories[region];
+ move16();
+
+ raw_mlt_ptr = &mlt_coefs[region*REGION_SIZE];
+ move16();
+
+ temp = sub(category,(NUM_CATEGORIES-1));
+ test();
+ if (temp < 0)
+ {
+ region_mlt_bit_counts[region] =
+ vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
+ &region_mlt_bits[shl(region,2)]);
+ }
+ else
+ {
+ region_mlt_bit_counts[region] = 0;
+ move16();
+ }
+ total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
+ temp = sub(total_mlt_bits,number_of_available_bits);
+ }
+
+ /* If too many bits... */
+ /* Set up for while loop test */
+ temp1 = sub(total_mlt_bits,number_of_available_bits);
+ temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
+ test();
+ test();
+ logic16();
+
+ while ((temp1 > 0) && (temp2 < 0))
+ {
+ /* operations for while contitions */
+ test();
+ test();
+ logic16();
+
+ region = category_balances[*p_categorization_control];
+ move16();
+
+ power_categories[region] = add(power_categories[region],1);
+ move16();
+
+ total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
+ category = power_categories[region];
+ move16();
+
+ temp = extract_l(L_mult0(region,REGION_SIZE));
+ raw_mlt_ptr = &mlt_coefs[temp];
+ move16();
+
+ temp = sub(category,(NUM_CATEGORIES-1));
+ test();
+ if (temp < 0)
+ {
+ region_mlt_bit_counts[region] =
+ vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
+ &region_mlt_bits[shl(region,2)]);
+ }
+ else
+ {
+ region_mlt_bit_counts[region] = 0;
+ move16();
+ }
+ total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
+ (*p_categorization_control)++;
+
+ temp1 = sub(total_mlt_bits,number_of_available_bits);
+ temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
+ }
+}
+
+/***************************************************************************
+ Function: vector_huffman
+
+ Syntax: Word16 vector_huffman(Word16 category,
+ Word16 power_index,
+ Word16 *raw_mlt_ptr,
+ UWord32 *word_ptr)
+
+ inputs: Word16 category
+ Word16 power_index
+ Word16 *raw_mlt_ptr
+
+ outputs: number_of_region_bits
+ *word_ptr
+
+
+ Description: Huffman encoding for each region based on category and power_index
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.03 | 0.03
+ -------|--------------|----------------
+ MAX | 0.04 | 0.04
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.03 | 0.03 | 0.03
+ -------|--------------|----------------|----------------
+ MAX | 0.04 | 0.04 | 0.04
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+Word16 vector_huffman(Word16 category,
+ Word16 power_index,
+ Word16 *raw_mlt_ptr,
+ UWord32 *word_ptr)
+{
+
+
+ Word16 inv_of_step_size_times_std_dev;
+ Word16 j,n;
+ Word16 k;
+ Word16 number_of_region_bits;
+ Word16 number_of_non_zero;
+ Word16 vec_dim;
+ Word16 num_vecs;
+ Word16 kmax, kmax_plus_one;
+ Word16 index,signs_index;
+ Word16 *bitcount_table_ptr;
+ UWord16 *code_table_ptr;
+ Word32 code_bits;
+ Word16 number_of_code_bits;
+ UWord32 current_word;
+ Word16 current_word_bits_free;
+
+ Word32 acca;
+ Word32 accb;
+ Word16 temp;
+
+ Word16 mytemp; /* new variable in Release 1.2 */
+ Word16 myacca; /* new variable in Release 1.2 */
+
+
+ /* initialize variables */
+ vec_dim = vector_dimension[category];
+ move16();
+
+ num_vecs = number_of_vectors[category];
+ move16();
+
+ kmax = max_bin[category];
+ move16();
+
+ kmax_plus_one = add(kmax,1);
+ move16();
+
+ current_word = 0L;
+ move16();
+
+ current_word_bits_free = 32;
+ move16();
+
+ number_of_region_bits = 0;
+ move16();
+
+ /* set up table pointers */
+ bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category];
+ code_table_ptr = (UWord16 *) table_of_code_tables[category];
+
+ /* compute inverse of step size * standard deviation */
+ acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]);
+ acca = L_shr(acca,1);
+ acca = L_add(acca,4096);
+ acca = L_shr(acca,13);
+
+ /*
+ * The next two lines are new to Release 1.2
+ */
+
+ mytemp = acca & 0x3;
+ acca = L_shr(acca,2);
+
+ inv_of_step_size_times_std_dev = extract_l(acca);
+
+
+ for (n=0; n<num_vecs; n++)
+ {
+ index = 0;
+ move16();
+
+ signs_index = 0;
+ move16();
+
+ number_of_non_zero = 0;
+ move16();
+
+ for (j=0; j<vec_dim; j++)
+ {
+ k = abs_s(*raw_mlt_ptr);
+
+ acca = L_mult(k,inv_of_step_size_times_std_dev);
+ acca = L_shr(acca,1);
+
+ /*
+ * The next four lines are new to Release 1.2
+ */
+
+ myacca = (Word16)L_mult(k,mytemp);
+ myacca = (Word16)L_shr(myacca,1);
+ myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]);
+ myacca = (Word16)L_shr(myacca,2);
+
+ acca = L_add(acca,int_dead_zone[category]);
+
+ /*
+ * The next two lines are new to Release 1.2
+ */
+
+ acca = L_add(acca,myacca);
+ acca = L_shr(acca,13);
+
+ k = extract_l(acca);
+
+ test();
+ if (k != 0)
+ {
+ number_of_non_zero = add(number_of_non_zero,1);
+ signs_index = shl(signs_index,1);
+
+ test();
+ if (*raw_mlt_ptr > 0)
+ {
+ signs_index = add(signs_index,1);
+ }
+
+ temp = sub(k,kmax);
+ test();
+ if (temp > 0)
+ {
+ k = kmax;
+ move16();
+ }
+ }
+ acca = L_shr(L_mult(index,(kmax_plus_one)),1);
+ index = extract_l(acca);
+ index = add(index,k);
+ raw_mlt_ptr++;
+ }
+
+ code_bits = *(code_table_ptr+index);
+ number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero);
+ number_of_region_bits = add(number_of_region_bits,number_of_code_bits);
+
+ acca = code_bits << number_of_non_zero;
+ accb = L_deposit_l(signs_index);
+ acca = L_add(acca,accb);
+ code_bits = acca;
+ move32();
+
+ /* msb of codebits is transmitted first. */
+ j = sub(current_word_bits_free,number_of_code_bits);
+ test();
+ if (j >= 0)
+ {
+ test();
+ acca = code_bits << j;
+ current_word = L_add(current_word,acca);
+ current_word_bits_free = j;
+ move16();
+ }
+ else
+ {
+ j = negate(j);
+ acca = L_shr(code_bits,j);
+ current_word = L_add(current_word,acca);
+
+ *word_ptr++ = current_word;
+ move16();
+
+ current_word_bits_free = sub(32,j);
+ test();
+ current_word = code_bits << current_word_bits_free;
+ }
+ }
+
+ *word_ptr++ = current_word;
+ move16();
+
+ return (number_of_region_bits);
+}
+
+
diff --git a/third_party/g7221/encode/sam2coef.c b/third_party/g7221/encode/sam2coef.c
new file mode 100644
index 00000000..08ee0e11
--- /dev/null
+++ b/third_party/g7221/encode/sam2coef.c
@@ -0,0 +1,270 @@
+/******************************************************************************
+**
+** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
+** > Software Release 2.1 (2008-06)
+** (Simple repackaging; no change from 2005-05 Release 2.0 code)
+**
+** © 2004 Polycom, Inc.
+**
+** All rights reserved.
+**
+******************************************************************************/
+
+/******************************************************************************
+* Filename: samples_to_rmlt_coefs.c
+*
+* Purpose: Convert Samples to Reversed MLT (Modulated Lapped Transform)
+* Coefficients
+*
+* The "Reversed MLT" is an overlapped block transform which uses
+* even symmetry * on the left, odd symmetry on the right and a
+* Type IV DCT as the block transform. * It is thus similar to a
+* MLT which uses odd symmetry on the left, even symmetry * on the
+* right and a Type IV DST as the block transform. In fact, it is
+* equivalent * to reversing the order of the samples, performing
+* an MLT and then negating all * the even-numbered coefficients.
+*
+******************************************************************************/
+
+/***************************************************************************
+ Include files
+***************************************************************************/
+#include "defs.h"
+#include "tables.h"
+#include "count.h"
+
+/***************************************************************************
+ Function: samples_to_rmlt_coefs
+
+ Syntax: Word16 samples_to_rmlt_coefs(new_samples,
+ old_samples,
+ coefs,
+ dct_length)
+ Word16 *new_samples;
+ Word16 *old_samples;
+ Word16 *coefs;
+ Word16 dct_length;
+
+ Description: Convert samples to MLT coefficients
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 1.40 | 1.40
+ -------|--------------|----------------
+ MAX | 1.40 | 1.40
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 3.07 | 3.07 | 3.07
+ -------|--------------|----------------|----------------
+ MAX | 3.10 | 3.10 | 3.10
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+Word16 samples_to_rmlt_coefs(Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length)
+{
+
+ Word16 index, vals_left,mag_shift,n;
+ Word16 windowed_data[MAX_DCT_LENGTH];
+ Word16 *new_ptr, *old_ptr, *sam_low, *sam_high;
+ Word16 *win_low, *win_high;
+ Word16 *dst_ptr;
+ Word16 neg_win_low;
+ Word16 samp_high;
+ Word16 half_dct_size;
+
+ Word32 acca;
+ Word32 accb;
+ Word16 temp;
+ Word16 temp1;
+ Word16 temp2;
+ Word16 temp5;
+
+ half_dct_size = shr(dct_length,1);
+
+ /*++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Get the first half of the windowed samples */
+ /*++++++++++++++++++++++++++++++++++++++++++++*/
+
+ dst_ptr = windowed_data;
+ move16();
+
+ /* address arithmetic */
+ test();
+ if (dct_length==DCT_LENGTH)
+ {
+ win_high = samples_to_rmlt_window + half_dct_size;
+ }
+ else
+ {
+ win_high = max_samples_to_rmlt_window + half_dct_size;
+ }
+
+ win_low = win_high;
+ move16();
+
+ /* address arithmetic */
+ sam_high = old_samples + half_dct_size;
+
+ sam_low = sam_high;
+ move16();
+
+ for (vals_left = half_dct_size;vals_left > 0;vals_left--)
+ {
+ acca = 0L;
+ move32();
+
+ acca = L_mac(acca,*--win_low, *--sam_low);
+ acca = L_mac(acca,*win_high++, *sam_high++);
+ temp = round(acca);
+
+ *dst_ptr++ = temp;
+ move16();
+ }
+
+ /*+++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Get the second half of the windowed samples */
+ /*+++++++++++++++++++++++++++++++++++++++++++++*/
+
+ sam_low = new_samples;
+ move16();
+
+ /* address arithmetic */
+ sam_high = new_samples + dct_length;
+
+ for (vals_left = half_dct_size; vals_left > 0; vals_left--)
+ {
+ acca = 0L;
+ move32();
+
+ acca = L_mac(acca,*--win_high, *sam_low++);
+ neg_win_low = negate(*win_low++);
+ samp_high = *--sam_high;
+ acca = L_mac(acca, neg_win_low, samp_high);
+ temp = round(acca);
+
+ *dst_ptr++=temp;
+ move16();
+ }
+
+ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Save the new samples for next time, when they will be the old samples */
+ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+ new_ptr = new_samples;
+ move16();
+
+ old_ptr = old_samples;
+ move16();
+
+ for (vals_left = dct_length;vals_left > 0;vals_left--)
+ {
+ *old_ptr++ = *new_ptr++;
+ move16();
+ }
+
+ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Calculate how many bits to shift up the input to the DCT. */
+ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+ temp1=0;
+ move16();
+
+ for(index=0;index<dct_length;index++)
+ {
+ temp2 = abs_s(windowed_data[index]);
+ temp = sub(temp2,temp1);
+ test();
+ if(temp > 0)
+ {
+ move16();
+ temp1 = temp2;
+ }
+ }
+
+ mag_shift=0;
+ move16();
+
+ temp = sub(temp1,14000);
+ test();
+ if (temp >= 0)
+ {
+ mag_shift = 0;
+ move16();
+ }
+ else
+ {
+ temp = sub(temp1,438);
+ test();
+ if(temp < 0)
+ temp = add(temp1,1);
+ else
+ {
+ temp = temp1;
+ move16();
+ }
+ accb = L_mult(temp,9587);
+ acca = L_shr(accb,20);
+ temp5 = extract_l(acca);
+ temp = norm_s(temp5);
+ test();
+ if (temp == 0)
+ {
+ mag_shift = 9;
+ move16();
+ }
+ else
+ mag_shift = sub(temp,6);
+
+ }
+
+ acca = 0L;
+ move32();
+ for(index=0; index<dct_length; index++)
+ {
+ temp = abs_s( windowed_data[index]);
+ acca = L_add(acca,temp);
+ }
+
+ acca = L_shr(acca,7);
+
+ test();
+ if (temp1 < acca)
+ {
+ mag_shift = sub(mag_shift,1);
+ }
+
+ test();
+ if (mag_shift > 0)
+ {
+ for(index=0;index<dct_length;index++)
+ {
+ windowed_data[index] = shl(windowed_data[index],mag_shift);
+ }
+ }
+ else
+ {
+ test();
+ if (mag_shift < 0)
+ {
+ n = negate(mag_shift);
+ for(index=0;index<dct_length;index++)
+ {
+ windowed_data[index] = shr(windowed_data[index],n);
+ move16();
+ }
+ }
+ }
+
+ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Perform a Type IV DCT on the windowed data to get the coefficients */
+ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+ dct_type_iv_a(windowed_data, coefs, dct_length);
+
+ return(mag_shift);
+}