summaryrefslogtreecommitdiff
path: root/third_party/g7221/decode
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/g7221/decode')
-rw-r--r--third_party/g7221/decode/coef2sam.c180
-rw-r--r--third_party/g7221/decode/dct4_s.c480
-rw-r--r--third_party/g7221/decode/dct4_s.h856
-rw-r--r--third_party/g7221/decode/decoder.c1112
4 files changed, 2628 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();
+ }
+}
diff --git a/third_party/g7221/decode/dct4_s.c b/third_party/g7221/decode/dct4_s.c
new file mode 100644
index 00000000..84514824
--- /dev/null
+++ b/third_party/g7221/decode/dct4_s.c
@@ -0,0 +1,480 @@
+/********************************************************************************
+**
+** 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_s.c
+*
+* Purpose: Discrete Cosine Transform, Type IV used for inverse 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_s.h"
+
+/***************************************************************************
+ External variable declarations
+***************************************************************************/
+extern Word16 syn_bias_7khz[DCT_LENGTH];
+extern Word16 dither[DCT_LENGTH];
+extern Word16 max_dither[MAX_DCT_LENGTH];
+
+extern Word16 dct_core_s[DCT_LENGTH_DIV_32][DCT_LENGTH_DIV_32];
+extern cos_msin_t s_cos_msin_2[DCT_LENGTH_DIV_32];
+extern cos_msin_t s_cos_msin_4[DCT_LENGTH_DIV_16];
+extern cos_msin_t s_cos_msin_8[DCT_LENGTH_DIV_8];
+extern cos_msin_t s_cos_msin_16[DCT_LENGTH_DIV_4];
+extern cos_msin_t s_cos_msin_32[DCT_LENGTH_DIV_2];
+extern cos_msin_t s_cos_msin_64[DCT_LENGTH];
+extern cos_msin_t *s_cos_msin_table[];
+
+/********************************************************************************
+ Function: dct_type_iv_s
+
+ Syntax: void dct_type_iv_s (Word16 *input,Word16 *output,Word16 dct_length)
+
+
+ Description: Discrete Cosine Transform, Type IV used for inverse MLT
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 1.74 | 1.74
+ -------|--------------|----------------
+ MAX | 1.74 | 1.74
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 3.62 | 3.62 | 3.62
+ -------|--------------|----------------|----------------
+ MAX | 3.62 | 3.62 | 3.62
+ -------|--------------|----------------|----------------
+
+********************************************************************************/
+
+void dct_type_iv_s (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 set_span, set_count, set_count_log, pairs_left, sets_left;
+ Word16 i,k;
+ Word16 index;
+ Word16 dummy;
+ Word32 sum;
+ cos_msin_t **table_ptr_ptr, *cos_msin_ptr;
+
+ Word32 acca;
+ Word16 temp;
+
+ Word16 dct_length_log;
+ Word16 *dither_ptr;
+
+ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ /* Do the sum/difference butterflies, the first part of */
+ /* converting one N-point transform into 32 - 10 point transforms */
+ /* transforms, where N = 1 << DCT_LENGTH_LOG. */
+ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+ test();
+ if (dct_length==DCT_LENGTH)
+ {
+ dct_length_log = DCT_LENGTH_LOG;
+ move16();
+ dither_ptr = dither;
+ move16();
+ }
+ else
+ {
+ dct_length_log = MAX_DCT_LENGTH_LOG;
+ move16();
+ dither_ptr = max_dither;
+ move16();
+ }
+
+ in_buffer = input;
+ move16();
+ out_buffer = buffer_a;
+ move16();
+
+ index=0;
+ move16();
+
+ i=0;
+ move16();
+
+ for (set_count_log = 0; set_count_log <= dct_length_log - 2; 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 */
+ /*=====================================*/
+ temp = sub(index,1);
+ test();
+ if(temp < 0)
+ {
+ for (sets_left = set_count;sets_left > 0;sets_left--)
+ {
+
+ /*||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Set up output pointers for the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||*/
+ /* pointer arithmetic */
+ out_ptr_low = next_out_base;
+ move16();
+ next_out_base += set_span;
+ move16();
+ out_ptr_high = next_out_base;
+ move16();
+
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Loop over all the butterflies in the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
+
+ do
+ {
+ in_val_low = *in_ptr++;
+ move16();
+ in_val_high = *in_ptr++;
+ move16();
+
+ /* BEST METHOD OF GETTING RID OF BIAS, BUT COMPUTATIONALLY UNPLEASANT */
+ /* ALTERNATIVE METHOD, SMEARS BIAS OVER THE ENTIRE FRAME, COMPUTATIONALLY SIMPLEST. */
+ /* IF THIS WORKS, IT'S PREFERABLE */
+
+ dummy = add(in_val_low,dither_ptr[i++]);
+ acca = L_add(dummy,in_val_high);
+ out_val_low = extract_l(L_shr(acca,1));
+
+ dummy = add(in_val_low,dither_ptr[i++]);
+ acca = L_add(dummy,-in_val_high);
+ out_val_high = extract_l(L_shr(acca,1));
+
+ *out_ptr_low++ = out_val_low;
+ move16();
+ *--out_ptr_high = out_val_high;
+ move16();
+
+ test();
+
+ /* this involves comparison of pointers */
+ /* pointer arithmetic */
+
+ } while (out_ptr_low < out_ptr_high);
+
+ } /* End of loop over sets of the current size */
+ }
+ else
+ {
+ for (sets_left = set_count; sets_left > 0; sets_left--)
+ {
+ /*||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Set up output pointers for the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||*/
+
+ out_ptr_low = next_out_base;
+ move16();
+ next_out_base += set_span;
+ move16();
+ out_ptr_high = next_out_base;
+ move16();
+
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Loop over all the butterflies in the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||*/
+
+ do
+ {
+ in_val_low = *in_ptr++;
+ move16();
+ in_val_high = *in_ptr++;
+ move16();
+
+ out_val_low = add(in_val_low,in_val_high);
+ out_val_high = add(in_val_low,negate(in_val_high));
+
+ *out_ptr_low++ = out_val_low;
+ move16();
+ *--out_ptr_high = out_val_high;
+ move16();
+
+ 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();
+
+ test();
+ if (out_buffer == buffer_a)
+ {
+ out_buffer = buffer_b;
+ move16();
+ }
+ else
+ {
+ out_buffer = buffer_a;
+ move16();
+ }
+
+ index = add(index,1);
+ } /* End of loop over set sizes */
+
+
+ /*++++++++++++++++++++++++++++++++*/
+ /* Do 32 - 10 point transforms */
+ /*++++++++++++++++++++++++++++++++*/
+
+ pair_ptr = in_buffer;
+ move16();
+ buffer_swap = buffer_c;
+ move16();
+
+ for (pairs_left = 1 << (dct_length_log - 1); 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_s[i][k]);
+ }
+ buffer_swap[k] = round(sum);
+ }
+
+ pair_ptr += CORE_SIZE;
+ move16();
+ buffer_swap += CORE_SIZE;
+ move16();
+ }
+
+ for (i=0;i<dct_length;i++)
+ {
+ in_buffer[i] = buffer_c[i];
+ move16();
+ }
+
+ table_ptr_ptr = s_cos_msin_table;
+ move16();
+
+ /*++++++++++++++++++++++++++++++*/
+ /* Perform rotation butterflies */
+ /*++++++++++++++++++++++++++++++*/
+ index=0;
+ move16();
+
+ for (set_count_log = dct_length_log - 2 ; 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;
+ move16();
+ }
+ else
+ {
+ 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 the pointers for the current set */
+ /*|||||||||||||||||||||||||||||||||||||||||*/
+
+ in_ptr_low = next_in_base;
+ move16();
+
+ temp = shr(set_span,1);
+ in_ptr_high = in_ptr_low + temp;
+ move16();
+
+ next_in_base += set_span;
+ move16();
+
+ out_ptr_low = next_out_base;
+ move16();
+
+ next_out_base += set_span;
+ move16();
+ out_ptr_high = next_out_base;
+ move16();
+
+ cos_msin_ptr = *table_ptr_ptr;
+ move16();
+
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
+ /* Loop over all the butterfly pairs in the current set */
+ /*||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
+
+ do
+ {
+ in_low_even = *in_ptr_low++;
+ move16();
+ in_low_odd = *in_ptr_low++;
+ move16();
+ in_high_even = *in_ptr_high++;
+ move16();
+ in_high_odd = *in_ptr_high++;
+ move16();
+ 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;
+ move32();
+
+ sum = L_mac(sum,cos_even,in_low_even);
+ sum = L_mac(sum,negate(msin_even),in_high_even);
+ out_low_even = round(L_shl(sum,1));
+
+ sum = 0L;
+ move32();
+ sum = L_mac(sum,msin_even,in_low_even);
+ sum = L_mac(sum,cos_even,in_high_even);
+ out_high_even = round(L_shl(sum,1));
+
+ sum = 0L;
+ move32();
+ sum = L_mac(sum,cos_odd,in_low_odd);
+ sum = L_mac(sum,msin_odd,in_high_odd);
+ out_low_odd = round(L_shl(sum,1));
+
+ sum = 0L;
+ move32();
+ sum = L_mac(sum,msin_odd,in_low_odd);
+ sum = L_mac(sum,negate(cos_odd),in_high_odd);
+ out_high_odd = round(L_shl(sum,1));
+
+ *out_ptr_low++ = out_low_even;
+ move16();
+ *--out_ptr_high = out_high_even;
+ move16();
+ *out_ptr_low++ = out_low_odd;
+ move16();
+ *--out_ptr_high = out_high_odd;
+ move16();
+
+ 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;
+ move16();
+ in_buffer = out_buffer;
+ move16();
+ out_buffer = buffer_swap;
+ move16();
+
+ index = add(index,1);
+ table_ptr_ptr++;
+ }
+ /*------------------------------------
+
+ ADD IN BIAS FOR OUTPUT
+
+ -----------------------------------*/
+ if (dct_length==DCT_LENGTH)
+ {
+ for(i=0;i<320;i++)
+ {
+ sum = L_add(output[i],syn_bias_7khz[i]);
+ acca = L_sub(sum,32767);
+ test();
+ if (acca > 0)
+ {
+ sum = 32767L;
+ move32();
+ }
+ acca = L_add(sum,32768L);
+ test();
+ if (acca < 0)
+ {
+ sum = -32768L;
+ move32();
+ }
+ output[i] = extract_l(sum);
+ }
+ }
+}
+
diff --git a/third_party/g7221/decode/dct4_s.h b/third_party/g7221/decode/dct4_s.h
new file mode 100644
index 00000000..010e52d8
--- /dev/null
+++ b/third_party/g7221/decode/dct4_s.h
@@ -0,0 +1,856 @@
+/***********************************************************************
+**
+** 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_s.h
+
+ Purpose: Contains tables used by dct4_s.c
+
+ Design Notes:
+
+***********************************************************************/
+
+/***************************************************************************
+ Include files
+***************************************************************************/
+
+typedef struct
+{
+ Word16 cosine;
+ Word16 minus_sine;
+} cos_msin_t;
+
+/***************************************************************************
+ The dct_core_s table was generated by the following code
+
+ for(i=0;i<10;++i)
+ {
+ for(k=0;k<10;++k)
+ {
+ dct_core_s[i][k]=(short) (FTOI(((.9*32768.)*cos(3.1415926*(k+0.5)*(i+0.5)/10.))));
+ }
+ }
+***************************************************************************/
+Word16 dct_core_s[10][10] = {
+{ 29400, 28676, 27246, 25145, 22425, 19153, 15409, 11286, 6885, 2314 },
+{ 28676, 22425, 11286, -2314, -15409, -25145, -29400, -27246, -19153, -6885 },
+{ 27246, 11286, -11286, -27246, -27246, -11286, 11286, 27246, 27246, 11286 },
+{ 25145, -2314, -27246, -22425, 6885, 28676, 19153, -11286, -29400, -15409 },
+{ 22425, -15409, -27246, 6885, 29400, 2314, -28676, -11286, 25145, 19153 },
+{ 19153, -25145, -11286, 28676, 2314, -29400, 6885, 27246, -15409, -22425 },
+{ 15409, -29400, 11286, 19153, -28676, 6885, 22425, -27246, 2314, 25145 },
+{ 11286, -27246, 27246, -11286, -11286, 27246, -27246, 11286, 11286, -27246 },
+{ 6885, -19153, 27246, -29400, 25145, -15409, 2314, 11286, -22425, 28676 },
+{ 2314, -6885, 11286, -15409, 19153, -22425, 25145, -27246, 28676, -29400 }
+};
+
+Word16 syn_bias_7khz[DCT_LENGTH] = {
+ -4, 4, -5, -2, 0, -4, 6, 2, -2, -4,
+ -3, 3, 0, 0, -2, 4, 0, 0, 3, -6,
+ 8, 5, 4, 5, -8, 0, -2, 0, 0, -3,
+ 3, 0, 0, 0, 1, -1, -2, 0, 0, 2,
+ -2, -5, -2, 3, 2, -1, -1, -6, 3, 1,
+ -7, 4, 4, 0, 1, 4, 1, 0, 1, -5,
+ -1, 1, -6, 0, -1, -1, 3, 0, -2, 1,
+ 2, -4, 0, 9, 0, -3, 1, 1, 1, 0,
+ -3, -2, -1, -4, -2, 0, 5, 2, -3, 5,
+ 0, -2, 4, 4, 0, -6, -4, 2, 0, 0,
+ 0, -1, -1, -2, 0, 6, 1, 0, 0, -1,
+ 0, -4, -1, 0, -4, 1, -1, -5, 0, 1,
+ 2, 4, 0, -8, -4, 0, -2, -2, 2, 5,
+ -3, -1, 1, -4, 0, 0, 0, -1, -3, 0,
+ -5, -4, 0, -2, 0, 7, 1, 0, 5, -2,
+ -1, 2, 2, -2, 3, 7, -3, 4, 1, -4,
+ 0, 0, 3, -7, -5, 0, 0, 4, 0, -2,
+ -1, 0, -5, 0, 2, 0, 11, 5, -1, 0,
+ 2, 2, -2, -2, 5, 4, -3, 1, 0, -2,
+ 1, 3, 2, 0, 1, 0, 0, 0, 5, 6,
+ -2, -1, 0, 2, 3, 2, 0, -3, 4, 5,
+ 0, -1, 0, 3, 1, -2, -3, -2, -1, 2,
+ -1, -1, -2, -7, 4, 6, -5, -6, -3, -4,
+ 0, 2, -5, -2, 3, 0, 0, 0, 2, -2,
+ -4, 3, 3, 1, 0, 0, 4, -1, 8, 13,
+ 1, 2, 0, 2, 0, -1, 4, -3, 1, 0,
+ -1, 3, 0, 0, -5, 0, 6, 2, 4, 5,
+ 2, -1, -1, 3, 6, 1, 1, 2, -4, 0,
+ -1, -6, -2, -2, 2, 1, 2, 6, 2, 0,
+ -2, -2, 0, -1, 2, 0, 0, 3, -2, 1,
+ 3, 1, 2, -1, -2, 2, 2, -4, 0, 0,
+ -3, 0, -4, -3, 6, 7, 2, 2, 0, -3};
+
+Word16 dither[DCT_LENGTH]= {
+ 1, 0, 0, 0, 1, 0, 0, 1, 1, 1,
+ 1, 0, 0, 0, 1, 1, 1, 1, 1, 0,
+ 0, 1, 1, 1, 0, 1, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 0, 1, 0,
+ 1, 0, 0, 0, 1, 0, 1, 0, 0, 0,
+ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 1,
+ 1, 1, 1, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1,
+ 0, 0, 1, 1, 0, 1, 0, 1, 1, 1,
+ 1, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 0, 0, 0, 1, 0, 1, 0, 0, 0, 1,
+ 1, 1, 0, 0, 1, 1, 1, 1, 1, 0,
+ 0, 1, 1, 1, 1, 0, 1, 1, 1, 0,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 1, 0, 0, 1, 0, 0, 1,
+ 0, 0, 0, 1, 1, 0, 0, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 0, 0, 1, 1, 0, 1, 1, 0, 0,
+ 1, 1, 1, 0, 1, 1, 0, 1, 0, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
+ 0, 1, 1, 1, 1, 0, 1, 1, 1, 0,
+ 1, 1, 1, 0, 1, 1, 1, 0, 1, 0,
+ 1, 1, 0, 0, 1, 0, 0, 1, 0, 1,
+ 0, 1, 1, 0, 1, 0, 1, 0, 1, 1,
+ 1, 0, 1, 0, 1, 0, 1, 1, 1, 1,
+ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
+ 1, 0, 0, 0, 1, 0, 0, 1, 0, 1,
+ 1, 0, 1, 1, 0, 0, 1, 1, 0, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 0, 1, 0, 0, 0, 1, 0};
+
+Word16 max_dither[MAX_DCT_LENGTH]= {
+ 1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
+ 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 0, 1, 1, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 0, 1, 0, 1, 1, 1, 1,
+ 0, 1, 0, 1, 1, 1, 1, 1, 1, 0,
+ 1, 0, 1, 1, 0, 1, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0,
+ 0, 0, 1, 1, 0, 0, 0, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
+ 1, 0, 1, 0, 1, 0, 0, 0, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 0, 1, 0,
+ 0, 0, 1, 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 1, 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 1, 1, 1, 1, 0, 1,
+ 1, 0, 0, 0, 1, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 1, 1, 0, 1,
+ 1, 0, 0, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0, 1, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 1, 1, 1, 0, 1, 1, 1, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
+ 0, 1, 1, 1, 0, 1, 0, 1, 0, 0,
+ 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
+ 1, 1, 0, 0, 1, 1, 1, 1, 0, 0,
+ 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
+ 1, 1, 1, 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 1, 1, 0, 1, 0, 1, 0, 0,
+ 1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
+ 0, 1, 1, 0, 1, 1, 1, 0, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
+ 0, 1, 0, 1, 0, 1, 1, 0, 1, 0,
+ 1, 1, 1, 0, 0, 1, 1, 0, 0, 1,
+ 0, 1, 0, 0, 0, 1, 1, 0, 0, 1,
+ 0, 0, 1, 1, 0, 1, 0, 1, 0, 1,
+ 1, 1, 0, 1, 0, 0, 1, 1, 0, 0,
+ 1, 0, 1, 0, 1, 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 1, 1, 1, 1, 1, 0,
+ 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
+ 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 1, 1, 0, 0, 1, 0, 1,
+ 1, 1, 1, 1, 0, 0, 1, 0, 1, 0,
+ 0, 1, 0, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 1, 0, 1, 0, 0, 1, 0, 1,
+ 1, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+ 1, 1, 1, 0, 1, 0, 0, 1, 1, 1,
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 1,
+ 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
+ 1, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
+ 1, 0, 1, 0, 1, 1, 0, 0, 0, 1,
+ 1, 0, 1, 0, 0, 1, 1, 1, 0, 1,
+ 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0
+};
+
+
+/********************************************************************************
+ The s_cos_min tables were generated by the following code:
+ double angle, scale;
+ int index;
+
+ for (index = 0;index < length;index++)
+ {
+ angle = scale * ((double)index + 0.5);
+ table[index].cosine = (short) (FTOI((18427)* cos(angle)));
+ table[index].minus_sine = (short) (FTOI((18427)*(-sin(angle))));
+ }
+
+
+********************************************************************************/
+
+cos_msin_t s_cos_msin_2[DCT_LENGTH_DIV_32] = {
+ { 18413 , -723 } ,
+ { 18299 , -2166 } ,
+ { 18073 , -3595 } ,
+ { 17735 , -5002 } ,
+ { 17288 , -6378 } ,
+ { 16734 , -7715 } ,
+ { 16077 , -9004 } ,
+ { 15321 , -10237 } ,
+ { 14471 , -11408 } ,
+ { 13531 , -12508 }
+ };
+cos_msin_t s_cos_msin_4[DCT_LENGTH_DIV_16] = {
+ { 18423 , -362 } ,
+ { 18395 , -1085 } ,
+ { 18338 , -1806 } ,
+ { 18253 , -2525 } ,
+ { 18140 , -3239 } ,
+ { 17999 , -3949 } ,
+ { 17830 , -4653 } ,
+ { 17634 , -5349 } ,
+ { 17410 , -6037 } ,
+ { 17159 , -6716 } ,
+ { 16883 , -7385 } ,
+ { 16580 , -8042 } ,
+ { 16251 , -8686 } ,
+ { 15898 , -9318 } ,
+ { 15520 , -9935 } ,
+ { 15118 , -10536 } ,
+ { 14692 , -11122 } ,
+ { 14244 , -11690 } ,
+ { 13774 , -12240 } ,
+ { 13283 , -12772 }
+ };
+cos_msin_t s_cos_msin_8[DCT_LENGTH_DIV_8] = {
+ { 18426 , -181 } ,
+ { 18419 , -543 } ,
+ { 18405 , -904 } ,
+ { 18384 , -1265 } ,
+ { 18355 , -1626 } ,
+ { 18320 , -1986 } ,
+ { 18277 , -2345 } ,
+ { 18228 , -2704 } ,
+ { 18171 , -3061 } ,
+ { 18107 , -3417 } ,
+ { 18037 , -3772 } ,
+ { 17959 , -4126 } ,
+ { 17875 , -4477 } ,
+ { 17783 , -4827 } ,
+ { 17685 , -5176 } ,
+ { 17580 , -5522 } ,
+ { 17468 , -5866 } ,
+ { 17350 , -6208 } ,
+ { 17225 , -6547 } ,
+ { 17093 , -6884 } ,
+ { 16954 , -7219 } ,
+ { 16809 , -7550 } ,
+ { 16658 , -7879 } ,
+ { 16500 , -8204 } ,
+ { 16336 , -8526 } ,
+ { 16165 , -8846 } ,
+ { 15988 , -9161 } ,
+ { 15805 , -9473 } ,
+ { 15616 , -9782 } ,
+ { 15421 , -10087 } ,
+ { 15220 , -10387 } ,
+ { 15013 , -10684 } ,
+ { 14801 , -10977 } ,
+ { 14582 , -11265 } ,
+ { 14358 , -11550 } ,
+ { 14129 , -11829 } ,
+ { 13894 , -12104 } ,
+ { 13654 , -12375 } ,
+ { 13408 , -12641 } ,
+ { 13157 , -12901 }
+ };
+cos_msin_t s_cos_msin_16[DCT_LENGTH_DIV_4] = {
+ { 18427 , -90 } ,
+ { 18425 , -271 } ,
+ { 18421 , -452 } ,
+ { 18416 , -633 } ,
+ { 18409 , -814 } ,
+ { 18400 , -995 } ,
+ { 18389 , -1175 } ,
+ { 18377 , -1356 } ,
+ { 18363 , -1536 } ,
+ { 18347 , -1716 } ,
+ { 18329 , -1896 } ,
+ { 18310 , -2076 } ,
+ { 18288 , -2256 } ,
+ { 18265 , -2435 } ,
+ { 18241 , -2614 } ,
+ { 18214 , -2793 } ,
+ { 18186 , -2972 } ,
+ { 18156 , -3150 } ,
+ { 18124 , -3328 } ,
+ { 18090 , -3506 } ,
+ { 18055 , -3684 } ,
+ { 18018 , -3861 } ,
+ { 17979 , -4037 } ,
+ { 17939 , -4214 } ,
+ { 17897 , -4390 } ,
+ { 17853 , -4565 } ,
+ { 17807 , -4740 } ,
+ { 17760 , -4915 } ,
+ { 17710 , -5089 } ,
+ { 17660 , -5262 } ,
+ { 17607 , -5436 } ,
+ { 17553 , -5608 } ,
+ { 17497 , -5780 } ,
+ { 17439 , -5952 } ,
+ { 17380 , -6123 } ,
+ { 17319 , -6293 } ,
+ { 17257 , -6463 } ,
+ { 17192 , -6632 } ,
+ { 17126 , -6800 } ,
+ { 17059 , -6968 } ,
+ { 16990 , -7135 } ,
+ { 16919 , -7302 } ,
+ { 16846 , -7467 } ,
+ { 16772 , -7632 } ,
+ { 16696 , -7797 } ,
+ { 16619 , -7960 } ,
+ { 16540 , -8123 } ,
+ { 16459 , -8285 } ,
+ { 16377 , -8446 } ,
+ { 16294 , -8607 } ,
+ { 16208 , -8766 } ,
+ { 16121 , -8925 } ,
+ { 16033 , -9083 } ,
+ { 15943 , -9240 } ,
+ { 15852 , -9396 } ,
+ { 15759 , -9551 } ,
+ { 15664 , -9705 } ,
+ { 15568 , -9858 } ,
+ { 15471 , -10011 } ,
+ { 15372 , -10162 } ,
+ { 15271 , -10313 } ,
+ { 15169 , -10462 } ,
+ { 15066 , -10610 } ,
+ { 14961 , -10758 } ,
+ { 14854 , -10904 } ,
+ { 14747 , -11049 } ,
+ { 14637 , -11194 } ,
+ { 14527 , -11337 } ,
+ { 14415 , -11479 } ,
+ { 14301 , -11620 } ,
+ { 14187 , -11760 } ,
+ { 14071 , -11898 } ,
+ { 13953 , -12036 } ,
+ { 13834 , -12172 } ,
+ { 13714 , -12308 } ,
+ { 13593 , -12442 } ,
+ { 13470 , -12575 } ,
+ { 13346 , -12706 } ,
+ { 13220 , -12837 } ,
+ { 13094 , -12966 }
+ };
+cos_msin_t s_cos_msin_32[DCT_LENGTH_DIV_2] = {
+ { 18427 , -45 } ,
+ { 18427 , -136 } ,
+ { 18426 , -226 } ,
+ { 18424 , -317 } ,
+ { 18423 , -407 } ,
+ { 18420 , -497 } ,
+ { 18418 , -588 } ,
+ { 18415 , -678 } ,
+ { 18411 , -769 } ,
+ { 18407 , -859 } ,
+ { 18403 , -949 } ,
+ { 18398 , -1040 } ,
+ { 18392 , -1130 } ,
+ { 18387 , -1220 } ,
+ { 18380 , -1310 } ,
+ { 18374 , -1401 } ,
+ { 18367 , -1491 } ,
+ { 18359 , -1581 } ,
+ { 18351 , -1671 } ,
+ { 18343 , -1761 } ,
+ { 18334 , -1851 } ,
+ { 18324 , -1941 } ,
+ { 18315 , -2031 } ,
+ { 18305 , -2121 } ,
+ { 18294 , -2211 } ,
+ { 18283 , -2301 } ,
+ { 18271 , -2390 } ,
+ { 18259 , -2480 } ,
+ { 18247 , -2570 } ,
+ { 18234 , -2659 } ,
+ { 18221 , -2749 } ,
+ { 18207 , -2838 } ,
+ { 18193 , -2927 } ,
+ { 18178 , -3017 } ,
+ { 18163 , -3106 } ,
+ { 18148 , -3195 } ,
+ { 18132 , -3284 } ,
+ { 18116 , -3373 } ,
+ { 18099 , -3462 } ,
+ { 18082 , -3551 } ,
+ { 18064 , -3639 } ,
+ { 18046 , -3728 } ,
+ { 18027 , -3816 } ,
+ { 18009 , -3905 } ,
+ { 17989 , -3993 } ,
+ { 17969 , -4081 } ,
+ { 17949 , -4170 } ,
+ { 17928 , -4258 } ,
+ { 17907 , -4346 } ,
+ { 17886 , -4434 } ,
+ { 17864 , -4521 } ,
+ { 17841 , -4609 } ,
+ { 17818 , -4696 } ,
+ { 17795 , -4784 } ,
+ { 17772 , -4871 } ,
+ { 17747 , -4958 } ,
+ { 17723 , -5045 } ,
+ { 17698 , -5132 } ,
+ { 17672 , -5219 } ,
+ { 17647 , -5306 } ,
+ { 17620 , -5392 } ,
+ { 17594 , -5479 } ,
+ { 17567 , -5565 } ,
+ { 17539 , -5651 } ,
+ { 17511 , -5737 } ,
+ { 17483 , -5823 } ,
+ { 17454 , -5909 } ,
+ { 17425 , -5994 } ,
+ { 17395 , -6080 } ,
+ { 17365 , -6165 } ,
+ { 17335 , -6250 } ,
+ { 17304 , -6335 } ,
+ { 17272 , -6420 } ,
+ { 17241 , -6505 } ,
+ { 17208 , -6590 } ,
+ { 17176 , -6674 } ,
+ { 17143 , -6758 } ,
+ { 17110 , -6842 } ,
+ { 17076 , -6926 } ,
+ { 17042 , -7010 } ,
+ { 17007 , -7093 } ,
+ { 16972 , -7177 } ,
+ { 16937 , -7260 } ,
+ { 16901 , -7343 } ,
+ { 16864 , -7426 } ,
+ { 16828 , -7509 } ,
+ { 16791 , -7591 } ,
+ { 16753 , -7674 } ,
+ { 16715 , -7756 } ,
+ { 16677 , -7838 } ,
+ { 16638 , -7919 } ,
+ { 16599 , -8001 } ,
+ { 16560 , -8082 } ,
+ { 16520 , -8164 } ,
+ { 16480 , -8245 } ,
+ { 16439 , -8325 } ,
+ { 16398 , -8406 } ,
+ { 16357 , -8486 } ,
+ { 16315 , -8567 } ,
+ { 16272 , -8647 } ,
+ { 16230 , -8726 } ,
+ { 16187 , -8806 } ,
+ { 16143 , -8885 } ,
+ { 16100 , -8964 } ,
+ { 16055 , -9043 } ,
+ { 16011 , -9122 } ,
+ { 15966 , -9200 } ,
+ { 15920 , -9279 } ,
+ { 15875 , -9357 } ,
+ { 15829 , -9435 } ,
+ { 15782 , -9512 } ,
+ { 15735 , -9589 } ,
+ { 15688 , -9667 } ,
+ { 15640 , -9744 } ,
+ { 15592 , -9820 } ,
+ { 15544 , -9897 } ,
+ { 15495 , -9973 } ,
+ { 15446 , -10049 } ,
+ { 15396 , -10124 } ,
+ { 15347 , -10200 } ,
+ { 15296 , -10275 } ,
+ { 15246 , -10350 } ,
+ { 15195 , -10425 } ,
+ { 15143 , -10499 } ,
+ { 15092 , -10573 } ,
+ { 15040 , -10647 } ,
+ { 14987 , -10721 } ,
+ { 14934 , -10794 } ,
+ { 14881 , -10868 } ,
+ { 14828 , -10941 } ,
+ { 14774 , -11013 } ,
+ { 14719 , -11086 } ,
+ { 14665 , -11158 } ,
+ { 14610 , -11230 } ,
+ { 14555 , -11301 } ,
+ { 14499 , -11372 } ,
+ { 14443 , -11444 } ,
+ { 14387 , -11514 } ,
+ { 14330 , -11585 } ,
+ { 14273 , -11655 } ,
+ { 14216 , -11725 } ,
+ { 14158 , -11795 } ,
+ { 14100 , -11864 } ,
+ { 14041 , -11933 } ,
+ { 13983 , -12002 } ,
+ { 13924 , -12070 } ,
+ { 13864 , -12138 } ,
+ { 13804 , -12206 } ,
+ { 13744 , -12274 } ,
+ { 13684 , -12341 } ,
+ { 13623 , -12408 } ,
+ { 13562 , -12475 } ,
+ { 13501 , -12541 } ,
+ { 13439 , -12608 } ,
+ { 13377 , -12673 } ,
+ { 13314 , -12739 } ,
+ { 13252 , -12804 } ,
+ { 13189 , -12869 } ,
+ { 13125 , -12934 } ,
+ { 13062 , -12998 }
+ };
+cos_msin_t s_cos_msin_64[DCT_LENGTH] = {
+{18426, -21},
+{18426, -66},
+{18426, -110},
+{18426, -154},
+{18425, -198},
+{18425, -242},
+{18424, -286},
+{18424, -331},
+{18423, -374},
+{18421, -419},
+{18421, -463},
+{18419, -507},
+{18418, -552},
+{18417, -595},
+{18415, -639},
+{18414, -684},
+{18412, -728},
+{18410, -772},
+{18408, -816},
+{18406, -860},
+{18404, -904},
+{18402, -949},
+{18400, -992},
+{18397, -1037},
+{18394, -1081},
+{18392, -1125},
+{18389, -1169},
+{18387, -1213},
+{18384, -1257},
+{18380, -1301},
+{18378, -1345},
+{18374, -1389},
+{18371, -1433},
+{18367, -1477},
+{18364, -1521},
+{18360, -1566},
+{18356, -1609},
+{18352, -1653},
+{18348, -1697},
+{18344, -1742},
+{18339, -1785},
+{18335, -1829},
+{18331, -1873},
+{18326, -1917},
+{18322, -1961},
+{18317, -2005},
+{18312, -2049},
+{18307, -2092},
+{18302, -2137},
+{18297, -2180},
+{18292, -2224},
+{18286, -2268},
+{18281, -2312},
+{18275, -2356},
+{18270, -2399},
+{18264, -2443},
+{18258, -2487},
+{18252, -2531},
+{18246, -2574},
+{18240, -2618},
+{18233, -2662},
+{18227, -2706},
+{18220, -2749},
+{18214, -2793},
+{18207, -2836},
+{18200, -2880},
+{18193, -2924},
+{18186, -2967},
+{18179, -3011},
+{18172, -3055},
+{18164, -3098},
+{18157, -3142},
+{18149, -3185},
+{18141, -3229},
+{18134, -3272},
+{18126, -3316},
+{18118, -3359},
+{18109, -3403},
+{18101, -3446},
+{18094, -3489},
+{18085, -3533},
+{18076, -3576},
+{18068, -3619},
+{18059, -3663},
+{18050, -3706},
+{18041, -3749},
+{18032, -3792},
+{18023, -3836},
+{18014, -3879},
+{18005, -3922},
+{17995, -3965},
+{17986, -4008},
+{17975, -4051},
+{17966, -4094},
+{17956, -4138},
+{17946, -4180},
+{17936, -4224},
+{17926, -4266},
+{17916, -4309},
+{17905, -4353},
+{17895, -4395},
+{17884, -4438},
+{17874, -4481},
+{17863, -4524},
+{17852, -4567},
+{17841, -4609},
+{17830, -4652},
+{17819, -4695},
+{17807, -4738},
+{17796, -4780},
+{17784, -4823},
+{17772, -4865},
+{17761, -4908},
+{17749, -4951},
+{17738, -4993},
+{17725, -5036},
+{17713, -5078},
+{17701, -5121},
+{17689, -5163},
+{17676, -5205},
+{17664, -5248},
+{17651, -5290},
+{17638, -5333},
+{17626, -5375},
+{17613, -5417},
+{17599, -5459},
+{17586, -5501},
+{17573, -5544},
+{17560, -5586},
+{17546, -5627},
+{17533, -5670},
+{17519, -5712},
+{17505, -5753},
+{17492, -5795},
+{17478, -5837},
+{17464, -5879},
+{17450, -5921},
+{17435, -5963},
+{17421, -6005},
+{17406, -6046},
+{17392, -6088},
+{17377, -6130},
+{17363, -6172},
+{17348, -6213},
+{17333, -6254},
+{17318, -6296},
+{17303, -6338},
+{17288, -6379},
+{17272, -6420},
+{17257, -6462},
+{17241, -6503},
+{17225, -6545},
+{17210, -6586},
+{17194, -6627},
+{17178, -6668},
+{17162, -6709},
+{17145, -6750},
+{17130, -6791},
+{17113, -6832},
+{17097, -6874},
+{17080, -6915},
+{17064, -6956},
+{17047, -6996},
+{17030, -7037},
+{17013, -7078},
+{16996, -7119},
+{16979, -7159},
+{16962, -7200},
+{16945, -7241},
+{16927, -7281},
+{16910, -7322},
+{16892, -7362},
+{16874, -7403},
+{16856, -7444},
+{16838, -7484},
+{16821, -7524},
+{16802, -7564},
+{16784, -7605},
+{16766, -7645},
+{16748, -7685},
+{16729, -7725},
+{16711, -7765},
+{16692, -7805},
+{16674, -7845},
+{16654, -7885},
+{16635, -7925},
+{16616, -7964},
+{16597, -8004},
+{16578, -8044},
+{16559, -8084},
+{16539, -8124},
+{16520, -8164},
+{16500, -8203},
+{16480, -8242},
+{16461, -8282},
+{16441, -8322},
+{16421, -8361},
+{16401, -8400},
+{16380, -8440},
+{16360, -8479},
+{16340, -8518},
+{16319, -8557},
+{16299, -8597},
+{16278, -8635},
+{16257, -8674},
+{16237, -8713},
+{16215, -8752},
+{16195, -8791},
+{16173, -8829},
+{16152, -8868},
+{16131, -8907},
+{16110, -8946},
+{16088, -8985},
+{16067, -9023},
+{16045, -9061},
+{16023, -9100},
+{16001, -9138},
+{15979, -9176},
+{15957, -9215},
+{15935, -9253},
+{15913, -9291},
+{15891, -9329},
+{15868, -9367},
+{15846, -9405},
+{15823, -9443},
+{15800, -9481},
+{15778, -9519},
+{15755, -9557},
+{15732, -9595},
+{15709, -9632},
+{15686, -9670},
+{15662, -9708},
+{15639, -9745},
+{15615, -9782},
+{15592, -9820},
+{15569, -9857},
+{15544, -9894},
+{15521, -9932},
+{15497, -9969},
+{15473, -10006},
+{15449, -10043},
+{15425, -10080},
+{15401, -10117},
+{15377, -10154},
+{15352, -10191},
+{15327, -10227},
+{15303, -10264},
+{15278, -10301},
+{15254, -10337},
+{15229, -10374},
+{15204, -10411},
+{15180, -10447},
+{15154, -10483},
+{15129, -10519},
+{15104, -10556},
+{15078, -10592},
+{15053, -10628},
+{15027, -10664},
+{15002, -10700},
+{14976, -10736},
+{14950, -10772},
+{14924, -10808},
+{14898, -10844},
+{14872, -10879},
+{14846, -10915},
+{14820, -10950},
+{14794, -10985},
+{14767, -11021},
+{14741, -11056},
+{14714, -11092},
+{14687, -11127},
+{14661, -11162},
+{14635, -11197},
+{14607, -11232},
+{14581, -11267},
+{14554, -11302},
+{14526, -11337},
+{14499, -11372},
+{14472, -11407},
+{14444, -11441},
+{14417, -11476},
+{14389, -11511},
+{14362, -11545},
+{14334, -11579},
+{14306, -11614},
+{14278, -11648},
+{14251, -11682},
+{14222, -11716},
+{14194, -11750},
+{14166, -11784},
+{14137, -11818},
+{14109, -11852},
+{14081, -11886},
+{14053, -11919},
+{14023, -11953},
+{13995, -11987},
+{13966, -12020},
+{13937, -12054},
+{13909, -12087},
+{13879, -12120},
+{13851, -12153},
+{13821, -12187},
+{13792, -12220},
+{13763, -12253},
+{13733, -12286},
+{13704, -12319},
+{13674, -12351},
+{13645, -12385},
+{13615, -12417},
+{13585, -12450},
+{13555, -12482},
+{13525, -12514},
+{13495, -12546},
+{13465, -12579},
+{13435, -12611},
+{13405, -12644},
+{13374, -12676},
+{13345, -12708},
+{13314, -12739},
+{13283, -12772}
+};
+
+
+
+cos_msin_t *s_cos_msin_table[] = {s_cos_msin_2, s_cos_msin_4,
+ s_cos_msin_8, s_cos_msin_16,
+ s_cos_msin_32, s_cos_msin_64
+ };
+
diff --git a/third_party/g7221/decode/decoder.c b/third_party/g7221/decode/decoder.c
new file mode 100644
index 00000000..c6b8c065
--- /dev/null
+++ b/third_party/g7221/decode/decoder.c
@@ -0,0 +1,1112 @@
+/***************************************************************************
+**
+** 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: decoder.c
+
+ Purpose: Contains files used to implement the G.722.1 Annex C decoder
+
+ Design Notes:
+
+***************************************************************************/
+
+/***************************************************************************
+ Include files
+***************************************************************************/
+#include "defs.h"
+#include "tables.h"
+#include "huff_def.h"
+#include "count.h"
+
+
+/***************************************************************************
+ Function: decoder
+
+ Syntax: void decoder(Bit_Obj *bitobj,
+ Rand_Obj *randobj,
+ Word16 number_of_regions,
+ Word16 *decoder_mlt_coefs,
+ Word16 *p_mag_shift,
+ Word16 *p_old_mag_shift,
+ Word16 *old_decoder_mlt_coefs,
+ Word16 frame_error_flag)
+
+ inputs: Bit_Obj *bitobj
+ Rand_Obj *randobj
+ Word16 number_of_regions
+ Word16 *p_old_mag_shift
+ Word16 *old_decoder_mlt_coefs
+ Word16 frame_error_flag
+
+ outputs: Word16 *decoder_mlt_coefs,
+ Word16 *p_mag_shift,
+
+
+
+ Description: Decodes the out_words into mlt coefs using G.722.1 Annex C
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|-------------|----------------
+ AVG | 0.84 | 0.94
+ -------|-------------|----------------
+ MAX | 0.90 | 1.00
+ -------|-------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|-------------|----------------|----------------
+ AVG | 1.31 | 1.56 | 1.88
+ -------|-------------|----------------|----------------
+ MAX | 1.59 | 1.80 | 1.98
+ -------|-------------|----------------|----------------
+
+***************************************************************************/
+void decoder(Bit_Obj *bitobj,
+ Rand_Obj *randobj,
+ Word16 number_of_regions,
+ Word16 *decoder_mlt_coefs,
+ Word16 *p_mag_shift,
+ Word16 *p_old_mag_shift,
+ Word16 *old_decoder_mlt_coefs,
+ Word16 frame_error_flag)
+{
+
+
+ Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
+ Word16 decoder_power_categories[MAX_NUMBER_OF_REGIONS];
+ Word16 decoder_category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];
+ UWord16 categorization_control;
+ Word16 decoder_region_standard_deviation[MAX_NUMBER_OF_REGIONS];
+ Word16 i;
+
+ Word16 num_categorization_control_bits;
+ Word16 num_categorization_control_possibilities;
+ Word16 number_of_coefs;
+ Word16 number_of_valid_coefs;
+
+
+ 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();
+ number_of_coefs = DCT_LENGTH;
+ move16();
+ number_of_valid_coefs = NUMBER_OF_VALID_COEFS;
+ move16();
+ }
+ else
+ {
+ num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS;
+ move16();
+ num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
+ move16();
+ number_of_coefs = MAX_DCT_LENGTH;
+ move16();
+ number_of_valid_coefs = MAX_NUMBER_OF_VALID_COEFS;
+ move16();
+ }
+
+ test();
+ if (frame_error_flag == 0)
+ {
+
+ /* convert the bits to absolute region power index and decoder_region_standard_deviation */
+
+ decode_envelope(bitobj,
+ number_of_regions,
+ decoder_region_standard_deviation,
+ absolute_region_power_index,
+ p_mag_shift);
+
+ /* fill the categorization_control with NUM_CATEGORIZATION_CONTROL_BITS */
+ categorization_control = 0;
+ for (i=0; i<num_categorization_control_bits; i++)
+ {
+ get_next_bit(bitobj);
+ categorization_control = shl(categorization_control,1);
+ categorization_control = add(categorization_control,bitobj->next_bit);
+ }
+
+ bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,num_categorization_control_bits);
+
+ /* obtain decoder power categories and category balances */
+ /* based on the absolute region power index */
+ categorize(bitobj->number_of_bits_left,
+ number_of_regions,
+ num_categorization_control_possibilities,
+ absolute_region_power_index,
+ decoder_power_categories,
+ decoder_category_balances);
+
+ /* perform adjustmaents to the power categories and category balances based on the cat control */
+ rate_adjust_categories(categorization_control,
+ decoder_power_categories,
+ decoder_category_balances);
+
+ /* decode the quantized bits into mlt coefs */
+ decode_vector_quantized_mlt_indices(bitobj,
+ randobj,
+ number_of_regions,
+ decoder_region_standard_deviation,
+ decoder_power_categories,
+ decoder_mlt_coefs);
+
+ /* test for frame errors */
+ test_4_frame_errors(bitobj,
+ number_of_regions,
+ num_categorization_control_possibilities,
+ &frame_error_flag,
+ categorization_control,
+ absolute_region_power_index);
+ }
+
+ /* perform error handling operations */
+ error_handling(number_of_coefs,
+ number_of_valid_coefs,
+ &frame_error_flag,
+ decoder_mlt_coefs,
+ old_decoder_mlt_coefs,
+ p_mag_shift,
+ p_old_mag_shift);
+
+}
+
+/***************************************************************************
+ Function: decode_envelope
+
+ Syntax: void decode_envelope(Bit_Obj *bitobj,
+ Word16 number_of_regions,
+ Word16 *decoder_region_standard_deviation,
+ Word16 *absolute_region_power_index,
+ Word16 *p_mag_shift)
+
+ inputs: Bit_Obj *bitobj
+ Word16 number_of_regions
+
+
+ outputs: Word16 *decoder_region_standard_deviation
+ Word16 *absolute_region_power_index
+ Word16 *p_mag_shift
+
+
+ Description: Recover differential_region_power_index from code bits
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.04 | 0.04
+ -------|--------------|----------------
+ MAX | 0.05 | 0.05
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.08 | 0.08 | 0.08
+ -------|--------------|----------------|----------------
+ MAX | 0.10 | 0.10 | 0.10
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void decode_envelope(Bit_Obj *bitobj,
+ Word16 number_of_regions,
+ Word16 *decoder_region_standard_deviation,
+ Word16 *absolute_region_power_index,
+ Word16 *p_mag_shift)
+
+{
+ Word16 region;
+ Word16 i;
+ Word16 index;
+ Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];
+ Word16 max_index;
+
+ Word16 temp;
+ Word16 temp1;
+ Word16 temp2;
+ Word32 acca;
+
+ index = 0;
+ move16();
+
+ /* get 5 bits from the current code word */
+ for (i=0; i<5; i++)
+ {
+ get_next_bit(bitobj);
+ index = shl(index,1);
+ index = add(index,bitobj->next_bit);
+ }
+ bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,5);
+
+ /* ESF_ADJUSTMENT_TO_RMS_INDEX compensates for the current (9/30/96)
+ IMLT being scaled to high by the ninth power of sqrt(2). */
+ differential_region_power_index[0] = sub(index,ESF_ADJUSTMENT_TO_RMS_INDEX);
+ move16();
+
+ /* obtain differential_region_power_index */
+ for (region=1; region<number_of_regions; region++)
+ {
+ index = 0;
+ move16();
+ do
+ {
+ get_next_bit(bitobj);
+ test();
+ if (bitobj->next_bit == 0)
+ {
+ index = differential_region_power_decoder_tree[region][index][0];
+ move16();
+ }
+ else
+ {
+ index = differential_region_power_decoder_tree[region][index][1];
+ move16();
+ }
+ bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);
+ test();
+ } while (index > 0);
+
+ differential_region_power_index[region] = negate(index);
+ move16();
+ }
+
+ /* Reconstruct absolute_region_power_index[] from differential_region_power_index[]. */
+ absolute_region_power_index[0] = differential_region_power_index[0];
+ move16();
+ for (region=1; region<number_of_regions; region++)
+ {
+ acca = L_add(absolute_region_power_index[region-1],differential_region_power_index[region]);
+ acca = L_add(acca,DRP_DIFF_MIN);
+ absolute_region_power_index[region] = extract_l(acca);
+ }
+
+ /* Reconstruct decoder_region_standard_deviation[] from absolute_region_power_index[]. */
+ /* DEBUG!!!! - This integer method jointly computes the mag_shift
+ and the standard deviations already mag_shift compensated. It
+ relies on REGION_POWER_STEPSIZE_DB being exactly 3.010299957 db
+ or a square root of 2 chnage in standard deviation. If
+ REGION_POWER_STEPSIZE_DB changes, this software must be
+ reworked. */
+
+ temp = 0;
+ move16();
+ max_index = 0;
+ move16();
+ for (region=0; region<number_of_regions; region++)
+ {
+ acca = L_add(absolute_region_power_index[region],REGION_POWER_TABLE_NUM_NEGATIVES);
+ i = extract_l(acca);
+
+ temp1 = sub(i,max_index);
+ test();
+ if (temp1 > 0)
+ {
+ max_index = i;
+ move16();
+ }
+ temp = add(temp,int_region_standard_deviation_table[i]);
+ }
+ i = 9;
+ move16();
+
+ temp1 = sub(temp,8);
+ temp2 = sub(max_index,28);
+ test();
+ test();
+ logic16();
+ test();
+ logic16();
+ while ((i >= 0) && ((temp1 >= 0) || (temp2 > 0)))
+ {
+ i = sub(i,1);
+ temp = shr(temp,1);
+ max_index = sub(max_index,2);
+ temp1 = sub(temp,8);
+ temp2 = sub(max_index,28);
+ test();
+ test();
+ logic16();
+ test();
+ logic16();
+ }
+
+ *p_mag_shift = i;
+ move16();
+
+ /* pointer arithmetic */
+ temp = (Word16 )(REGION_POWER_TABLE_NUM_NEGATIVES + (*p_mag_shift * 2));
+
+ for (region=0; region<number_of_regions; region++)
+ {
+ acca = L_add(absolute_region_power_index[region],temp);
+ i = extract_l(acca);
+ decoder_region_standard_deviation[region] = int_region_standard_deviation_table[i];
+ move16();
+ }
+
+}
+
+/***************************************************************************
+ Function: rate_adjust_categories
+
+ Syntax: void rate_adjust_categories(Word16 categorization_control,
+ Word16 *decoder_power_categories,
+ Word16 *decoder_category_balances)
+
+ inputs: Word16 categorization_control,
+ Word16 *decoder_power_categories,
+ Word16 *decoder_category_balances
+
+ outputs: Word16 categorization_control,
+ Word16 *decoder_power_categories,
+
+ Description: Adjust the power categories based on the categorization control
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.00 | 0.00
+ -------|--------------|----------------
+ MAX | 0.00 | 0.00
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+ MAX | 0.01 | 0.01 | 0.01
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void rate_adjust_categories(Word16 categorization_control,
+ Word16 *decoder_power_categories,
+ Word16 *decoder_category_balances)
+{
+ Word16 i;
+ Word16 region;
+
+ i = 0;
+ move16();
+
+ test();
+ while (categorization_control > 0)
+ {
+ region = decoder_category_balances[i++];
+ move16();
+ decoder_power_categories[region] = add(decoder_power_categories[region],1);
+ move16();
+ categorization_control = sub(categorization_control,1);
+ }
+
+}
+
+/***************************************************************************
+ Function: decode_vector_quantized_mlt_indices
+
+ Syntax: void decode_vector_quantized_mlt_indices(Bit_Obj *bitobj,
+ Rand_Obj *randobj,
+ Word16 number_of_regions,
+ Word16 *decoder_region_standard_deviation,
+ Word16 *decoder_power_categories,
+ Word16 *decoder_mlt_coefs)
+ inputs: Bit_Obj *bitobj
+ Rand_Obj *randobj
+ Word16 number_of_regions
+ Word16 *decoder_region_standard_deviation
+ Word16 *decoder_power_categories
+
+
+ outputs: Word16 *decoder_mlt_coefs
+
+
+ Description: Decode MLT coefficients
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.60 | 0.72
+ -------|--------------|----------------
+ MAX | 0.67 | 0.76
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.77 | 0.98 | 1.28
+ -------|--------------|----------------|----------------
+ MAX | 1.05 | 1.18 | 1.36
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void decode_vector_quantized_mlt_indices(Bit_Obj *bitobj,
+ Rand_Obj *randobj,
+ Word16 number_of_regions,
+ Word16 *decoder_region_standard_deviation,
+ Word16 *decoder_power_categories,
+ Word16 *decoder_mlt_coefs)
+{
+ Word16 standard_deviation;
+ Word16 *decoder_mlt_ptr;
+ Word16 decoder_mlt_value;
+ Word16 noifillpos;
+ Word16 noifillneg;
+ Word16 noise_fill_factor[3] = {5793,8192,23170};
+ Word16 region;
+ Word16 category;
+ Word16 j,n;
+ Word16 k[MAX_VECTOR_DIMENSION];
+ Word16 vec_dim;
+ Word16 num_vecs;
+ Word16 index;
+ Word16 signs_index;
+ Word16 bit;
+ Word16 num_sign_bits;
+ Word16 ran_out_of_bits_flag;
+ Word16 *decoder_table_ptr;
+ Word16 random_word;
+
+ Word16 temp1;
+ Word16 temp;
+ Word32 acca;
+
+ ran_out_of_bits_flag = 0;
+ move16();
+
+ for (region=0; region<number_of_regions; region++)
+ {
+ category = (Word16)decoder_power_categories[region];
+ move16();
+ acca = L_mult0(region,REGION_SIZE);
+ index = extract_l(acca);
+ decoder_mlt_ptr = &decoder_mlt_coefs[index];
+ move16();
+ standard_deviation = decoder_region_standard_deviation[region];
+ move16();
+
+ temp = sub(category,7);
+ test();
+ if (temp < 0)
+ {
+ /* Get the proper table of decoder tables, vec_dim, and num_vecs for the cat */
+ decoder_table_ptr = (Word16 *) table_of_decoder_tables[category];
+ move16();
+ vec_dim = vector_dimension[category];
+ move16();
+ num_vecs = number_of_vectors[category];
+ move16();
+
+ for (n=0; n<num_vecs; n++)
+ {
+ index = 0;
+ move16();
+
+ /* get index */
+ do
+ {
+ test();
+ if (bitobj->number_of_bits_left <= 0)
+ {
+ ran_out_of_bits_flag = 1;
+ move16();
+ break;
+ }
+
+ get_next_bit(bitobj);
+
+ test();
+ if (bitobj->next_bit == 0)
+ {
+ temp = shl(index,1);
+ index = (Word16)*(decoder_table_ptr + temp);
+ move16();
+ }
+ else
+ {
+ temp = shl(index,1);
+ index = (Word16)*(decoder_table_ptr + temp + 1);
+ move16();
+ }
+ bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);
+ test();
+
+ } while (index > 0);
+
+ test();
+ if (ran_out_of_bits_flag != 0)
+ break;
+
+ index = negate(index);
+
+ /* convert index into array used to access the centroid table */
+ /* get the number of sign bits in the index */
+ num_sign_bits = index_to_array(index,k,category);
+
+ temp = sub(bitobj->number_of_bits_left,num_sign_bits);
+ test();
+ if (temp >= 0)
+ {
+ test();
+ if (num_sign_bits != 0)
+ {
+ signs_index = 0;
+ move16();
+ for (j=0; j<num_sign_bits; j++)
+ {
+ get_next_bit(bitobj);
+ signs_index = shl(signs_index,1);
+ signs_index = add(signs_index,bitobj->next_bit);
+ bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);
+ }
+ temp = sub(num_sign_bits,1);
+ bit = shl(1,(temp));
+ }
+
+ for (j=0; j<vec_dim; j++)
+ {
+ acca = L_mult0(standard_deviation,mlt_quant_centroid[category][k[j]]);
+ acca = L_shr(acca,12);
+ decoder_mlt_value = extract_l(acca);
+
+ test();
+ if (decoder_mlt_value != 0)
+ {
+ test();
+ if ((signs_index & bit) == 0)
+ decoder_mlt_value = negate(decoder_mlt_value);
+ bit = shr(bit,1);
+ }
+ *decoder_mlt_ptr++ = decoder_mlt_value;
+ move16();
+ }
+ }
+ else
+ {
+ ran_out_of_bits_flag = 1;
+ move16();
+ break;
+ }
+ }
+ /* If ran out of bits during decoding do noise fill for remaining regions. */
+ /* DEBUG!! - For now also redo all of last region with all noise fill. */
+ test();
+ if (ran_out_of_bits_flag != 0)
+ {
+ temp = add(region,1);
+ for (j=temp; j<number_of_regions; j++)
+ {
+ decoder_power_categories[j] = 7;
+ move16();
+ }
+ category = 7;
+ move16();
+ decoder_mlt_ptr = &decoder_mlt_coefs[region*REGION_SIZE];
+ move16();
+ }
+ }
+
+ temp = sub(category,5);
+ temp1 = sub(category,6);
+ test();
+ test();
+ logic16();
+ if ((temp == 0) || (temp1 == 0))
+ {
+
+ decoder_mlt_ptr = &decoder_mlt_coefs[region*REGION_SIZE];
+ move16();
+ noifillpos = mult(standard_deviation,noise_fill_factor[category - 5]);
+ noifillneg = negate(noifillpos);
+
+ random_word = get_rand(randobj);
+
+ for (j=0; j<10; j++)
+ {
+ test();
+ if (*decoder_mlt_ptr == 0)
+ {
+ logic16();
+ test();
+ if ((random_word & 1) == 0)
+ {
+ temp1 = noifillneg;
+ move16();
+ }
+ else
+ {
+ temp1 = noifillpos;
+ move16();
+ }
+ *decoder_mlt_ptr = temp1;
+ move16();
+ random_word = shr(random_word,1);
+ }
+ /* pointer arithmetic */
+ decoder_mlt_ptr++;
+ }
+ random_word = get_rand(randobj);
+ for (j=0; j<10; j++)
+ {
+ test();
+ if (*decoder_mlt_ptr == 0)
+ {
+ logic16();
+ test();
+ if ((random_word & 1) == 0)
+ {
+ temp1 = noifillneg;
+ move16();
+ }
+ else
+ {
+ temp1 = noifillpos;
+ move16();
+ }
+ *decoder_mlt_ptr = temp1;
+ move16();
+ random_word = shr(random_word,1);
+ }
+ /* pointer arithmetic */
+ decoder_mlt_ptr++;
+ }
+ }
+
+ /* if (category == 7) */
+ temp1 = sub(category,7);
+ test();
+ if (temp1 == 0)
+ {
+ index = sub(category,5);
+ noifillpos = mult(standard_deviation,noise_fill_factor[index]);
+ noifillneg = negate(noifillpos);
+
+ random_word = get_rand(randobj);
+ for (j=0; j<10; j++)
+ {
+ logic16();
+ test();
+ if ((random_word & 1) == 0)
+ {
+ temp1 = noifillneg;
+ move16();
+ }
+ else
+ {
+ temp1 = noifillpos;
+ move16();
+ }
+ *decoder_mlt_ptr++ = temp1;
+ move16();
+ random_word = shr(random_word,1);
+ }
+ random_word = get_rand(randobj);
+ for (j=0; j<10; j++)
+ {
+ logic16();
+ test();
+ if ((random_word & 1) == 0)
+ {
+ temp1 = noifillneg;
+ move16();
+ }
+ else
+ {
+ temp1 = noifillpos;
+ move16();
+ }
+
+ *decoder_mlt_ptr++ = temp1;
+ move16();
+ random_word = shr(random_word,1);
+ }
+ }
+ }
+
+ test();
+ if (ran_out_of_bits_flag)
+ bitobj->number_of_bits_left = sub(bitobj->number_of_bits_left,1);
+}
+/****************************************************************************************
+ Function: index_to_array
+
+ Syntax: number_of_non_zero = index_to_array(Word16 index,
+ Word16 array[MAX_VECTOR_DIMENSION],
+ Word16 category)
+
+ inputs: Word16 index
+ Word16 category
+
+ outputs: Word16 array[MAX_VECTOR_DIMENSION] - used in decoder to access
+ mlt_quant_centroid table
+
+ Word16 number_of_non_zero - number of non zero elements
+ in the array
+
+ Description: Computes an array of sign bits with the length of the category vector
+ Returns the number of sign bits and the array
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.00 | 0.00
+ -------|--------------|----------------
+ MAX | 0.00 | 0.00
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+ MAX | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+
+****************************************************************************************/
+Word16 index_to_array(Word16 index,Word16 *array,Word16 category)
+{
+ Word16 j,q,p;
+ Word16 number_of_non_zero;
+ Word16 max_bin_plus_one;
+ Word16 inverse_of_max_bin_plus_one;
+ Word16 temp;
+
+ number_of_non_zero = 0;
+ move16();
+
+ p = index;
+ move16();
+
+ max_bin_plus_one = add(max_bin[category],1);
+ inverse_of_max_bin_plus_one = max_bin_plus_one_inverse[category];
+ move16();
+
+ temp = sub(vector_dimension[category],1);
+ for (j=temp; j>=0; j--)
+ {
+ q = mult(p,inverse_of_max_bin_plus_one);
+ temp = extract_l(L_mult0(q,max_bin_plus_one));
+ array[j] = sub(p,temp);
+ move16();
+
+ p = q;
+ move16();
+
+ temp = array[j];
+ move16();
+ test();
+ if (temp != 0)
+ number_of_non_zero = add(number_of_non_zero,1);
+ }
+ return(number_of_non_zero);
+}
+/***************************************************************************
+ Function: test_4_frame_errors
+
+ Syntax: void test_4_frame_errors(Bit_Obj *bitobj,
+ Word16 number_of_regions,
+ Word16 num_categorization_control_possibilities,
+ Word16 *frame_error_flag,
+ Word16 categorization_control,
+ Word16 *absolute_region_power_index)
+
+ inputs: bit_obj
+ number_of_regions
+ num_categorization_control_possibilities
+ frame_error_flag
+ categorization_control
+ absolute_region_power_index
+
+
+ outputs: frame_error_flag
+
+
+
+
+ Description: Tests for error conditions and sets the frame_error_flag accordingly
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.01 | 0.01
+ -------|--------------|----------------
+ MAX | 0.04 | 0.08
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.01 | 0.01 | 0.01
+ -------|--------------|----------------|----------------
+ MAX | 0.02 | 0.06 | 0.08
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void test_4_frame_errors(Bit_Obj *bitobj,
+ Word16 number_of_regions,
+ Word16 num_categorization_control_possibilities,
+ Word16 *frame_error_flag,
+ Word16 categorization_control,
+ Word16 *absolute_region_power_index)
+{
+ Word16 region;
+ Word16 i;
+ Word16 temp;
+ Word32 acca;
+ Word32 accb;
+
+ /* Test for bit stream errors. */
+
+ test();
+ if (bitobj->number_of_bits_left > 0)
+ {
+ for (i=0; i<bitobj->number_of_bits_left; i++)
+ {
+ get_next_bit(bitobj);
+ test();
+ if (bitobj->next_bit == 0)
+ {
+ *frame_error_flag = 1;
+ move16();
+ }
+ }
+ }
+ else
+ {
+ temp = sub(categorization_control,sub(num_categorization_control_possibilities,1));
+ test();
+ if (temp < 0)
+ {
+ test();
+ if (bitobj->number_of_bits_left < 0)
+ {
+ *frame_error_flag |= 2;
+ logic16();
+ }
+ }
+ }
+
+ /* checks to ensure that abs_region_power_index is within range */
+ /* the error flag is set if it is out of range */
+ for (region=0; region<number_of_regions; region++)
+ {
+ /* the next two lines of comments were modified in release 1.2
+ * to correct the description of the range of
+ * absolute_region_power_index[] to be tested in the next
+ * 9 lines of code.
+ */
+ /* if ((absolute_region_power_index[region] > 31) ||
+ (absolute_region_power_index[region] < -8) */
+
+ acca = L_add(absolute_region_power_index[region],ESF_ADJUSTMENT_TO_RMS_INDEX);
+ accb = L_sub(acca,31);
+ acca = L_add(acca,8);
+ test();
+
+ /* the next line was modifed in release 1.2 to
+ * correct miss typed code and error checking.
+ */
+ if ((accb > 0) || (acca < 0))
+ {
+ *frame_error_flag |= 4;
+ logic16();
+ }
+ }
+
+}
+/***************************************************************************
+ Function: error_handling
+
+ Syntax: void error_handling(Word16 number_of_coefs,
+ Word16 number_of_valid_coefs,
+ Word16 *frame_error_flag,
+ Word16 *decoder_mlt_coefs,
+ Word16 *old_decoder_mlt_coefs,
+ Word16 *p_mag_shift,
+ Word16 *p_old_mag_shift)
+
+ inputs: number_of_coefs
+ number_of_valid_coefs
+ frame_error_flag
+ old_decoder_mlt_coefs
+ p_old_mag_shift
+
+
+ outputs: decoder_mlt_coefs
+ old_decoder_mlt_coefs
+ p_mag_shift
+ p_old_mag_shift
+
+
+
+ Description: If both the current and previous frames are errored,
+ set the mlt coefficients to 0. If only the current frame
+ is errored, then repeat the previous frame's mlt coefficients.
+
+ Design Notes:
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.02 | 0.02
+ -------|--------------|----------------
+ MAX | 0.03 | 0.03
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.03 | 0.03 | 0.03
+ -------|--------------|----------------|----------------
+ MAX | 0.03 | 0.03 | 0.06
+ -------|--------------|----------------|----------------
+
+***************************************************************************/
+void error_handling(Word16 number_of_coefs,
+ Word16 number_of_valid_coefs,
+ Word16 *frame_error_flag,
+ Word16 *decoder_mlt_coefs,
+ Word16 *old_decoder_mlt_coefs,
+ Word16 *p_mag_shift,
+ Word16 *p_old_mag_shift)
+{
+ Word16 i;
+
+ test();
+ if (*frame_error_flag != 0)
+ {
+
+ for (i = 0; i < number_of_valid_coefs; i++)
+ {
+ decoder_mlt_coefs[i] = old_decoder_mlt_coefs[i];
+ move16();
+ }
+
+ for (i = 0; i < number_of_valid_coefs; i++)
+ {
+ old_decoder_mlt_coefs[i] = 0;
+ move16();
+ }
+
+ *p_mag_shift = *p_old_mag_shift;
+ move16();
+
+ *p_old_mag_shift = 0;
+ move16();
+ }
+ else
+ {
+ /* Store in case next frame is errored. */
+ for (i = 0; i < number_of_valid_coefs; i++)
+ {
+ old_decoder_mlt_coefs[i] = decoder_mlt_coefs[i];
+ move16();
+ }
+
+ *p_old_mag_shift = *p_mag_shift;
+ move16();
+ }
+
+
+ /* Zero out the upper 1/8 of the spectrum. */
+ for (i = number_of_valid_coefs; i < number_of_coefs; i++)
+ {
+ decoder_mlt_coefs[i] = 0;
+ move16();
+ }
+
+}
+/****************************************************************************************
+ Function: get_next_bit
+
+ Syntax: void get_next_bit(Bit_Obj *bitobj)
+
+ Description: Returns the next bit in the current word inside the bit object
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.00 | 0.00
+ -------|--------------|----------------
+ MAX | 0.00 | 0.00
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+ MAX | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+
+****************************************************************************************/
+void get_next_bit(Bit_Obj *bitobj)
+{
+ Word16 temp;
+
+ test();
+ if (bitobj->code_bit_count == 0)
+ {
+ bitobj->current_word = *bitobj->code_word_ptr++;
+ move16();
+ bitobj->code_bit_count = 16;
+ move16();
+ }
+ bitobj->code_bit_count = sub(bitobj->code_bit_count,1);
+ temp = shr(bitobj->current_word,bitobj->code_bit_count);
+ logic16();
+ bitobj->next_bit = (Word16 )(temp & 1);
+
+}
+/****************************************************************************************
+ Function: get_rand
+
+ Syntax: Word16 get_rand(Rand_Obj *randobj)
+
+ Description: Returns a random Word16 based on the seeds inside the rand object
+
+ WMOPS: 7kHz | 24kbit | 32kbit
+ -------|--------------|----------------
+ AVG | 0.00 | 0.00
+ -------|--------------|----------------
+ MAX | 0.00 | 0.00
+ -------|--------------|----------------
+
+ 14kHz | 24kbit | 32kbit | 48kbit
+ -------|--------------|----------------|----------------
+ AVG | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+ MAX | 0.00 | 0.00 | 0.00
+ -------|--------------|----------------|----------------
+
+****************************************************************************************/
+Word16 get_rand(Rand_Obj *randobj)
+{
+ Word16 random_word;
+ Word32 acca;
+
+ acca = L_add(randobj->seed0,randobj->seed3);
+ random_word = extract_l(acca);
+
+ logic16();
+ test();
+ if ((random_word & 32768L) != 0)
+ random_word = add(random_word,1);
+
+ randobj->seed3 = randobj->seed2;
+ move16();
+ randobj->seed2 = randobj->seed1;
+ move16();
+ randobj->seed1 = randobj->seed0;
+ move16();
+ randobj->seed0 = random_word;
+ move16();
+
+ return(random_word);
+}