ac3enc: shift coefficients to 24-bit following MDCT rather than using an exponent...
authorJustin Ruggles <justin.ruggles@gmail.com>
Tue, 8 Mar 2011 18:18:56 +0000 (13:18 -0500)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 8 Mar 2011 18:44:36 +0000 (19:44 +0100)
This makes channel coupling more accurate, increasing quality for stereo
content.  It also simplifies exponent extraction and mantissa quantization
by no longer needing to apply an offset to the exponents.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/ac3enc.c
libavcodec/ac3enc_fixed.c
tests/ref/acodec/ac3_fixed

index e792eaf..4fc8106 100644 (file)
@@ -78,7 +78,7 @@ typedef struct AC3Block {
     int16_t  **band_psd;                        ///< psd per critical band
     int16_t  **mask;                            ///< masking curve
     uint16_t **qmant;                           ///< quantized mantissas
-    int8_t   exp_shift[AC3_MAX_CHANNELS];       ///< exponent shift values
+    int8_t   coeff_shift[AC3_MAX_CHANNELS];     ///< fixed-point coefficient shift values
     uint8_t  new_rematrixing_strategy;          ///< send new rematrixing flags in this block
     uint8_t  rematrixing_flags[4];              ///< rematrixing flags
 } AC3Block;
@@ -269,7 +269,7 @@ static void apply_mdct(AC3EncodeContext *s)
 
             apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE);
 
-            block->exp_shift[ch] = normalize_samples(s);
+            block->coeff_shift[ch] = normalize_samples(s);
 
             mdct512(&s->mdct, block->mdct_coef[ch], s->windowed_samples);
         }
@@ -416,14 +416,13 @@ static void extract_exponents(AC3EncodeContext *s)
             AC3Block *block = &s->blocks[blk];
             uint8_t *exp   = block->exp[ch];
             int32_t *coef = block->fixed_coef[ch];
-            int exp_shift  = block->exp_shift[ch];
             for (i = 0; i < AC3_MAX_COEFS; i++) {
                 int e;
                 int v = abs(coef[i]);
                 if (v == 0)
                     e = 24;
                 else {
-                    e = 23 - av_log2(v) + exp_shift;
+                    e = 23 - av_log2(v);
                     if (e >= 24) {
                         e = 24;
                         coef[i] = 0;
@@ -1139,7 +1138,7 @@ static inline int asym_quant(int c, int e, int qbits)
  * Quantize a set of mantissas for a single channel in a single block.
  */
 static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
-                                      int8_t exp_shift, uint8_t *exp,
+                                      uint8_t *exp,
                                       uint8_t *bap, uint16_t *qmant, int n)
 {
     int i;
@@ -1147,7 +1146,7 @@ static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
     for (i = 0; i < n; i++) {
         int v;
         int c = fixed_coef[i];
-        int e = exp[i] - exp_shift;
+        int e = exp[i];
         int b = bap[i];
         switch (b) {
         case 0:
@@ -1243,7 +1242,7 @@ static void quantize_mantissas(AC3EncodeContext *s)
         s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
 
         for (ch = 0; ch < s->channels; ch++) {
-            quantize_mantissas_blk_ch(s, block->fixed_coef[ch], block->exp_shift[ch],
+            quantize_mantissas_blk_ch(s, block->fixed_coef[ch],
                                       block->exp[ch], block->bap[ch],
                                       block->qmant[ch], s->nb_coefs[ch]);
         }
index 3de00ee..e5853a3 100644 (file)
@@ -295,28 +295,54 @@ static void lshift_tab(int16_t *tab, int n, unsigned int lshift)
 
 
 /**
+ * Shift each value in an array by a specified amount.
+ * @param src    input array
+ * @param n      number of values in the array
+ * @param shift  shift amount (negative=right, positive=left)
+ */
+static void shift_int32(int32_t *src, int n, int shift)
+{
+    int i;
+
+    if (shift > 0) {
+        for (i = 0; i < n; i++)
+            src[i] <<= shift;
+    } else if (shift < 0) {
+        shift = -shift;
+        for (i = 0; i < n; i++)
+            src[i] >>= shift;
+    }
+}
+
+
+/**
  * Normalize the input samples to use the maximum available precision.
- * This assumes signed 16-bit input samples. Exponents are reduced by 9 to
- * match the 24-bit internal precision for MDCT coefficients.
+ * This assumes signed 16-bit input samples.
  *
- * @return exponent shift
+ * @return coefficient shift
  */
 static int normalize_samples(AC3EncodeContext *s)
 {
     int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE);
     lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
-    return v - 9;
+    return 9 - v;
 }
 
 
 /**
- * Scale MDCT coefficients from float to fixed-point.
+ * Scale MDCT coefficients to 24-bit fixed-point.
  */
 static void scale_coefficients(AC3EncodeContext *s)
 {
-    /* scaling/conversion is obviously not needed for the fixed-point encoder
-       since the coefficients are already fixed-point. */
-    return;
+    int blk, ch;
+
+    for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+        AC3Block *block = &s->blocks[blk];
+        for (ch = 0; ch < s->channels; ch++) {
+            shift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
+                        block->coeff_shift[ch]);
+        }
+    }
 }
 
 
index f32443d..89e0be5 100644 (file)
@@ -1,2 +1,2 @@
-07bd593823ebd721b3a32ef298bdfc20 *./tests/data/acodec/ac3.rm
+5f1255da35a4ed00a2e932887c9aef77 *./tests/data/acodec/ac3.rm
 98751 ./tests/data/acodec/ac3.rm