Originally committed as revision 26206 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -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 */ |