Browse code

Move fixed-point parts of the AC-3 encoder to separate files.

Originally committed as revision 26206 to svn://svn.ffmpeg.org/ffmpeg/trunk

Justin Ruggles authored on 2011/01/04 01:08:56
Showing 4 changed files
... ...
@@ -54,7 +54,7 @@ OBJS-$(CONFIG_AAC_ENCODER)             += aacenc.o aaccoder.o    \
54 54
                                           mpeg4audio.o
55 55
 OBJS-$(CONFIG_AASC_DECODER)            += aasc.o msrledec.o
56 56
 OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3dec_data.o ac3.o
57
-OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc.o ac3tab.o ac3.o
57
+OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_fixed.o ac3tab.o ac3.o
58 58
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o
59 59
 OBJS-$(CONFIG_ALAC_ENCODER)            += alacenc.o
60 60
 OBJS-$(CONFIG_ALS_DECODER)             += alsdec.o bgmc.o mpeg4audio.o
... ...
@@ -43,35 +43,11 @@
43 43
 /** Scale a float value by 2^bits and convert to an integer. */
44 44
 #define SCALE_FLOAT(a, bits) lrintf((a) * (float)(1 << (bits)))
45 45
 
46
-typedef int16_t SampleType;
47
-typedef int32_t CoefType;
48 46
 
49
-#define SCALE_COEF(a) (a)
50
-
51
-/** Scale a float value by 2^15, convert to an integer, and clip to range -32767..32767. */
52
-#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767)
47
+#include "ac3enc_fixed.h"
53 48
 
54 49
 
55 50
 /**
56
- * Compex number.
57
- * Used in fixed-point MDCT calculation.
58
- */
59
-typedef struct IComplex {
60
-    int16_t re,im;
61
-} IComplex;
62
-
63
-typedef struct AC3MDCTContext {
64
-    const int16_t *window;                  ///< MDCT window function
65
-    int nbits;                              ///< log2(transform size)
66
-    int16_t *costab;                        ///< FFT cos table
67
-    int16_t *sintab;                        ///< FFT sin table
68
-    int16_t *xcos1;                         ///< MDCT cos table
69
-    int16_t *xsin1;                         ///< MDCT sin table
70
-    int16_t *rot_tmp;                       ///< temp buffer for pre-rotated samples
71
-    IComplex *cplx_tmp;                     ///< temp buffer for complex pre-rotated samples
72
-} AC3MDCTContext;
73
-
74
-/**
75 51
  * Data for a single audio block.
76 52
  */
77 53
 typedef struct AC3Block {
... ...
@@ -154,6 +130,21 @@ typedef struct AC3EncodeContext {
154 154
 } AC3EncodeContext;
155 155
 
156 156
 
157
+/* prototypes for functions in ac3enc_fixed.c */
158
+
159
+static av_cold void mdct_end(AC3MDCTContext *mdct);
160
+
161
+static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
162
+                             int nbits);
163
+
164
+static void mdct512(AC3MDCTContext *mdct, CoefType *out, SampleType *in);
165
+
166
+static void apply_window(SampleType *output, const SampleType *input,
167
+                         const SampleType *window, int n);
168
+
169
+static int normalize_samples(AC3EncodeContext *s);
170
+
171
+
157 172
 /**
158 173
  * LUT for number of exponent groups.
159 174
  * exponent_group_tab[exponent strategy-1][number of coefficients]
... ...
@@ -234,291 +225,6 @@ static void deinterleave_input_samples(AC3EncodeContext *s,
234 234
 
235 235
 
236 236
 /**
237
- * Finalize MDCT and free allocated memory.
238
- */
239
-static av_cold void mdct_end(AC3MDCTContext *mdct)
240
-{
241
-    mdct->nbits = 0;
242
-    av_freep(&mdct->costab);
243
-    av_freep(&mdct->sintab);
244
-    av_freep(&mdct->xcos1);
245
-    av_freep(&mdct->xsin1);
246
-    av_freep(&mdct->rot_tmp);
247
-    av_freep(&mdct->cplx_tmp);
248
-}
249
-
250
-
251
-/**
252
- * Initialize FFT tables.
253
- * @param ln log2(FFT size)
254
- */
255
-static av_cold int fft_init(AVCodecContext *avctx, AC3MDCTContext *mdct, int ln)
256
-{
257
-    int i, n, n2;
258
-    float alpha;
259
-
260
-    n  = 1 << ln;
261
-    n2 = n >> 1;
262
-
263
-    FF_ALLOC_OR_GOTO(avctx, mdct->costab, n2 * sizeof(*mdct->costab), fft_alloc_fail);
264
-    FF_ALLOC_OR_GOTO(avctx, mdct->sintab, n2 * sizeof(*mdct->sintab), fft_alloc_fail);
265
-
266
-    for (i = 0; i < n2; i++) {
267
-        alpha     = 2.0 * M_PI * i / n;
268
-        mdct->costab[i] = FIX15(cos(alpha));
269
-        mdct->sintab[i] = FIX15(sin(alpha));
270
-    }
271
-
272
-    return 0;
273
-fft_alloc_fail:
274
-    mdct_end(mdct);
275
-    return AVERROR(ENOMEM);
276
-}
277
-
278
-
279
-/**
280
- * Initialize MDCT tables.
281
- * @param nbits log2(MDCT size)
282
- */
283
-static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
284
-                             int nbits)
285
-{
286
-    int i, n, n4, ret;
287
-
288
-    n  = 1 << nbits;
289
-    n4 = n >> 2;
290
-
291
-    mdct->nbits = nbits;
292
-
293
-    ret = fft_init(avctx, mdct, nbits - 2);
294
-    if (ret)
295
-        return ret;
296
-
297
-    mdct->window = ff_ac3_window;
298
-
299
-    FF_ALLOC_OR_GOTO(avctx, mdct->xcos1,    n4 * sizeof(*mdct->xcos1),    mdct_alloc_fail);
300
-    FF_ALLOC_OR_GOTO(avctx, mdct->xsin1,    n4 * sizeof(*mdct->xsin1),    mdct_alloc_fail);
301
-    FF_ALLOC_OR_GOTO(avctx, mdct->rot_tmp,  n  * sizeof(*mdct->rot_tmp),  mdct_alloc_fail);
302
-    FF_ALLOC_OR_GOTO(avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp), mdct_alloc_fail);
303
-
304
-    for (i = 0; i < n4; i++) {
305
-        float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;
306
-        mdct->xcos1[i] = FIX15(-cos(alpha));
307
-        mdct->xsin1[i] = FIX15(-sin(alpha));
308
-    }
309
-
310
-    return 0;
311
-mdct_alloc_fail:
312
-    mdct_end(mdct);
313
-    return AVERROR(ENOMEM);
314
-}
315
-
316
-
317
-/** Butterfly op */
318
-#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1)  \
319
-{                                                       \
320
-  int ax, ay, bx, by;                                   \
321
-  bx  = pre1;                                           \
322
-  by  = pim1;                                           \
323
-  ax  = qre1;                                           \
324
-  ay  = qim1;                                           \
325
-  pre = (bx + ax) >> 1;                                 \
326
-  pim = (by + ay) >> 1;                                 \
327
-  qre = (bx - ax) >> 1;                                 \
328
-  qim = (by - ay) >> 1;                                 \
329
-}
330
-
331
-
332
-/** Complex multiply */
333
-#define CMUL(pre, pim, are, aim, bre, bim)              \
334
-{                                                       \
335
-   pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15;     \
336
-   pim = (MUL16(are, bim) + MUL16(bre, aim)) >> 15;     \
337
-}
338
-
339
-
340
-/**
341
- * Calculate a 2^n point complex FFT on 2^ln points.
342
- * @param z  complex input/output samples
343
- * @param ln log2(FFT size)
344
- */
345
-static void fft(AC3MDCTContext *mdct, IComplex *z, int ln)
346
-{
347
-    int j, l, np, np2;
348
-    int nblocks, nloops;
349
-    register IComplex *p,*q;
350
-    int tmp_re, tmp_im;
351
-
352
-    np = 1 << ln;
353
-
354
-    /* reverse */
355
-    for (j = 0; j < np; j++) {
356
-        int k = av_reverse[j] >> (8 - ln);
357
-        if (k < j)
358
-            FFSWAP(IComplex, z[k], z[j]);
359
-    }
360
-
361
-    /* pass 0 */
362
-
363
-    p = &z[0];
364
-    j = np >> 1;
365
-    do {
366
-        BF(p[0].re, p[0].im, p[1].re, p[1].im,
367
-           p[0].re, p[0].im, p[1].re, p[1].im);
368
-        p += 2;
369
-    } while (--j);
370
-
371
-    /* pass 1 */
372
-
373
-    p = &z[0];
374
-    j = np >> 2;
375
-    do {
376
-        BF(p[0].re, p[0].im, p[2].re,  p[2].im,
377
-           p[0].re, p[0].im, p[2].re,  p[2].im);
378
-        BF(p[1].re, p[1].im, p[3].re,  p[3].im,
379
-           p[1].re, p[1].im, p[3].im, -p[3].re);
380
-        p+=4;
381
-    } while (--j);
382
-
383
-    /* pass 2 .. ln-1 */
384
-
385
-    nblocks = np >> 3;
386
-    nloops  =  1 << 2;
387
-    np2     = np >> 1;
388
-    do {
389
-        p = z;
390
-        q = z + nloops;
391
-        for (j = 0; j < nblocks; j++) {
392
-            BF(p->re, p->im, q->re, q->im,
393
-               p->re, p->im, q->re, q->im);
394
-            p++;
395
-            q++;
396
-            for(l = nblocks; l < np2; l += nblocks) {
397
-                CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
398
-                BF(p->re, p->im, q->re,  q->im,
399
-                   p->re, p->im, tmp_re, tmp_im);
400
-                p++;
401
-                q++;
402
-            }
403
-            p += nloops;
404
-            q += nloops;
405
-        }
406
-        nblocks = nblocks >> 1;
407
-        nloops  = nloops  << 1;
408
-    } while (nblocks);
409
-}
410
-
411
-
412
-/**
413
- * Calculate a 512-point MDCT
414
- * @param out 256 output frequency coefficients
415
- * @param in  512 windowed input audio samples
416
- */
417
-static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in)
418
-{
419
-    int i, re, im, n, n2, n4;
420
-    int16_t *rot = mdct->rot_tmp;
421
-    IComplex *x  = mdct->cplx_tmp;
422
-
423
-    n  = 1 << mdct->nbits;
424
-    n2 = n >> 1;
425
-    n4 = n >> 2;
426
-
427
-    /* shift to simplify computations */
428
-    for (i = 0; i <n4; i++)
429
-        rot[i] = -in[i + 3*n4];
430
-    memcpy(&rot[n4], &in[0], 3*n4*sizeof(*in));
431
-
432
-    /* pre rotation */
433
-    for (i = 0; i < n4; i++) {
434
-        re =  ((int)rot[   2*i] - (int)rot[ n-1-2*i]) >> 1;
435
-        im = -((int)rot[n2+2*i] - (int)rot[n2-1-2*i]) >> 1;
436
-        CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
437
-    }
438
-
439
-    fft(mdct, x, mdct->nbits - 2);
440
-
441
-    /* post rotation */
442
-    for (i = 0; i < n4; i++) {
443
-        re = x[i].re;
444
-        im = x[i].im;
445
-        CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]);
446
-    }
447
-}
448
-
449
-
450
-/**
451
- * Apply KBD window to input samples prior to MDCT.
452
- */
453
-static void apply_window(int16_t *output, const int16_t *input,
454
-                         const int16_t *window, int n)
455
-{
456
-    int i;
457
-    int n2 = n >> 1;
458
-
459
-    for (i = 0; i < n2; i++) {
460
-        output[i]     = MUL16(input[i],     window[i]) >> 15;
461
-        output[n-i-1] = MUL16(input[n-i-1], window[i]) >> 15;
462
-    }
463
-}
464
-
465
-
466
-/**
467
- * Calculate the log2() of the maximum absolute value in an array.
468
- * @param tab input array
469
- * @param n   number of values in the array
470
- * @return    log2(max(abs(tab[])))
471
- */
472
-static int log2_tab(int16_t *tab, int n)
473
-{
474
-    int i, v;
475
-
476
-    v = 0;
477
-    for (i = 0; i < n; i++)
478
-        v |= abs(tab[i]);
479
-
480
-    return av_log2(v);
481
-}
482
-
483
-
484
-/**
485
- * Left-shift each value in an array by a specified amount.
486
- * @param tab    input array
487
- * @param n      number of values in the array
488
- * @param lshift left shift amount. a negative value means right shift.
489
- */
490
-static void lshift_tab(int16_t *tab, int n, int lshift)
491
-{
492
-    int i;
493
-
494
-    if (lshift > 0) {
495
-        for (i = 0; i < n; i++)
496
-            tab[i] <<= lshift;
497
-    } else if (lshift < 0) {
498
-        lshift = -lshift;
499
-        for (i = 0; i < n; i++)
500
-            tab[i] >>= lshift;
501
-    }
502
-}
503
-
504
-
505
-/**
506
- * Normalize the input samples to use the maximum available precision.
507
- * This assumes signed 16-bit input samples. Exponents are reduced by 9 to
508
- * match the 24-bit internal precision for MDCT coefficients.
509
- *
510
- * @return exponent shift
511
- */
512
-static int normalize_samples(AC3EncodeContext *s)
513
-{
514
-    int v = 14 - log2_tab(s->windowed_samples, AC3_WINDOW_SIZE);
515
-    v = FFMAX(0, v);
516
-    lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
517
-    return v - 9;
518
-}
519
-
520
-
521
-/**
522 237
  * Apply the MDCT to input samples to generate frequency coefficients.
523 238
  * This applies the KBD window and normalizes the input to reduce precision
524 239
  * loss due to fixed-point calculations.
... ...
@@ -1982,113 +1688,3 @@ init_fail:
1982 1982
     ac3_encode_close(avctx);
1983 1983
     return ret;
1984 1984
 }
1985
-
1986
-
1987
-#ifdef TEST
1988
-/*************************************************************************/
1989
-/* TEST */
1990
-
1991
-#include "libavutil/lfg.h"
1992
-
1993
-#define MDCT_NBITS 9
1994
-#define MDCT_SAMPLES (1 << MDCT_NBITS)
1995
-#define FN (MDCT_SAMPLES/4)
1996
-
1997
-
1998
-static void fft_test(AC3MDCTContext *mdct, AVLFG *lfg)
1999
-{
2000
-    IComplex in[FN], in1[FN];
2001
-    int k, n, i;
2002
-    float sum_re, sum_im, a;
2003
-
2004
-    for (i = 0; i < FN; i++) {
2005
-        in[i].re = av_lfg_get(lfg) % 65535 - 32767;
2006
-        in[i].im = av_lfg_get(lfg) % 65535 - 32767;
2007
-        in1[i]   = in[i];
2008
-    }
2009
-    fft(mdct, in, 7);
2010
-
2011
-    /* do it by hand */
2012
-    for (k = 0; k < FN; k++) {
2013
-        sum_re = 0;
2014
-        sum_im = 0;
2015
-        for (n = 0; n < FN; n++) {
2016
-            a = -2 * M_PI * (n * k) / FN;
2017
-            sum_re += in1[n].re * cos(a) - in1[n].im * sin(a);
2018
-            sum_im += in1[n].re * sin(a) + in1[n].im * cos(a);
2019
-        }
2020
-        av_log(NULL, AV_LOG_DEBUG, "%3d: %6d,%6d %6.0f,%6.0f\n",
2021
-               k, in[k].re, in[k].im, sum_re / FN, sum_im / FN);
2022
-    }
2023
-}
2024
-
2025
-
2026
-static void mdct_test(AC3MDCTContext *mdct, AVLFG *lfg)
2027
-{
2028
-    int16_t input[MDCT_SAMPLES];
2029
-    int32_t output[AC3_MAX_COEFS];
2030
-    float input1[MDCT_SAMPLES];
2031
-    float output1[AC3_MAX_COEFS];
2032
-    float s, a, err, e, emax;
2033
-    int i, k, n;
2034
-
2035
-    for (i = 0; i < MDCT_SAMPLES; i++) {
2036
-        input[i]  = (av_lfg_get(lfg) % 65535 - 32767) * 9 / 10;
2037
-        input1[i] = input[i];
2038
-    }
2039
-
2040
-    mdct512(mdct, output, input);
2041
-
2042
-    /* do it by hand */
2043
-    for (k = 0; k < AC3_MAX_COEFS; k++) {
2044
-        s = 0;
2045
-        for (n = 0; n < MDCT_SAMPLES; n++) {
2046
-            a = (2*M_PI*(2*n+1+MDCT_SAMPLES/2)*(2*k+1) / (4 * MDCT_SAMPLES));
2047
-            s += input1[n] * cos(a);
2048
-        }
2049
-        output1[k] = -2 * s / MDCT_SAMPLES;
2050
-    }
2051
-
2052
-    err  = 0;
2053
-    emax = 0;
2054
-    for (i = 0; i < AC3_MAX_COEFS; i++) {
2055
-        av_log(NULL, AV_LOG_DEBUG, "%3d: %7d %7.0f\n", i, output[i], output1[i]);
2056
-        e = output[i] - output1[i];
2057
-        if (e > emax)
2058
-            emax = e;
2059
-        err += e * e;
2060
-    }
2061
-    av_log(NULL, AV_LOG_DEBUG, "err2=%f emax=%f\n", err / AC3_MAX_COEFS, emax);
2062
-}
2063
-
2064
-
2065
-int main(void)
2066
-{
2067
-    AVLFG lfg;
2068
-    AC3MDCTContext mdct;
2069
-
2070
-    mdct.avctx = NULL;
2071
-    av_log_set_level(AV_LOG_DEBUG);
2072
-    mdct_init(&mdct, 9);
2073
-
2074
-    fft_test(&mdct, &lfg);
2075
-    mdct_test(&mdct, &lfg);
2076
-
2077
-    return 0;
2078
-}
2079
-#endif /* TEST */
2080
-
2081
-
2082
-AVCodec ac3_encoder = {
2083
-    "ac3",
2084
-    AVMEDIA_TYPE_AUDIO,
2085
-    CODEC_ID_AC3,
2086
-    sizeof(AC3EncodeContext),
2087
-    ac3_encode_init,
2088
-    ac3_encode_frame,
2089
-    ac3_encode_close,
2090
-    NULL,
2091
-    .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
2092
-    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
2093
-    .channel_layouts = ac3_channel_layouts,
2094
-};
2095 1985
new file mode 100644
... ...
@@ -0,0 +1,428 @@
0
+/*
1
+ * The simplest AC-3 encoder
2
+ * Copyright (c) 2000 Fabrice Bellard
3
+ * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
4
+ * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
5
+ *
6
+ * This file is part of FFmpeg.
7
+ *
8
+ * FFmpeg is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Lesser General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2.1 of the License, or (at your option) any later version.
12
+ *
13
+ * FFmpeg is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Lesser General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public
19
+ * License along with FFmpeg; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ */
22
+
23
+/**
24
+ * @file
25
+ * fixed-point AC-3 encoder.
26
+ */
27
+
28
+#include "ac3enc.c"
29
+
30
+
31
+/** Scale a float value by 2^15, convert to an integer, and clip to range -32767..32767. */
32
+#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767)
33
+
34
+
35
+/**
36
+ * Finalize MDCT and free allocated memory.
37
+ */
38
+static av_cold void mdct_end(AC3MDCTContext *mdct)
39
+{
40
+    mdct->nbits = 0;
41
+    av_freep(&mdct->costab);
42
+    av_freep(&mdct->sintab);
43
+    av_freep(&mdct->xcos1);
44
+    av_freep(&mdct->xsin1);
45
+    av_freep(&mdct->rot_tmp);
46
+    av_freep(&mdct->cplx_tmp);
47
+}
48
+
49
+
50
+/**
51
+ * Initialize FFT tables.
52
+ * @param ln log2(FFT size)
53
+ */
54
+static av_cold int fft_init(AVCodecContext *avctx, AC3MDCTContext *mdct, int ln)
55
+{
56
+    int i, n, n2;
57
+    float alpha;
58
+
59
+    n  = 1 << ln;
60
+    n2 = n >> 1;
61
+
62
+    FF_ALLOC_OR_GOTO(avctx, mdct->costab, n2 * sizeof(*mdct->costab), fft_alloc_fail);
63
+    FF_ALLOC_OR_GOTO(avctx, mdct->sintab, n2 * sizeof(*mdct->sintab), fft_alloc_fail);
64
+
65
+    for (i = 0; i < n2; i++) {
66
+        alpha     = 2.0 * M_PI * i / n;
67
+        mdct->costab[i] = FIX15(cos(alpha));
68
+        mdct->sintab[i] = FIX15(sin(alpha));
69
+    }
70
+
71
+    return 0;
72
+fft_alloc_fail:
73
+    mdct_end(mdct);
74
+    return AVERROR(ENOMEM);
75
+}
76
+
77
+
78
+/**
79
+ * Initialize MDCT tables.
80
+ * @param nbits log2(MDCT size)
81
+ */
82
+static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
83
+                             int nbits)
84
+{
85
+    int i, n, n4, ret;
86
+
87
+    n  = 1 << nbits;
88
+    n4 = n >> 2;
89
+
90
+    mdct->nbits = nbits;
91
+
92
+    ret = fft_init(avctx, mdct, nbits - 2);
93
+    if (ret)
94
+        return ret;
95
+
96
+    mdct->window = ff_ac3_window;
97
+
98
+    FF_ALLOC_OR_GOTO(avctx, mdct->xcos1,    n4 * sizeof(*mdct->xcos1),    mdct_alloc_fail);
99
+    FF_ALLOC_OR_GOTO(avctx, mdct->xsin1,    n4 * sizeof(*mdct->xsin1),    mdct_alloc_fail);
100
+    FF_ALLOC_OR_GOTO(avctx, mdct->rot_tmp,  n  * sizeof(*mdct->rot_tmp),  mdct_alloc_fail);
101
+    FF_ALLOC_OR_GOTO(avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp), mdct_alloc_fail);
102
+
103
+    for (i = 0; i < n4; i++) {
104
+        float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;
105
+        mdct->xcos1[i] = FIX15(-cos(alpha));
106
+        mdct->xsin1[i] = FIX15(-sin(alpha));
107
+    }
108
+
109
+    return 0;
110
+mdct_alloc_fail:
111
+    mdct_end(mdct);
112
+    return AVERROR(ENOMEM);
113
+}
114
+
115
+
116
+/** Butterfly op */
117
+#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1)  \
118
+{                                                       \
119
+  int ax, ay, bx, by;                                   \
120
+  bx  = pre1;                                           \
121
+  by  = pim1;                                           \
122
+  ax  = qre1;                                           \
123
+  ay  = qim1;                                           \
124
+  pre = (bx + ax) >> 1;                                 \
125
+  pim = (by + ay) >> 1;                                 \
126
+  qre = (bx - ax) >> 1;                                 \
127
+  qim = (by - ay) >> 1;                                 \
128
+}
129
+
130
+
131
+/** Complex multiply */
132
+#define CMUL(pre, pim, are, aim, bre, bim)              \
133
+{                                                       \
134
+   pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15;     \
135
+   pim = (MUL16(are, bim) + MUL16(bre, aim)) >> 15;     \
136
+}
137
+
138
+
139
+/**
140
+ * Calculate a 2^n point complex FFT on 2^ln points.
141
+ * @param z  complex input/output samples
142
+ * @param ln log2(FFT size)
143
+ */
144
+static void fft(AC3MDCTContext *mdct, IComplex *z, int ln)
145
+{
146
+    int j, l, np, np2;
147
+    int nblocks, nloops;
148
+    register IComplex *p,*q;
149
+    int tmp_re, tmp_im;
150
+
151
+    np = 1 << ln;
152
+
153
+    /* reverse */
154
+    for (j = 0; j < np; j++) {
155
+        int k = av_reverse[j] >> (8 - ln);
156
+        if (k < j)
157
+            FFSWAP(IComplex, z[k], z[j]);
158
+    }
159
+
160
+    /* pass 0 */
161
+
162
+    p = &z[0];
163
+    j = np >> 1;
164
+    do {
165
+        BF(p[0].re, p[0].im, p[1].re, p[1].im,
166
+           p[0].re, p[0].im, p[1].re, p[1].im);
167
+        p += 2;
168
+    } while (--j);
169
+
170
+    /* pass 1 */
171
+
172
+    p = &z[0];
173
+    j = np >> 2;
174
+    do {
175
+        BF(p[0].re, p[0].im, p[2].re,  p[2].im,
176
+           p[0].re, p[0].im, p[2].re,  p[2].im);
177
+        BF(p[1].re, p[1].im, p[3].re,  p[3].im,
178
+           p[1].re, p[1].im, p[3].im, -p[3].re);
179
+        p+=4;
180
+    } while (--j);
181
+
182
+    /* pass 2 .. ln-1 */
183
+
184
+    nblocks = np >> 3;
185
+    nloops  =  1 << 2;
186
+    np2     = np >> 1;
187
+    do {
188
+        p = z;
189
+        q = z + nloops;
190
+        for (j = 0; j < nblocks; j++) {
191
+            BF(p->re, p->im, q->re, q->im,
192
+               p->re, p->im, q->re, q->im);
193
+            p++;
194
+            q++;
195
+            for(l = nblocks; l < np2; l += nblocks) {
196
+                CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
197
+                BF(p->re, p->im, q->re,  q->im,
198
+                   p->re, p->im, tmp_re, tmp_im);
199
+                p++;
200
+                q++;
201
+            }
202
+            p += nloops;
203
+            q += nloops;
204
+        }
205
+        nblocks = nblocks >> 1;
206
+        nloops  = nloops  << 1;
207
+    } while (nblocks);
208
+}
209
+
210
+
211
+/**
212
+ * Calculate a 512-point MDCT
213
+ * @param out 256 output frequency coefficients
214
+ * @param in  512 windowed input audio samples
215
+ */
216
+static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in)
217
+{
218
+    int i, re, im, n, n2, n4;
219
+    int16_t *rot = mdct->rot_tmp;
220
+    IComplex *x  = mdct->cplx_tmp;
221
+
222
+    n  = 1 << mdct->nbits;
223
+    n2 = n >> 1;
224
+    n4 = n >> 2;
225
+
226
+    /* shift to simplify computations */
227
+    for (i = 0; i <n4; i++)
228
+        rot[i] = -in[i + 3*n4];
229
+    memcpy(&rot[n4], &in[0], 3*n4*sizeof(*in));
230
+
231
+    /* pre rotation */
232
+    for (i = 0; i < n4; i++) {
233
+        re =  ((int)rot[   2*i] - (int)rot[ n-1-2*i]) >> 1;
234
+        im = -((int)rot[n2+2*i] - (int)rot[n2-1-2*i]) >> 1;
235
+        CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
236
+    }
237
+
238
+    fft(mdct, x, mdct->nbits - 2);
239
+
240
+    /* post rotation */
241
+    for (i = 0; i < n4; i++) {
242
+        re = x[i].re;
243
+        im = x[i].im;
244
+        CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]);
245
+    }
246
+}
247
+
248
+
249
+/**
250
+ * Apply KBD window to input samples prior to MDCT.
251
+ */
252
+static void apply_window(int16_t *output, const int16_t *input,
253
+                         const int16_t *window, int n)
254
+{
255
+    int i;
256
+    int n2 = n >> 1;
257
+
258
+    for (i = 0; i < n2; i++) {
259
+        output[i]     = MUL16(input[i],     window[i]) >> 15;
260
+        output[n-i-1] = MUL16(input[n-i-1], window[i]) >> 15;
261
+    }
262
+}
263
+
264
+
265
+/**
266
+ * Calculate the log2() of the maximum absolute value in an array.
267
+ * @param tab input array
268
+ * @param n   number of values in the array
269
+ * @return    log2(max(abs(tab[])))
270
+ */
271
+static int log2_tab(int16_t *tab, int n)
272
+{
273
+    int i, v;
274
+
275
+    v = 0;
276
+    for (i = 0; i < n; i++)
277
+        v |= abs(tab[i]);
278
+
279
+    return av_log2(v);
280
+}
281
+
282
+
283
+/**
284
+ * Left-shift each value in an array by a specified amount.
285
+ * @param tab    input array
286
+ * @param n      number of values in the array
287
+ * @param lshift left shift amount. a negative value means right shift.
288
+ */
289
+static void lshift_tab(int16_t *tab, int n, int lshift)
290
+{
291
+    int i;
292
+
293
+    if (lshift > 0) {
294
+        for (i = 0; i < n; i++)
295
+            tab[i] <<= lshift;
296
+    } else if (lshift < 0) {
297
+        lshift = -lshift;
298
+        for (i = 0; i < n; i++)
299
+            tab[i] >>= lshift;
300
+    }
301
+}
302
+
303
+
304
+/**
305
+ * Normalize the input samples to use the maximum available precision.
306
+ * This assumes signed 16-bit input samples. Exponents are reduced by 9 to
307
+ * match the 24-bit internal precision for MDCT coefficients.
308
+ *
309
+ * @return exponent shift
310
+ */
311
+static int normalize_samples(AC3EncodeContext *s)
312
+{
313
+    int v = 14 - log2_tab(s->windowed_samples, AC3_WINDOW_SIZE);
314
+    v = FFMAX(0, v);
315
+    lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
316
+    return v - 9;
317
+}
318
+
319
+
320
+#ifdef TEST
321
+/*************************************************************************/
322
+/* TEST */
323
+
324
+#include "libavutil/lfg.h"
325
+
326
+#define MDCT_NBITS 9
327
+#define MDCT_SAMPLES (1 << MDCT_NBITS)
328
+#define FN (MDCT_SAMPLES/4)
329
+
330
+
331
+static void fft_test(AC3MDCTContext *mdct, AVLFG *lfg)
332
+{
333
+    IComplex in[FN], in1[FN];
334
+    int k, n, i;
335
+    float sum_re, sum_im, a;
336
+
337
+    for (i = 0; i < FN; i++) {
338
+        in[i].re = av_lfg_get(lfg) % 65535 - 32767;
339
+        in[i].im = av_lfg_get(lfg) % 65535 - 32767;
340
+        in1[i]   = in[i];
341
+    }
342
+    fft(mdct, in, 7);
343
+
344
+    /* do it by hand */
345
+    for (k = 0; k < FN; k++) {
346
+        sum_re = 0;
347
+        sum_im = 0;
348
+        for (n = 0; n < FN; n++) {
349
+            a = -2 * M_PI * (n * k) / FN;
350
+            sum_re += in1[n].re * cos(a) - in1[n].im * sin(a);
351
+            sum_im += in1[n].re * sin(a) + in1[n].im * cos(a);
352
+        }
353
+        av_log(NULL, AV_LOG_DEBUG, "%3d: %6d,%6d %6.0f,%6.0f\n",
354
+               k, in[k].re, in[k].im, sum_re / FN, sum_im / FN);
355
+    }
356
+}
357
+
358
+
359
+static void mdct_test(AC3MDCTContext *mdct, AVLFG *lfg)
360
+{
361
+    int16_t input[MDCT_SAMPLES];
362
+    int32_t output[AC3_MAX_COEFS];
363
+    float input1[MDCT_SAMPLES];
364
+    float output1[AC3_MAX_COEFS];
365
+    float s, a, err, e, emax;
366
+    int i, k, n;
367
+
368
+    for (i = 0; i < MDCT_SAMPLES; i++) {
369
+        input[i]  = (av_lfg_get(lfg) % 65535 - 32767) * 9 / 10;
370
+        input1[i] = input[i];
371
+    }
372
+
373
+    mdct512(mdct, output, input);
374
+
375
+    /* do it by hand */
376
+    for (k = 0; k < AC3_MAX_COEFS; k++) {
377
+        s = 0;
378
+        for (n = 0; n < MDCT_SAMPLES; n++) {
379
+            a = (2*M_PI*(2*n+1+MDCT_SAMPLES/2)*(2*k+1) / (4 * MDCT_SAMPLES));
380
+            s += input1[n] * cos(a);
381
+        }
382
+        output1[k] = -2 * s / MDCT_SAMPLES;
383
+    }
384
+
385
+    err  = 0;
386
+    emax = 0;
387
+    for (i = 0; i < AC3_MAX_COEFS; i++) {
388
+        av_log(NULL, AV_LOG_DEBUG, "%3d: %7d %7.0f\n", i, output[i], output1[i]);
389
+        e = output[i] - output1[i];
390
+        if (e > emax)
391
+            emax = e;
392
+        err += e * e;
393
+    }
394
+    av_log(NULL, AV_LOG_DEBUG, "err2=%f emax=%f\n", err / AC3_MAX_COEFS, emax);
395
+}
396
+
397
+
398
+int main(void)
399
+{
400
+    AVLFG lfg;
401
+    AC3MDCTContext mdct;
402
+
403
+    mdct.avctx = NULL;
404
+    av_log_set_level(AV_LOG_DEBUG);
405
+    mdct_init(&mdct, 9);
406
+
407
+    fft_test(&mdct, &lfg);
408
+    mdct_test(&mdct, &lfg);
409
+
410
+    return 0;
411
+}
412
+#endif /* TEST */
413
+
414
+
415
+AVCodec ac3_encoder = {
416
+    "ac3",
417
+    AVMEDIA_TYPE_AUDIO,
418
+    CODEC_ID_AC3,
419
+    sizeof(AC3EncodeContext),
420
+    ac3_encode_init,
421
+    ac3_encode_frame,
422
+    ac3_encode_close,
423
+    NULL,
424
+    .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
425
+    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
426
+    .channel_layouts = ac3_channel_layouts,
427
+};
0 428
new file mode 100644
... ...
@@ -0,0 +1,60 @@
0
+/*
1
+ * The simplest AC-3 encoder
2
+ * Copyright (c) 2000 Fabrice Bellard
3
+ * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
4
+ * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
5
+ *
6
+ * This file is part of FFmpeg.
7
+ *
8
+ * FFmpeg is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Lesser General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2.1 of the License, or (at your option) any later version.
12
+ *
13
+ * FFmpeg is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Lesser General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public
19
+ * License along with FFmpeg; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ */
22
+
23
+/**
24
+ * @file
25
+ * fixed-point AC-3 encoder header.
26
+ */
27
+
28
+#ifndef AVCODEC_AC3ENC_FIXED_H
29
+#define AVCODEC_AC3ENC_FIXED_H
30
+
31
+#include <stdint.h>
32
+
33
+
34
+typedef int16_t SampleType;
35
+typedef int32_t CoefType;
36
+
37
+#define SCALE_COEF(a) (a)
38
+
39
+
40
+/**
41
+ * Compex number.
42
+ * Used in fixed-point MDCT calculation.
43
+ */
44
+typedef struct IComplex {
45
+    int16_t re,im;
46
+} IComplex;
47
+
48
+typedef struct AC3MDCTContext {
49
+    const int16_t *window;                  ///< MDCT window function
50
+    int nbits;                              ///< log2(transform size)
51
+    int16_t *costab;                        ///< FFT cos table
52
+    int16_t *sintab;                        ///< FFT sin table
53
+    int16_t *xcos1;                         ///< MDCT cos table
54
+    int16_t *xsin1;                         ///< MDCT sin table
55
+    int16_t *rot_tmp;                       ///< temp buffer for pre-rotated samples
56
+    IComplex *cplx_tmp;                     ///< temp buffer for complex pre-rotated samples
57
+} AC3MDCTContext;
58
+
59
+#endif /* AVCODEC_AC3ENC_FIXED_H */