summaryrefslogtreecommitdiff
path: root/third_party/g7221/encode/sam2coef.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/g7221/encode/sam2coef.c')
-rw-r--r--third_party/g7221/encode/sam2coef.c270
1 files changed, 270 insertions, 0 deletions
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);
+}