Also configure fixed-point encoding with --disable-ac3enc-float.
Make floating-point the default and use it in the regression test.
---
 configure                 |    5 +
 libavcodec/ac3enc.c       |  341 +-------------------------------------------
 libavcodec/ac3enc_fixed.c |  267 +++++++++++++++++++++++++++++++++++
 libavcodec/ac3enc_fixed.h |   57 ++++++++
 libavcodec/ac3enc_float.c |   61 ++++++++
 libavcodec/ac3enc_float.h |   50 +++++++
 tests/codec-regression.sh |    5 +-
 tests/ref/acodec/ac3      |    4 +-
 8 files changed, 453 insertions(+), 337 deletions(-)
 create mode 100644 libavcodec/ac3enc_fixed.c
 create mode 100644 libavcodec/ac3enc_fixed.h
 create mode 100644 libavcodec/ac3enc_float.c
 create mode 100644 libavcodec/ac3enc_float.h

diff --git configure configure
index 99920ab..b79c847 100755
--- configure
+++ configure
@@ -96,6 +96,7 @@ Configuration options:
   --enable-x11grab         enable X11 grabbing [no]
   --disable-network        disable network support [no]
   --disable-mpegaudio-hp   faster (but less accurate) MPEG audio decoding [no]
+  --disable-ac3enc-float   faster (but less accurate) AC-3 audio encoding [no]
   --enable-gray            enable full grayscale support (slower color)
   --disable-swscale-alpha  disable alpha channel support in swscale
   --disable-fastdiv        disable table-based division
@@ -907,6 +908,7 @@ CONFIG_LIST="
     memalign_hack
     mlib
     mpegaudio_hp
+    ac3enc_float
     network
     nonfree
     pic
@@ -1496,6 +1498,8 @@ test_deps _encoder _decoder                                             \
     wmv1                                                                \
     wmv2                                                                \
 
+ac3_test_deps="${ac3_test_deps} ac3enc_float rm_muxer rm_demuxer"
+
 test_deps _muxer _demuxer                                               \
     aiff                                                                \
     pcm_alaw=alaw                                                       \
@@ -1583,6 +1587,7 @@ enable ffplay
 enable ffprobe
 enable ffserver
 enable mpegaudio_hp
+enable ac3enc_float
 enable network
 enable optimizations
 enable protocols
diff --git libavcodec/ac3enc.c libavcodec/ac3enc.c
index 106cc05..919c51a 100644
--- libavcodec/ac3enc.c
+++ libavcodec/ac3enc.c
@@ -38,36 +38,12 @@
 #include "ac3.h"
 #include "audioconvert.h"
 
-//#define CONFIG_FLOAT 1
-
-#ifndef CONFIG_FLOAT
-#define CONFIG_FLOAT 0
-#endif
-
-#if CONFIG_FLOAT
-#include "fft.h"
-#endif
-
 #define SCALE_FLOAT(a, bits) (lrintf(a * (float)(1 << (bits))))
 
-#if CONFIG_FLOAT
-    typedef float SampleType;
-    typedef float CoefType;
-#   define FIX(a) (a)
-#   define MULFUNC(a, b) ((a) * (b))
-#   define FIX_SHIFT(a) (a)
-#   define RSHIFT1(a) ((a) * 0.5f)
-#   define SCALE_COEF(a) SCALE_FLOAT((a), 24)
-#   define INPUT_SAMPLE_FMT SAMPLE_FMT_FLT
+#if CONFIG_AC3ENC_FLOAT
+#include "ac3enc_float.h"
 #else
-    typedef int16_t SampleType;
-    typedef int32_t CoefType;
-#   define FIX(a) (av_clip_int16(SCALE_FLOAT(a, 15)))
-#   define MULFUNC MUL16
-#   define FIX_SHIFT(a) ((a) >> 15)
-#   define RSHIFT1(a) ((a) >> 1)
-#   define SCALE_COEF(a) (a)
-#   define INPUT_SAMPLE_FMT SAMPLE_FMT_S16
+#include "ac3enc_fixed.h"
 #endif
 
 typedef struct AC3EncOptions {
@@ -96,28 +72,6 @@ typedef struct AC3EncOptions {
     /* encoding options */
 } AC3EncOptions;
 
-#if !CONFIG_FLOAT
-typedef struct IComplex {
-    SampleType re,im;
-} IComplex;
-#endif
-
-typedef struct AC3MDCTContext {
-    const SampleType *window;               ///< MDCT window function
-    AVCodecContext *avctx;                  ///< parent context for av_log()
-    int nbits;                              ///< log2(transform size)
-#if CONFIG_FLOAT
-    FFTContext fft;                         ///< FFT Context for MDCT calculation
-#else
-    SampleType *costab;                     ///< FFT cos table
-    SampleType *sintab;                     ///< FFT sin table
-    SampleType *xcos1;                      ///< MDCT cos table
-    SampleType *xsin1;                      ///< MDCT sin table
-    SampleType *rot_tmp;                    ///< temp buffer for pre-rotated samples
-    IComplex *cplx_tmp;                     ///< temp buffer for complex pre-rotated samples
-#endif
-} AC3MDCTContext;
-
 typedef struct AC3Block {
     uint8_t **bap;                          ///< bap for each channel in this block
     CoefType **mdct_coef;                   ///< MDCT coefficients for each channel in this block
@@ -278,291 +232,12 @@ static const AVClass class = { "ac3", av_default_item_name, options, LIBAVUTIL_V
  */
 int exponent_group_tab[3][256];
 
-#if CONFIG_FLOAT
-static av_cold void mdct_end(AC3MDCTContext *mdct)
-{
-    mdct->nbits = 0;
-    ff_mdct_end(&mdct->fft);
-    av_freep(&mdct->window);
-}
+#if CONFIG_AC3ENC_FLOAT
+#include "ac3enc_float.c"
 #else
-static av_cold void mdct_end(AC3MDCTContext *mdct)
-{
-    mdct->nbits = 0;
-    av_freep(&mdct->costab);
-    av_freep(&mdct->sintab);
-    av_freep(&mdct->xcos1);
-    av_freep(&mdct->xsin1);
-    av_freep(&mdct->rot_tmp);
-    av_freep(&mdct->cplx_tmp);
-}
+#include "ac3enc_fixed.c"
 #endif
 
-#if !CONFIG_FLOAT
-static av_cold int fft_init(AC3MDCTContext *mdct, int ln)
-{
-    int i, n, n2;
-    float alpha;
-
-    n = 1 << ln;
-    n2 = n >> 1;
-
-    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->costab, n2 * sizeof(*mdct->costab),
-                     fft_alloc_fail);
-    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->sintab, n2 * sizeof(*mdct->sintab),
-                     fft_alloc_fail);
-
-    for (i = 0; i < n2; i++) {
-        alpha = 2 * M_PI * (float)i / (float)n;
-        mdct->costab[i] = FIX(cos(alpha));
-        mdct->sintab[i] = FIX(sin(alpha));
-    }
-
-    return 0;
-
-fft_alloc_fail:
-    mdct_end(mdct);
-    return AVERROR(ENOMEM);
-}
-#endif
-
-#if CONFIG_FLOAT
-static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
-{
-    SampleType *window;
-    int n = 1 << nbits;
-    int n2 = (1 << mdct->nbits) >> 1;
-
-    mdct->nbits = nbits;
-
-    window = av_malloc(n2 * sizeof(*window));
-    if (!window)
-        return AVERROR(ENOMEM);
-    ff_kbd_window_init(window, 5.0, n2);
-    mdct->window = window;
-
-    return ff_mdct_init(&mdct->fft, nbits, 0, -2.0 / n);
-}
-#else
-static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
-{
-    int ret;
-    int n = 1 << nbits;
-    int i, n2, n4;
-
-    mdct->nbits = nbits;
-
-    ret = fft_init(mdct, nbits - 2);
-    if (ret)
-        return ret;
-
-    mdct->window = ff_ac3_window;
-
-    n2 = n >> 1;
-    n4 = n >> 2;
-
-    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xcos1,    n4 * sizeof(*mdct->xcos1),
-                     mdct_alloc_fail);
-    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xsin1 ,   n4 * sizeof(*mdct->xsin1),
-                     mdct_alloc_fail);
-    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->rot_tmp,  n  * sizeof(*mdct->rot_tmp),
-                     mdct_alloc_fail);
-    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp),
-                     mdct_alloc_fail);
-
-    for (i = 0; i < n4; i++) {
-        float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;
-        mdct->xcos1[i] = FIX(-cos(alpha));
-        mdct->xsin1[i] = FIX(-sin(alpha));
-    }
-
-    return 0;
-
-mdct_alloc_fail:
-    mdct_end(mdct);
-    return AVERROR(ENOMEM);
-}
-#endif
-
-#if !CONFIG_FLOAT
-
-/* butter fly op */
-#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \
-{\
-  CoefType ax, ay, bx, by;\
-  bx  = pre1;\
-  by  = pim1;\
-  ax  = qre1;\
-  ay  = qim1;\
-  pre = RSHIFT1(bx + ax);\
-  pim = RSHIFT1(by + ay);\
-  qre = RSHIFT1(bx - ax);\
-  qim = RSHIFT1(by - ay);\
-}
-
-#define CMUL(pre, pim, are, aim, bre, bim) \
-{\
-   pre = FIX_SHIFT(MULFUNC(are, bre) - MULFUNC(aim, bim));\
-   pim = FIX_SHIFT(MULFUNC(are, bim) + MULFUNC(bre, aim));\
-}
-
-
-/* do a 2^n point complex fft on 2^ln points. */
-static void calc_fft(AC3MDCTContext *mdct, IComplex *z, int ln)
-{
-    int j, l, np, np2;
-    int nblocks, nloops;
-    register IComplex *p,*q;
-    CoefType tmp_re, tmp_im;
-
-    np = 1 << ln;
-
-    /* reverse */
-    for(j = 0; j < np; j++) {
-        int k = av_reverse[j] >> (8 - ln);
-        if (k < j)
-            FFSWAP(IComplex, z[k], z[j]);
-    }
-
-    /* pass 0 */
-
-    p = &z[0];
-    j = np >> 1;
-    do {
-        BF(p[0].re, p[0].im, p[1].re, p[1].im,
-           p[0].re, p[0].im, p[1].re, p[1].im);
-        p += 2;
-    } while (--j);
-
-    /* pass 1 */
-
-    p = &z[0];
-    j = np >> 2;
-    do {
-        BF(p[0].re, p[0].im, p[2].re, p[2].im,
-           p[0].re, p[0].im, p[2].re, p[2].im);
-        BF(p[1].re, p[1].im, p[3].re, p[3].im,
-           p[1].re, p[1].im, p[3].im, -p[3].re);
-        p += 4;
-    } while (--j);
-
-    /* pass 2 .. ln-1 */
-
-    nblocks = np >> 3;
-    nloops  = 1  << 2;
-    np2     = np >> 1;
-    do {
-        p = z;
-        q = z + nloops;
-        for (j = 0; j < nblocks; j++) {
-            BF(p->re, p->im, q->re, q->im,
-               p->re, p->im, q->re, q->im);
-
-            p++;
-            q++;
-            for (l = nblocks; l < np2; l += nblocks) {
-                CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
-                BF(p->re, p->im, q->re, q->im,
-                   p->re, p->im, tmp_re, tmp_im);
-                p++;
-                q++;
-            }
-            p += nloops;
-            q += nloops;
-        }
-        nblocks = nblocks >> 1;
-        nloops  = nloops  << 1;
-    } while (nblocks != 0);
-}
-
-/* do a 512 point mdct */
-static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
-{
-    int i;
-    CoefType re, im;
-    int n, n2, n4;
-    SampleType *rot = mdct->rot_tmp;
-    IComplex *x  = mdct->cplx_tmp;
-
-    n  = 1 << mdct->nbits;
-    n2 = n >> 1;
-    n4 = n >> 2;
-
-    /* shift to simplify computations */
-    for (i = 0; i < n4; i++)
-        rot[i] = -in[i+3*n4];
-    memcpy(rot+n4, in, 3*n4 * sizeof(*in));
-
-    /* pre rotation */
-    for (i = 0; i < n4; i++) {
-        re = RSHIFT1( ((CoefType)rot[   2*i] - (CoefType)rot[ n-1-2*i]));
-        im = RSHIFT1(-((CoefType)rot[n2+2*i] - (CoefType)rot[n2-1-2*i]));
-        CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
-    }
-
-    calc_fft(mdct, x, mdct->nbits - 2);
-
-    /* post rotation */
-    for (i = 0; i < n4; i++) {
-        re = x[i].re;
-        im = x[i].im;
-        CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]);
-    }
-}
-#else /* CONFIG_FLOAT */
-static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
-{
-    ff_mdct_calc(&mdct->fft, out, in);
-}
-#endif /* !CONFIG_FLOAT */
-
-#if !CONFIG_FLOAT
-/* compute log2(max(abs(tab[]))) */
-static int log2_tab(int16_t *tab, int n)
-{
-    int i, v;
-
-    v = 0;
-    for (i = 0; i < n; i++)
-        v |= abs(tab[i]);
-    return av_log2(v);
-}
-
-static void lshift_tab(int16_t *tab, int n, int lshift)
-{
-    int i;
-
-    if (lshift > 0) {
-        for (i = 0; i < n; i++)
-            tab[i] <<= lshift;
-    } else if (lshift < 0) {
-        lshift = -lshift;
-        for (i = 0; i < n; i++)
-            tab[i] >>= lshift;
-    }
-}
-
-/**
- * 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.
- *
- * @return exponent shift
- */
-static int normalize_samples(AC3EncodeContext *s)
-{
-    int v = 14 - log2_tab(s->windowed_samples, AC3_WINDOW_SIZE);
-    v = FFMAX(0, v);
-    lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
-    return v - 9;
-}
-#else /* CONFIG_FLOAT */
-static int normalize_samples(AC3EncodeContext *s)
-{
-    return 0;
-}
-#endif /* !CONFIG_FLOAT */
-
 static void apply_window(SampleType *output, const SampleType *input,
                          const SampleType *window, int n)
 {
@@ -1935,7 +1610,7 @@ static int AC3_encode_frame(AVCodecContext *avctx,
     return s->frame_size;
 }
 
-#if !CONFIG_FLOAT
+#if !CONFIG_AC3ENC_FLOAT
 #ifdef TEST
 /*************************************************************************/
 /* TEST */
@@ -2058,7 +1733,7 @@ int main(void)
     return 0;
 }
 #endif /* TEST */
-#endif /* !CONFIG_FLOAT */
+#endif /* !CONFIG_AC3ENC_FLOAT */
 
 AVCodec ac3_encoder = {
     "ac3",
diff --git libavcodec/ac3enc_fixed.c libavcodec/ac3enc_fixed.c
new file mode 100644
index 0000000..6d0cd1b
--- /dev/null
+++ libavcodec/ac3enc_fixed.c
@@ -0,0 +1,267 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder fixed-point functions.
+ */
+
+static av_cold void mdct_end(AC3MDCTContext *mdct)
+{
+    mdct->nbits = 0;
+    av_freep(&mdct->costab);
+    av_freep(&mdct->sintab);
+    av_freep(&mdct->xcos1);
+    av_freep(&mdct->xsin1);
+    av_freep(&mdct->rot_tmp);
+    av_freep(&mdct->cplx_tmp);
+}
+
+static av_cold int fft_init(AC3MDCTContext *mdct, int ln)
+{
+    int i, n, n2;
+    float alpha;
+
+    n = 1 << ln;
+    n2 = n >> 1;
+
+    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->costab, n2 * sizeof(*mdct->costab),
+                     fft_alloc_fail);
+    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->sintab, n2 * sizeof(*mdct->sintab),
+                     fft_alloc_fail);
+
+    for (i = 0; i < n2; i++) {
+        alpha = 2 * M_PI * (float)i / (float)n;
+        mdct->costab[i] = FIX(cos(alpha));
+        mdct->sintab[i] = FIX(sin(alpha));
+    }
+
+    return 0;
+
+fft_alloc_fail:
+    mdct_end(mdct);
+    return AVERROR(ENOMEM);
+}
+
+static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
+{
+    int ret;
+    int n = 1 << nbits;
+    int i, n2, n4;
+
+    mdct->nbits = nbits;
+
+    ret = fft_init(mdct, nbits - 2);
+    if (ret)
+        return ret;
+
+    mdct->window = ff_ac3_window;
+
+    n2 = n >> 1;
+    n4 = n >> 2;
+
+    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xcos1,    n4 * sizeof(*mdct->xcos1),
+                     mdct_alloc_fail);
+    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xsin1 ,   n4 * sizeof(*mdct->xsin1),
+                     mdct_alloc_fail);
+    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->rot_tmp,  n  * sizeof(*mdct->rot_tmp),
+                     mdct_alloc_fail);
+    FF_ALLOC_OR_GOTO(mdct->avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp),
+                     mdct_alloc_fail);
+
+    for (i = 0; i < n4; i++) {
+        float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;
+        mdct->xcos1[i] = FIX(-cos(alpha));
+        mdct->xsin1[i] = FIX(-sin(alpha));
+    }
+
+    return 0;
+
+mdct_alloc_fail:
+    mdct_end(mdct);
+    return AVERROR(ENOMEM);
+}
+
+/* butter fly op */
+#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \
+{\
+  CoefType ax, ay, bx, by;\
+  bx  = pre1;\
+  by  = pim1;\
+  ax  = qre1;\
+  ay  = qim1;\
+  pre = RSHIFT1(bx + ax);\
+  pim = RSHIFT1(by + ay);\
+  qre = RSHIFT1(bx - ax);\
+  qim = RSHIFT1(by - ay);\
+}
+
+#define CMUL(pre, pim, are, aim, bre, bim) \
+{\
+   pre = FIX_SHIFT(MULFUNC(are, bre) - MULFUNC(aim, bim));\
+   pim = FIX_SHIFT(MULFUNC(are, bim) + MULFUNC(bre, aim));\
+}
+
+
+/* do a 2^n point complex fft on 2^ln points. */
+static void calc_fft(AC3MDCTContext *mdct, IComplex *z, int ln)
+{
+    int j, l, np, np2;
+    int nblocks, nloops;
+    register IComplex *p,*q;
+    CoefType tmp_re, tmp_im;
+
+    np = 1 << ln;
+
+    /* reverse */
+    for(j = 0; j < np; j++) {
+        int k = av_reverse[j] >> (8 - ln);
+        if (k < j)
+            FFSWAP(IComplex, z[k], z[j]);
+    }
+
+    /* pass 0 */
+
+    p = &z[0];
+    j = np >> 1;
+    do {
+        BF(p[0].re, p[0].im, p[1].re, p[1].im,
+           p[0].re, p[0].im, p[1].re, p[1].im);
+        p += 2;
+    } while (--j);
+
+    /* pass 1 */
+
+    p = &z[0];
+    j = np >> 2;
+    do {
+        BF(p[0].re, p[0].im, p[2].re, p[2].im,
+           p[0].re, p[0].im, p[2].re, p[2].im);
+        BF(p[1].re, p[1].im, p[3].re, p[3].im,
+           p[1].re, p[1].im, p[3].im, -p[3].re);
+        p += 4;
+    } while (--j);
+
+    /* pass 2 .. ln-1 */
+
+    nblocks = np >> 3;
+    nloops  = 1  << 2;
+    np2     = np >> 1;
+    do {
+        p = z;
+        q = z + nloops;
+        for (j = 0; j < nblocks; j++) {
+            BF(p->re, p->im, q->re, q->im,
+               p->re, p->im, q->re, q->im);
+
+            p++;
+            q++;
+            for (l = nblocks; l < np2; l += nblocks) {
+                CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
+                BF(p->re, p->im, q->re, q->im,
+                   p->re, p->im, tmp_re, tmp_im);
+                p++;
+                q++;
+            }
+            p += nloops;
+            q += nloops;
+        }
+        nblocks = nblocks >> 1;
+        nloops  = nloops  << 1;
+    } while (nblocks != 0);
+}
+
+/* do a 512 point mdct */
+static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
+{
+    int i;
+    CoefType re, im;
+    int n, n2, n4;
+    SampleType *rot = mdct->rot_tmp;
+    IComplex *x  = mdct->cplx_tmp;
+
+    n  = 1 << mdct->nbits;
+    n2 = n >> 1;
+    n4 = n >> 2;
+
+    /* shift to simplify computations */
+    for (i = 0; i < n4; i++)
+        rot[i] = -in[i+3*n4];
+    memcpy(rot+n4, in, 3*n4 * sizeof(*in));
+
+    /* pre rotation */
+    for (i = 0; i < n4; i++) {
+        re = RSHIFT1( ((CoefType)rot[   2*i] - (CoefType)rot[ n-1-2*i]));
+        im = RSHIFT1(-((CoefType)rot[n2+2*i] - (CoefType)rot[n2-1-2*i]));
+        CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
+    }
+
+    calc_fft(mdct, x, mdct->nbits - 2);
+
+    /* post rotation */
+    for (i = 0; i < n4; i++) {
+        re = x[i].re;
+        im = x[i].im;
+        CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]);
+    }
+}
+
+/* compute log2(max(abs(tab[]))) */
+static int log2_tab(int16_t *tab, int n)
+{
+    int i, v;
+
+    v = 0;
+    for (i = 0; i < n; i++)
+        v |= abs(tab[i]);
+    return av_log2(v);
+}
+
+static void lshift_tab(int16_t *tab, int n, int lshift)
+{
+    int i;
+
+    if (lshift > 0) {
+        for (i = 0; i < n; i++)
+            tab[i] <<= lshift;
+    } else if (lshift < 0) {
+        lshift = -lshift;
+        for (i = 0; i < n; i++)
+            tab[i] >>= lshift;
+    }
+}
+
+/**
+ * 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.
+ *
+ * @return exponent shift
+ */
+static int normalize_samples(AC3EncodeContext *s)
+{
+    int v = 14 - log2_tab(s->windowed_samples, AC3_WINDOW_SIZE);
+    v = FFMAX(0, v);
+    lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
+    return v - 9;
+}
diff --git libavcodec/ac3enc_fixed.h libavcodec/ac3enc_fixed.h
new file mode 100644
index 0000000..0d1fc26
--- /dev/null
+++ libavcodec/ac3enc_fixed.h
@@ -0,0 +1,57 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder fixed-point header.
+ */
+
+#ifndef AVCODEC_AC3ENC_FIXED_H
+#define AVCODEC_AC3ENC_FIXED_H
+
+typedef int16_t SampleType;
+typedef int32_t CoefType;
+#define FIX(a) (av_clip_int16(SCALE_FLOAT(a, 15)))
+#define MULFUNC MUL16
+#define FIX_SHIFT(a) ((a) >> 15)
+#define RSHIFT1(a) ((a) >> 1)
+#define SCALE_COEF(a) (a)
+#define INPUT_SAMPLE_FMT SAMPLE_FMT_S16
+
+typedef struct IComplex {
+    SampleType re,im;
+} IComplex;
+
+typedef struct AC3MDCTContext {
+    const SampleType *window;               ///< MDCT window function
+    AVCodecContext *avctx;                  ///< parent context for av_log()
+    int nbits;                              ///< log2(transform size)
+    SampleType *costab;                     ///< FFT cos table
+    SampleType *sintab;                     ///< FFT sin table
+    SampleType *xcos1;                      ///< MDCT cos table
+    SampleType *xsin1;                      ///< MDCT sin table
+    SampleType *rot_tmp;                    ///< temp buffer for pre-rotated samples
+    IComplex *cplx_tmp;                     ///< temp buffer for complex pre-rotated samples
+} AC3MDCTContext;
+
+#endif /* AVCODEC_AC3ENC_FIXED_H */
diff --git libavcodec/ac3enc_float.c libavcodec/ac3enc_float.c
new file mode 100644
index 0000000..e08310e
--- /dev/null
+++ libavcodec/ac3enc_float.c
@@ -0,0 +1,61 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder floating-point functions.
+ */
+
+static av_cold void mdct_end(AC3MDCTContext *mdct)
+{
+    mdct->nbits = 0;
+    ff_mdct_end(&mdct->fft);
+    av_freep(&mdct->window);
+}
+
+static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
+{
+    SampleType *window;
+    int n  = 1 << nbits;
+    int n2 = n >> 1;
+
+    mdct->nbits = nbits;
+
+    window = av_malloc(n2 * sizeof(*window));
+    if (!window)
+        return AVERROR(ENOMEM);
+    ff_kbd_window_init(window, 5.0, n2);
+    mdct->window = window;
+
+    return ff_mdct_init(&mdct->fft, nbits, 0, -2.0 / n);
+}
+
+static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
+{
+    ff_mdct_calc(&mdct->fft, out, in);
+}
+
+static int normalize_samples(AC3EncodeContext *s)
+{
+    return 0;
+}
diff --git libavcodec/ac3enc_float.h libavcodec/ac3enc_float.h
new file mode 100644
index 0000000..c42044f
--- /dev/null
+++ libavcodec/ac3enc_float.h
@@ -0,0 +1,50 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder floating-point header.
+ */
+
+#ifndef AVCODEC_AC3ENC_FLOAT_H
+#define AVCODEC_AC3ENC_FLOAT_H
+
+#include "fft.h"
+
+typedef float SampleType;
+typedef float CoefType;
+#define FIX(a) (a)
+#define MULFUNC(a, b) ((a) * (b))
+#define FIX_SHIFT(a) (a)
+#define RSHIFT1(a) ((a) * 0.5f)
+#define SCALE_COEF(a) SCALE_FLOAT((a), 24)
+#define INPUT_SAMPLE_FMT SAMPLE_FMT_FLT
+
+typedef struct AC3MDCTContext {
+    const SampleType *window;   ///< MDCT window function
+    AVCodecContext *avctx;      ///< parent context for av_log()
+    int nbits;                  ///< log2(transform size)
+    FFTContext fft;             ///< FFT Context for MDCT calculation
+} AC3MDCTContext;
+
+#endif /* AVCODEC_AC3ENC_FLOAT_H */
diff --git tests/codec-regression.sh tests/codec-regression.sh
index 2a2ca1c..0fe1df4 100755
--- tests/codec-regression.sh
+++ tests/codec-regression.sh
@@ -271,9 +271,8 @@ fi
 
 if [ -n "$do_ac3" ] ; then
 do_audio_encoding ac3.rm "" -vn
-# binaries configured with --disable-sse decode ac3 differently
-#do_audio_decoding
-#$tiny_psnr $pcm_dst $pcm_ref 2 1024 >> $logfile
+do_ffmpeg_nomd5 $pcm_dst -i $target_path/$file -f wav
+$tiny_psnr $pcm_dst $pcm_ref 2 1024 >> $logfile
 fi
 
 if [ -n "$do_g726" ] ; then
diff --git tests/ref/acodec/ac3 tests/ref/acodec/ac3
index 32f47e0..0b750ca 100644
--- tests/ref/acodec/ac3
+++ tests/ref/acodec/ac3
@@ -1,2 +1,4 @@
-464093173530736050e338caf152044c *./tests/data/acodec/ac3.rm
+7a367bc8be390924baf879fe5d9eac23 *./tests/data/acodec/ac3.rm
 98751 ./tests/data/acodec/ac3.rm
+stddev:10491.51 PSNR: 15.91 MAXDIFF:65534 bytes:  1062912/  1058400
+stddev: 4626.53 PSNR: 23.02 MAXDIFF:62579 bytes:  1061888/  1058400
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to