diff options
Diffstat (limited to 'third_party/g7221/decode')
-rw-r--r-- | third_party/g7221/decode/coef2sam.c | 180 | ||||
-rw-r--r-- | third_party/g7221/decode/dct4_s.c | 480 | ||||
-rw-r--r-- | third_party/g7221/decode/dct4_s.h | 856 | ||||
-rw-r--r-- | third_party/g7221/decode/decoder.c | 1112 |
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); +} |