summaryrefslogtreecommitdiff
path: root/third_party/g7221/decode/coef2sam.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/g7221/decode/coef2sam.c')
-rw-r--r--third_party/g7221/decode/coef2sam.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/third_party/g7221/decode/coef2sam.c b/third_party/g7221/decode/coef2sam.c
new file mode 100644
index 00000000..18a88acd
--- /dev/null
+++ b/third_party/g7221/decode/coef2sam.c
@@ -0,0 +1,180 @@
+/*****************************************************************************
+**
+** 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: rmlt_coefs_to_samples.c
+*
+* Purpose: Convert Reversed MLT (Modulated Lapped Transform)
+* Coefficients to Samples
+*
+* 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: rmlt_coefs_to_samples
+
+ Syntax: void rmlt_coefs_to_samples(Word16 *coefs,
+ Word16 *old_samples,
+ Word16 *out_samples,
+ Word16 dct_length,
+ Word16 mag_shift)
+
+ inputs: Word16 *coefs
+ Word16 *old_samples
+ Word16 dct_length
+ Word16 mag_shift
+
+
+ outputs: Word16 *out_samples
+
+ Description: Converts the mlt_coefs to samples
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 1.91 | 1.91
+ -------|--------------|----------------
+ MAX | 1.91 | 1.91
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 3.97 | 3.97 | 3.97
+ -------|--------------|----------------|----------------
+ MAX | 3.97 | 3.97 | 3.97
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+void rmlt_coefs_to_samples(Word16 *coefs,
+ Word16 *old_samples,
+ Word16 *out_samples,
+ Word16 dct_length,
+ Word16 mag_shift)
+{
+
+
+ Word16 index, vals_left;
+ Word16 new_samples[MAX_DCT_LENGTH];
+ Word16 *new_ptr, *old_ptr;
+ Word16 *win_new, *win_old;
+ Word16 *out_ptr;
+ Word16 half_dct_size;
+ Word32 sum;
+
+
+
+ half_dct_size = shr(dct_length,1);
+
+ /* Perform a Type IV (inverse) DCT on the coefficients */
+ dct_type_iv_s(coefs, new_samples, dct_length);
+
+ test();
+ if (mag_shift > 0)
+ {
+ for(index=0;index<dct_length;index++)
+ {
+ new_samples[index] = shr(new_samples[index],mag_shift);
+ move16();
+ }
+ }
+ else
+ {
+ test();
+ if (mag_shift < 0)
+ {
+ mag_shift = negate(mag_shift);
+ for(index=0;index<dct_length;index++)
+ {
+ new_samples[index] = shl(new_samples[index],mag_shift);
+ move16();
+ }
+ }
+
+ }
+
+ /* Get the first half of the windowed samples */
+
+ out_ptr = out_samples;
+ move16();
+ test();
+ if (dct_length==DCT_LENGTH)
+ {
+ win_new = rmlt_to_samples_window;
+ move16();
+ win_old = rmlt_to_samples_window + dct_length;
+ move16();
+ }
+ else
+ {
+ win_new = max_rmlt_to_samples_window;
+ move16();
+ win_old = max_rmlt_to_samples_window + dct_length;
+ move16();
+ }
+ old_ptr = old_samples;
+ move16();
+ new_ptr = new_samples + half_dct_size;
+ move16();
+
+ for (vals_left = half_dct_size; vals_left > 0; vals_left--)
+ {
+ sum = 0L;
+ move32();
+ sum = L_mac(sum,*win_new++, *--new_ptr);
+ sum = L_mac(sum,*--win_old, *old_ptr++);
+ *out_ptr++ = round(L_shl(sum,2));
+ move16();
+
+ }
+
+ /* Get the second half of the windowed samples */
+
+ for (vals_left = half_dct_size; vals_left > 0; vals_left--)
+ {
+ sum = 0L;
+ move32();
+ sum = L_mac(sum,*win_new++, *new_ptr++);
+ sum = L_mac(sum,negate(*--win_old), *--old_ptr);
+ *out_ptr++ = round(L_shl(sum,2));
+ move16();
+ }
+
+ /* Save the second half of the new samples for */
+ /* next time, when they will be the old samples. */
+
+ /* pointer arithmetic */
+ new_ptr = new_samples + half_dct_size;
+ move16();
+ old_ptr = old_samples;
+ move16();
+ for (vals_left = half_dct_size; vals_left > 0; vals_left--)
+ {
+ *old_ptr++ = *new_ptr++;
+ move16();
+ }
+}