From d8b2a2e6ab69169bab5ca40b69bfa5dac893bd0e Mon Sep 17 00:00:00 2001 From: Guenter Bartsch Date: Tue, 10 Jul 2001 21:50:31 +0000 Subject: latest libac3 from walken CVS patchset: 265 CVS date: 2001/07/10 21:50:31 --- src/libac3/Makefile.am | 9 +- src/libac3/ac3.h | 108 ++++-- src/libac3/ac3_internal.h | 134 +------ src/libac3/bit_allocate.c | 75 ++-- src/libac3/bit_allocate.h | 26 -- src/libac3/bitstream.c | 17 +- src/libac3/coeff.c | 337 ---------------- src/libac3/coeff.h | 24 -- src/libac3/debug.c | 58 --- src/libac3/debug.h | 37 -- src/libac3/decode.c | 163 -------- src/libac3/decode.h | 22 -- src/libac3/dither.c | 114 ------ src/libac3/dither.h | 37 -- src/libac3/downmix.c | 956 ++++++++++++++++++++++------------------------ src/libac3/downmix.h | 29 -- src/libac3/imdct.c | 118 ++---- src/libac3/imdct.h | 26 -- src/libac3/parse.c | 563 +++++++++++++++++++-------- src/libac3/parse.h | 26 -- src/libac3/rematrix.c | 81 ---- src/libac3/rematrix.h | 25 -- src/libac3/sanity_check.c | 117 ------ src/libac3/sanity_check.h | 27 -- src/libac3/stats.c | 107 ------ src/libac3/stats.h | 27 -- src/libac3/xine_decoder.c | 203 ++++++++-- 27 files changed, 1197 insertions(+), 2269 deletions(-) delete mode 100644 src/libac3/bit_allocate.h delete mode 100644 src/libac3/coeff.c delete mode 100644 src/libac3/coeff.h delete mode 100644 src/libac3/debug.c delete mode 100644 src/libac3/debug.h delete mode 100644 src/libac3/decode.c delete mode 100644 src/libac3/decode.h delete mode 100644 src/libac3/dither.c delete mode 100644 src/libac3/dither.h delete mode 100644 src/libac3/downmix.h delete mode 100644 src/libac3/imdct.h delete mode 100644 src/libac3/parse.h delete mode 100644 src/libac3/rematrix.c delete mode 100644 src/libac3/rematrix.h delete mode 100644 src/libac3/sanity_check.c delete mode 100644 src/libac3/sanity_check.h delete mode 100644 src/libac3/stats.c delete mode 100644 src/libac3/stats.h (limited to 'src') diff --git a/src/libac3/Makefile.am b/src/libac3/Makefile.am index e783c3fb9..38b5f5b39 100644 --- a/src/libac3/Makefile.am +++ b/src/libac3/Makefile.am @@ -7,15 +7,12 @@ libdir = $(XINE_PLUGINDIR) lib_LTLIBRARIES = xineplug_decode_ac3.la xineplug_decode_ac3_la_SOURCES = bitstream.c bit_allocate.c \ - coeff.c decode.c debug.c dither.c downmix.c imdct.c \ - imdct_mlib.c parse.c rematrix.c sanity_check.c stats.c \ + parse.c downmix.c imdct.c imdct_mlib.c \ xine_decoder.c xineplug_decode_ac3_la_LDFLAGS = -avoid-version -module -noinst_HEADERS = ac3.h ac3_internal.h bit_allocate.h \ - bitstream.h coeff.h debug.h decode.h dither.h \ - downmix.h imdct.h parse.h rematrix.h \ - sanity_check.h stats.h +noinst_HEADERS = ac3.h ac3_internal.h \ + bitstream.h tables.h ## ## Install header files (default=$includedir/xine) diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h index 69c11b9ed..305a10e49 100644 --- a/src/libac3/ac3.h +++ b/src/libac3/ac3.h @@ -22,30 +22,84 @@ * */ -#include - -#define AC3_DOLBY_SURR_ENABLE 0x1 - -typedef struct ac3_config_s -{ - //Bit flags that enable various things - uint32_t flags; - //Callback that points the decoder to new stream data - void (* fill_buffer_callback) (uint8_t **, uint8_t **); - //Number of discrete channels in final output (for downmixing) - uint16_t num_output_ch; - //Which channel of a dual mono stream to select - uint16_t dual_mono_ch_sel; -} ac3_config_t; - -typedef struct ac3_frame_s -{ - uint32_t sampling_rate; - int16_t * audio_data; - int num_channels; -} ac3_frame_t; - -void ac3_init(void); -int ac3_frame_length(uint8_t * buf); -int ac3_sampling_rate(uint8_t * buf); -ac3_frame_t* ac3_decode_frame(uint8_t * buf, int max_num_channels); +typedef struct ac3_ba_s { + uint16_t fsnroffst; // fine SNR offset + uint16_t fgaincod; // fast gain + uint16_t deltbae; // delta bit allocation exists + int8_t deltba[50]; // per-band delta bit allocation +} ac3_ba_t; + +typedef struct ac3_state_s { + uint8_t fscod; // sample rate + uint8_t halfrate; // halfrate factor + uint8_t acmod; // coded channels + float clev; // centre channel mix level + float slev; // surround channels mix level + uint8_t lfeon; // coded lfe channel + + int output; // type of output + float level; // output level + float bias; // output bias + + uint16_t cplinu; // coupling in use + uint16_t chincpl[5]; // channel coupled + uint16_t phsflginu; // phase flags in use (stereo only) + uint16_t cplbndstrc[18]; // coupling band structure + uint16_t cplstrtmant; // coupling channel start mantissa + uint16_t cplendmant; // coupling channel end mantissa + float cplco[5][18]; // coupling coordinates + + // derived information + uint16_t cplstrtbnd; // coupling start band (for bit allocation) + uint16_t ncplbnd; // number of coupling bands + + uint16_t rematflg[4]; // stereo rematrixing + + uint16_t endmant[5]; // channel end mantissa + + uint8_t cpl_exp[256]; // decoded coupling channel exponents + uint8_t fbw_exp[5][256]; // decoded channel exponents + uint8_t lfe_exp[7]; // decoded lfe channel exponents + + uint16_t sdcycod; // slow decay + uint16_t fdcycod; // fast decay + uint16_t sgaincod; // slow gain + uint16_t dbpbcod; // dB per bit - encodes the dbknee value + uint16_t floorcod; // masking floor + + uint16_t csnroffst; // coarse SNR offset + ac3_ba_t cplba; // coupling bit allocation parameters + ac3_ba_t ba[5]; // channel bit allocation parameters + ac3_ba_t lfeba; // lfe bit allocation parameters + + uint16_t cplfleak; // coupling fast leak init + uint16_t cplsleak; // coupling slow leak init + + // derived bit allocation information + int8_t fbw_bap[5][256]; + int8_t cpl_bap[256]; + int8_t lfe_bap[7]; +} ac3_state_t; + +#define AC3_CHANNEL 0 +#define AC3_MONO 1 +#define AC3_STEREO 2 +#define AC3_3F 3 +#define AC3_2F1R 4 +#define AC3_3F1R 5 +#define AC3_2F2R 6 +#define AC3_3F2R 7 +#define AC3_CHANNEL1 8 +#define AC3_CHANNEL2 9 +#define AC3_DOLBY 10 +#define AC3_CHANNEL_MASK 15 + +#define AC3_LFE 16 +#define AC3_ADJUST_LEVEL 32 + +void ac3_init (void); +int ac3_syncinfo (uint8_t * buf, int * flags, + int * sample_rate, int * bit_rate); +int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, + float * level, float bias); +int ac3_block (ac3_state_t * state); diff --git a/src/libac3/ac3_internal.h b/src/libac3/ac3_internal.h index d90fc598a..b414578bd 100644 --- a/src/libac3/ac3_internal.h +++ b/src/libac3/ac3_internal.h @@ -21,9 +21,10 @@ * */ -#ifndef __GNUC__ -#define inline -#endif +#define LEVEL_PLUS3DB 1.4142135623730951 +#define LEVEL_3DB 0.7071067811865476 +#define LEVEL_45DB 0.5946035575013605 +#define LEVEL_6DB 0.5 /* Exponent strategy constants */ #define EXP_REUSE (0) @@ -40,123 +41,14 @@ /* samples work structure */ typedef float stream_samples_t[6][256]; -/* global error flag */ -extern uint32_t error_flag; - -/* Everything you wanted to know about band structure */ -/* - * The entire frequency domain is represented by 256 real - * floating point fourier coefficients. Only the lower 253 - * coefficients are actually utilized however. We use arrays - * of 256 to be efficient in some cases. - * - * The 5 full bandwidth channels (fbw) can have their higher - * frequencies coupled together. These coupled channels then - * share their high frequency components. - * - * This coupling band is broken up into 18 sub-bands starting - * at mantissa number 37. Each sub-band is 12 bins wide. - * - * There are 50 bit allocation sub-bands which cover the entire - * frequency range. The sub-bands are of non-uniform width, and - * approximate a 1/6 octave scale. - */ - -/* The following structures are filled in by their corresponding parse_* - * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for - * full details on each field. Indented fields are used to denote - * conditional fields. - */ - -typedef struct ac3_state_s { - int nfchans; // number of channels, derived from acmod - - /* from syncinfo */ - uint8_t fscod; // sample rate - - /* from bsi */ - uint8_t acmod; // coded channels - uint8_t cmixlev; // centre channel mix level - uint8_t surmixlev; // surround channels mix level - uint8_t lfeon; // coded lfe channel -} ac3_state_t; - -typedef struct ac3_ba_s { - uint16_t fsnroffst; // fine SNR offset - uint16_t fgaincod; // fast gain - uint16_t deltbae; // delta bit allocation exists - int8_t deltba[50]; // per-band delta bit allocation -} ac3_ba_t; - -/* more pain */ -typedef struct audblk_s { - uint32_t magic1; - - // not reused between blocks - uint16_t blksw[5]; // imdct block transform switch - uint16_t dithflag[5]; // channel dither flag - - uint16_t cplinu; // coupling in use - uint16_t chincpl[5]; // channel coupled - uint16_t phsflginu; // phase flags in use (stereo only) - uint16_t cplbegf; // coupling begin frequency code - uint16_t cplendf; // coupling end frequency code - uint16_t cplbndstrc[18]; // coupling band structure - // derived information - uint16_t cplstrtmant; // coupling channel start mantissa - uint16_t cplendmant; // coupling channel end mantissa - uint16_t ncplsubnd; // number of coupling sub-bands - uint16_t ncplbnd; // number of coupling bands - - // should we simply have float cplco[5][18] instead of these 4 ? - uint8_t mstrcplco[5]; // per channel master coupling coordinate - uint8_t cplcoexp[5][18]; // per band coupling exponent - uint8_t cplcomant[5][18]; // per band coupling mantissa - uint8_t phsflg[18]; // per band phase flags for stereo - - uint16_t rematflg[4]; // stereo rematrixing - - uint16_t chbwcod[5]; // channel bandwidth for independant channels - - uint32_t magic2; - - uint16_t sdcycod; // slow decay - uint16_t fdcycod; // fast decay - uint16_t sgaincod; // slow gain - uint16_t dbpbcod; // dB per bit - encodes the dbknee value - uint16_t floorcod; // masking floor - - uint16_t csnroffst; // coarse SNR offset - ac3_ba_t cplba; // coupling bit allocation parameters - ac3_ba_t ba[5]; // channel bit allocation parameters - ac3_ba_t lfeba; // lfe bit allocation parameters - - uint16_t cplfleak; // coupling fast leak init - uint16_t cplsleak; // coupling slow leak init - - - - - /* coupling mantissas */ - uint16_t cplmant[256]; - - - /* -- Information not in the bitstream, but derived thereof -- */ - - /* End mantissa numbers of fbw channels */ - uint16_t endmant[5]; - - /* Decoded exponent info */ - uint8_t fbw_exp[5][256]; - uint8_t cpl_exp[256]; - uint8_t lfe_exp[7]; - - /* Bit allocation pointer results */ - int8_t fbw_bap[5][256]; - int8_t cpl_bap[256]; - int8_t lfe_bap[7]; - - uint32_t magic3; -} audblk_t; +void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart, + int start, int end, int fastleak, int slowleak, + uint8_t * exp, int8_t * bap); +int downmix_init (int input, int flags, float * level, float clev, float slev); +void downmix (float * samples, int acmod, int output, float level, float bias, + float clev, float slev); +void imdct_init (void); +extern void (* imdct_256) (float data[], float delay[]); +extern void (* imdct_512) (float data[], float delay[]); diff --git a/src/libac3/bit_allocate.c b/src/libac3/bit_allocate.c index 17f35b159..307c0074c 100644 --- a/src/libac3/bit_allocate.c +++ b/src/libac3/bit_allocate.c @@ -21,11 +21,11 @@ * */ +#include #include #include #include "ac3.h" #include "ac3_internal.h" -#include "bit_allocate.h" static int hthtab[3][50] = { {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860, @@ -46,17 +46,17 @@ static int hthtab[3][50] = { }; static int8_t baptab[305] = { - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, // 93 padding entries - - 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, - 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, - 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, - 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, // 93 padding entries + + 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14, + 14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, + 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, + 5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -113,18 +113,16 @@ do { \ do { \ if (psd > dbknee) \ mask -= (psd - dbknee) >> 2; \ - if (mask > hth[i]) \ - mask = hth[i]; \ - if (deltba != NULL) \ - mask -= 128 * deltba[i]; \ - mask -= snroffset; \ + if (mask > hth [i >> halfrate]) \ + mask = hth [i >> halfrate]; \ + mask -= snroffset + 128 * deltba[i]; \ mask = (mask > 0) ? 0 : ((-mask) >> 5); \ mask -= floor; \ } while (0) -void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, - int bndstart, int start, int end, int fastleak, int slowleak, - uint8_t * exp, int8_t * bap) +void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart, + int start, int end, int fastleak, int slowleak, + uint8_t * exp, int8_t * bap) { static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410}; static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100}; @@ -136,16 +134,22 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, int psd, mask; int8_t * deltba; int * hth; + int halfrate; - fdecay = 63 + 20 * audblk->fdcycod; + halfrate = state->halfrate; + fdecay = (63 + 20 * state->fdcycod) >> halfrate; fgain = 128 + 128 * ba->fgaincod; - sdecay = 15 + 2 * audblk->sdcycod; - sgain = slowgain[audblk->sgaincod]; - dbknee = dbpbtab[audblk->dbpbcod]; - hth = hthtab[fscod]; - deltba = (ba->deltbae == DELTA_BIT_NONE) ? NULL : ba->deltba; - floor = floortab[audblk->floorcod]; - snroffset = 960 - 64 * audblk->csnroffst - 4 * ba->fsnroffst + floor; + sdecay = (15 + 2 * state->sdcycod) >> halfrate; + sgain = slowgain[state->sgaincod]; + dbknee = dbpbtab[state->dbpbcod]; + hth = hthtab[state->fscod]; + /* + * if there is no delta bit allocation, make deltba point to an area + * known to contain zeroes. baptab+156 here. + */ + deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba; + floor = floortab[state->floorcod]; + snroffset = 960 - 64 * state->csnroffst - 4 * ba->fsnroffst + floor; floor >>= 5; i = bndstart; @@ -165,8 +169,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, psd = 128 * exp[i]; mask = psd + fgain + lowcomp; COMPUTE_MASK (); - bap[i] = (baptab+156)[mask + 4 * exp[i]]; - i++; + bap[i++] = (baptab+156)[mask + 4 * exp[i]]; } while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1]))); fastleak = psd + fgain; slowleak = psd + sgain; @@ -183,8 +186,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, mask = ((fastleak + lowcomp < slowleak) ? fastleak + lowcomp : slowleak); COMPUTE_MASK (); - bap[i] = (baptab+156)[mask + 4 * exp[i]]; - i++; + bap[i++] = (baptab+156)[mask + 4 * exp[i]]; } if (end == 7) // lfe channel @@ -200,8 +202,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, mask = ((fastleak + lowcomp < slowleak) ? fastleak + lowcomp : slowleak); COMPUTE_MASK (); - bap[i] = (baptab+156)[mask + 4 * exp[i]]; - i++; + bap[i++] = (baptab+156)[mask + 4 * exp[i]]; } while (i < 20); while (lowcomp > 128) { // two iterations maximum @@ -211,8 +212,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, mask = ((fastleak + lowcomp < slowleak) ? fastleak + lowcomp : slowleak); COMPUTE_MASK (); - bap[i] = (baptab+156)[mask + 4 * exp[i]]; - i++; + bap[i++] = (baptab+156)[mask + 4 * exp[i]]; } j = i; } @@ -249,8 +249,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, do { // max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp // min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 - bap[j] = (baptab+156)[mask + 4 * exp[j]]; - j++; + bap[j++] = (baptab+156)[mask + 4 * exp[j]]; } while (j < endband); } while (j < end); } diff --git a/src/libac3/bit_allocate.h b/src/libac3/bit_allocate.h deleted file mode 100644 index 089acc56c..000000000 --- a/src/libac3/bit_allocate.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * bit_allocate.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, - int bndstart, int start, int end, int fastleak, int slowleak, - uint8_t * exp, int8_t * bap); diff --git a/src/libac3/bitstream.c b/src/libac3/bitstream.c index 2a06ea747..7e9bd1f66 100644 --- a/src/libac3/bitstream.c +++ b/src/libac3/bitstream.c @@ -21,8 +21,8 @@ * */ +#include #include -#include #include #include "ac3.h" @@ -31,30 +31,21 @@ #define BUFFER_SIZE 4096 -struct uint32_alignment { - char a; - uint32_t b; -}; -#define UINT32_ALIGNMENT offsetof(struct uint32_alignment, b) - - -static uint32_t *buffer_start; +static uint8_t *buffer_start; uint32_t bits_left; uint32_t current_word; void bitstream_set_ptr (uint8_t * buf) { - int align = (long)buf & (UINT32_ALIGNMENT-1); - buffer_start = (uint32_t *) (buf - align); + buffer_start = buf; bits_left = 0; - if (align > 0) bitstream_get(align * 8); } static inline void bitstream_fill_current() { - current_word = *buffer_start++; + current_word = *((uint32_t*)buffer_start)++; current_word = swab32(current_word); } diff --git a/src/libac3/coeff.c b/src/libac3/coeff.c deleted file mode 100644 index 2913c18d4..000000000 --- a/src/libac3/coeff.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * coeff.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -#include -#include -#include "ac3.h" -#include "ac3_internal.h" - - -#include "decode.h" -#include "bitstream.h" -#include "dither.h" -#include "coeff.h" - -// -//Lookup tables of 0.15 two's complement quantization values -// -static const uint16_t q_1[3] = -{ - ( -2 << 15)/3, 0,( 2 << 15)/3 -}; - -static const uint16_t q_2[5] = -{ - ( -4 << 15)/5,( -2 << 15)/5, 0, - ( 2 << 15)/5,( 4 << 15)/5 -}; - -static const uint16_t q_3[7] = -{ - ( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, 0, - ( 2 << 15)/7,( 4 << 15)/7,( 6 << 15)/7 -}; - -static const uint16_t q_4[11] = -{ - (-10 << 15)/11,(-8 << 15)/11,(-6 << 15)/11, ( -4 << 15)/11,(-2 << 15)/11, 0, - ( 2 << 15)/11,( 4 << 15)/11,( 6 << 15)/11, ( 8 << 15)/11,(10 << 15)/11 -}; - -static const uint16_t q_5[15] = -{ - (-14 << 15)/15,(-12 << 15)/15,(-10 << 15)/15, - ( -8 << 15)/15,( -6 << 15)/15,( -4 << 15)/15, - ( -2 << 15)/15, 0 ,( 2 << 15)/15, - ( 4 << 15)/15,( 6 << 15)/15,( 8 << 15)/15, - ( 10 << 15)/15,( 12 << 15)/15,( 14 << 15)/15 -}; - -// -// Scale factors for convert_to_float -// - -static const uint32_t u32_scale_factors[25] = -{ - 0x38000000, //2 ^ -(0 + 15) - 0x37800000, //2 ^ -(1 + 15) - 0x37000000, //2 ^ -(2 + 15) - 0x36800000, //2 ^ -(3 + 15) - 0x36000000, //2 ^ -(4 + 15) - 0x35800000, //2 ^ -(5 + 15) - 0x35000000, //2 ^ -(6 + 15) - 0x34800000, //2 ^ -(7 + 15) - 0x34000000, //2 ^ -(8 + 15) - 0x33800000, //2 ^ -(9 + 15) - 0x33000000, //2 ^ -(10 + 15) - 0x32800000, //2 ^ -(11 + 15) - 0x32000000, //2 ^ -(12 + 15) - 0x31800000, //2 ^ -(13 + 15) - 0x31000000, //2 ^ -(14 + 15) - 0x30800000, //2 ^ -(15 + 15) - 0x30000000, //2 ^ -(16 + 15) - 0x2f800000, //2 ^ -(17 + 15) - 0x2f000000, //2 ^ -(18 + 15) - 0x2e800000, //2 ^ -(19 + 15) - 0x2e000000, //2 ^ -(20 + 15) - 0x2d800000, //2 ^ -(21 + 15) - 0x2d000000, //2 ^ -(22 + 15) - 0x2c800000, //2 ^ -(23 + 15) - 0x2c000000 //2 ^ -(24 + 15) -}; - -static float *scale_factor = (float*)u32_scale_factors; - -//These store the persistent state of the packed mantissas -static uint16_t m_1[3]; -static uint16_t m_2[3]; -static uint16_t m_4[2]; -static uint16_t m_1_pointer; -static uint16_t m_2_pointer; -static uint16_t m_4_pointer; - -//Conversion from bap to number of bits in the mantissas -//zeros account for cases 0,1,2,4 which are special cased -static uint16_t qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16}; - -static void coeff_reset(void); -static int16_t coeff_get_mantissa(uint16_t bap, uint16_t dithflag); -static void coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch); - -// -// Convert a 0.15 fixed point number into IEEE single -// precision floating point and scale by 2^-exp -// -static inline float -convert_to_float(uint16_t exp, int16_t mantissa) -{ - float x; - - //the scale by 2^-15 is built into the scale factor table - x = mantissa * scale_factor[exp]; - - return x; -} - -void -coeff_unpack(ac3_state_t *state, audblk_t *audblk, stream_samples_t samples) -{ - uint16_t i,j; - uint32_t done_cpl = 0; - int16_t mantissa; - - coeff_reset(); - - for(i=0; i< state->nfchans; i++) { - for(j=0; j < audblk->endmant[i]; j++) { - mantissa = coeff_get_mantissa(audblk->fbw_bap[i][j],audblk->dithflag[i]); - samples[i][j] = convert_to_float(audblk->fbw_exp[i][j],mantissa); - } - - if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) { - // ncplmant is equal to 12 * ncplsubnd - // Don't dither coupling channel until channel separation so that - // interchannel noise is uncorrelated - for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++) - audblk->cplmant[j] = coeff_get_mantissa(audblk->cpl_bap[j],0); - done_cpl = 1; - } - } - - //uncouple the channel if necessary - if(audblk->cplinu) { - for(i=0; i< state->nfchans; i++) { - if(audblk->chincpl[i]) - coeff_uncouple_ch(samples[i],state,audblk,i); - } - } - - if(state->lfeon) { - // There are always 7 mantissas for lfe, no dither for lfe - for(j=0; j < 7 ; j++) { - mantissa = coeff_get_mantissa(audblk->lfe_bap[j],0); - samples[5][j] = convert_to_float(audblk->lfe_exp[j],mantissa); - } - } -} - -// -//Fetch a mantissa from the bitstream -// -//The mantissa returned is a signed 0.15 fixed point number -// -static int16_t -coeff_get_mantissa(uint16_t bap, uint16_t dithflag) -{ - uint16_t mantissa; - uint16_t group_code; - - //If the bap is 0-5 then we have special cases to take care of - switch(bap) { - case 0: - if(dithflag) - mantissa = dither_gen(); - else - mantissa = 0; - break; - - case 1: - if(m_1_pointer > 2) { - group_code = bitstream_get(5); - - if(group_code > 26) - goto error; - - m_1[0] = group_code / 9; - m_1[1] = (group_code % 9) / 3; - m_1[2] = (group_code % 9) % 3; - m_1_pointer = 0; - } - mantissa = m_1[m_1_pointer++]; - mantissa = q_1[mantissa]; - break; - case 2: - - if(m_2_pointer > 2) { - group_code = bitstream_get(7); - - if(group_code > 124) - goto error; - - m_2[0] = group_code / 25; - m_2[1] = (group_code % 25) / 5 ; - m_2[2] = (group_code % 25) % 5 ; - m_2_pointer = 0; - } - mantissa = m_2[m_2_pointer++]; - mantissa = q_2[mantissa]; - break; - - case 3: - mantissa = bitstream_get(3); - - if(mantissa > 6) - goto error; - - mantissa = q_3[mantissa]; - break; - - case 4: - if(m_4_pointer > 1) { - group_code = bitstream_get(7); - - if(group_code > 120) - goto error; - - m_4[0] = group_code / 11; - m_4[1] = group_code % 11; - m_4_pointer = 0; - } - mantissa = m_4[m_4_pointer++]; - mantissa = q_4[mantissa]; - break; - - case 5: - mantissa = bitstream_get(4); - - if(mantissa > 14) - goto error; - - mantissa = q_5[mantissa]; - break; - - default: - mantissa = bitstream_get(qnttztab[bap]); - mantissa <<= 16 - qnttztab[bap]; - } - - return mantissa; - - - -error: - if(!error_flag) - fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); - error_flag = 1; - - return 0; -} - -// -// Reset the mantissa state -// -static void -coeff_reset(void) -{ - m_1[2] = m_1[1] = m_1[0] = 0; - m_2[2] = m_2[1] = m_2[0] = 0; - m_4[1] = m_4[0] = 0; - m_1_pointer = m_2_pointer = m_4_pointer = 3; -} - -// -// Uncouple the coupling channel into a fbw channel -// -static void -coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch) -{ - uint32_t bnd = 0; - uint32_t sub_bnd = 0; - uint32_t i,j; - float cpl_coord = 1.0; - uint32_t cpl_exp_tmp; - uint32_t cpl_mant_tmp; - int16_t mantissa; - - for(i=audblk->cplstrtmant;icplendmant;) { - if(!audblk->cplbndstrc[sub_bnd++]) { - cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; - if(audblk->cplcoexp[ch][bnd] == 15) - cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11; - else - cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10; - - cpl_coord = convert_to_float(cpl_exp_tmp,cpl_mant_tmp) * 8.0f; - - //Invert the phase for the right channel if necessary - if(state->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd]) - cpl_coord *= -1; - - bnd++; - } - - for(j=0;j < 12; j++) { - //Get new dither values for each channel if necessary, so - //the channels are uncorrelated - if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0) - mantissa = dither_gen(); - else - mantissa = audblk->cplmant[i]; - - samples[i] = cpl_coord * convert_to_float(audblk->cpl_exp[i],mantissa); - - i++; - } - } -} diff --git a/src/libac3/coeff.h b/src/libac3/coeff.h deleted file mode 100644 index fd3e1a6d9..000000000 --- a/src/libac3/coeff.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * coeff.h - * - * Copyright (C) Aaron Holtzman - Feb 2000 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -void coeff_unpack(ac3_state_t * state, audblk_t *audblk,stream_samples_t samples); diff --git a/src/libac3/debug.c b/src/libac3/debug.c deleted file mode 100644 index b7d6a3b08..000000000 --- a/src/libac3/debug.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * debug.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include "debug.h" - -static int debug_level = -1; - -// Determine is debug output is required. -// We could potentially have multiple levels of debug info -int debug_is_on(void) -{ - char *env_var; - - if(debug_level < 0) - { - env_var = getenv("AC3_DEBUG"); - - if (env_var) - { - debug_level = 1; - } - else - debug_level = 0; - } - - return debug_level; -} - -//If you don't have gcc, then ya don't get debug output -#ifndef __GNUC__ -void dprintf(char fmt[],...) -{ - int foo = 0; -} -#endif - diff --git a/src/libac3/debug.h b/src/libac3/debug.h deleted file mode 100644 index f45cb5b1a..000000000 --- a/src/libac3/debug.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * debug.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -int debug_is_on(void); - -#ifdef __GNUC__ -#define dprintf(format,args...)\ -{\ - if (debug_is_on())\ - {\ - fprintf(stderr,format,## args);\ - }\ -} -#else -void dprintf(char fmt[],...); -#endif diff --git a/src/libac3/decode.c b/src/libac3/decode.c deleted file mode 100644 index c859525e8..000000000 --- a/src/libac3/decode.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * decode.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#include -#include -#include -#include -#include -#include -#include "ac3.h" -#include "ac3_internal.h" -#include "bitstream.h" -#include "imdct.h" -#include "coeff.h" -#include "bit_allocate.h" -#include "parse.h" -#include "stats.h" -#include "rematrix.h" -#include "sanity_check.h" -#include "downmix.h" -#include "debug.h" - -//our global config structure -uint32_t error_flag = 0; - -static audblk_t audblk; -static ac3_state_t state; -static uint32_t frame_count = 0; -static uint32_t done_banner; -static ac3_frame_t frame; - -//the floating point samples for one audblk -static stream_samples_t samples; - -//the integer samples for the entire frame (with enough space for 5 ch out) -//if this size change, be sure to change the size when muting -static int16_t s16_samples[5 * 6 * 256]; - -void -ac3_init(void) -{ - imdct_init(); - sanity_check_init(&state,&audblk); - - frame.audio_data = s16_samples; -} - -int ac3_frame_length(uint8_t * buf) -{ - int dummy; - - return parse_syncinfo (buf, &dummy, &dummy); -} - -int ac3_sampling_rate(uint8_t * buf) -{ - int dummy, rate; - - parse_syncinfo (buf, &rate, &dummy); - return rate; -} - -ac3_frame_t* -ac3_decode_frame(uint8_t * buf, int max_num_channels) -{ - uint32_t i; - int dummy; - int num_channels; - - if (!parse_syncinfo (buf, &frame.sampling_rate, &dummy)) - goto error; - - dprintf("(decode) begin frame %d\n",frame_count++); - - if (parse_bsi (&state, buf)) - goto error; - - switch (state.acmod) { - case 7 : - case 5 : - /* case 3 : FIXME : implement downmix functions*/ - num_channels = (max_num_channels<5) ? max_num_channels : 5; - break; - case 4 : - case 6 : - num_channels = (max_num_channels<4) ? max_num_channels : 4; - break; - default: - num_channels = 2; - } - - frame.num_channels = num_channels; - - if (!done_banner) { - stats_print_banner (&state); - done_banner = 1; - } - - for(i=0; i < 6; i++) { - //Initialize freq/time sample storage - memset(samples,0,sizeof(float) * 256 * (state.nfchans + state.lfeon)); - - // Extract most of the audblk info from the bitstream - // (minus the mantissas - if (parse_audblk (&state, &audblk)) - goto error; - - // Figure out how many bits per mantissa - //bit_allocate(&state,&audblk); - - // Extract the mantissas from the stream and - // generate floating point frequency coefficients - coeff_unpack(&state,&audblk,samples); - if(error_flag) - goto error; - - if(state.acmod == 0x2) - rematrix(&audblk,samples); - - // Convert the frequency samples into time samples - imdct(&state,&audblk,samples); - - // Downmix into the requested number of channels - // and convert floating point to int16_t - downmix(&state,samples,&s16_samples[i * num_channels * 256], - num_channels); - - sanity_check(&state,&audblk); - if(error_flag) - goto error; - } - - - return &frame; - -error: - //mute the frame - memset(s16_samples,0,sizeof(int16_t) * 256 * 2 * 6); - - error_flag = 0; - return &frame; -} diff --git a/src/libac3/decode.h b/src/libac3/decode.h deleted file mode 100644 index bb84a1105..000000000 --- a/src/libac3/decode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * decode.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ diff --git a/src/libac3/dither.c b/src/libac3/dither.c deleted file mode 100644 index 8b7ef3427..000000000 --- a/src/libac3/dither.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * dither.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -#include -#include -#include "ac3.h" -#include "ac3_internal.h" - - -#include "dither.h" - - -const uint16_t dither_lut[256] = -{ - 0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055, - 0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb, - 0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198, - 0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176, - 0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf, - 0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321, - 0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202, - 0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec, - 0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761, - 0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f, - 0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac, - 0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642, - 0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb, - 0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415, - 0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536, - 0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8, - 0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c, - 0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2, - 0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1, - 0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f, - 0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6, - 0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58, - 0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b, - 0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95, - 0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918, - 0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6, - 0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5, - 0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b, - 0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82, - 0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c, - 0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f, - 0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1 -}; - -uint16_t lfsr_state = 1; - -// -// see dither_gen (inline-able) in dither.h -// - -#if 0 - -// -// this is the old dither_gen with is much slower than the new inlined -// lut version and is still here because it's easier to understand. -// - -/* - * Generate eight bits of pseudo-entropy using a 16 bit linear - * feedback shift register (LFSR). The primitive polynomial used - * is 1 + x^4 + x^14 + x^16. - * - * The distribution is uniform, over the range [-0.707,0.707] - * - */ - -uint16_t dither_gen(void) -{ - int i; - uint32_t state; - - //explicitly bring the state into a local var as gcc > 3.0? - //doesn't know how to optimize out the stores - state = lfsr_state; - - //Generate eight pseudo random bits - for(i=0;i<8;i++) { - state <<= 1; - - if(state & 0x10000) - state ^= 0xa011; - } - - lfsr_state = state; - - return (((((int32_t)state<<8)>>8) * (int32_t) (0.707106 * 256.0))>>16); -} - -#endif diff --git a/src/libac3/dither.h b/src/libac3/dither.h deleted file mode 100644 index 1a605ee14..000000000 --- a/src/libac3/dither.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * dither.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -extern uint16_t lfsr_state; -extern const uint16_t dither_lut[256]; - -static inline uint16_t dither_gen(void) -{ - int16_t state; - - state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8); - - lfsr_state = (uint16_t) state; - - return ((state * (int32_t) (0.707106 * 256.0))>>8); -} diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c index fd801308d..9e7fbfb8b 100644 --- a/src/libac3/downmix.c +++ b/src/libac3/downmix.c @@ -25,567 +25,509 @@ * */ +#include #include #include #include +#include #include "ac3.h" #include "ac3_internal.h" -#include "decode.h" -#include "downmix.h" -#include "debug.h" +#define CONVERT(acmod,output) (((output) << 3) + (acmod)) +int downmix_init (int input, int flags, float * level, float clev, float slev) +{ + static uint8_t table[11][8] = { + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO, + AC3_STEREO, AC3_STEREO, AC3_STEREO, AC3_STEREO}, + {AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO, + AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO, + AC3_STEREO, AC3_STEREO, AC3_STEREO, AC3_STEREO}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_3F, + AC3_STEREO, AC3_3F, AC3_STEREO, AC3_3F}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO, + AC3_2F1R, AC3_2F1R, AC3_2F1R, AC3_2F1R}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO, + AC3_2F1R, AC3_3F1R, AC3_2F1R, AC3_3F1R}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_3F, + AC3_2F2R, AC3_2F2R, AC3_2F2R, AC3_2F2R}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_3F, + AC3_2F2R, AC3_3F2R, AC3_2F2R, AC3_3F2R}, + {AC3_CHANNEL1, AC3_MONO, AC3_MONO, AC3_MONO, + AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO}, + {AC3_CHANNEL2, AC3_MONO, AC3_MONO, AC3_MONO, + AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO}, + {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_DOLBY, + AC3_DOLBY, AC3_DOLBY, AC3_DOLBY, AC3_DOLBY} + }; + int output; + + output = flags & AC3_CHANNEL_MASK; + if (output > AC3_DOLBY) + return -1; + + output = table[output][input & 7]; + + if ((output == AC3_STEREO) && + ((input == AC3_DOLBY) || ((input == AC3_3F) && (clev == LEVEL_3DB)))) + output = AC3_DOLBY; + + if (flags & AC3_ADJUST_LEVEL) + switch (CONVERT (input & 7, output)) { + + case CONVERT (AC3_3F, AC3_MONO): + *level *= LEVEL_3DB / (1 + clev); + break; -//Pre-scaled downmix coefficients -static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 }; -static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 }; + case CONVERT (AC3_STEREO, AC3_MONO): + case CONVERT (AC3_2F2R, AC3_2F1R): + case CONVERT (AC3_3F2R, AC3_3F1R): + level_3db: + *level *= LEVEL_3DB; + break; -static void -downmix_3f_2r_to_5ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) -{ - uint32_t j; - float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - left_sur = samples[3]; - right_sur = samples[4]; - - for (j = 0; j < 256; j++) - { - s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f); - s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f); - s16_samples[j * 5 + 2] = (int16_t) (*left_sur++ * 32767.0f); - s16_samples[j * 5 + 3] = (int16_t) (*right_sur++ * 32767.0f); - s16_samples[j * 5 + 4] = (int16_t) (*centre++ * 32767.0f); - } + case CONVERT (AC3_3F2R, AC3_2F1R): + if (clev < LEVEL_PLUS3DB - 1) + goto level_3db; + // break thru + case CONVERT (AC3_3F, AC3_STEREO): + case CONVERT (AC3_3F1R, AC3_2F1R): + case CONVERT (AC3_3F1R, AC3_2F2R): + case CONVERT (AC3_3F2R, AC3_2F2R): + *level /= 1 + clev; + break; + + case CONVERT (AC3_2F1R, AC3_MONO): + *level *= LEVEL_PLUS3DB / (2 + slev); + break; + + case CONVERT (AC3_2F1R, AC3_STEREO): + case CONVERT (AC3_3F1R, AC3_3F): + *level /= 1 + slev * LEVEL_3DB; + break; + + case CONVERT (AC3_3F1R, AC3_MONO): + *level *= LEVEL_3DB / (1 + clev + 0.5 * slev); + break; + + case CONVERT (AC3_3F1R, AC3_STEREO): + *level /= 1 + clev + slev * LEVEL_3DB; + break; + + case CONVERT (AC3_2F2R, AC3_MONO): + *level *= LEVEL_3DB / (1 + slev); + break; + + case CONVERT (AC3_2F2R, AC3_STEREO): + case CONVERT (AC3_3F2R, AC3_3F): + *level /= (1 + slev); + break; + + case CONVERT (AC3_3F2R, AC3_MONO): + *level *= LEVEL_3DB / (1 + clev + slev); + break; + + case CONVERT (AC3_3F2R, AC3_STEREO): + *level /= 1 + clev + slev; + break; + + case CONVERT (AC3_MONO, AC3_DOLBY): + *level *= LEVEL_PLUS3DB; + break; + + case CONVERT (AC3_3F, AC3_DOLBY): + case CONVERT (AC3_2F1R, AC3_DOLBY): + *level *= 1 / (1 + LEVEL_3DB); + break; + + case CONVERT (AC3_3F1R, AC3_DOLBY): + case CONVERT (AC3_2F2R, AC3_DOLBY): + *level *= 1 / (1 + 2 * LEVEL_3DB); + break; + + case CONVERT (AC3_3F2R, AC3_DOLBY): + *level *= 1 / (1 + 3 * LEVEL_3DB); + break; + } + + return output; } -static void -downmix_3f_2r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix1to1 (float * samples, float level, float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - left_sur = samples[3]; - right_sur = samples[4]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.5000f * *left++ + 0.500f * *centre ; - right_tmp= 0.5000f * *right++ + 0.500f * *centre++ ; - - s16_samples[j * 4 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 4 + 1] = (int16_t) (right_tmp * 32767.0f); - s16_samples[j * 4 + 2] = (int16_t) (*left_sur++ * 32767.0f); - s16_samples[j * 4 + 3] = (int16_t) (*right_sur++ * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + samples[i] = samples[i] * level + bias; } -static void -downmix_3f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void move1to1 (float * src, float * dest, float level, float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float clev,slev; - float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - left_sur = samples[3]; - right_sur = samples[4]; - - clev = cmixlev_lut[state->cmixlev]; - slev = smixlev_lut[state->surmixlev]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.4142f * *left++ + clev * *centre + slev * *left_sur++; - right_tmp= 0.4142f * *right++ + clev * *centre++ + slev * *right_sur++; - - s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + dest[i] = src[i] * level + bias; } -static void -downmix_2f_2r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix2to1 (float * samples, float level, float bias) { - uint32_t j; - float slev; - float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; - - left = samples[0]; - right = samples[1]; - left_sur = samples[2]; - right_sur = samples[3]; - - slev = smixlev_lut[state->surmixlev]; - - for (j = 0; j < 256; j++) - { - s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f); - s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f); - s16_samples[j * 5 + 2] = (int16_t) (*left_sur++ * 32767.0f); - s16_samples[j * 5 + 3] = (int16_t) (*right_sur++ * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + samples[i] = (samples[i] + samples[i + 256]) * level + bias; } -static void -downmix_2f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void move2to1 (float * src, float * dest, float level, float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float slev; - float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; - - left = samples[0]; - right = samples[1]; - left_sur = samples[2]; - right_sur = samples[3]; - - slev = smixlev_lut[state->surmixlev]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.4142f * *left++ + slev * *left_sur++; - right_tmp= 0.4142f * *right++ + slev * *right_sur++; - - s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + dest[i] = (src[i] + src[i + 256]) * level + bias; } -static void -downmix_3f_1r_to_5ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix3to1 (float * samples, float level, float clev, float bias) { - uint32_t j; - float *centre = 0, *left = 0, *right = 0, *sur = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - //Mono surround - sur = samples[3]; - - for (j = 0; j < 256; j++) - { - s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f); - s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f); - s16_samples[j * 5 + 2] = (int16_t) (*sur * 32767.0f); - s16_samples[j * 5 + 3] = (int16_t) (*sur++ * 32767.0f); - s16_samples[j * 5 + 4] = (int16_t) (*centre++ * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + samples[i] = ((samples[i] + samples[i + 512]) * level + + samples[i + 256] * clev + bias); } -static void -downmix_3f_1r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix21to1 (float * samples, float level, float slev, float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float clev,slev; - float *centre = 0, *left = 0, *right = 0, *sur = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - //Mono surround - sur = samples[3]; - - clev = cmixlev_lut[state->cmixlev]; - slev = smixlev_lut[state->surmixlev]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.5000f * *left++ + 0.500f * *centre ; - right_tmp= 0.5000f * *right++ + 0.500f * *centre++ ; - - s16_samples[j * 4 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 4 + 1] = (int16_t) (right_tmp * 32767.0f); - s16_samples[j * 4 + 2] = (int16_t) (*sur * 32767.0f); - s16_samples[j * 4 + 3] = (int16_t) (*sur++ * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + samples[i] = ((samples[i] + samples[i + 256]) * level + + samples[i + 512] * slev + bias); } -static void -downmix_3f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix31to1 (float * samples, float level, float clev, float slev, + float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float clev,slev; - float *centre = 0, *left = 0, *right = 0, *sur = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - //Mono surround - sur = samples[3]; - - clev = cmixlev_lut[state->cmixlev]; - slev = smixlev_lut[state->surmixlev]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *sur; - right_tmp= 0.4142f * *right++ + clev * *centre + slev * *sur++; - - s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + samples[i] = ((samples[i] + samples[i + 512]) * level + + samples[i + 256] * clev + samples[i + 768] * slev + + bias); } +static void mix22to1 (float * samples, float level, float slev, float bias) +{ + int i; + + for (i = 0; i < 256; i++) + samples[i] = ((samples[i] + samples[i + 256]) * level + + (samples[i + 512] + samples[i + 768]) * slev + bias); +} -static void -downmix_2f_1r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix32to1 (float * samples, float level, float clev, float slev, + float bias) { - uint32_t j; - float *left = 0, *right = 0, *sur = 0; - - left = samples[0]; - right = samples[1]; - //Mono surround - sur = samples[2]; - - for (j = 0; j < 256; j++) - { - s16_samples[j * 4 ] = (int16_t) (*left++ * 32767.0f); - s16_samples[j * 4 + 1] = (int16_t) (*right++ * 32767.0f); - s16_samples[j * 4 + 2] = (int16_t) (*sur * 32767.0f); - s16_samples[j * 4 + 3] = (int16_t) (*sur++ * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + samples[i] = ((samples[i] + samples[i + 512]) * level + + samples[i + 256] * clev + + (samples[i + 768] + samples[i + 1024]) * slev + bias); } -static void -downmix_2f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix1to2 (float * src, float * dest, float level, float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float slev; - float *left = 0, *right = 0, *sur = 0; - - left = samples[0]; - right = samples[1]; - //Mono surround - sur = samples[2]; - - slev = smixlev_lut[state->surmixlev]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.4142f * *left++ + slev * *sur; - right_tmp= 0.4142f * *right++ + slev * *sur++; - - s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); - } + int i; + + for (i = 0; i < 256; i++) + dest[i] = src[i] = src[i] * level + bias; } -static void -downmix_3f_0r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +static void mix3to2 (float * samples, float level, float clev, float bias) { - uint32_t j; - float right_tmp; - float left_tmp; - float clev; - float *centre = 0, *left = 0, *right = 0; - - left = samples[0]; - centre = samples[1]; - right = samples[2]; - - clev = cmixlev_lut[state->cmixlev]; - - for (j = 0; j < 256; j++) - { - left_tmp = 0.4142f * *left++ + clev * *centre; - right_tmp= 0.4142f * *right++ + clev * *centre++; - - s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); - s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); - } + int i; + float common; + + for (i = 0; i < 256; i++) { + common = samples[i + 256] * clev + bias; + samples[i] = samples[i] * level + common; + samples[i + 256] = samples[i + 512] * level + common; + } } - -static void -downmix_2f_0r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) + +static void mix21to2 (float * left, float * right, float level, float slev, + float bias) { - uint32_t j; - float *left = 0, *right = 0; + int i; + float common; + + for (i = 0; i < 256; i++) { + common = right[i + 256] * slev + bias; + left[i] = left[i] * level + common; + right[i] = right[i] * level + common; + } +} - left = samples[0]; - right = samples[1]; +static void mix11to1 (float * front, float * rear, float level, float slev, + float bias) +{ + int i; - for (j = 0; j < 256; j++) - { - s16_samples[j * 2 ] = (int16_t) (*left++ * 32767.0f); - s16_samples[j * 2 + 1] = (int16_t) (*right++ * 32767.0f); - } + for (i = 0; i < 256; i++) + front[i] = front[i] * level + rear[i] * slev + bias; } -static void -downmix_1f_0r_to_2ch(float *centre,int16_t *s16_samples) +static void mix31to2 (float * samples, float level, float clev, float slev, + float bias) { - uint32_t j; - float tmp; - - //Mono program! + int i; + float common; + + for (i = 0; i < 256; i++) { + common = samples[i + 256] * clev + samples[i + 768] * slev + bias; + samples[i] = samples[i] * level + common; + samples[i + 256] = samples[i + 512] * level + common; + } +} - for (j = 0; j < 256; j++) - { - tmp = 32767.0f * 0.7071f * *centre++; +static void mix32to2 (float * samples, float level, float clev, float slev, + float bias) +{ + int i; + float common; + + for (i = 0; i < 256; i++) { + common = samples[i + 256] * clev + bias; + samples[i] = samples[i] * level + common + samples[i + 768] * slev; + samples[i + 256] = (samples[i + 512] * level + common + + samples[i + 1024] * slev); + } +} - s16_samples[j * 2 ] = s16_samples[j * 2 + 1] = (int16_t) tmp; - } +static void mix21toS (float * samples, float level, float level3db, float bias) +{ + int i; + float surround; + + for (i = 0; i < 256; i++) { + surround = samples[i + 512] * level3db; + samples[i] = samples[i] * level - surround + bias; + samples[i + 256] = samples[i + 256] * level + surround + bias; + } } -// -// Downmix into 2 or 4 or 5 channels (4 ch isn't in quite yet) -// -// The downmix function names have the following format -// -// downmix_Xf_Yr_to_[2|4|5]ch[_dolby] -// -// where X = number of front channels -// Y = number of rear channels -// [2|4|5] = number of output channels -// [_dolby] = with or without dolby surround mix -// - -void downmix(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples, int num_channels) +static void mix22toS (float * samples, float level, float level3db, float bias) { - if(state->acmod > 7) - dprintf("(downmix) invalid acmod number\n"); - -#if 0 - // - //There are two main cases, with or without Dolby Surround - // - if(ac3_config.flags & AC3_DOLBY_SURR_ENABLE) - { - fprintf(stderr,"Dolby Surround Mixes not currently enabled\n"); - exit(1); - } -#endif - - //Non-Dolby surround downmixes - switch(state->acmod) - { - // 3/2 - case 7: - switch (num_channels) { - case 5: - downmix_3f_2r_to_5ch(state, samples,s16_samples); - break; - case 4: - downmix_3f_2r_to_4ch(state, samples,s16_samples); - break; - case 2: - downmix_3f_2r_to_2ch(state, samples,s16_samples); - break; - } - break; - - // 2/2 - case 6: - if (num_channels == 4) - downmix_2f_2r_to_4ch(state, samples,s16_samples); - else - downmix_2f_2r_to_2ch(state, samples,s16_samples); - break; - - // 3/1 - case 5: - - switch (num_channels) { - case 5: - downmix_3f_1r_to_5ch(state, samples,s16_samples); - break; - case 4: - downmix_3f_1r_to_4ch(state, samples,s16_samples); - break; - case 2: - downmix_3f_1r_to_2ch(state, samples,s16_samples); - break; - } - - break; - - // 2/1 - case 4: - if (num_channels == 4) - downmix_2f_1r_to_4ch(state, samples,s16_samples); - else - downmix_2f_1r_to_2ch(state, samples,s16_samples); - break; - - // 3/0 - case 3: - downmix_3f_0r_to_2ch(state, samples,s16_samples); - break; - - case 2: - downmix_2f_0r_to_2ch(state, samples,s16_samples); - break; - - // 1/0 - case 1: - downmix_1f_0r_to_2ch(samples[0],s16_samples); - break; - - // 1+1 - case 0: -#if 0 - downmix_1f_0r_to_2ch(samples[ac3_config.dual_mono_ch_sel],s16_samples); -#endif - break; - } + int i; + float surround; + + for (i = 0; i < 256; i++) { + surround = (samples[i + 512] + samples[i + 768]) * level3db; + samples[i] = samples[i] * level - surround + bias; + samples[i + 256] = samples[i + 256] * level + surround + bias; + } } +static void mix31toS (float * samples, float level, float level3db, float bias) +{ + int i; + float common, surround; + + for (i = 0; i < 256; i++) { + common = samples[i + 256] * level3db + bias; + surround = samples[i + 768] * level3db; + samples[i] = samples[i] * level + common - surround; + samples[i + 256] = samples[i + 512] * level + common + surround; + } +} +static void mix32toS (float * samples, float level, float level3db, float bias) +{ + int i; + float common, surround; + + for (i = 0; i < 256; i++) { + common = samples[i + 256] * level3db + bias; + surround = (samples[i + 768] + samples[i + 1024]) * level3db; + samples[i] = samples[i] * level + common - surround; + samples[i + 256] = samples[i + 512] * level + common + surround; + } +} -#if 0 - - //the dolby mixes lay here for the time being - switch(state->acmod) - { - // 3/2 - case 7: - left = samples[0]; - centre = samples[1]; - right = samples[2]; - left_sur = samples[3]; - right_sur = samples[4]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++; - left_tmp = -1 * right_tmp; - right_tmp += 0.3204f * *right++ + 0.2265f * *centre; - left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; - - samples[1][j] = right_tmp; - samples[0][j] = left_tmp; - } - - break; - - // 2/2 - case 6: - left = samples[0]; - right = samples[1]; - left_sur = samples[2]; - right_sur = samples[3]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++; - left_tmp = -1 * right_tmp; - right_tmp += 0.3204f * *right++; - left_tmp += 0.3204f * *left++ ; - - samples[1][j] = right_tmp; - samples[0][j] = left_tmp; - } - break; - - // 3/1 - case 5: - left = samples[0]; - centre = samples[1]; - right = samples[2]; - //Mono surround - right_sur = samples[3]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.2265f * *right_sur++; - left_tmp = -1 * right_tmp; - right_tmp += 0.3204f * *right++ + 0.2265f * *centre; - left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; - - samples[1][j] = right_tmp; - samples[0][j] = left_tmp; - } - break; - - // 2/1 - case 4: - left = samples[0]; - right = samples[1]; - //Mono surround - right_sur = samples[2]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.2265f * *right_sur++; - left_tmp = -1 * right_tmp; - right_tmp += 0.3204f * *right++; - left_tmp += 0.3204f * *left++; - - samples[1][j] = right_tmp; - samples[0][j] = left_tmp; - } - break; - - // 3/0 - case 3: - left = samples[0]; - centre = samples[1]; - right = samples[2]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.3204f * *right++ + 0.2265f * *centre; - left_tmp = 0.3204f * *left++ + 0.2265f * *centre++; - - samples[1][j] = right_tmp; - samples[0][j] = left_tmp; - } - break; - - // 2/0 - case 2: - //Do nothing! - break; - - // 1/0 - case 1: - //Mono program! - right = samples[0]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.7071f * *right++; - - samples[1][j] = right_tmp; - samples[0][j] = right_tmp; - } - - break; - - // 1+1 - case 0: - //Dual mono, output selected by user - right = samples[ac3_config.dual_mono_ch_sel]; - - for (j = 0; j < 256; j++) - { - right_tmp = 0.7071f * *right++; - - samples[1][j] = right_tmp; - samples[0][j] = right_tmp; - } - break; -#endif +void downmix (float * samples, int acmod, int output, float level, float bias, + float clev, float slev) +{ + switch (CONVERT (acmod, output & AC3_CHANNEL_MASK)) { + + case CONVERT (AC3_3F2R, AC3_3F2R): + mix1to1 (samples + 1024, level, bias); + case CONVERT (AC3_3F1R, AC3_3F1R): + case CONVERT (AC3_2F2R, AC3_2F2R): + mix1to1 (samples + 768, level, bias); + case CONVERT (AC3_3F, AC3_3F): + case CONVERT (AC3_2F1R, AC3_2F1R): + mix_3to3: + mix1to1 (samples + 512, level, bias); + case CONVERT (AC3_CHANNEL, AC3_CHANNEL): + case CONVERT (AC3_STEREO, AC3_STEREO): + case CONVERT (AC3_STEREO, AC3_DOLBY): + mix_2to2: + mix1to1 (samples + 256, level, bias); + case CONVERT (AC3_CHANNEL, AC3_CHANNEL1): + case CONVERT (AC3_MONO, AC3_MONO): + mix1to1 (samples, level, bias); + break; + + case CONVERT (AC3_CHANNEL, AC3_CHANNEL2): + mix_1to1_b: + mix1to1 (samples + 256, level, bias); + break; + + case CONVERT (AC3_STEREO, AC3_MONO): + mix_2to1: + mix2to1 (samples, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_2F1R, AC3_MONO): + if (slev == 0) + goto mix_2to1; + mix21to1 (samples, level * LEVEL_3DB, level * slev * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_2F2R, AC3_MONO): + if (slev == 0) + goto mix_2to1; + mix22to1 (samples, level * LEVEL_3DB, level * slev * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F, AC3_MONO): + mix_3to1: + mix3to1 (samples, level * LEVEL_3DB, level * clev * LEVEL_PLUS3DB, + bias); + break; + + case CONVERT (AC3_3F1R, AC3_MONO): + if (slev == 0) + goto mix_3to1; + mix31to1 (samples, level * LEVEL_3DB, level * clev * LEVEL_PLUS3DB, + level * slev * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F2R, AC3_MONO): + if (slev == 0) + goto mix_3to1; + mix32to1 (samples, level * LEVEL_3DB, level * clev * LEVEL_PLUS3DB, + level * slev * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_CHANNEL, AC3_MONO): + mix2to1 (samples, level * LEVEL_6DB, bias); + break; + + case CONVERT (AC3_MONO, AC3_DOLBY): + mix1to2 (samples, samples + 256, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F, AC3_DOLBY): + clev = LEVEL_3DB; + case CONVERT (AC3_3F, AC3_STEREO): + mix_3to2: + mix3to2 (samples, level, level * clev, bias); + break; + + case CONVERT (AC3_2F1R, AC3_DOLBY): + mix21toS (samples, level, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F1R, AC3_DOLBY): + mix31toS (samples, level, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_2F2R, AC3_DOLBY): + mix22toS (samples, level, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F2R, AC3_DOLBY): + mix32toS (samples, level, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_2F1R, AC3_STEREO): + if (slev == 0) + goto mix_2to2; + mix21to2 (samples, samples + 256, level, level * slev * LEVEL_3DB, + bias); + break; + + case CONVERT (AC3_3F1R, AC3_STEREO): + if (slev == 0) + goto mix_3to2; + mix31to2 (samples, level, level * clev, level * slev * LEVEL_3DB, + bias); + break; + + case CONVERT (AC3_2F2R, AC3_STEREO): + if (slev == 0) + goto mix_2to2; + mix11to1 (samples, samples + 512, level, level * slev, bias); + mix11to1 (samples + 256, samples + 768, level, level * slev, bias); + break; + + case CONVERT (AC3_3F2R, AC3_STEREO): + if (slev == 0) + goto mix_3to2; + mix32to2 (samples, level, level * clev, level * slev, bias); + break; + + case CONVERT (AC3_3F1R, AC3_3F): + if (slev == 0) + goto mix_3to3; + mix21to2 (samples, samples + 512, level, level * slev * LEVEL_3DB, + bias); + + case CONVERT (AC3_3F2R, AC3_3F): + if (slev == 0) + goto mix_3to3; + mix11to1 (samples, samples + 768, level, level * slev, bias); + mix11to1 (samples + 512, samples + 1024, level, level * slev, bias); + goto mix_1to1_b; + + case CONVERT (AC3_2F1R, AC3_2F2R): + mix1to2 (samples + 512, samples + 768, level * LEVEL_3DB, bias); + goto mix_2to2; + + case CONVERT (AC3_3F1R, AC3_3F2R): + mix1to2 (samples + 768, samples + 1024, level * LEVEL_3DB, bias); + goto mix_3to3; + + case CONVERT (AC3_2F2R, AC3_2F1R): + mix2to1 (samples + 512, level * LEVEL_3DB, bias); + goto mix_2to2; + + case CONVERT (AC3_3F2R, AC3_3F1R): + mix2to1 (samples + 768, level * LEVEL_3DB, bias); + goto mix_3to3; + + case CONVERT (AC3_3F1R, AC3_2F2R): + mix3to2 (samples, level, level * clev, bias); + mix1to2 (samples + 768, samples + 512, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F1R, AC3_2F1R): + mix3to2 (samples, level, level * clev, bias); + move1to1 (samples + 768, samples + 512, level, bias); + break; + + case CONVERT (AC3_3F2R, AC3_2F1R): + mix3to2 (samples, level, level * clev, bias); + move2to1 (samples + 768, samples + 512, level * LEVEL_3DB, bias); + break; + + case CONVERT (AC3_3F2R, AC3_2F2R): + mix3to2 (samples, level, level * clev, bias); + move1to1 (samples + 768, samples + 512, level, bias); + move1to1 (samples + 1024, samples + 768, level, bias); + break; + + } +} diff --git a/src/libac3/downmix.h b/src/libac3/downmix.h deleted file mode 100644 index 28c6aea15..000000000 --- a/src/libac3/downmix.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * downmix.h - * - * Copyright (C) Aaron Holtzman - Sept 1999 - * - * Originally based on code by Yeqing Deng. - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -void downmix(ac3_state_t * state, stream_samples_t stream_samples,int16_t *s16_samples, - int num_channels); diff --git a/src/libac3/imdct.c b/src/libac3/imdct.c index a2e83d423..030026a54 100644 --- a/src/libac3/imdct.c +++ b/src/libac3/imdct.c @@ -24,32 +24,23 @@ #include "config.h" +#include #include #include #include #include "ac3.h" #include "ac3_internal.h" - -#include "decode.h" -#include "imdct.h" - -void imdct_do_256(float data[],float delay[]); -void imdct_do_512(float data[],float delay[]); - -void imdct_do_256_mlib(float data[],float delay[]); -void imdct_do_512_mlib(float data[],float delay[]); +void (* imdct_256) (float data[], float delay[]); +void (* imdct_512) (float data[], float delay[]); typedef struct complex_s { - float real; - float imag; + float real; + float imag; } complex_t; -#define N 512 - - /* 128 point bit-reverse LUT */ static uint8_t bit_reverse_512[] = { 0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, @@ -82,7 +73,6 @@ static uint8_t bit_reverse_256[] = { static complex_t buf[128]; /* Twiddle factor LUT */ -static complex_t *w[7]; static complex_t w_1[1]; static complex_t w_2[2]; static complex_t w_4[4]; @@ -90,6 +80,7 @@ static complex_t w_8[8]; static complex_t w_16[16]; static complex_t w_32[32]; static complex_t w_64[64]; +static complex_t * w[7] = {w_1, w_2, w_4, w_8, w_16, w_32, w_64}; /* Twiddle factors for IMDCT */ static float xcos1[128]; @@ -97,9 +88,6 @@ static float xsin1[128]; static float xcos2[64]; static float xsin2[64]; -/* Delay buffer for time domain interleaving */ -static float delay[6][256]; - /* Windowing function for Modified DCT - Thank you acroread */ float imdct_window[] = { 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130, @@ -157,51 +145,6 @@ static inline complex_t cmplx_mult(complex_t a, complex_t b) return ret; } -void imdct_init(void) -{ - int i,k; - complex_t angle_step; - complex_t current_angle; - -#ifdef LIBAC3_MLIB - return; -#endif - - /* Twiddle factors to turn IFFT into IMDCT */ - for( i=0; i < 128; i++) { - xcos1[i] = -cos(2.0f * M_PI * (8*i+1)/(8*N)) ; - xsin1[i] = -sin(2.0f * M_PI * (8*i+1)/(8*N)) ; - } - - /* More twiddle factors to turn IFFT into IMDCT */ - for( i=0; i < 64; i++) { - xcos2[i] = -cos(2.0f * M_PI * (8*i+1)/(4*N)) ; - xsin2[i] = -sin(2.0f * M_PI * (8*i+1)/(4*N)) ; - } - - /* Canonical twiddle factors for FFT */ - w[0] = w_1; - w[1] = w_2; - w[2] = w_4; - w[3] = w_8; - w[4] = w_16; - w[5] = w_32; - w[6] = w_64; - - for( i = 0; i < 7; i++) { - angle_step.real = cos(-2.0 * M_PI / (1 << (i+1))); - angle_step.imag = sin(-2.0 * M_PI / (1 << (i+1))); - - current_angle.real = 1.0; - current_angle.imag = 0.0; - - for (k = 0; k < 1 << i; k++) { - w[i][k] = current_angle; - current_angle = cmplx_mult(current_angle,angle_step); - } - } -} - void imdct_do_512(float data[],float delay[]) { @@ -429,30 +372,37 @@ imdct_do_256(float data[],float delay[]) } } -void -imdct(ac3_state_t *state,audblk_t *audblk, stream_samples_t samples) { - int i; - +void imdct_init (void) +{ #ifdef LIBAC3_MLIB - for(i=0; infchans;i++) { - if(audblk->blksw[i]) - imdct_do_256_mlib(samples[i],delay[i]); - else - imdct_do_512_mlib(samples[i],delay[i]); + void imdct_do_256_mlib(float data[],float delay[]); + void imdct_do_512_mlib(float data[],float delay[]); + + imdct_512 = imdct_do_512_mlib; + imdct_256 = imdct_do_256_mlib; +#else + int i, j, k; + + /* Twiddle factors to turn IFFT into IMDCT */ + for (i = 0; i < 128; i++) { + xcos1[i] = -cos ((M_PI / 2048) * (8 * i + 1)); + xsin1[i] = -sin ((M_PI / 2048) * (8 * i + 1)); } - return; -#endif - for(i=0; infchans;i++) { - if(audblk->blksw[i]) - imdct_do_256(samples[i],delay[i]); - else - imdct_do_512(samples[i],delay[i]); + /* More twiddle factors to turn IFFT into IMDCT */ + for (i = 0; i < 64; i++) { + xcos2[i] = -cos ((M_PI / 1024) * (8 * i + 1)); + xsin2[i] = -sin ((M_PI / 1024) * (8 * i + 1)); } - //XXX We don't bother with the IMDCT for the LFE as it's currently - //unused. - //if (state->lfeon) - // imdct_do_512(coeffs->lfe,samples->channel[5],delay[5]); - // + for (i = 0; i < 7; i++) { + j = 1 << i; + for (k = 0; k < j; k++) { + w[i][k].real = cos (-M_PI * k / j); + w[i][k].imag = sin (-M_PI * k / j); + } + } + imdct_512 = imdct_do_512; + imdct_256 = imdct_do_256; +#endif } diff --git a/src/libac3/imdct.h b/src/libac3/imdct.h deleted file mode 100644 index c6b3325a9..000000000 --- a/src/libac3/imdct.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * imdct.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -void imdct(ac3_state_t *state,audblk_t *audblk, stream_samples_t samples); -void imdct_init(void); diff --git a/src/libac3/parse.c b/src/libac3/parse.c index 7feee2bbe..98ee09012 100644 --- a/src/libac3/parse.c +++ b/src/libac3/parse.c @@ -22,78 +22,106 @@ * */ -#include -#include +#include #include + #include "ac3.h" #include "ac3_internal.h" #include "bitstream.h" -#include "stats.h" -#include "debug.h" -#include "parse.h" -#include "bit_allocate.h" +#include "tables.h" + +extern stream_samples_t samples; // FIXME +static float delay[6][256]; + +void ac3_init (void) +{ + imdct_init (); +} -static const uint8_t nfchans[8] = {2, 1, 2, 3, 3, 4, 4, 5}; +static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3}; -int parse_syncinfo (uint8_t * buf, int * sample_rate, int * bit_rate) +int ac3_syncinfo (uint8_t * buf, int * flags, + int * sample_rate, int * bit_rate) { static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640}; + static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01}; int frmsizecod; int bitrate; + int half; + int acmod; if ((buf[0] != 0x0b) || (buf[1] != 0x77)) // syncword return 0; + if (buf[5] >= 0x60) // bsid >= 12 + return 0; + half = halfrate[buf[5] >> 3]; + + // acmod, dsurmod and lfeon + acmod = buf[6] >> 5; + *flags = (((buf[6] & 0xf8) == 0x50) ? AC3_DOLBY : acmod) | + ((buf[6] & lfeon[acmod]) ? AC3_LFE : 0); + frmsizecod = buf[4] & 63; if (frmsizecod >= 38) return 0; - *bit_rate = bitrate = rate [frmsizecod >> 1]; + bitrate = rate [frmsizecod >> 1]; + *bit_rate = (bitrate * 1000) >> half; switch (buf[4] & 0xc0) { case 0: // 48 KHz - *sample_rate = 48000; + *sample_rate = 48000 >> half; return 4 * bitrate; case 0x40: - *sample_rate = 44100; + *sample_rate = 44100 >> half; return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); case 0x80: - *sample_rate = 32000; + *sample_rate = 32000 >> half; return 6 * bitrate; default: return 0; } } -int parse_bsi (ac3_state_t * state, uint8_t * buf) +int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, float * level, + float bias) { + static float clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB}; + static float slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB}; int chaninfo; + int acmod; state->fscod = buf[4] >> 6; - - if (buf[5] >= 0x48) // bsid >= 9 - return 1; - - state->acmod = buf[6] >> 5; - state->nfchans = nfchans[state->acmod]; + state->halfrate = halfrate[buf[5] >> 3]; + state->acmod = acmod = buf[6] >> 5; bitstream_set_ptr (buf + 6); bitstream_get (3); // skip acmod we already parsed - if ((state->acmod & 0x1) && (state->acmod != 0x1)) - state->cmixlev = bitstream_get (2); + if ((acmod == 2) && (bitstream_get (2) == 2)) // dsurmod + acmod = AC3_DOLBY; - if (state->acmod & 0x4) - state->surmixlev = bitstream_get (2); + if ((acmod & 1) && (acmod != 1)) + state->clev = clev[bitstream_get (2)]; // cmixlev - if (state->acmod == 0x2) - bitstream_get (2); // dsurmod + if (acmod & 4) + state->slev = slev[bitstream_get (2)]; // surmixlev state->lfeon = bitstream_get (1); - chaninfo = (state->acmod) ? 0 : 1; + state->output = downmix_init (acmod, *flags, level, + state->clev, state->slev); + if (state->output < 0) { + return 1; + } + *flags = state->output; + state->level = *level; + state->bias = bias; + + chaninfo = !acmod; do { bitstream_get (5); // dialnorm if (bitstream_get (1)) // compre @@ -120,7 +148,6 @@ int parse_bsi (ac3_state_t * state, uint8_t * buf) } while (addbsil--); } - stats_print_bsi(state); return 0; } @@ -128,18 +155,11 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent, uint8_t * dest) { int exps; - int8_t exp_1, exp_2, exp_3; while (ngrps--) { exps = bitstream_get (7); - if (exps >= 125) - return 1; - exp_1 = exps / 25; - exp_2 = (exps - (exp_1 * 25)) / 5; - exp_3 = exps - (exp_1 * 25) - (exp_2 * 5) ; - - exponent += (exp_1 - 2); + exponent += exp_1[exps]; if (exponent > 24) return 1; @@ -153,7 +173,7 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent, *(dest++) = exponent; } - exponent += (exp_2 - 2); + exponent += exp_2[exps]; if (exponent > 24) return 1; @@ -167,7 +187,7 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent, *(dest++) = exponent; } - exponent += (exp_3 - 2); + exponent += exp_3[exps]; if (exponent > 24) return 1; @@ -209,106 +229,252 @@ static int parse_deltba (int8_t * deltba) return 0; } -static inline int zero_snr_offsets (ac3_state_t * state, audblk_t * audblk) +static inline int zero_snr_offsets (int nfchans, ac3_state_t * state) { int i; - if ((audblk->csnroffst) || - (audblk->cplinu && audblk->cplba.fsnroffst) || - (state->lfeon && audblk->lfeba.fsnroffst)) + if ((state->csnroffst) || (state->cplinu && state->cplba.fsnroffst) || + (state->lfeon && state->lfeba.fsnroffst)) return 0; - for (i = 0; i < state->nfchans; i++) - if (audblk->ba[i].fsnroffst) + for (i = 0; i < nfchans; i++) + if (state->ba[i].fsnroffst) return 0; return 1; } -int parse_audblk (ac3_state_t * state, audblk_t * audblk) +static float q_1[2]; +static float q_2[2]; +static float q_4; +static int q_1_pointer; +static int q_2_pointer; +static int q_4_pointer; + +#define GET_COEFF(COEFF,DITHER) \ + switch (bap[i]) { \ + case 0: \ + DITHER (scale_factor[exp[i]]); \ + \ + case -1: \ + if (q_1_pointer >= 0) { \ + COEFF (q_1[q_1_pointer--] * scale_factor[exp[i]]); \ + } else { \ + int code; \ + \ + code = bitstream_get (5); \ + \ + q_1_pointer = 1; \ + q_1[0] = q_1_2[code]; \ + q_1[1] = q_1_1[code]; \ + COEFF (q_1_0[code] * scale_factor[exp[i]]); \ + } \ + \ + case -2: \ + if (q_2_pointer >= 0) { \ + COEFF (q_2[q_2_pointer--] * scale_factor[exp[i]]); \ + } else { \ + int code; \ + \ + code = bitstream_get (7); \ + \ + q_2_pointer = 1; \ + q_2[0] = q_2_2[code]; \ + q_2[1] = q_2_1[code]; \ + COEFF (q_2_0[code] * scale_factor[exp[i]]); \ + } \ + \ + case 3: \ + COEFF (q_3[bitstream_get (3)] * scale_factor[exp[i]]); \ + \ + case -3: \ + if (q_4_pointer == 0) { \ + q_4_pointer = -1; \ + COEFF (q_4 * scale_factor[exp[i]]); \ + } else { \ + int code; \ + \ + code = bitstream_get (7); \ + \ + q_4_pointer = 0; \ + q_4 = q_4_1[code]; \ + COEFF (q_4_0[code] * scale_factor[exp[i]]); \ + } \ + \ + case 4: \ + COEFF (q_5[bitstream_get (4)] * scale_factor[exp[i]]); \ + \ + default: \ + COEFF (((int16_t)(bitstream_get(bap[i]) << (16 - bap[i]))) * \ + scale_factor[exp[i]]); \ + } + +#define CHANNEL_COEFF(val) \ + coeff[i++] = val; \ + continue; + +#define CHANNEL_DITHER(val) \ + if (dither) { \ + coeff[i++] = dither_gen () * val; \ + continue; \ + } else { \ + coeff[i++] = 0; \ + continue; \ + } + +static uint16_t lfsr_state = 1; + +static inline int16_t dither_gen(void) +{ + int16_t state; + + state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8); + + lfsr_state = (uint16_t) state; + + return ((state * (int) (LEVEL_3DB * 256)) >> 8); +} + +static void coeff_get (float * coeff, uint8_t * exp, int8_t * bap, + int dither, int end) { - int i, chaninfo; - uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc; + int i; + + i = 0; + while (i < end) + GET_COEFF (CHANNEL_COEFF, CHANNEL_DITHER); +} + +#define COUPLING_COEFF(val) \ + cplcoeff = val; \ + break; + +#define COUPLING_DITHER(val) \ + cplcoeff = val; \ + for (ch = 0; ch < nfchans; ch++) \ + if (state->chincpl[ch]) { \ + if (dithflag[ch]) \ + samples[ch][i] = \ + state->cplco[ch][bnd] * dither_gen () * cplcoeff; \ + else \ + samples[ch][i] = 0; \ + } \ + i++; \ + continue; + +int ac3_block (ac3_state_t * state) +{ + static const uint8_t nfchans_tbl[8] = {2, 1, 2, 3, 3, 4, 4, 5}; + static int rematrix_band[4] = {25, 37, 61, 253}; + int i, nfchans, chaninfo; + uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl; + uint8_t blksw[5], dithflag[5]; + + nfchans = nfchans_tbl[state->acmod]; - for (i = 0; i < state->nfchans; i++) - audblk->blksw[i] = bitstream_get (1); + for (i = 0; i < nfchans; i++) + blksw[i] = bitstream_get (1); - for (i = 0; i < state->nfchans; i++) - audblk->dithflag[i] = bitstream_get (1); + for (i = 0; i < nfchans; i++) + dithflag[i] = bitstream_get (1); - chaninfo = (state->acmod) ? 0 : 1; + chaninfo = !(state->acmod); do { if (bitstream_get (1)) // dynrnge bitstream_get (8); // dynrng } while (chaninfo--); if (bitstream_get (1)) { // cplstre - audblk->cplinu = bitstream_get (1); - if (audblk->cplinu) { - for (i = 0; i < state->nfchans; i++) - audblk->chincpl[i] = bitstream_get (1); - if (state->acmod == 0x2) - audblk->phsflginu = bitstream_get (1); - audblk->cplbegf = bitstream_get (4); - audblk->cplendf = bitstream_get (4); - - audblk->cplstrtmant = audblk->cplbegf * 12 + 37; - audblk->cplendmant = audblk->cplendf * 12 + 73; - audblk->ncplsubnd = audblk->cplendf + 3 - audblk->cplbegf; - audblk->ncplbnd = audblk->ncplsubnd; - - for(i = 1; i< audblk->ncplsubnd; i++) { - audblk->cplbndstrc[i] = bitstream_get (1); - audblk->ncplbnd -= audblk->cplbndstrc[i]; + state->cplinu = bitstream_get (1); + if (state->cplinu) { + static int bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44, + 45, 45, 46, 46, 47, 47, 48, 48}; + int cplbegf; + int cplendf; + int ncplsubnd; + + for (i = 0; i < nfchans; i++) + state->chincpl[i] = bitstream_get (1); + switch (state->acmod) { + case 0: case 1: + return 1; + case 2: + state->phsflginu = bitstream_get (1); } + cplbegf = bitstream_get (4); + cplendf = bitstream_get (4); + + if (cplendf + 3 - cplbegf < 0) + return 1; + state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf; + state->cplstrtbnd = bndtab[cplbegf]; + state->cplstrtmant = cplbegf * 12 + 37; + state->cplendmant = cplendf * 12 + 73; + + for (i = 0; i < ncplsubnd - 1; i++) { + state->cplbndstrc[i] = bitstream_get (1); + state->ncplbnd -= state->cplbndstrc[i]; + } + state->cplbndstrc[i] = 0; // last value is a sentinel } } - if (audblk->cplinu) { + if (state->cplinu) { int j, cplcoe; cplcoe = 0; - for (i = 0; i < state->nfchans; i++) - if (audblk->chincpl[i]) + for (i = 0; i < nfchans; i++) + if (state->chincpl[i]) if (bitstream_get (1)) { // cplcoe + int mstrcplco, cplcoexp, cplcomant; + cplcoe = 1; - audblk->mstrcplco[i] = bitstream_get (2); - for (j = 0; j < audblk->ncplbnd; j++) { - audblk->cplcoexp[i][j] = bitstream_get (4); - audblk->cplcomant[i][j] = bitstream_get (4); + mstrcplco = 3 * bitstream_get (2); + for (j = 0; j < state->ncplbnd; j++) { + cplcoexp = bitstream_get (4); + cplcomant = bitstream_get (4); + if (cplcoexp == 15) + cplcomant <<= 14; + else + cplcomant = (cplcomant | 0x10) << 13; + state->cplco[i][j] = + cplcomant * scale_factor[cplcoexp + mstrcplco]; } } - if ((state->acmod == 0x2) && audblk->phsflginu && cplcoe) - for (j = 0; j < audblk->ncplbnd; j++) - audblk->phsflg[j] = bitstream_get (1); + if ((state->acmod == 2) && state->phsflginu && cplcoe) + for (j = 0; j < state->ncplbnd; j++) + if (bitstream_get (1)) // phsflg + state->cplco[1][j] = -state->cplco[1][j]; } - if ((state->acmod == 0x2) && (bitstream_get (1))) { // rematstr - if ((audblk->cplbegf > 2) || (audblk->cplinu == 0)) - for (i = 0; i < 4; i++) - audblk->rematflg[i] = bitstream_get (1); - else if ((audblk->cplbegf == 0) && audblk->cplinu) - for (i = 0; i < 2; i++) - audblk->rematflg[i] = bitstream_get (1); - else if ((audblk->cplbegf <= 2) && audblk->cplinu) - for(i = 0; i < 3; i++) - audblk->rematflg[i] = bitstream_get (1); + if ((state->acmod == 2) && (bitstream_get (1))) { // rematstr + int end; + + end = (state->cplinu) ? state->cplstrtmant : 253; + i = 0; + do + state->rematflg[i] = bitstream_get (1); + while (rematrix_band[i++] < end); } cplexpstr = EXP_REUSE; lfeexpstr = EXP_REUSE; - if (audblk->cplinu) + if (state->cplinu) cplexpstr = bitstream_get (2); - for (i = 0; i < state->nfchans; i++) + for (i = 0; i < nfchans; i++) chexpstr[i] = bitstream_get (2); if (state->lfeon) lfeexpstr = bitstream_get (1); - for (i = 0; i < state->nfchans; i++) + for (i = 0; i < nfchans; i++) if (chexpstr[i] != EXP_REUSE) { - if (audblk->cplinu && audblk->chincpl[i]) - audblk->endmant[i] = audblk->cplstrtmant; + if (state->cplinu && state->chincpl[i]) + state->endmant[i] = state->cplstrtmant; else { - audblk->chbwcod[i] = bitstream_get (6); - audblk->endmant[i] = audblk->chbwcod[i] * 3 + 73; + int chbwcod; + + chbwcod = bitstream_get (6); + if (chbwcod > 60) + return 1; + state->endmant[i] = chbwcod * 3 + 73; } } @@ -318,103 +484,97 @@ int parse_audblk (ac3_state_t * state, audblk_t * audblk) int cplabsexp, ncplgrps; do_bit_alloc = 1; - ncplgrps = ((audblk->cplendmant - audblk->cplstrtmant) / + ncplgrps = ((state->cplendmant - state->cplstrtmant) / (3 << (cplexpstr - 1))); cplabsexp = bitstream_get (4) << 1; if (parse_exponents (cplexpstr, ncplgrps, cplabsexp, - audblk->cpl_exp + audblk->cplstrtmant)) + state->cpl_exp + state->cplstrtmant)) return 1; } - for (i = 0; i < state->nfchans; i++) + for (i = 0; i < nfchans; i++) if (chexpstr[i] != EXP_REUSE) { int grp_size, nchgrps; do_bit_alloc = 1; - grp_size = 3 * (1 << (chexpstr[i] - 1)); - nchgrps = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size; - audblk->fbw_exp[i][0] = bitstream_get (4); - if (parse_exponents (chexpstr[i], nchgrps, audblk->fbw_exp[i][0], - audblk->fbw_exp[i] + 1)) + grp_size = 3 << (chexpstr[i] - 1); + nchgrps = (state->endmant[i] + grp_size - 4) / grp_size; + state->fbw_exp[i][0] = bitstream_get (4); + if (parse_exponents (chexpstr[i], nchgrps, state->fbw_exp[i][0], + state->fbw_exp[i] + 1)) return 1; bitstream_get (2); // gainrng } if (lfeexpstr != EXP_REUSE) { do_bit_alloc = 1; - audblk->lfe_exp[0] = bitstream_get (4); - if (parse_exponents (lfeexpstr, 2, audblk->lfe_exp[0], - audblk->lfe_exp + 1)) + state->lfe_exp[0] = bitstream_get (4); + if (parse_exponents (lfeexpstr, 2, state->lfe_exp[0], + state->lfe_exp + 1)) return 1; } if (bitstream_get (1)) { // baie do_bit_alloc = 1; - audblk->sdcycod = bitstream_get (2); - audblk->fdcycod = bitstream_get (2); - audblk->sgaincod = bitstream_get (2); - audblk->dbpbcod = bitstream_get (2); - audblk->floorcod = bitstream_get (3); + state->sdcycod = bitstream_get (2); + state->fdcycod = bitstream_get (2); + state->sgaincod = bitstream_get (2); + state->dbpbcod = bitstream_get (2); + state->floorcod = bitstream_get (3); } if (bitstream_get (1)) { //snroffste do_bit_alloc = 1; - audblk->csnroffst = bitstream_get (6); - if (audblk->cplinu) { - audblk->cplba.fsnroffst = bitstream_get (4); - audblk->cplba.fgaincod = bitstream_get (3); + state->csnroffst = bitstream_get (6); + if (state->cplinu) { + state->cplba.fsnroffst = bitstream_get (4); + state->cplba.fgaincod = bitstream_get (3); } - for (i = 0; i < state->nfchans; i++) { - audblk->ba[i].fsnroffst = bitstream_get (4); - audblk->ba[i].fgaincod = bitstream_get (3); + for (i = 0; i < nfchans; i++) { + state->ba[i].fsnroffst = bitstream_get (4); + state->ba[i].fgaincod = bitstream_get (3); } if (state->lfeon) { - audblk->lfeba.fsnroffst = bitstream_get (4); - audblk->lfeba.fgaincod = bitstream_get (3); + state->lfeba.fsnroffst = bitstream_get (4); + state->lfeba.fgaincod = bitstream_get (3); } } - if ((audblk->cplinu) && (bitstream_get (1))) { // cplleake + if ((state->cplinu) && (bitstream_get (1))) { // cplleake do_bit_alloc = 1; - audblk->cplfleak = bitstream_get (3); - audblk->cplsleak = bitstream_get (3); + state->cplfleak = 2304 - (bitstream_get (3) << 8); + state->cplsleak = 2304 - (bitstream_get (3) << 8); } if (bitstream_get (1)) { // deltbaie do_bit_alloc = 1; - if (audblk->cplinu) - audblk->cplba.deltbae = bitstream_get (2); - for (i = 0; i < state->nfchans; i++) - audblk->ba[i].deltbae = bitstream_get (2); - if (audblk->cplinu && (audblk->cplba.deltbae == DELTA_BIT_NEW) && - parse_deltba (audblk->cplba.deltba)) + if (state->cplinu) + state->cplba.deltbae = bitstream_get (2); + for (i = 0; i < nfchans; i++) + state->ba[i].deltbae = bitstream_get (2); + if (state->cplinu && (state->cplba.deltbae == DELTA_BIT_NEW) && + parse_deltba (state->cplba.deltba)) return 1; - for (i = 0; i < state->nfchans; i++) - if ((audblk->ba[i].deltbae == DELTA_BIT_NEW) && - parse_deltba (audblk->ba[i].deltba)) + for (i = 0; i < nfchans; i++) + if ((state->ba[i].deltbae == DELTA_BIT_NEW) && + parse_deltba (state->ba[i].deltba)) return 1; } if (do_bit_alloc) { - if (zero_snr_offsets (state, audblk)) { - memset (audblk->cpl_bap, 0, sizeof (audblk->cpl_bap)); - memset (audblk->fbw_bap, 0, sizeof (audblk->fbw_bap)); - memset (audblk->lfe_bap, 0, sizeof (audblk->lfe_bap)); + if (zero_snr_offsets (nfchans, state)) { + memset (state->cpl_bap, 0, sizeof (state->cpl_bap)); + memset (state->fbw_bap, 0, sizeof (state->fbw_bap)); + memset (state->lfe_bap, 0, sizeof (state->lfe_bap)); } else { - static int bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44, - 45, 45, 46, 46, 47, 47, 48, 48}; - - if (audblk->cplinu) - bit_allocate (state->fscod, audblk, &audblk->cplba, - bndtab[audblk->cplbegf], audblk->cplstrtmant, - audblk->cplendmant, - 2304 - (audblk->cplfleak << 8), - 2304 - (audblk->cplsleak << 8), - audblk->cpl_exp, audblk->cpl_bap); - for (i = 0; i < state->nfchans; i++) - bit_allocate (state->fscod, audblk, audblk->ba + i, 0, 0, - audblk->endmant[i], 0, 0, - audblk->fbw_exp[i], audblk->fbw_bap[i]); + if (state->cplinu) + bit_allocate (state, &state->cplba, state->cplstrtbnd, + state->cplstrtmant, state->cplendmant, + state->cplfleak, state->cplsleak, + state->cpl_exp, state->cpl_bap); + for (i = 0; i < nfchans; i++) + bit_allocate (state, state->ba + i, 0, 0, state->endmant[i], + 0, 0, state->fbw_exp[i], state->fbw_bap[i]); if (state->lfeon) { - audblk->lfeba.deltbae = DELTA_BIT_NONE; - bit_allocate (state->fscod, audblk, &audblk->lfeba, 0, 0, 7, - 0, 0, audblk->lfe_exp, audblk->lfe_bap); + state->lfeba.deltbae = DELTA_BIT_NONE; + bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0, + state->lfe_exp, state->lfe_bap); } } } @@ -425,6 +585,101 @@ int parse_audblk (ac3_state_t * state, audblk_t * audblk) bitstream_get (8); } - stats_print_audblk(state,audblk); + q_1_pointer = q_2_pointer = q_4_pointer = -1; + done_cpl = 0; + + for (i = 0; i < nfchans; i++) { + int j; + + coeff_get (samples[i], state->fbw_exp[i], state->fbw_bap[i], + dithflag[i], state->endmant[i]); + + if (state->cplinu && state->chincpl[i]) { + if (!done_cpl) { + int i, i_end, bnd, sub_bnd, ch; + float cplcoeff; + + done_cpl = 1; + +#define bap state->cpl_bap +#define exp state->cpl_exp + + sub_bnd = bnd = 0; + i = state->cplstrtmant; + while (i < state->cplendmant) { + i_end = i + 12; + while (state->cplbndstrc[sub_bnd++]) + i_end += 12; + + while (i < i_end) { + GET_COEFF (COUPLING_COEFF, COUPLING_DITHER); + for (ch = 0; ch < nfchans; ch++) + if (state->chincpl[ch]) + samples[ch][i] = + state->cplco[ch][bnd] * cplcoeff; + i++; + } + bnd++; + } + +#undef bap +#undef exp + } + j = state->cplendmant; + } else + j = state->endmant[i]; + for (; j < 256; j++) + samples[i][j] = 0; + } + + if (state->acmod == 2) { + int j, end, band; + + end = ((state->endmant[0] < state->endmant[1]) ? + state->endmant[0] : state->endmant[1]); + + i = 0; + j = 13; + do { + if (!state->rematflg[i]) { + j = rematrix_band[i++]; + continue; + } + band = rematrix_band[i++]; + if (band > end) + band = end; + do { + float tmp0, tmp1; + + tmp0 = samples[0][j]; + tmp1 = samples[1][j]; + samples[0][j] = tmp0 + tmp1; + samples[1][j] = tmp0 - tmp1; + } while (++j < band); + } while (j < end); + } + + if (state->lfeon) { + coeff_get (samples[5], state->lfe_exp, state->lfe_bap, 0, 7); +#if 0 + for (i = 7; i < 256; i++) + samples[5][i] = 0; +#endif + } + + for (i = 0; i < nfchans; i++) + if (blksw[i]) + imdct_256 (samples[i], delay[i]); + else + imdct_512 (samples[i], delay[i]); + +#if 0 + if (state->lfeon) + imdct_512 (samples[5], delay[5]); +#endif + + downmix (*samples, state->acmod, state->output, state->level, state->bias, + state->clev, state->slev); + return 0; } diff --git a/src/libac3/parse.h b/src/libac3/parse.h deleted file mode 100644 index 39b5d8a2a..000000000 --- a/src/libac3/parse.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * parse.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -int parse_syncinfo(uint8_t * buf, int * sample_rate, int * bit_rate); -int parse_audblk(ac3_state_t *state,audblk_t *audblk); -int parse_bsi(ac3_state_t *state, uint8_t * buf); diff --git a/src/libac3/rematrix.c b/src/libac3/rematrix.c deleted file mode 100644 index 7098f0526..000000000 --- a/src/libac3/rematrix.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * rematrix.c - * - * Copyright (C) Aaron Holtzman - July 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -#include -#include -#include "ac3.h" -#include "ac3_internal.h" - - -#include "decode.h" -#include "rematrix.h" - -struct rematrix_band_s -{ - uint32_t start; - uint32_t end; -}; - -struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}}; - -static inline uint32_t min(uint32_t a,uint32_t b); - -static inline uint32_t -min(uint32_t a,uint32_t b) -{ - return (a < b ? a : b); -} - -/* This routine simply does stereo rematixing for the 2 channel - * stereo mode */ -void rematrix(audblk_t *audblk, stream_samples_t samples) -{ - uint32_t num_bands; - uint32_t start; - uint32_t end; - uint32_t i,j; - float left,right; - - if(!audblk->cplinu || audblk->cplbegf > 2) - num_bands = 4; - else if (audblk->cplbegf > 0) - num_bands = 3; - else - num_bands = 2; - - for(i=0;i < num_bands; i++) { - if(!audblk->rematflg[i]) - continue; - - start = rematrix_band[i].start; - end = min(rematrix_band[i].end ,12 * audblk->cplbegf + 36); - - for(j=start;j < end; j++) { - left = samples[0][j] + samples[1][j]; - right = samples[0][j] - samples[1][j]; - samples[0][j] = left; - samples[1][j] = right; - } - } -} diff --git a/src/libac3/rematrix.h b/src/libac3/rematrix.h deleted file mode 100644 index 0be6528f6..000000000 --- a/src/libac3/rematrix.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * rematrix.h - * - * Copyright (C) Aaron Holtzman - July 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - */ - -void rematrix(audblk_t *audblk, stream_samples_t samples); diff --git a/src/libac3/sanity_check.c b/src/libac3/sanity_check.c deleted file mode 100644 index 199fe6b4c..000000000 --- a/src/libac3/sanity_check.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * sanity_check.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include "ac3.h" -#include "ac3_internal.h" -#include "sanity_check.h" - - -void -sanity_check_init(ac3_state_t * state, audblk_t *audblk) -{ - audblk->magic1 = AC3_MAGIC_NUMBER; - audblk->magic2 = AC3_MAGIC_NUMBER; - audblk->magic3 = AC3_MAGIC_NUMBER; -} - -void -sanity_check(ac3_state_t * state, audblk_t *audblk) -{ - int i; - - if(audblk->magic1 != AC3_MAGIC_NUMBER) - { - fprintf(stderr,"\n** Sanity check failed -- audblk magic number 1 **"); - error_flag = 1; - } - - if(audblk->magic2 != AC3_MAGIC_NUMBER) - { - fprintf(stderr,"\n** Sanity check failed -- audblk magic number 2 **"); - error_flag = 1; - } - - if(audblk->magic3 != AC3_MAGIC_NUMBER) - { - fprintf(stderr,"\n** Sanity check failed -- audblk magic number 3 **"); - error_flag = 1; - } - - for(i = 0;i < 5 ; i++) - { - if (audblk->fbw_exp[i][255] !=0 || audblk->fbw_exp[i][254] !=0 || - audblk->fbw_exp[i][253] !=0) - { - fprintf(stderr,"\n** Sanity check failed -- fbw_exp out of bounds **"); - error_flag = 1; - } - - if (audblk->fbw_bap[i][255] !=0 || audblk->fbw_bap[i][254] !=0 || - audblk->fbw_bap[i][253] !=0) - { - fprintf(stderr,"\n** Sanity check failed -- fbw_bap out of bounds **"); - error_flag = 1; - } - - } - - if (audblk->cpl_exp[255] !=0 || audblk->cpl_exp[254] !=0 || - audblk->cpl_exp[253] !=0) - { - fprintf(stderr,"\n** Sanity check failed -- cpl_exp out of bounds **"); - error_flag = 1; - } - - if (audblk->cpl_bap[255] !=0 || audblk->cpl_bap[254] !=0 || - audblk->cpl_bap[253] !=0) - { - fprintf(stderr,"\n** Sanity check failed -- cpl_bap out of bounds **"); - error_flag = 1; - } - - if (audblk->cplmant[255] !=0 || audblk->cplmant[254] !=0 || - audblk->cplmant[253] !=0) - { - fprintf(stderr,"\n** Sanity check failed -- cpl_mant out of bounds **"); - error_flag = 1; - } - - if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2))) - { - fprintf(stderr,"\n** Sanity check failed -- cpl params inconsistent **"); - error_flag = 1; - } - - for(i=0; i < state->nfchans; i++) - { - if((audblk->chincpl[i] == 0) && (audblk->chbwcod[i] > 60)) - { - fprintf(stderr,"\n** Sanity check failed -- chbwcod too big **"); - error_flag = 1; - } - } - - return; -} diff --git a/src/libac3/sanity_check.h b/src/libac3/sanity_check.h deleted file mode 100644 index e098aebce..000000000 --- a/src/libac3/sanity_check.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * sanity_check.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define AC3_MAGIC_NUMBER 0xdeadbeef - -void sanity_check_init(ac3_state_t * state, audblk_t *audblk); -void sanity_check(ac3_state_t * state, audblk_t *audblk); diff --git a/src/libac3/stats.c b/src/libac3/stats.c deleted file mode 100644 index 7f73ceb62..000000000 --- a/src/libac3/stats.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * stats.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include "config.h" -#include "ac3.h" -#include "ac3_internal.h" - - -#include "decode.h" -#include "stats.h" -#include "debug.h" - - -struct mixlev_s -{ - float clev; - char *desc; -}; - -static const struct mixlev_s cmixlev_tbl[4] = -{ - {0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"}, - {0.500, "(-6.0 dB)"}, {1.0, "Invalid"} -}; - -static const struct mixlev_s smixlev_tbl[4] = -{ - {0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"}, - { 0.0, "off "}, { 1.0, "Invalid"} -}; - -void stats_print_banner(ac3_state_t * state) -{ - fprintf(stdout,"%d.%d Mode\n",state->nfchans,state->lfeon); -} - -void stats_print_syncinfo(ac3_state_t * state) -{ - dprintf("(syncinfo) "); - - switch (state->fscod) - { - case 2: - dprintf("32 KHz "); - break; - case 1: - dprintf("44.1 KHz "); - break; - case 0: - dprintf("48 KHz "); - break; - default: - dprintf("Invalid sampling rate "); - break; - } -} - -void stats_print_bsi(ac3_state_t * state) -{ - dprintf("(bsi) "); - dprintf(" %d.%d Mode ",state->nfchans,state->lfeon); - if ((state->acmod & 0x1) && (state->acmod != 0x1)) - dprintf(" Centre Mix Level %s ",cmixlev_tbl[state->cmixlev].desc); - if (state->acmod & 0x4) - dprintf(" Sur Mix Level %s ",smixlev_tbl[state->cmixlev].desc); - dprintf("\n"); - -} - -char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "}; - -void stats_print_audblk(ac3_state_t * state,audblk_t *audblk) -{ - uint32_t i; - - dprintf("(audblk) "); - dprintf("%s ",audblk->cplinu ? "cpl on " : "cpl off"); - dprintf("%s ",audblk->phsflginu? "phsflg " : " "); - dprintf("["); - for(i=0;infchans;i++) - dprintf("%1d",audblk->blksw[i]); - dprintf("]"); - - dprintf("\n"); -} diff --git a/src/libac3/stats.h b/src/libac3/stats.h deleted file mode 100644 index a87911888..000000000 --- a/src/libac3/stats.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * stats.h - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -void stats_print_syncinfo(ac3_state_t * state); -void stats_print_bsi(ac3_state_t * state); -void stats_print_audblk(ac3_state_t * state,audblk_t *audblk); -void stats_print_banner(ac3_state_t * state); diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c index 46ac1b8a3..8249618f6 100644 --- a/src/libac3/xine_decoder.c +++ b/src/libac3/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.10 2001/06/09 17:07:21 guenter Exp $ + * $Id: xine_decoder.c,v 1.11 2001/07/10 21:50:31 guenter Exp $ * * stuff needed to turn libac3 into a xine decoder plugin */ @@ -36,11 +36,14 @@ #include "audio_out.h" #include "ac3.h" +#include "ac3_internal.h" #include "buffer.h" #include "xine_internal.h" #define FRAME_SIZE 4096 +stream_samples_t samples; + /* int ac3file; */ typedef struct ac3dec_decoder_s { @@ -54,10 +57,20 @@ typedef struct ac3dec_decoder_s { int frame_length, frame_todo; uint16_t syncword; + ac3_state_t ac3_state; + int ac3_flags; + int ac3_bit_rate; + int ac3_sample_rate; + float ac3_level; + + int ac3_flags_map[8]; + int ao_flags_map[8]; + + int16_t samples [6 * 6 * 256]; + ao_functions_t *audio_out; int audio_caps; int bypass_mode; - int max_num_channels; int output_sampling_rate; int output_open; int output_mode; @@ -72,6 +85,7 @@ int ac3dec_can_handle (audio_decoder_t *this_gen, int buf_type) { void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; + /* int i; */ this->audio_out = audio_out; this->audio_caps = audio_out->get_capabilities(audio_out); @@ -91,31 +105,94 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { else { this->bypass_mode = 0; + this->ac3_flags_map[AC3_MONO] = AC3_MONO; + this->ac3_flags_map[AC3_STEREO] = AC3_STEREO; + this->ac3_flags_map[AC3_3F] = AC3_STEREO; + this->ac3_flags_map[AC3_2F1R] = AC3_STEREO; + this->ac3_flags_map[AC3_3F1R] = AC3_STEREO; + this->ac3_flags_map[AC3_2F2R] = AC3_STEREO; + this->ac3_flags_map[AC3_3F2R] = AC3_STEREO; + + this->ao_flags_map[AC3_MONO] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_STEREO] = AO_CAP_MODE_STEREO; + this->ao_flags_map[AC3_3F] = AO_CAP_MODE_STEREO; + this->ao_flags_map[AC3_2F1R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[AC3_3F1R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_STEREO; + this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_STEREO; + /* find best mode */ - if (this->audio_caps & AO_CAP_MODE_5CHANNEL) - this->max_num_channels = 5; - else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) - this->max_num_channels = 4; - else if (this->audio_caps & AO_CAP_MODE_STEREO) - this->max_num_channels = 2; - else { + if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { + + this->ac3_flags_map[AC3_2F2R] = AC3_2F2R; + this->ac3_flags_map[AC3_3F2R] = AC3_3F2R; + this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) { + + this->ac3_flags_map[AC3_2F2R] = AC3_2F2R; + this->ac3_flags_map[AC3_3F2R] = AC3_2F2R; + + this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_4CHANNEL; + + /* else if (this->audio_caps & AO_CAP_MODE_STEREO) + defaults are ok */ + } else { printf ("HELP! a mono-only audio driver?!\n"); - this->max_num_channels = 1; + + this->ac3_flags_map[AC3_MONO] = AC3_MONO; + this->ac3_flags_map[AC3_STEREO] = AC3_MONO; + this->ac3_flags_map[AC3_3F] = AC3_MONO; + this->ac3_flags_map[AC3_2F1R] = AC3_MONO; + this->ac3_flags_map[AC3_3F1R] = AC3_MONO; + this->ac3_flags_map[AC3_2F2R] = AC3_MONO; + this->ac3_flags_map[AC3_3F2R] = AC3_MONO; + + this->ao_flags_map[AC3_MONO] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_STEREO] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_3F] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_2F1R] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_3F1R] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_MONO; + this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_MONO; } } + /* + for (i = 0; i<8; i++) + this->ac3_flags_map[i] |= AC3_ADJUST_LEVEL; +*/ /* ac3file = open ("test.ac3", O_CREAT); */ } +static inline int16_t blah (int32_t i) +{ + if (i > 0x43c07fff) + return 32767; + else if (i < 0x43bf8000) + return -32768; + else + return i - 0x43c00000; +} + +static inline void float_to_int (float * _f, int16_t * s16, int num_channels) { + int i; + int32_t * f = (int32_t *) _f; /* XXX assumes IEEE float format */ + + for (i = 0; i < 256; i++) { + s16[num_channels*i] = blah (f[i]); + } +} + void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; uint8_t *current = buf->content; uint8_t *end = buf->content + buf->size; - ac3_frame_t *ac3_frame=NULL; -/* int sampling_rate; */ int output_mode = AO_CAP_MODE_STEREO; uint8_t byte; @@ -123,7 +200,8 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (buf->decoder_info[0] == 0) return; - this->pts = buf->PTS; + if (buf->PTS) + this->pts = buf->PTS; while (current != end) { @@ -144,7 +222,7 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->frame_buffer[0] = 0x0b; this->frame_buffer[1] = 0x77; - this->sync_todo = 4; + this->sync_todo = 5; this->frame_ptr = this->frame_buffer+2; } } else { @@ -152,8 +230,12 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->sync_todo--; if (this->sync_todo==0) { - this->frame_length = ac3_frame_length (this->frame_buffer); - this->frame_todo = this->frame_length - 6; + + this->frame_length = ac3_syncinfo (this->frame_buffer, + &this->ac3_flags, + &this->ac3_sample_rate, + &this->ac3_bit_rate); + this->frame_todo = this->frame_length - 7; } } @@ -175,33 +257,69 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { */ if (!this->bypass_mode) { + + int ac3_output_flags, i; + float level = this->ac3_level; /* oki, decode this frame in software*/ /* write (ac3file, this->frame_buffer, this->frame_length); */ - ac3_frame = ac3_decode_frame (this->frame_buffer, this->max_num_channels); - /* determine output mode */ - switch (ac3_frame->num_channels) { - case 1: - output_mode = AO_CAP_MODE_MONO; - break; - case 2: - output_mode = AO_CAP_MODE_STEREO; - break; - case 4: - output_mode = AO_CAP_MODE_4CHANNEL; - break; - case 5: - output_mode = AO_CAP_MODE_5CHANNEL; - break; + + ac3_output_flags = this->ac3_flags_map[this->ac3_flags & AC3_CHANNEL_MASK]; + + if (ac3_frame (&this->ac3_state, + this->frame_buffer, + &ac3_output_flags, + &level, 384)) { + printf ("libac3: ac3_frame error\n"); + goto error; } + output_mode = this->ao_flags_map[ac3_output_flags]; + + /* + * decode ac3 and convert/interleave samples + */ + + for (i = 0; i < 6; i++) { + if (ac3_block (&this->ac3_state)) { + printf ("libac3: ac3_block error\n"); + goto error; + } + + switch (output_mode) { + case AO_CAP_MODE_MONO: + float_to_int (*samples, this->samples+i*256, 1); + break; + case AO_CAP_MODE_STEREO: + float_to_int (samples[0], this->samples+i*256*2, 2); + float_to_int (samples[1], this->samples+1+i*256*2, 2); + break; + case AO_CAP_MODE_4CHANNEL: + float_to_int (samples[0], this->samples+i*256*4, 4); + float_to_int (samples[1], this->samples+1+i*256*4, 4); + float_to_int (samples[2], this->samples+2+i*256*4, 4); + float_to_int (samples[3], this->samples+3+i*256*4, 4); + break; + case AO_CAP_MODE_5CHANNEL: + float_to_int (samples[0], this->samples+i*256*5, 5); + float_to_int (samples[1], this->samples+1+i*256*5, 5); + float_to_int (samples[2], this->samples+2+i*256*5, 5); + float_to_int (samples[3], this->samples+3+i*256*5, 5); + float_to_int (samples[4], this->samples+4+i*256*5, 5); + break; + default: + printf ("libac3: help - unsupported mode %08x\n", output_mode); + } + } + + /* output decoded samples */ if (!this->output_open - || (ac3_frame->sampling_rate != this->output_sampling_rate) + || (this->ac3_sample_rate != this->output_sampling_rate) || (output_mode != this->output_mode)) { if (this->output_open) @@ -209,19 +327,23 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->output_open = (this->audio_out->open (this->audio_out, 16, - ac3_frame->sampling_rate, + this->ac3_sample_rate, output_mode) == 1); - this->output_sampling_rate = ac3_frame->sampling_rate; + this->output_sampling_rate = this->ac3_sample_rate; this->output_mode = output_mode; } if (this->output_open) { + this->audio_out->write_audio_data (this->audio_out, - ac3_frame->audio_data, + this->samples, 256*6, this->pts); this->pts = 0; } + + error: + } else { /* @@ -229,8 +351,13 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { */ if (!this->output_open) { + + int sample_rate, bit_rate, flags; + + ac3_syncinfo (this->frame_buffer, &flags, &sample_rate, &bit_rate); + this->output_open = (this->audio_out->open (this->audio_out, 16, - ac3_sampling_rate(this->frame_buffer), + sample_rate, AO_CAP_MODE_AC3) == 1); this->output_mode = AO_CAP_MODE_AC3; } @@ -261,6 +388,8 @@ void ac3dec_close (audio_decoder_t *this_gen) { if (this->output_open) this->audio_out->close (this->audio_out); + this->output_open = 0; + /* close (ac3file); */ } @@ -283,6 +412,8 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t * this->audio_decoder.decode_data = ac3dec_decode_data; this->audio_decoder.close = ac3dec_close; this->audio_decoder.get_identifier = ac3dec_get_id; + + this->ac3_level = (float) cfg->lookup_int (cfg, "ac3_level", 100) / 100.0; return (audio_decoder_t *) this; } -- cgit v1.2.3