diff --git a/doc/encoders.texi b/doc/encoders.texi
index 0b1c69e982..60e763a704 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -151,10 +151,9 @@ the undocumented RealAudio 3 (a.k.a. dnet).
 The @var{ac3} encoder uses floating-point math, while the @var{ac3_fixed}
 encoder only uses fixed-point integer math. This does not mean that one is
 always faster, just that one or the other may be better suited to a
-particular system. The floating-point encoder will generally produce better
-quality audio for a given bitrate. The @var{ac3_fixed} encoder is not the
-default codec for any of the output formats, so it must be specified explicitly
-using the option @code{-acodec ac3_fixed} in order to use it.
+particular system. The @var{ac3_fixed} encoder is not the default codec for
+any of the output formats, so it must be specified explicitly using the option
+@code{-acodec ac3_fixed} in order to use it.
 
 @subsection AC-3 Metadata
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 35318f4f4d..0546e6f6c5 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -181,7 +181,7 @@ OBJS-$(CONFIG_AC3_DECODER)             += ac3dec_float.o ac3dec_data.o ac3.o kbd
 OBJS-$(CONFIG_AC3_FIXED_DECODER)       += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o
 OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_float.o ac3enc.o ac3tab.o \
                                           ac3.o kbdwin.o
-OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
+OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o
 OBJS-$(CONFIG_AC3_MF_ENCODER)          += mfenc.o mf_utils.o
 OBJS-$(CONFIG_ACELP_KELVIN_DECODER)    += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
 OBJS-$(CONFIG_AGM_DECODER)             += agm.o
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 044564ecb4..ba62891371 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -30,8 +30,6 @@
 
 #include <stdint.h>
 
-#include "libavutil/float_dsp.h"
-
 #include "ac3.h"
 #include "ac3dsp.h"
 #include "avcodec.h"
@@ -53,6 +51,7 @@
 #define AC3ENC_TYPE_EAC3        2
 
 #if AC3ENC_FLOAT
+#include "libavutil/float_dsp.h"
 #define AC3_NAME(x) ff_ac3_float_ ## x
 #define MAC_COEF(d,a,b) ((d)+=(a)*(b))
 #define COEF_MIN (-16777215.0/16777216.0)
@@ -62,12 +61,13 @@ typedef float SampleType;
 typedef float CoefType;
 typedef float CoefSumType;
 #else
+#include "libavutil/fixed_dsp.h"
 #define AC3_NAME(x) ff_ac3_fixed_ ## x
 #define MAC_COEF(d,a,b) MAC64(d,a,b)
 #define COEF_MIN -16777215
 #define COEF_MAX  16777215
 #define NEW_CPL_COORD_THRESHOLD 503317
-typedef int16_t SampleType;
+typedef int32_t SampleType;
 typedef int32_t CoefType;
 typedef int64_t CoefSumType;
 #endif
@@ -141,7 +141,6 @@ typedef struct AC3Block {
     uint16_t **qmant;                           ///< quantized mantissas
     uint8_t  **cpl_coord_exp;                   ///< coupling coord exponents           (cplcoexp)
     uint8_t  **cpl_coord_mant;                  ///< coupling coord mantissas           (cplcomant)
-    uint8_t  coeff_shift[AC3_MAX_CHANNELS];     ///< fixed-point coefficient shift values
     uint8_t  new_rematrixing_strategy;          ///< send new rematrixing flags in this block
     int      num_rematrixing_bands;             ///< number of rematrixing bands
     uint8_t  rematrixing_flags[4];              ///< rematrixing flags
@@ -165,7 +164,11 @@ typedef struct AC3EncodeContext {
     AVCodecContext *avctx;                  ///< parent AVCodecContext
     PutBitContext pb;                       ///< bitstream writer context
     AudioDSPContext adsp;
+#if AC3ENC_FLOAT
     AVFloatDSPContext *fdsp;
+#else
+    AVFixedDSPContext *fdsp;
+#endif
     MECmpContext mecc;
     AC3DSPContext ac3dsp;                   ///< AC-3 optimized functions
     FFTContext mdct;                        ///< FFT context for MDCT calculation
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 7818dd8c35..7aaa55f2e7 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -26,12 +26,14 @@
  * fixed-point AC-3 encoder.
  */
 
-#define FFT_FLOAT 0
 #define AC3ENC_FLOAT 0
+#define FFT_FLOAT 0
+#define FFT_FIXED_32 1
 #include "internal.h"
 #include "audiodsp.h"
 #include "ac3enc.h"
 #include "eac3enc.h"
+#include "kbdwin.h"
 
 #define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED
 #include "ac3enc_opts_template.c"
@@ -43,37 +45,6 @@ static const AVClass ac3enc_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-/*
- * Normalize the input samples to use the maximum available precision.
- * This assumes signed 16-bit input samples.
- */
-static int normalize_samples(AC3EncodeContext *s)
-{
-    int v = s->ac3dsp.ac3_max_msb_abs_int16(s->windowed_samples, AC3_WINDOW_SIZE);
-    v = 14 - av_log2(v);
-    if (v > 0)
-        s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v);
-    /* +6 to right-shift from 31-bit to 25-bit */
-    return v + 6;
-}
-
-
-/*
- * Scale MDCT coefficients to 25-bit signed fixed-point.
- */
-static void scale_coefficients(AC3EncodeContext *s)
-{
-    int blk, ch;
-
-    for (blk = 0; blk < s->num_blocks; blk++) {
-        AC3Block *block = &s->blocks[blk];
-        for (ch = 1; ch <= s->channels; ch++) {
-            s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
-                                       block->coeff_shift[ch]);
-        }
-    }
-}
-
 static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4],
                                  const int32_t *coef0, const int32_t *coef1,
                                  int len)
@@ -118,9 +89,10 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
 static av_cold void ac3_fixed_mdct_end(AC3EncodeContext *s)
 {
     ff_mdct_end(&s->mdct);
+    av_freep(&s->fdsp);
+    av_freep(&s->mdct_window);
 }
 
-
 /**
  * Initialize MDCT tables.
  *
@@ -130,7 +102,28 @@ static av_cold void ac3_fixed_mdct_end(AC3EncodeContext *s)
 static av_cold int ac3_fixed_mdct_init(AC3EncodeContext *s)
 {
     int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0);
-    s->mdct_window = ff_ac3_window;
+    if (ret < 0)
+        return ret;
+
+    int32_t *iwin = av_malloc_array(AC3_WINDOW_SIZE, sizeof(*iwin));
+    if (!iwin)
+        return AVERROR(ENOMEM);
+
+    float fwin[AC3_WINDOW_SIZE/2];
+    ff_kbd_window_init(fwin, 5.0, AC3_WINDOW_SIZE/2);
+
+    for (int i = 0; i < AC3_WINDOW_SIZE/2; i++)
+        iwin[i] = lrintf(fwin[i] * (1 << 22));
+
+    for (int i = 0; i < AC3_WINDOW_SIZE/2; i++)
+        iwin[AC3_WINDOW_SIZE-1-i] = iwin[i];
+
+    s->mdct_window = iwin;
+
+    s->fdsp = avpriv_alloc_fixed_dsp(s->avctx->flags & AV_CODEC_FLAG_BITEXACT);
+    if (!s->fdsp)
+        return AVERROR(ENOMEM);
+
     return ret;
 }
 
@@ -155,7 +148,7 @@ AVCodec ff_ac3_fixed_encoder = {
     .init            = ac3_fixed_encode_init,
     .encode2         = ff_ac3_fixed_encode_frame,
     .close           = ff_ac3_encode_close,
-    .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
+    .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class      = &ac3enc_class,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 0fdc95b968..de6eba71d8 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -91,18 +91,11 @@ static void apply_mdct(AC3EncodeContext *s)
             AC3Block *block = &s->blocks[blk];
             const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
 
-#if AC3ENC_FLOAT
             s->fdsp->vector_fmul(s->windowed_samples, input_samples,
-                                s->mdct_window, AC3_WINDOW_SIZE);
-#else
-            s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples,
-                                         s->mdct_window, AC3_WINDOW_SIZE);
-
-            block->coeff_shift[ch + 1] = normalize_samples(s);
-#endif
+                                 s->mdct_window, AC3_WINDOW_SIZE);
 
-            s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1],
-                               s->windowed_samples);
+            s->mdct.mdct_calc(&s->mdct, block->mdct_coef[ch+1],
+                              s->windowed_samples);
         }
     }
 }
@@ -390,9 +383,6 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt,
 
     apply_mdct(s);
 
-    if (!AC3ENC_FLOAT)
-        scale_coefficients(s);
-
     clip_coefficients(&s->adsp, s->blocks[0].mdct_coef[1],
                       AC3_MAX_COEFS * s->num_blocks * s->channels);
 
@@ -404,8 +394,9 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt,
 
     compute_rematrixing_strategy(s);
 
-    if (AC3ENC_FLOAT)
-        scale_coefficients(s);
+#if AC3ENC_FLOAT
+    scale_coefficients(s);
+#endif
 
     return ff_ac3_encode_frame_common_end(avctx, avpkt, frame, got_packet_ptr);
 }
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 5b92afe60a..1420439044 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR 115
-#define LIBAVCODEC_VERSION_MICRO 102
+#define LIBAVCODEC_VERSION_MINOR 116
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index 757cd51cf2..d76e22bade 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -90,7 +90,7 @@ fate-ac3-fixed-encode: tests/data/asynth-44100-2.wav
 fate-ac3-fixed-encode: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
 fate-ac3-fixed-encode: CMD = md5 -i $(SRC) -c ac3_fixed -ab 128k -f ac3 -flags +bitexact -af aresample
 fate-ac3-fixed-encode: CMP = oneline
-fate-ac3-fixed-encode: REF = a1d1fc116463b771abf5aef7ed37d7b1
+fate-ac3-fixed-encode: REF = 1f548175e11a95e62ce20e442fcc8d08
 
 FATE_EAC3-$(call ALLYES, EAC3_DEMUXER EAC3_MUXER EAC3_CORE_BSF) += fate-eac3-core-bsf
 fate-eac3-core-bsf: CMD = md5pipe -i $(TARGET_SAMPLES)/eac3/the_great_wall_7.1.eac3 -c:a copy -bsf:a eac3_core -fflags +bitexact -f eac3
