[FFmpeg-soc] [soc]: r2211 - in eac3: ac3dec.c ac3dec.h eac3dec.c

jbr subversion at mplayerhq.hu
Mon May 26 19:20:46 CEST 2008


Author: jbr
Date: Mon May 26 19:20:45 2008
New Revision: 2211

Log:
use 24-bit signed fixed-point transform coefficients

Modified:
   eac3/ac3dec.c
   eac3/ac3dec.h
   eac3/eac3dec.c

Modified: eac3/ac3dec.c
==============================================================================
--- eac3/ac3dec.c	(original)
+++ eac3/ac3dec.c	Mon May 26 19:20:45 2008
@@ -40,22 +40,16 @@
 #include "random.h"
 #include "ac3dec.h"
 
-/**
- * table for exponent to scale_factor mapping
- * ff_ac3_scale_factors[i] = 2 ^ -i
- */
-float ff_ac3_scale_factors[25];
-
 /** table for grouping exponents */
 static uint8_t exp_ungroup_tab[128][3];
 
 
 /** tables for ungrouping mantissas */
-static float b1_mantissas[32][3];
-static float b2_mantissas[128][3];
-static float b3_mantissas[8];
-static float b4_mantissas[128][2];
-static float b5_mantissas[16];
+static int b1_mantissas[32][3];
+static int b2_mantissas[128][3];
+static int b3_mantissas[8];
+static int b4_mantissas[128][2];
+static int b5_mantissas[16];
 
 /**
  * Quantization table: levels for symmetric. bits for asymmetric.
@@ -124,10 +118,10 @@ static const uint8_t ac3_default_coeffs[
  * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
  *            Tables 7.19 to 7.23
  */
-static inline float
+static inline int
 symmetric_dequant(int code, int levels)
 {
-    return (code - (levels >> 1)) * (2.0f / levels);
+    return ((code - (levels >> 1)) << 24) / levels;
 }
 
 /*
@@ -173,11 +167,6 @@ static void ac3_tables_init(void)
         dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20);
     }
 
-    /* generate scale factors for exponents and asymmetrical dequantization
-       reference: Section 7.3.2 Expansion of Mantissas for Asymmetric Quantization */
-    for (i = 0; i < 25; i++)
-        ff_ac3_scale_factors[i] = pow(2.0, -i);
-
     /* generate exponent tables
        reference: Section 7.1.3 Exponent Decoding */
     for(i=0; i<128; i++) {
@@ -405,9 +394,9 @@ static void uncouple_channels(AC3DecodeC
             for(j=0; j<12; j++) {
                 for(ch=1; ch<=s->fbw_channels; ch++) {
                     if(s->channel_in_cpl[ch]) {
-                        s->transform_coeffs[ch][i] = s->transform_coeffs[CPL_CH][i] * s->cpl_coords[ch][bnd] * 8.0f;
+                        s->fixed_coeffs[ch][i] = ((int64_t)s->fixed_coeffs[CPL_CH][i] * (int64_t)s->cpl_coords[ch][bnd]) >> 23;
                         if (ch == 2 && s->phase_flags[bnd])
-                            s->transform_coeffs[ch][i] = -s->transform_coeffs[ch][i];
+                            s->fixed_coeffs[ch][i] = -s->fixed_coeffs[ch][i];
                     }
                 }
                 i++;
@@ -420,9 +409,9 @@ static void uncouple_channels(AC3DecodeC
  * Grouped mantissas for 3-level 5-level and 11-level quantization
  */
 typedef struct {
-    float b1_mant[3];
-    float b2_mant[3];
-    float b4_mant[2];
+    int b1_mant[3];
+    int b2_mant[3];
+    int b4_mant[2];
     int b1ptr;
     int b2ptr;
     int b4ptr;
@@ -438,11 +427,11 @@ static int ac3_get_transform_coeffs_ch(A
     int i, gcode, tbap, start, end;
     uint8_t *exps;
     uint8_t *bap;
-    float *coeffs;
+    int *coeffs;
 
     exps = s->dexps[ch_index];
     bap = s->bap[ch_index];
-    coeffs = s->transform_coeffs[ch_index];
+    coeffs = s->fixed_coeffs[ch_index];
     start = s->start_freq[ch_index];
     end = s->end_freq[ch_index];
 
@@ -450,7 +439,7 @@ static int ac3_get_transform_coeffs_ch(A
         tbap = bap[i];
         switch (tbap) {
             case 0:
-                coeffs[i] = ((av_random(&s->dith_state) & 0xFFFF) / 65535.0f) - 0.5f;
+                coeffs[i] = (av_random(&s->dith_state) & 0x7FFFFF) - 4194304;
                 break;
 
             case 1:
@@ -493,12 +482,14 @@ static int ac3_get_transform_coeffs_ch(A
                 coeffs[i] = b5_mantissas[get_bits(gbc, 4)];
                 break;
 
-            default:
+            default: {
                 /* asymmetric dequantization */
-                coeffs[i] = get_sbits(gbc, quantization_tab[tbap]) * ff_ac3_scale_factors[quantization_tab[tbap]-1];
+                int qlevel = quantization_tab[tbap];
+                coeffs[i] = get_sbits(gbc, qlevel) << (24 - qlevel);
                 break;
+            }
         }
-        coeffs[i] *= ff_ac3_scale_factors[exps[i]];
+        coeffs[i] >>= exps[i];
     }
 
     return 0;
@@ -511,12 +502,12 @@ static int ac3_get_transform_coeffs_ch(A
 static void remove_dithering(AC3DecodeContext *s) {
     int ch, i;
     int end=0;
-    float *coeffs;
+    int *coeffs;
     uint8_t *bap;
 
     for(ch=1; ch<=s->fbw_channels; ch++) {
         if(!s->dither_flag[ch]) {
-            coeffs = s->transform_coeffs[ch];
+            coeffs = s->fixed_coeffs[ch];
             bap = s->channel_uses_aht[ch] ? s->hebap[ch] : s->bap[ch];
             if(s->channel_in_cpl[ch])
                 end = s->start_freq[CPL_CH];
@@ -524,13 +515,13 @@ static void remove_dithering(AC3DecodeCo
                 end = s->end_freq[ch];
             for(i=0; i<end; i++) {
                 if(!bap[i])
-                    coeffs[i] = 0.0f;
+                    coeffs[i] = 0;
             }
             if(s->channel_in_cpl[ch]) {
                 bap = s->channel_uses_aht[CPL_CH] ? s->hebap[CPL_CH] : s->bap[CPL_CH];
                 for(; i<s->end_freq[CPL_CH]; i++) {
                     if(!bap[i])
-                        coeffs[i] = 0.0f;
+                        coeffs[i] = 0;
                 }
             }
         }
@@ -584,7 +575,7 @@ static int get_transform_coeffs(AC3Decod
             end = s->end_freq[ch];
         }
         do
-            s->transform_coeffs[ch][end] = 0;
+            s->fixed_coeffs[ch][end] = 0;
         while(++end < 256);
     }
 
@@ -603,7 +594,7 @@ static void do_rematrixing(AC3DecodeCont
 {
     int bnd, i;
     int end, bndend;
-    float tmp0, tmp1;
+    int tmp0, tmp1;
 
     end = FFMIN(s->end_freq[1], s->end_freq[2]);
 
@@ -611,10 +602,10 @@ static void do_rematrixing(AC3DecodeCont
         if(s->rematrixing_flags[bnd]) {
             bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd+1]);
             for(i=ff_ac3_rematrix_band_tab[bnd]; i<bndend; i++) {
-                tmp0 = s->transform_coeffs[1][i];
-                tmp1 = s->transform_coeffs[2][i];
-                s->transform_coeffs[1][i] = tmp0 + tmp1;
-                s->transform_coeffs[2][i] = tmp0 - tmp1;
+                tmp0 = s->fixed_coeffs[1][i];
+                tmp1 = s->fixed_coeffs[2][i];
+                s->fixed_coeffs[1][i] = tmp0 + tmp1;
+                s->fixed_coeffs[2][i] = tmp0 - tmp1;
             }
         }
     }
@@ -868,10 +859,10 @@ static int decode_audio_block(AC3DecodeC
                         cpl_coord_exp = get_bits(gbc, 4);
                         cpl_coord_mant = get_bits(gbc, 4);
                         if (cpl_coord_exp == 15)
-                            s->cpl_coords[ch][bnd] = cpl_coord_mant / 16.0f;
+                            s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;
                         else
-                            s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16.0f) / 32.0f;
-                        s->cpl_coords[ch][bnd] *= ff_ac3_scale_factors[cpl_coord_exp + master_cpl_coord];
+                            s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;
+                        s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
                     }
                 }
             } else {
@@ -1118,14 +1109,14 @@ static int decode_audio_block(AC3DecodeC
 
     /* apply scaling to coefficients (headroom, dynrng) */
     for(ch=1; ch<=s->channels; ch++) {
-        float gain = 2.0f * s->mul_bias;
+        float gain = s->mul_bias / 4194304.0f;
         if(s->channel_mode == AC3_CHMODE_DUALMONO) {
             gain *= s->dynamic_range[ch-1];
         } else {
             gain *= s->dynamic_range[0];
         }
-        for(i=0; i<s->end_freq[ch]; i++) {
-            s->transform_coeffs[ch][i] *= gain;
+        for(i=0; i<256; i++) {
+            s->transform_coeffs[ch][i] = s->fixed_coeffs[ch][i] * gain;
         }
     }
 

Modified: eac3/ac3dec.h
==============================================================================
--- eac3/ac3dec.h	(original)
+++ eac3/ac3dec.h	Mon May 26 19:20:45 2008
@@ -98,13 +98,13 @@ typedef struct AC3DecodeContext {
     int cpl_band_struct[18];                    ///< Coupling band structure (cplbndstrc)
     int firstchincpl;                           ///< First channel in coupling
     int first_cpl_coords[AC3_MAX_CHANNELS];     ///< First coupling coordinates states (firstcplcos)
-    float cpl_coords[AC3_MAX_CHANNELS][18];     ///< coupling coordinates (cplco)
+    int cpl_coords[AC3_MAX_CHANNELS][18];       ///< coupling coordinates (cplco)
 ///@}
 
 ///@defgroup aht Adaptive Hybrid Transform
     int channel_uses_aht[AC3_MAX_CHANNELS];     ///< Channel AHT in use (chahtinu)
     int gaq_gain[256];                              ///< Gain adaptive quantization gain
-    float pre_mantissa[6][AC3_MAX_CHANNELS][256];   ///< Pre-IDCT mantissas
+    int pre_mantissa[6][AC3_MAX_CHANNELS][256]; ///< Pre-IDCT mantissas
 ///@}
 
 #if TEST_SPX
@@ -211,6 +211,8 @@ typedef struct AC3DecodeContext {
     float mul_bias;     ///< scaling for float_to_int16 conversion
 ///@}
 
+    int fixed_coeffs[AC3_MAX_CHANNELS][256];    ///< fixed-point transform coefficients
+
 ///@defgroup arrays Aligned Arrays
     DECLARE_ALIGNED_16(float, transform_coeffs[AC3_MAX_CHANNELS][AC3_MAX_COEFS]);   ///< Frequency Coefficients
     DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]);             ///< delay - added to the next block

Modified: eac3/eac3dec.c
==============================================================================
--- eac3/eac3dec.c	(original)
+++ eac3/eac3dec.c	Mon May 26 19:20:45 2008
@@ -34,7 +34,7 @@ typedef enum {
 
 #define EAC3_SR_CODE_REDUCED  3
 
-static float idct_cos_tab[6][5];
+static int idct_cos_tab[6][5];
 
 static int gaq_ungroup_tab[32][3];
 
@@ -171,7 +171,7 @@ static void spectral_extension(AC3Decode
 void ff_eac3_get_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch){
     int bin, blk, gs;
     int hebap, end_bap, gaq_mode, bits, pre_mantissa, remap, log_gain;
-    float mant;
+    int mant;
     GetBitContext *gbc = &s->gbc;
 
     gaq_mode = get_bits(gbc, 2);
@@ -208,13 +208,13 @@ void ff_eac3_get_transform_coeffs_aht_ch
         if (!hebap) {
             /* hebap=0 */
             for (blk = 0; blk < 6; blk++) {
-                s->pre_mantissa[blk][ch][bin] = ((av_random(&s->dith_state) & 0xFFFF) / 65535.0f) - 0.5f;
+                s->pre_mantissa[blk][ch][bin] = (av_random(&s->dith_state) & 0x7FFFFF) - 4194304;
             }
         } else if (hebap < 8) {
             /* Vector Quantization */
             int v = get_bits(gbc, bits);
             for (blk = 0; blk < 6; blk++) {
-                s->pre_mantissa[blk][ch][bin] = ff_eac3_vq_hebap[hebap][v][blk] / 32768.0f;
+                s->pre_mantissa[blk][ch][bin] = ff_eac3_vq_hebap[hebap][v][blk] << 8;
             }
         } else {
             /* Gain Adaptive Quantization */
@@ -229,30 +229,28 @@ void ff_eac3_get_transform_coeffs_aht_ch
                 pre_mantissa = get_sbits(gbc, gbits);
                 if (log_gain == 0) {
                     // Gk = 1, GAQ mode = 0, or hebap is outside of GAQ range
-                    mant = pre_mantissa * ff_ac3_scale_factors[bits-1];
+                    mant = pre_mantissa << (24 - bits);
                     remap = 1;
                 } else if (pre_mantissa == -(1 << (gbits-1))) {
                     // large mantissa
                     if(log_gain == 1) {
                         // Gk = 2
-                        pre_mantissa = get_sbits(gbc, bits-1);
-                        mant = pre_mantissa * ff_ac3_scale_factors[bits-2];
+                        mant = get_sbits(gbc, bits-1) << (25 - bits);
                     } else {
                         // Gk = 4
-                        pre_mantissa = get_sbits(gbc, bits);
-                        mant = pre_mantissa * ff_ac3_scale_factors[bits-1];
+                        mant = get_sbits(gbc, bits) << (24 - bits);
                     }
                     remap = 1;
                 } else {
                     // small mantissa, Gk = 2 or 4
-                    mant = pre_mantissa * ff_ac3_scale_factors[bits-1];
+                    mant = pre_mantissa << (24 - bits);
                     remap = 0;
                 }
 
                 if (remap) {
-                    int a = ff_eac3_gaq_remap[hebap-8][0][log_gain][0] + 32768;
-                    int b = ff_eac3_gaq_remap[hebap-8][mant<0][log_gain][1];
-                    mant = (a * mant + b) / 32768;
+                    int64_t a = ff_eac3_gaq_remap[hebap-8][0][log_gain][0] + 32768;
+                    int64_t b = ff_eac3_gaq_remap[hebap-8][mant<0][log_gain][1];
+                    mant = (a * mant + b) >> 15;
                 }
                 s->pre_mantissa[blk][ch][bin] = mant;
             }
@@ -263,13 +261,13 @@ void ff_eac3_get_transform_coeffs_aht_ch
 void ff_eac3_idct_transform_coeffs_ch(AC3DecodeContext *s, int ch, int blk){
     // TODO fast IDCT
     int bin, i;
-    float tmp;
+    int64_t tmp;
     for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
         tmp = s->pre_mantissa[0][ch][bin];
         for (i = 1; i < 6; i++) {
-            tmp += idct_cos_tab[blk][i-1] * s->pre_mantissa[i][ch][bin];
+            tmp += ((int64_t)idct_cos_tab[blk][i-1] * (int64_t)s->pre_mantissa[i][ch][bin]) >> 23;
         }
-        s->transform_coeffs[ch][bin] = tmp * ff_ac3_scale_factors[s->dexps[ch][bin]];
+        s->fixed_coeffs[ch][bin] = tmp >> s->dexps[ch][bin];
     }
 }
 
@@ -1232,7 +1230,7 @@ void ff_eac3_tables_init(void) {
     // initialize IDCT cosine table for use with AHT
     for(blk=0; blk<6; blk++) {
         for(i=1; i<6; i++) {
-            idct_cos_tab[blk][i-1] = M_SQRT2 * cos(M_PI*i*(2*blk + 1)/12);
+            idct_cos_tab[blk][i-1] = (M_SQRT2 * cos(M_PI*i*(2*blk + 1)/12) * 8388608.0) + 0.5;
         }
     }
 



More information about the FFmpeg-soc mailing list