From 6bc7ac7c38396945c07fdc3764a2e88c3291278a Mon Sep 17 00:00:00 2001 From: Michel Kaempf Date: Tue, 18 Jan 2000 13:55:43 +0000 Subject: [PATCH] =?utf8?q?*=20Modification=20de=20l'input=20afin=20de=20sp?= =?utf8?q?awner=20un=20d=EF=BF=BDcodeur=20ac3=20lorsqu'un=20tel=20flux=20e?= =?utf8?q?st=20d=EF=BF=BDtect=EF=BF=BD=20;?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Impl�mentation du d�codeur ac3 ; * Il est rewlz(ac3dec) - 2h00 :-) --- Makefile | 9 +- include/ac3_bit_allocate.h | 1 + include/ac3_decoder.h | 321 +++++++++++ include/ac3_downmix.h | 1 + include/ac3_exponent.h | 5 + include/ac3_imdct.h | 2 + include/ac3_mantissa.h | 1 + include/ac3_parse.h | 4 + include/ac3_rematrix.h | 1 + include/input.h | 2 +- src/ac3_decoder/ac3_bit_allocate.c | 485 ++++++++++++++++ src/ac3_decoder/ac3_decoder.c | 46 +- src/ac3_decoder/ac3_downmix.c | 394 +++++++++++++ src/ac3_decoder/ac3_exponent.c | 126 ++++ src/ac3_decoder/ac3_imdct.c | 425 ++++++++++++++ src/ac3_decoder/ac3_mantissa.c | 481 ++++++++++++++++ src/ac3_decoder/ac3_parse.c | 892 +++++++++++++++++++++++++++++ src/ac3_decoder/ac3_rematrix.c | 75 +++ src/input/input.c | 38 +- src/input/input_ctrl.c | 15 + src/input/input_psi.c | 52 +- 21 files changed, 3339 insertions(+), 37 deletions(-) create mode 100644 include/ac3_bit_allocate.h create mode 100644 include/ac3_downmix.h create mode 100644 include/ac3_exponent.h create mode 100644 include/ac3_imdct.h create mode 100644 include/ac3_mantissa.h create mode 100644 include/ac3_parse.h create mode 100644 include/ac3_rematrix.h create mode 100644 src/ac3_decoder/ac3_bit_allocate.c create mode 100644 src/ac3_decoder/ac3_downmix.c create mode 100644 src/ac3_decoder/ac3_exponent.c create mode 100644 src/ac3_decoder/ac3_imdct.c create mode 100644 src/ac3_decoder/ac3_mantissa.c create mode 100644 src/ac3_decoder/ac3_parse.c create mode 100644 src/ac3_decoder/ac3_rematrix.c diff --git a/Makefile b/Makefile index ba68aabfa0..50e8121f72 100644 --- a/Makefile +++ b/Makefile @@ -176,7 +176,14 @@ video_output_obj = video_output/video_output.o \ video_output/video_$(video).o \ video_output/video_yuv_c.o -ac3_decoder_obj = ac3_decoder/ac3_decoder.o +ac3_decoder_obj = ac3_decoder/ac3_decoder.o \ + ac3_decoder/ac3_parse.o \ + ac3_decoder/ac3_exponent.o \ + ac3_decoder/ac3_bit_allocate.o \ + ac3_decoder/ac3_mantissa.o \ + ac3_decoder/ac3_rematrix.o \ + ac3_decoder/ac3_imdct.o \ + ac3_decoder/ac3_downmix.o audio_decoder_obj = audio_decoder/audio_decoder.o \ audio_decoder/audio_math.o diff --git a/include/ac3_bit_allocate.h b/include/ac3_bit_allocate.h new file mode 100644 index 0000000000..9332be6b32 --- /dev/null +++ b/include/ac3_bit_allocate.h @@ -0,0 +1 @@ +void bit_allocate( ac3dec_thread_t * ); diff --git a/include/ac3_decoder.h b/include/ac3_decoder.h index fb4add8af4..7f367b4f4f 100644 --- a/include/ac3_decoder.h +++ b/include/ac3_decoder.h @@ -3,6 +3,320 @@ * (c)1999 VideoLAN *****************************************************************************/ +/* Exponent strategy constants */ +#define EXP_REUSE (0) +#define EXP_D15 (1) +#define EXP_D25 (2) +#define EXP_D45 (3) + +/* Delta bit allocation constants */ +#define DELTA_BIT_REUSE (0) +#define DELTA_BIT_NEW (1) +#define DELTA_BIT_NONE (2) +#define DELTA_BIT_RESERVED (3) + +/* 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 syncinfo_s +{ + /* Sync word == 0x0B77 */ + /* u16 syncword; */ + /* crc for the first 5/8 of the sync block */ + /* u16 crc1; */ + /* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */ + u16 fscod; + /* Frame size code */ + u16 frmsizecod; + + /* Information not in the AC-3 bitstream, but derived */ + /* Frame size in 16 bit words */ + u16 frame_size; + /* Bit rate in kilobits */ + u16 bit_rate; + +} syncinfo_t; + +typedef struct bsi_s +{ + /* Bit stream identification == 0x8 */ + u16 bsid; + /* Bit stream mode */ + u16 bsmod; + /* Audio coding mode */ + u16 acmod; + /* If we're using the centre channel then */ + /* centre mix level */ + u16 cmixlev; + /* If we're using the surround channel then */ + /* surround mix level */ + u16 surmixlev; + /* If we're in 2/0 mode then */ + /* Dolby surround mix level - NOT USED - */ + u16 dsurmod; + /* Low frequency effects on */ + u16 lfeon; + /* Dialogue Normalization level */ + u16 dialnorm; + /* Compression exists */ + u16 compre; + /* Compression level */ + u16 compr; + /* Language code exists */ + u16 langcode; + /* Language code */ + u16 langcod; + /* Audio production info exists*/ + u16 audprodie; + u16 mixlevel; + u16 roomtyp; + /* If we're in dual mono mode (acmod == 0) then extra stuff */ + u16 dialnorm2; + u16 compr2e; + u16 compr2; + u16 langcod2e; + u16 langcod2; + u16 audprodi2e; + u16 mixlevel2; + u16 roomtyp2; + /* Copyright bit */ + u16 copyrightb; + /* Original bit */ + u16 origbs; + /* Timecode 1 exists */ + u16 timecod1e; + /* Timecode 1 */ + u16 timecod1; + /* Timecode 2 exists */ + u16 timecod2e; + /* Timecode 2 */ + u16 timecod2; + /* Additional bit stream info exists */ + u16 addbsie; + /* Additional bit stream length - 1 (in bytes) */ + u16 addbsil; + /* Additional bit stream information (max 64 bytes) */ + u8 addbsi[64]; + + /* Information not in the AC-3 bitstream, but derived */ + /* Number of channels (excluding LFE) + * Derived from acmod */ + u16 nfchans; + +} bsi_t; + +/* more pain */ +typedef struct audblk_s +{ + /* block switch bit indexed by channel num */ + u16 blksw[5]; + /* dither enable bit indexed by channel num */ + u16 dithflag[5]; + /* dynamic range gain exists */ + u16 dynrnge; + /* dynamic range gain */ + u16 dynrng; + /* if acmod==0 then */ + /* dynamic range 2 gain exists */ + u16 dynrng2e; + /* dynamic range 2 gain */ + u16 dynrng2; + /* coupling strategy exists */ + u16 cplstre; + /* coupling in use */ + u16 cplinu; + /* channel coupled */ + u16 chincpl[5]; + /* if acmod==2 then */ + /* Phase flags in use */ + u16 phsflginu; + /* coupling begin frequency code */ + u16 cplbegf; + /* coupling end frequency code */ + u16 cplendf; + /* coupling band structure bits */ + u16 cplbndstrc[18]; + /* Do coupling co-ords exist for this channel? */ + u16 cplcoe[5]; + /* Master coupling co-ordinate */ + u16 mstrcplco[5]; + /* Per coupling band coupling co-ordinates */ + u16 cplcoexp[5][18]; + u16 cplcomant[5][18]; + /* Phase flags for dual mono */ + u16 phsflg[18]; + /* Is there a rematrixing strategy */ + u16 rematstr; + /* Rematrixing bits */ + u16 rematflg[4]; + /* Coupling exponent strategy */ + u16 cplexpstr; + /* Exponent strategy for full bandwidth channels */ + u16 chexpstr[5]; + /* Exponent strategy for lfe channel */ + u16 lfeexpstr; + /* Channel bandwidth for independent channels */ + u16 chbwcod[5]; + /* The absolute coupling exponent */ + u16 cplabsexp; + /* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */ + u16 cplexps[18 * 12 / 3]; + /* Sanity checking constant */ + u32 magic2; + /* fbw channel exponents */ + u16 exps[5][252 / 3]; + /* channel gain range */ + u16 gainrng[5]; + /* low frequency exponents */ + u16 lfeexps[3]; + + /* Bit allocation info */ + u16 baie; + /* Slow decay code */ + u16 sdcycod; + /* Fast decay code */ + u16 fdcycod; + /* Slow gain code */ + u16 sgaincod; + /* dB per bit code */ + u16 dbpbcod; + /* masking floor code */ + u16 floorcod; + + /* SNR offset info */ + u16 snroffste; + /* coarse SNR offset */ + u16 csnroffst; + /* coupling fine SNR offset */ + u16 cplfsnroffst; + /* coupling fast gain code */ + u16 cplfgaincod; + /* fbw fine SNR offset */ + u16 fsnroffst[5]; + /* fbw fast gain code */ + u16 fgaincod[5]; + /* lfe fine SNR offset */ + u16 lfefsnroffst; + /* lfe fast gain code */ + u16 lfefgaincod; + + /* Coupling leak info */ + u16 cplleake; + /* coupling fast leak initialization */ + u16 cplfleak; + /* coupling slow leak initialization */ + u16 cplsleak; + + /* delta bit allocation info */ + u16 deltbaie; + /* coupling delta bit allocation exists */ + u16 cpldeltbae; + /* fbw delta bit allocation exists */ + u16 deltbae[5]; + /* number of cpl delta bit segments */ + u16 cpldeltnseg; + /* coupling delta bit allocation offset */ + u16 cpldeltoffst[8]; + /* coupling delta bit allocation length */ + u16 cpldeltlen[8]; + /* coupling delta bit allocation length */ + u16 cpldeltba[8]; + /* number of delta bit segments */ + u16 deltnseg[5]; + /* fbw delta bit allocation offset */ + u16 deltoffst[5][8]; + /* fbw delta bit allocation length */ + u16 deltlen[5][8]; + /* fbw delta bit allocation length */ + u16 deltba[5][8]; + + /* skip length exists */ + u16 skiple; + /* skip length */ + u16 skipl; + + /* channel mantissas */ +// u16 chmant[5][256]; + + /* coupling mantissas */ + float cplfbw[ 256 ]; +// u16 cplmant[256]; + + /* coupling mantissas */ +// u16 lfemant[7]; + + /* -- Information not in the bitstream, but derived thereof -- */ + + /* Number of coupling sub-bands */ + u16 ncplsubnd; + + /* Number of combined coupling sub-bands + * Derived from ncplsubnd and cplbndstrc */ + u16 ncplbnd; + + /* Number of exponent groups by channel + * Derived from strmant, endmant */ + u16 nchgrps[5]; + + /* Number of coupling exponent groups + * Derived from cplbegf, cplendf, cplexpstr */ + u16 ncplgrps; + + /* End mantissa numbers of fbw channels */ + u16 endmant[5]; + + /* Start and end mantissa numbers for the coupling channel */ + u16 cplstrtmant; + u16 cplendmant; + + /* Decoded exponent info */ + u16 fbw_exp[5][256]; + u16 cpl_exp[256]; + u16 lfe_exp[7]; + + /* Bit allocation pointer results */ + u16 fbw_bap[5][256]; + //FIXME figure out exactly how many entries there should be (253-37?) + u16 cpl_bap[256]; + u16 lfe_bap[7]; + +} audblk_t; + +/* 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. + */ + +typedef struct stream_coeffs_s +{ + float fbw[5][256]; + float lfe[256]; + +} stream_coeffs_t; + +typedef struct stream_samples_s +{ + float channel[6][256]; + +} stream_samples_t; + #define AC3DEC_FRAME_SIZE (2*256) /***************************************************************************** @@ -34,6 +348,13 @@ typedef struct ac3dec_thread_s */ unsigned int total_bits_read; + syncinfo_t syncinfo; + bsi_t bsi; + audblk_t audblk; + + stream_coeffs_t coeffs; + stream_samples_t samples; + /* * Output properties */ diff --git a/include/ac3_downmix.h b/include/ac3_downmix.h new file mode 100644 index 0000000000..41e135a7d6 --- /dev/null +++ b/include/ac3_downmix.h @@ -0,0 +1 @@ +void downmix( ac3dec_thread_t *, s16 * ); diff --git a/include/ac3_exponent.h b/include/ac3_exponent.h new file mode 100644 index 0000000000..0ff520f5e6 --- /dev/null +++ b/include/ac3_exponent.h @@ -0,0 +1,5 @@ +#define UNPACK_FBW 1 +#define UNPACK_CPL 2 +#define UNPACK_LFE 4 + +void exponent_unpack( ac3dec_thread_t * ); diff --git a/include/ac3_imdct.h b/include/ac3_imdct.h new file mode 100644 index 0000000000..c2c11d80f5 --- /dev/null +++ b/include/ac3_imdct.h @@ -0,0 +1,2 @@ +void imdct( ac3dec_thread_t * p_ac3dec ); +void imdct_init( void ); diff --git a/include/ac3_mantissa.h b/include/ac3_mantissa.h new file mode 100644 index 0000000000..fa93fe46ce --- /dev/null +++ b/include/ac3_mantissa.h @@ -0,0 +1 @@ +void mantissa_unpack( ac3dec_thread_t * ); diff --git a/include/ac3_parse.h b/include/ac3_parse.h new file mode 100644 index 0000000000..00d0f57fcf --- /dev/null +++ b/include/ac3_parse.h @@ -0,0 +1,4 @@ +void parse_syncinfo( ac3dec_thread_t * ); +void parse_bsi( ac3dec_thread_t * ); +void parse_audblk( ac3dec_thread_t * ); +void parse_auxdata( ac3dec_thread_t * ); diff --git a/include/ac3_rematrix.h b/include/ac3_rematrix.h new file mode 100644 index 0000000000..7d493006c0 --- /dev/null +++ b/include/ac3_rematrix.h @@ -0,0 +1 @@ +void rematrix( ac3dec_thread_t * ); diff --git a/include/input.h b/include/input.h index 743c27656d..140cf2ef9d 100644 --- a/include/input.h +++ b/include/input.h @@ -164,7 +164,7 @@ typedef struct #define MPEG2_VIDEO_ES 0x02 #define MPEG1_AUDIO_ES 0x03 #define MPEG2_AUDIO_ES 0x04 - +#define AC3_AUDIO_ES 0x81 /****************************************************************************** * program_descriptor_t diff --git a/src/ac3_decoder/ac3_bit_allocate.c b/src/ac3_decoder/ac3_bit_allocate.c new file mode 100644 index 0000000000..6dfc3c9fc1 --- /dev/null +++ b/src/ac3_decoder/ac3_bit_allocate.c @@ -0,0 +1,485 @@ +#include /* getpid() */ + +#include /* "intf_msg.h" */ +#include /* malloc(), free() */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_bit_allocate.h" + +/* +static inline s16 logadd(s16 a,s16 b); +static s16 calc_lowcomp(s16 a,s16 b0,s16 b1,s16 bin); +static inline u16 min(s16 a,s16 b); +static inline u16 max(s16 a,s16 b); +*/ +static void ba_compute_psd(s16 start, s16 end, s16 exps[], + s16 psd[], s16 bndpsd[]); + +static void ba_compute_excitation(s16 start, s16 end,s16 fgain, + s16 fastleak, s16 slowleak, s16 is_lfe, s16 bndpsd[], + s16 excite[]); +static void ba_compute_mask(s16 start, s16 end, u16 fscod, + u16 deltbae, u16 deltnseg, u16 deltoffst[], u16 deltba[], + u16 deltlen[], s16 excite[], s16 mask[]); +static void ba_compute_bap(s16 start, s16 end, s16 snroffset, + s16 psd[], s16 mask[], s16 bap[]); + +/* Misc LUTs for bit allocation process */ + +static s16 slowdec[] = { 0x0f, 0x11, 0x13, 0x15 }; +static s16 fastdec[] = { 0x3f, 0x53, 0x67, 0x7b }; +static s16 slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 }; +static s16 dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 }; + +static u16 floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 }; +static s16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 }; + + +static s16 bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, + 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, + 79, 85, 97, 109, 121, 133, 157, 181, 205, 229 }; + +static s16 bndsz[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, + 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 }; + +static s16 masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29, + 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, + 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, + 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, + 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 }; + + +static s16 latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039, + 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032, + 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c, + 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026, + 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021, + 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c, + 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018, + 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015, + 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012, + 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f, + 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d, + 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000}; + +static s16 hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0, + 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, + 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, + 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, + 0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420, + 0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, + 0x0840, 0x0840 }, + + { 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0, + 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, + 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, + 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0, + 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0, + 0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, + 0x0840, 0x0840 }, + + { 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0, + 0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, + 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390, + 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330, + 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310, + 0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440, + 0x0450, 0x04e0 }}; + + +static s16 baptab[] = { 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; + +static s16 sdecay; +static s16 fdecay; +static s16 sgain; +static s16 dbknee; +static s16 floor; +static s16 psd[256]; +static s16 bndpsd[256]; +static s16 excite[256]; +static s16 mask[256]; + +static __inline__ u16 max( s16 a, s16 b ) +{ + return( a > b ? a : b ); +} + +static __inline__ u16 min( s16 a, s16 b ) +{ + return( a < b ? a : b ); +} + +static __inline__ s16 logadd( s16 a, s16 b ) +{ + s16 c; + + if ( (c = a - b) >= 0 ) + { + return( a + latab[min(((c) >> 1), 255)] ); + } + else + { + return( b + latab[min(((-c) >> 1), 255)] ); + } +} + +static __inline__ s16 calc_lowcomp( s16 a, s16 b0, s16 b1, s16 bin ) +{ + if (bin < 7) + { + if ((b0 + 256) == b1) + a = 384; + else if (b0 > b1) + a = max(0, a - 64); + } + else if (bin < 20) + { + if ((b0 + 256) == b1) + a = 320; + else if (b0 > b1) + a = max(0, a - 64) ; + } + else + a = max(0, a - 128); + + return(a); +} + +void bit_allocate( ac3dec_thread_t * p_ac3dec ) +{ + u16 i; + s16 fgain; + s16 snroffset; + s16 start; + s16 end; + s16 fastleak; + s16 slowleak; + + /* Only perform bit_allocation if the exponents have changed or we + * have new sideband information */ + if (p_ac3dec->audblk.chexpstr[0] == 0 && p_ac3dec->audblk.chexpstr[1] == 0 && + p_ac3dec->audblk.chexpstr[2] == 0 && p_ac3dec->audblk.chexpstr[3] == 0 && + p_ac3dec->audblk.chexpstr[4] == 0 && p_ac3dec->audblk.cplexpstr == 0 && + p_ac3dec->audblk.lfeexpstr == 0 && p_ac3dec->audblk.baie == 0 && + p_ac3dec->audblk.snroffste == 0 && p_ac3dec->audblk.deltbaie == 0) + return; + + /* Do some setup before we do the bit alloc */ + sdecay = slowdec[p_ac3dec->audblk.sdcycod]; + fdecay = fastdec[p_ac3dec->audblk.fdcycod]; + sgain = slowgain[p_ac3dec->audblk.sgaincod]; + dbknee = dbpbtab[p_ac3dec->audblk.dbpbcod]; + floor = floortab[p_ac3dec->audblk.floorcod]; + + /* if all the SNR offset constants are zero then the whole block is zero */ + if(!p_ac3dec->audblk.csnroffst && !p_ac3dec->audblk.fsnroffst[0] && + !p_ac3dec->audblk.fsnroffst[1] && !p_ac3dec->audblk.fsnroffst[2] && + !p_ac3dec->audblk.fsnroffst[3] && !p_ac3dec->audblk.fsnroffst[4] && + !p_ac3dec->audblk.cplfsnroffst && !p_ac3dec->audblk.lfefsnroffst) + { + memset(p_ac3dec->audblk.fbw_bap,0,sizeof(u16) * 256 * 5); + memset(p_ac3dec->audblk.cpl_bap,0,sizeof(u16) * 256); + memset(p_ac3dec->audblk.lfe_bap,0,sizeof(u16) * 7); + return; + } + + for(i = 0; i < p_ac3dec->bsi.nfchans; i++) + { + start = 0; + end = p_ac3dec->audblk.endmant[i] ; + fgain = fastgain[p_ac3dec->audblk.fgaincod[i]]; + snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.fsnroffst[i]) << 2 ; + fastleak = 0; + slowleak = 0; + + ba_compute_psd(start, end, p_ac3dec->audblk.fbw_exp[i], psd, bndpsd); + + ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite); + +// if ( p_ac3dec->audblk.deltnseg[i] >= 8 ) +// fprintf( stderr, "ba debug: p_ac3dec->audblk.deltnseg[%i] == %i\n", i, p_ac3dec->audblk.deltnseg[i] ); + ba_compute_mask(start, end, p_ac3dec->syncinfo.fscod, p_ac3dec->audblk.deltbae[i], p_ac3dec->audblk.deltnseg[i], p_ac3dec->audblk.deltoffst[i], p_ac3dec->audblk.deltba[i], p_ac3dec->audblk.deltlen[i], excite, mask); + + ba_compute_bap(start, end, snroffset, psd, mask, p_ac3dec->audblk.fbw_bap[i]); + } + + if(p_ac3dec->audblk.cplinu) + { + start = p_ac3dec->audblk.cplstrtmant; + end = p_ac3dec->audblk.cplendmant; + fgain = fastgain[p_ac3dec->audblk.cplfgaincod]; + snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.cplfsnroffst) << 2 ; + fastleak = (p_ac3dec->audblk.cplfleak << 8) + 768; + slowleak = (p_ac3dec->audblk.cplsleak << 8) + 768; + + ba_compute_psd(start, end, p_ac3dec->audblk.cpl_exp, psd, bndpsd); + + ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite); + + ba_compute_mask(start, end, p_ac3dec->syncinfo.fscod, p_ac3dec->audblk.cpldeltbae, p_ac3dec->audblk.cpldeltnseg, p_ac3dec->audblk.cpldeltoffst, p_ac3dec->audblk.cpldeltba, p_ac3dec->audblk.cpldeltlen, excite, mask); + + ba_compute_bap(start, end, snroffset, psd, mask, p_ac3dec->audblk.cpl_bap); + } + + if(p_ac3dec->bsi.lfeon) + { + start = 0; + end = 7; + fgain = fastgain[p_ac3dec->audblk.lfefgaincod]; + snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.lfefsnroffst) << 2 ; + fastleak = 0; + slowleak = 0; + + ba_compute_psd(start, end, p_ac3dec->audblk.lfe_exp, psd, bndpsd); + + ba_compute_excitation(start, end , fgain, fastleak, slowleak, 1, bndpsd, excite); + + ba_compute_mask(start, end, p_ac3dec->syncinfo.fscod, 2, 0, 0, 0, 0, excite, mask); + + ba_compute_bap(start, end, snroffset, psd, mask, p_ac3dec->audblk.lfe_bap); + } +} + + +static void ba_compute_psd(s16 start, s16 end, s16 exps[], + s16 psd[], s16 bndpsd[]) +{ + int bin,i,j,k; + s16 lastbin = 0; + + /* Map the exponents into dBs */ + for (bin=start; bin lastbin); +} + +static void ba_compute_excitation(s16 start, s16 end,s16 fgain, + s16 fastleak, s16 slowleak, s16 is_lfe, s16 bndpsd[], + s16 excite[]) +{ +#if 1 + int bin; + s16 bndstrt; + s16 bndend; + s16 lowcomp = 0; + s16 begin = 0; + + /* Compute excitation function */ + bndstrt = masktab[start]; + bndend = masktab[end - 1] + 1; + + if (bndstrt == 0) /* For fbw and lfe channels */ + { + lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0); + excite[0] = bndpsd[0] - fgain - lowcomp; + lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1); + excite[1] = bndpsd[1] - fgain - lowcomp; + begin = 7 ; + + /* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */ + for (bin = 2; bin < 7; bin++) + { + if (!(is_lfe && (bin == 6))) + lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); + fastleak = bndpsd[bin] - fgain; + slowleak = bndpsd[bin] - sgain; + excite[bin] = fastleak - lowcomp; + + if (!(is_lfe && (bin == 6))) + { + if (bndpsd[bin] <= bndpsd[bin+1]) + { + begin = bin + 1 ; + break; + } + } + } + + for (bin = begin; bin < min(bndend, 22); bin++) + { + if (!(is_lfe && (bin == 6))) + lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); + fastleak -= fdecay ; + fastleak = max(fastleak, bndpsd[bin] - fgain); + slowleak -= sdecay ; + slowleak = max(slowleak, bndpsd[bin] - sgain); + excite[bin] = max(fastleak - lowcomp, slowleak); + } + begin = 22; + } + else /* For coupling channel */ + { + begin = bndstrt; + } + + for (bin = begin; bin < bndend; bin++) + { + fastleak -= fdecay; + fastleak = max(fastleak, bndpsd[bin] - fgain); + slowleak -= sdecay; + slowleak = max(slowleak, bndpsd[bin] - sgain); + excite[bin] = max(fastleak, slowleak) ; + } +#endif +} + +static void ba_compute_mask(s16 start, s16 end, u16 fscod, + u16 deltbae, u16 deltnseg, u16 deltoffst[], u16 deltba[], + u16 deltlen[], s16 excite[], s16 mask[]) +{ +#if 1 + int bin,k; + s16 bndstrt; + s16 bndend; + s16 delta; + + bndstrt = masktab[start]; + bndend = masktab[end - 1] + 1; + + /* Compute the masking curve */ + for (bin = bndstrt; bin < bndend; bin++) + { + if (bndpsd[bin] < dbknee) + { + excite[bin] += ((dbknee - bndpsd[bin]) >> 2); + } + mask[bin] = max(excite[bin], hth[fscod][bin]); + } + + /* Perform delta bit modulation if necessary */ + if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) + { + s16 band = 0; + s16 seg = 0; + + for (seg = 0; seg < deltnseg+1; seg++) + { + band += deltoffst[seg]; + if (deltba[seg] >= 4) + { + delta = (deltba[seg] - 3) << 7; + } + else + { + delta = (deltba[seg] - 4) << 7; + } + for (k = 0; k < deltlen[seg]; k++) + { +// mask[band] += delta; + band++; + } + } + } +#endif +} + +static void ba_compute_bap(s16 start, s16 end, s16 snroffset, + s16 psd[], s16 mask[], s16 bap[]) +{ +#if 1 + int i,j,k; + s16 lastbin = 0; + s16 address = 0; + + /* Compute the bit allocation pointer for each bin */ + i = start; + j = masktab[start]; + + do + { + lastbin = min(bndtab[j] + bndsz[j], end); + mask[j] -= snroffset; + mask[j] -= floor; + + if (mask[j] < 0) + mask[j] = 0; + + mask[j] &= 0x1fe0; + mask[j] += floor; + for (k = i; k < lastbin; k++) + { + address = (psd[i] - mask[j]) >> 5; + address = min(63, max(0, address)); + bap[i] = baptab[address]; + i++; + } + j++; + } while (end > lastbin); +#endif +} diff --git a/src/ac3_decoder/ac3_decoder.c b/src/ac3_decoder/ac3_decoder.c index 043a4baa35..6cc6d9c017 100644 --- a/src/ac3_decoder/ac3_decoder.c +++ b/src/ac3_decoder/ac3_decoder.c @@ -6,6 +6,10 @@ /***************************************************************************** * Preamble *****************************************************************************/ +#include +#include +#include + #include /* getpid() */ #include /* "intf_msg.h" */ @@ -28,6 +32,13 @@ #include "audio_output.h" #include "ac3_decoder.h" +#include "ac3_parse.h" +#include "ac3_exponent.h" +#include "ac3_bit_allocate.h" +#include "ac3_mantissa.h" +#include "ac3_rematrix.h" +#include "ac3_imdct.h" +#include "ac3_downmix.h" /***************************************************************************** * Local prototypes @@ -85,6 +96,8 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) p_ac3dec->p_aout = p_input->p_aout; p_ac3dec->p_aout_fifo = NULL; + imdct_init(); + /* Spawn the ac3 decoder thread */ if ( vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec) ) { @@ -177,6 +190,10 @@ static int InitThread( ac3dec_thread_t * p_ac3dec ) *****************************************************************************/ static void RunThread( ac3dec_thread_t * p_ac3dec ) { + int i; + mtime_t mdate = 0; + byte_t byte; + intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() ); /* Initializing the ac3 decoder thread */ @@ -185,14 +202,39 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) p_ac3dec->b_error = 1; } + i = open( "/tmp/taxi.ac3", O_WRONLY|O_CREAT|O_TRUNC ); /* ac3 decoder thread's main loop */ while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) ) { - if ( decode_find_sync(p_ac3dec) == 0 ) + byte = GetByte( &(p_ac3dec->bit_stream) ); + write( i, &byte, 1 ); +#if 0 + decode_find_sync( p_ac3dec ); + parse_syncinfo( p_ac3dec ); + parse_bsi( p_ac3dec ); + for ( i = 0; i < 6; i++ ) { - fprintf( stderr, "ac3dec debug: decode_find_sync() == 0\n" ); + parse_audblk( p_ac3dec ); + exponent_unpack( p_ac3dec ); + bit_allocate( p_ac3dec ); + mantissa_unpack( p_ac3dec ); + if ( p_ac3dec->bsi.acmod == 0x2 ) + { + rematrix( p_ac3dec ); + } + imdct( p_ac3dec ); + + vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock ); + downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] ); + p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = mdate; + p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE; + vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock ); + mdate += 5333; } + parse_auxdata( p_ac3dec ); +#endif } + close( i ); /* If b_error is set, the ac3 decoder thread enters the error loop */ if ( p_ac3dec->b_error ) diff --git a/src/ac3_decoder/ac3_downmix.c b/src/ac3_decoder/ac3_downmix.c new file mode 100644 index 0000000000..aa643ac520 --- /dev/null +++ b/src/ac3_decoder/ac3_downmix.c @@ -0,0 +1,394 @@ +#include /* getpid() */ + +#include /* "intf_msg.h" */ +#include /* malloc(), free() */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_downmix.h" + +typedef struct prefs_s +{ + u16 use_dolby_surround; + u16 dual_mono_channel_select; + +} prefs_t; + +prefs_t global_prefs = {0,0}; + +//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 }; + +/* Downmix into _two_ channels...other downmix modes aren't implemented + * to reduce complexity. Realistically, there aren't many machines around + * with > 2 channel output anyways */ + +void downmix( ac3dec_thread_t * p_ac3dec, s16 * out_buf ) +{ + int j; + float right_tmp; + float left_tmp; + float clev,slev; + float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; + + /* + if(p_ac3dec->bsi.acmod > 7) + dprintf("(downmix) invalid acmod number\n"); + */ + + //There are two main cases, with or without Dolby Surround + if(global_prefs.use_dolby_surround) + { + switch(p_ac3dec->bsi.acmod) + { + // 3/2 + case 7: + left = p_ac3dec->samples.channel[0]; + centre = p_ac3dec->samples.channel[1]; + right = p_ac3dec->samples.channel[2]; + left_sur = p_ac3dec->samples.channel[3]; + right_sur = p_ac3dec->samples.channel[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++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 2/2 + case 6: + left = p_ac3dec->samples.channel[0]; + right = p_ac3dec->samples.channel[1]; + left_sur = p_ac3dec->samples.channel[2]; + right_sur = p_ac3dec->samples.channel[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++ ; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 3/1 + case 5: + left = p_ac3dec->samples.channel[0]; + centre = p_ac3dec->samples.channel[1]; + right = p_ac3dec->samples.channel[2]; + //Mono surround + right_sur = p_ac3dec->samples.channel[3]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.2265f * *right_sur++; + left_tmp = - right_tmp; + right_tmp += 0.3204f * *right++ + 0.2265f * *centre; + left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 2/1 + case 4: + left = p_ac3dec->samples.channel[0]; + right = p_ac3dec->samples.channel[1]; + //Mono surround + right_sur = p_ac3dec->samples.channel[2]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.2265f * *right_sur++; + left_tmp = - right_tmp; + right_tmp += 0.3204f * *right++; + left_tmp += 0.3204f * *left++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 3/0 + case 3: + left = p_ac3dec->samples.channel[0]; + centre = p_ac3dec->samples.channel[1]; + right = p_ac3dec->samples.channel[2]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.3204f * *right++ + 0.2265f * *centre; + left_tmp = 0.3204f * *left++ + 0.2265f * *centre++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 2/0 + case 2: + left = p_ac3dec->samples.channel[0]; + right = p_ac3dec->samples.channel[1]; + + for ( j = 0; j < 256; j++ ) + { + *(out_buf++) = *(left++) * 32766; + *(out_buf++) = *(right++) * 32766; + } + break; + + // 1/0 + case 1: + //Mono program! + right = p_ac3dec->samples.channel[0]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.7071f * *right++; + + *(out_buf++) = right_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = right_tmp; + */ + } + break; + + // 1+1 + case 0: + //Dual mono, output selected by user + right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.7071f * *right++; + + *(out_buf++) = right_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = right_tmp; + */ + } + break; + } + } + else + { + //Non-Dolby surround downmixes + switch(p_ac3dec->bsi.acmod) + { + // 3/2 + case 7: + left = p_ac3dec->samples.channel[0]; + centre = p_ac3dec->samples.channel[1]; + right = p_ac3dec->samples.channel[2]; + left_sur = p_ac3dec->samples.channel[3]; + right_sur = p_ac3dec->samples.channel[4]; + + clev = cmixlev_lut[p_ac3dec->bsi.cmixlev]; + slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; + + for (j = 0; j < 256; j++) + { + right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur++; + left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *left_sur++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 2/2 + case 6: + left = p_ac3dec->samples.channel[0]; + right = p_ac3dec->samples.channel[1]; + left_sur = p_ac3dec->samples.channel[2]; + right_sur = p_ac3dec->samples.channel[3]; + + slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; + + for (j = 0; j < 256; j++) + { + right_tmp= 0.4142f * *right++ + slev * *right_sur++; + left_tmp = 0.4142f * *left++ + slev * *left_sur++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 3/1 + case 5: + left = p_ac3dec->samples.channel[0]; + centre = p_ac3dec->samples.channel[1]; + right = p_ac3dec->samples.channel[2]; + //Mono surround + right_sur = p_ac3dec->samples.channel[3]; + + clev = cmixlev_lut[p_ac3dec->bsi.cmixlev]; + slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; + + for (j = 0; j < 256; j++) + { + right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur; + left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *right_sur++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 2/1 + case 4: + left = p_ac3dec->samples.channel[0]; + right = p_ac3dec->samples.channel[1]; + //Mono surround + right_sur = p_ac3dec->samples.channel[2]; + + slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; + + for (j = 0; j < 256; j++) + { + right_tmp= 0.4142f * *right++ + slev * *right_sur; + left_tmp = 0.4142f * *left++ + slev * *right_sur++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + // 3/0 + case 3: + left = p_ac3dec->samples.channel[0]; + centre = p_ac3dec->samples.channel[1]; + right = p_ac3dec->samples.channel[2]; + + clev = cmixlev_lut[p_ac3dec->bsi.cmixlev]; + + for (j = 0; j < 256; j++) + { + right_tmp= 0.4142f * *right++ + clev * *centre; + left_tmp = 0.4142f * *left++ + clev * *centre++; + + *(out_buf++) = left_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = left_tmp; + */ + } + break; + + case 2: + left = p_ac3dec->samples.channel[0]; + right = p_ac3dec->samples.channel[1]; + + for ( j = 0; j < 256; j++ ) + { + *(out_buf++) = *(left++) * 32766; + *(out_buf++) = *(right++) * 32766; + } + break; + + // 1/0 + case 1: + //Mono program! + right = p_ac3dec->samples.channel[0]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.7071f * *right++; + + *(out_buf++) = right_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = right_tmp; + */ + } + break; + + // 1+1 + case 0: + //Dual mono, output selected by user + right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.7071f * *right++; + + *(out_buf++) = right_tmp * 32766; + *(out_buf++) = right_tmp * 32766; + /* + p_ac3dec->samples.channel[1][j] = right_tmp; + p_ac3dec->samples.channel[0][j] = right_tmp; + */ + } + break; + } + } +} diff --git a/src/ac3_decoder/ac3_exponent.c b/src/ac3_decoder/ac3_exponent.c new file mode 100644 index 0000000000..c6154a0490 --- /dev/null +++ b/src/ac3_decoder/ac3_exponent.c @@ -0,0 +1,126 @@ +#include /* getpid() */ + +#include /* "intf_msg.h" */ +#include /* malloc(), free() */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_exponent.h" + +static const s16 exps_1[128] = { 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5 }; +static const s16 exps_2[128] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0 }; +static const s16 exps_3[128] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2 }; + +static __inline__ void exp_unpack_ch( u16 type, u16 expstr, u16 ngrps, u16 initial_exp, u16 exps[], u16 * dest ) +{ + u16 i,j; + s16 exp_acc; + /* + s16 exp_1,exp_2,exp_3; + */ + + if(expstr == EXP_REUSE) + return; + + /* Handle the initial absolute exponent */ + exp_acc = initial_exp; + j = 0; + + /* In the case of a fbw channel then the initial absolute values is + * also an exponent */ + if(type != UNPACK_CPL) + dest[j++] = exp_acc; + + /* Loop through the groups and fill the dest array appropriately */ + for ( i = 0; i < ngrps; i++ ) + { + /* + if ( exps[i] > 124 ) + { + //FIXME set an error flag and mute the frame + printf( "\n!! Invalid exponent !!\n" ); + exit( 1 ); + } + */ + + /* + exp_1 = exps[i] / 25; + exp_2 = (exps[i] - (exp_1 * 25)) / 5; + exp_3 = exps[i] - (exp_1 * 25) - (exp_2 * 5) ; + */ + + switch ( expstr ) + { + case EXP_D45: + exp_acc += (exps_1[exps[i]] - 2); + dest[j++] = exp_acc; + dest[j++] = exp_acc; + dest[j++] = exp_acc; + dest[j++] = exp_acc; + exp_acc += (exps_2[exps[i]] - 2); + dest[j++] = exp_acc; + dest[j++] = exp_acc; + dest[j++] = exp_acc; + dest[j++] = exp_acc; + exp_acc += (exps_3[exps[i]] - 2); + dest[j++] = exp_acc; + dest[j++] = exp_acc; + dest[j++] = exp_acc; + dest[j++] = exp_acc; + break; + + case EXP_D25: + exp_acc += (exps_1[exps[i]] - 2); + dest[j++] = exp_acc; + dest[j++] = exp_acc; + exp_acc += (exps_2[exps[i]] - 2); + dest[j++] = exp_acc; + dest[j++] = exp_acc; + exp_acc += (exps_3[exps[i]] - 2); + dest[j++] = exp_acc; + dest[j++] = exp_acc; + break; + + case EXP_D15: + exp_acc += (exps_1[exps[i]] - 2); + dest[j++] = exp_acc; + exp_acc += (exps_2[exps[i]] - 2); + dest[j++] = exp_acc; + exp_acc += (exps_3[exps[i]] - 2); + dest[j++] = exp_acc; + break; + } + } +} + +void exponent_unpack( ac3dec_thread_t * p_ac3dec ) +{ + u16 i; + + for(i=0; i< p_ac3dec->bsi.nfchans; i++) + exp_unpack_ch(UNPACK_FBW, p_ac3dec->audblk.chexpstr[i], p_ac3dec->audblk.nchgrps[i], p_ac3dec->audblk.exps[i][0], + &p_ac3dec->audblk.exps[i][1], p_ac3dec->audblk.fbw_exp[i]); + + if(p_ac3dec->audblk.cplinu) + exp_unpack_ch(UNPACK_CPL, p_ac3dec->audblk.cplexpstr, p_ac3dec->audblk.ncplgrps, p_ac3dec->audblk.cplabsexp << 1, + p_ac3dec->audblk.cplexps, &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]); + + if(p_ac3dec->bsi.lfeon) + exp_unpack_ch(UNPACK_LFE, p_ac3dec->audblk.lfeexpstr, 2, p_ac3dec->audblk.lfeexps[0], + &p_ac3dec->audblk.lfeexps[1], p_ac3dec->audblk.lfe_exp); +} diff --git a/src/ac3_decoder/ac3_imdct.c b/src/ac3_decoder/ac3_imdct.c new file mode 100644 index 0000000000..ea24bb2538 --- /dev/null +++ b/src/ac3_decoder/ac3_imdct.c @@ -0,0 +1,425 @@ +#include /* getpid() */ + +#include + +#include /* "intf_msg.h" */ +#include /* malloc(), free() */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_imdct.h" + +void imdct_do_256(float x[],float y[],float delay[]); +void imdct_do_512(float x[],float y[],float delay[]); + +typedef struct complex_s +{ + float real; + float imag; +} complex_t; + +#define N 512 + +static complex_t buf[N/4]; + +/* 128 point bit-reverse LUT */ +static u8 bit_reverse_512[] = { + 0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, + 0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78, + 0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74, + 0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c, + 0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72, + 0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a, + 0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76, + 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e, + 0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71, + 0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79, + 0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75, + 0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d, + 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73, + 0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b, + 0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77, + 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f}; + +static u8 bit_reverse_256[] = { + 0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38, + 0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c, + 0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a, + 0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e, + 0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39, + 0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d, + 0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b, + 0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f}; + +/* 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]; +static complex_t w_8[8]; +static complex_t w_16[16]; +static complex_t w_32[32]; +static complex_t w_64[64]; + +/* Twiddle factors for IMDCT */ +static float xcos1[N/4]; +static float xsin1[N/4]; +static float xcos2[N/8]; +static float xsin2[N/8]; + +/* Delay buffer for time domain interleaving */ +static float delay[6][256]; + +/* Windowing function for Modified DCT - Thank you acroread */ +static float window[] = { + 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130, + 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443, + 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061, + 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121, + 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770, + 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153, + 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389, + 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563, + 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699, + 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757, + 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626, + 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126, + 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019, + 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031, + 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873, + 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269, + 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981, + 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831, + 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716, + 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610, + 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560, + 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674, + 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099, + 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994, + 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513, + 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788, + 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919, + 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974, + 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993, + 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999, + 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, + 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 }; + +static __inline__ void swap_cmplx(complex_t *a, complex_t *b) +{ + complex_t tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} + +static __inline__ complex_t cmplx_mult(complex_t a, complex_t b) +{ + complex_t ret; + + ret.real = a.real * b.real - a.imag * b.imag; + ret.imag = a.real * b.imag + a.imag * b.real; + + return ret; +} + +void imdct_init(void) +{ + int i,k; + complex_t angle_step; + complex_t current_angle; + + /* Twiddle factors to turn IFFT into IMDCT */ + for( i=0; i < N/4; i++) + { + xcos1[i] = -cos(2 * M_PI * (8*i+1)/(8*N)) ; + xsin1[i] = -sin(2 * M_PI * (8*i+1)/(8*N)) ; + } + + /* More twiddle factors to turn IFFT into IMDCT */ + for( i=0; i < N/8; i++) + { + xcos2[i] = -cos(2 * M_PI * (8*i+1)/(4*N)) ; + xsin2[i] = -sin(2 * 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.0f * M_PI / (1 << (i+1))); + angle_step.imag = sin(-2.0f * M_PI / (1 << (i+1))); + + current_angle.real = 1.0f; + current_angle.imag = 0.0f; + + for (k = 0; k < 1 << i; k++) + { + w[i][k] = current_angle; + current_angle = cmplx_mult(current_angle,angle_step); + } + } +} + +void imdct( ac3dec_thread_t * p_ac3dec ) +{ + int i; + + for(i=0; ibsi.nfchans;i++) + { + if(p_ac3dec->audblk.blksw[i]) + imdct_do_256(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]); + else + imdct_do_512(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]); + } + + //XXX We don't bother with the IMDCT for the LFE as it's currently + //unused. + //if (bsi->lfeon) + // imdct_do_512(coeffs->lfe,samples->channel[5],delay[5]); + // +} + +void +imdct_do_512(float x[],float y[],float delay[]) +{ + int i,k; + int p,q; + int m; + int two_m; + int two_m_plus_one; + + float tmp_a_i; + float tmp_a_r; + float tmp_b_i; + float tmp_b_r; + + + float *y_ptr; + float *delay_ptr; + float *window_ptr; + + // Pre IFFT complex multiply plus IFFT cmplx conjugate + for( i=0; i < N/4; i++) + { + /* z[i] = (X[N/2-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */ + buf[i].real = (x[N/2-2*i-1] * xcos1[i]) - (x[2*i] * xsin1[i]); + buf[i].imag = -((x[2*i] * xcos1[i]) + (x[N/2-2*i-1] * xsin1[i])); + } + + //Bit reversed shuffling + for(i=0; i /* getpid() */ + +#include /* "intf_msg.h" */ +#include /* malloc(), free() */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_mantissa.h" + +static float q_1_0[ 32 ] = { (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, 0, 0, 0, 0, 0 }; +static float q_1_1[ 32 ] = { (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, 0, 0, 0, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, 0, 0, 0, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, (-2 << 15) / 3, 0, 0, 0, (2 << 15) / 3, (2 << 15) / 3, (2 << 15) / 3, 0, 0, 0, 0, 0 }; +static float q_1_2[ 32 ] = { (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, (-2 << 15) / 3, 0, (2 << 15) / 3, 0, 0, 0, 0, 0 }; + +static float q_2_0[ 128 ] = { (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, 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, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, 0, 0, 0 }; +static float q_2_1[ 128 ] = { (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, 0, 0, 0, 0, 0, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, 0, 0, 0, 0, 0, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, 0, 0, 0, 0, 0, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, 0, 0, 0, 0, 0, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, (-2 << 15) / 5, 0, 0, 0, 0, 0, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (2 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, (4 << 15) / 5, 0, 0, 0 }; +static float q_2_2[ 128 ] = { (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, (-4 << 15) / 5, (-2 << 15) / 5, 0, (2 << 15) / 5, (4 << 15) / 5, 0, 0, 0 }; + +static float q_4_0[ 128 ] = { (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-10 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-8 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-6 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-4 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, (-2 << 15) / 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (2 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (4 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (6 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (8 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, (10 << 15) / 11, 0, 0, 0, 0, 0, 0, 0 }; +static float q_4_1[ 128 ] = { (-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, (-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, (-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, (-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, (-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, (-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, (-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, (-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, (-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, (-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, (-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, 0, 0, 0, 0, 0, 0, 0 }; + +//Lookup tables of 0.16 two's complement quantization values + +/* +s32 q_1[3] = {( -2 << 15)/3, 0 ,( 2 << 15)/3 }; + +s32 q_2[5] = {( -4 << 15)/5,( -2 << 15)/5, 0 , + ( 2 << 15)/5,( 4 << 15)/5}; +*/ + +static float q_3[7] = {( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, + 0 ,( 2 << 15)/7,( 4 << 15)/7, + ( 6 << 15)/7}; + +/* +s32 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 float 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}; + +//These store the persistent state of the packed mantissas +static float q_1[2]; +static float q_2[2]; +static float q_4[1]; +static s32 q_1_pointer; +static s32 q_2_pointer; +static s32 q_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 u16 qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16}; + +static float exp_lut[ 25 ] = +{ + 6.10351562500000000000000000e-05, + 3.05175781250000000000000000e-05, + 1.52587890625000000000000000e-05, + 7.62939453125000000000000000e-06, + 3.81469726562500000000000000e-06, + 1.90734863281250000000000000e-06, + 9.53674316406250000000000000e-07, + 4.76837158203125000000000000e-07, + 2.38418579101562500000000000e-07, + 1.19209289550781250000000000e-07, + 5.96046447753906250000000000e-08, + 2.98023223876953125000000000e-08, + 1.49011611938476562500000000e-08, + 7.45058059692382812500000000e-09, + 3.72529029846191406250000000e-09, + 1.86264514923095703125000000e-09, + 9.31322574615478515625000000e-10, + 4.65661287307739257812500000e-10, + 2.32830643653869628906250000e-10, + 1.16415321826934814453125000e-10, + 5.82076609134674072265625000e-11, + 2.91038304567337036132812500e-11, + 1.45519152283668518066406250e-11, + 7.27595761418342590332031250e-12, + 3.63797880709171295166015625e-12, +}; + +#ifdef DITHER +#if 0 +static u32 lfsr_state = 1; + +static __inline__ float dither_gen( u16 exp ) +{ + int i; + u32 state; + s16 mantissa; + + //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; + + mantissa = ((((s32)state<<8)>>8) * (s32) (0.707106f * 256.0f))>>16; + return( mantissa * exp_lut[exp] ); +} +#else +static int fuck[31] = +{ + 0x00000001, + 0x00000002, + 0x00000004, + 0x00000008, + 0x00000010, + 0x00000020, + 0x00000040, + 0x00000080, + 0x00000100, + 0x80000200, + 0x00000400, + 0x00000800, + 0x00001000, + 0x00002000, + 0x00004000, + 0x00008000, + 0x80010000, + 0x00020000, + 0x00040000, + 0x00080000, + 0x00100000, + 0x80200000, + 0x00400000, + 0x00800000, + 0x01000000, + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000 +}; + +static int index = 0; + +static __inline__ float dither_gen( u16 exp ) +{ + int tmp; + tmp = fuck[(index+3)%31]; + tmp ^= fuck[index]; + fuck[index] = tmp; + index = (index+1)%31; + return( tmp * 1.52587890625e-5f * 0.707106f * exp_lut[exp] ); +} +#endif +#endif + +/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */ +#ifdef DITHER +static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 dithflag, u16 exp ) +#else +static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 exp ) +#endif +{ + u32 group_code; + + //If the bap is 0-5 then we have special cases to take care of + switch ( bap ) + { + case 0: +#ifdef DITHER + if(dithflag) + return( dither_gen(exp) ); + else +#endif + return( 0 ); + + case 1: + if ( q_1_pointer >= 0 ) + { + return( q_1[q_1_pointer--] * exp_lut[exp] ); + } + NeedBits( &(p_ac3dec->bit_stream), 5 ); + group_code = p_ac3dec->bit_stream.fifo.buffer >> (32 - 5); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + + /* + if(group_code > 26) + //FIXME do proper block error handling + printf("\n!! Invalid mantissa !!\n"); + */ + + //q_1[ 0 ] = q_1_0[ group_code ]; + q_1[ 1 ] = q_1_1[ group_code ]; + q_1[ 0 ] = q_1_2[ group_code ]; + + q_1_pointer = 1; + + return( q_1_0[group_code] * exp_lut[exp] ); + + case 2: + if ( q_2_pointer >= 0 ) + { + return( q_2[q_2_pointer--] * exp_lut[exp] ); + } + NeedBits( &(p_ac3dec->bit_stream), 7 ); + group_code = p_ac3dec->bit_stream.fifo.buffer >> (32 - 7); + DumpBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->total_bits_read += 7; + + /* + if(group_code > 124) + //FIXME do proper block error handling + printf("\n!! Invalid mantissa !!\n"); + */ + + //q_2[ 0 ] = q_2_0[ group_code ]; + q_2[ 1 ] = q_2_1[ group_code ]; + q_2[ 0 ] = q_2_2[ group_code ]; + + q_2_pointer = 1; + + return( q_2_0[ group_code ] * exp_lut[exp] ); + + case 3: + NeedBits( &(p_ac3dec->bit_stream), 3 ); + group_code = p_ac3dec->bit_stream.fifo.buffer >> (32 - 3); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + + /* + if(group_code > 6) + //FIXME do proper block error handling + printf("\n!! Invalid mantissa !!\n"); + */ + + return( q_3[group_code] * exp_lut[exp] ); + + case 4: + if ( q_4_pointer >= 0 ) + { + return( q_4[q_4_pointer--] * exp_lut[exp] ); + } + NeedBits( &(p_ac3dec->bit_stream), 7 ); + group_code = p_ac3dec->bit_stream.fifo.buffer >> (32 - 7); + DumpBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->total_bits_read += 7; + + /* + if(group_code > 120) + //FIXME do proper block error handling + printf("\n!! Invalid mantissa !!\n"); + */ + + //q_4[ 0 ] = q_4_0[ group_code ]; + q_4[ 0 ] = q_4_1[ group_code ]; + + q_4_pointer = 0; + + return( q_4_0[ group_code ] * exp_lut[exp] ); + + case 5: + NeedBits( &(p_ac3dec->bit_stream), 4 ); + group_code = p_ac3dec->bit_stream.fifo.buffer >> (32 - 4); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + + /* + if(group_code > 14) + //FIXME do proper block error handling + printf("\n!! Invalid mantissa !!\n"); + */ + + return( q_5[group_code] * exp_lut[exp] ); + + default: + NeedBits( &(p_ac3dec->bit_stream), qnttztab[bap] ); + group_code = (((s32)(p_ac3dec->bit_stream.fifo.buffer)) >> (32 - qnttztab[bap])) << (16 - qnttztab[bap]); + DumpBits( &(p_ac3dec->bit_stream), qnttztab[bap] ); + p_ac3dec->total_bits_read += qnttztab[bap]; + + return( ((s32)group_code) * exp_lut[exp] ); + } +} + +static __inline__ void uncouple_channel( ac3dec_thread_t * p_ac3dec, u32 ch ) +{ + u32 bnd = 0; + u32 i,j; + float cpl_coord = 0; + //float coeff; + u32 cpl_exp_tmp; + u32 cpl_mant_tmp; + + for(i=p_ac3dec->audblk.cplstrtmant;iaudblk.cplendmant;) + { + if(!p_ac3dec->audblk.cplbndstrc[bnd]) + { + cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] + 3 * p_ac3dec->audblk.mstrcplco[ch]; + if(p_ac3dec->audblk.cplcoexp[ch][bnd] == 15) + cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 12; + else + cpl_mant_tmp = ((0x10) | p_ac3dec->audblk.cplcomant[ch][bnd]) << 11; + + cpl_coord = ((s16)cpl_mant_tmp) * exp_lut[cpl_exp_tmp]; + } + bnd++; + + for(j=0;j < 12; j++) + { + //Get new dither values for each channel if necessary, so + //the channels are uncorrelated +#ifdef DITHER + if ( p_ac3dec->audblk.dithflag[ch] && p_ac3dec->audblk.cpl_bap[i] == 0 ) + p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * dither_gen( p_ac3dec->audblk.cpl_exp[i] ); + else +#endif + p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i]; + i++; + } + } +} + +#if 0 +void +uncouple(bsi_t *bsi,audblk_t *audblk,stream_coeffs_t *coeffs) +{ + int i,j; + + for(i=0; i< bsi->nfchans; i++) + { + for(j=0; j < audblk->endmant[i]; j++) + convert_to_float(audblk->fbw_exp[i][j],audblk->chmant[i][j], + (u32*) &coeffs->fbw[i][j]); + } + + if(audblk->cplinu) + { + for(i=0; i< bsi->nfchans; i++) + { + if(audblk->chincpl[i]) + { + uncouple_channel(coeffs,audblk,i); + } + } + + } + + if(bsi->lfeon) + { + /* There are always 7 mantissas for lfe */ + for(j=0; j < 7 ; j++) + convert_to_float(audblk->lfe_exp[j],audblk->lfemant[j], + (u32*) &coeffs->lfe[j]); + + } + +} +#endif + +/* +void mantissa_unpack( bsi_t * bsi, audblk_t * audblk, bitstream_t * bs ) +*/ +void mantissa_unpack( ac3dec_thread_t * p_ac3dec ) +{ + int i, j; + + q_1_pointer = -1; + q_2_pointer = -1; + q_4_pointer = -1; + + if ( p_ac3dec->audblk.cplinu ) + { + /* 1 */ + for ( i = 0; !p_ac3dec->audblk.chincpl[i]; i++ ) + { + for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) + { +#ifdef DITHER + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j] ); +#else + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] ); +#endif + } + } + + /* 2 */ + for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) + { +#ifdef DITHER + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j] ); +#else + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] ); +#endif + } + for ( j = p_ac3dec->audblk.cplstrtmant; j < p_ac3dec->audblk.cplendmant; j++ ) + { +#ifdef DITHER + p_ac3dec->audblk.cplfbw[j] = float_get( p_ac3dec, p_ac3dec->audblk.cpl_bap[j], 0, p_ac3dec->audblk.cpl_exp[j] ); +#else + p_ac3dec->audblk.cplfbw[j] = float_get( p_ac3dec, p_ac3dec->audblk.cpl_bap[j], p_ac3dec->audblk.cpl_exp[j] ); +#endif + } +// uncouple_channel( coeffs, audblk, i ); + + /* 3 */ + for ( i++; i < p_ac3dec->bsi.nfchans; i++ ) + { + for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) + { +#ifdef DITHER + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j] ); +#else + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] ); +#endif + } + if ( p_ac3dec->audblk.chincpl[i] ) + { +// uncouple_channel( coeffs, audblk, i ); + } + } + + for ( i = 0; i < p_ac3dec->bsi.nfchans; i++ ) + { + if ( p_ac3dec->audblk.chincpl[i] ) + { + uncouple_channel( p_ac3dec, i ); + } + } + } + else + { + for ( i = 0; i < p_ac3dec->bsi.nfchans; i++ ) + { + for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) + { +#ifdef DITHER + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j] ); +#else + p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] ); +#endif + } + } + } + + if ( p_ac3dec->bsi.lfeon ) + { + /* There are always 7 mantissas for lfe, no dither for lfe */ + for ( j = 0; j < 7; j++ ) + { +#ifdef DITHER + p_ac3dec->coeffs.lfe[j] = float_get( p_ac3dec, p_ac3dec->audblk.lfe_bap[j], 0, p_ac3dec->audblk.lfe_exp[j] ); +#else + p_ac3dec->coeffs.lfe[j] = float_get( p_ac3dec, p_ac3dec->audblk.lfe_bap[j], p_ac3dec->audblk.lfe_exp[j] ); +#endif + } + } +} diff --git a/src/ac3_decoder/ac3_parse.c b/src/ac3_decoder/ac3_parse.c new file mode 100644 index 0000000000..e34568a208 --- /dev/null +++ b/src/ac3_decoder/ac3_parse.c @@ -0,0 +1,892 @@ +#include /* "intf_msg.h" */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_parse.h" + +/* Misc LUT */ +static u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 }; + +struct frmsize_s +{ + u16 bit_rate; + u16 frm_size[3]; +}; + +static struct frmsize_s frmsizecod_tbl[] = { + { 32 ,{64 ,69 ,96 } }, + { 32 ,{64 ,70 ,96 } }, + { 40 ,{80 ,87 ,120 } }, + { 40 ,{80 ,88 ,120 } }, + { 48 ,{96 ,104 ,144 } }, + { 48 ,{96 ,105 ,144 } }, + { 56 ,{112 ,121 ,168 } }, + { 56 ,{112 ,122 ,168 } }, + { 64 ,{128 ,139 ,192 } }, + { 64 ,{128 ,140 ,192 } }, + { 80 ,{160 ,174 ,240 } }, + { 80 ,{160 ,175 ,240 } }, + { 96 ,{192 ,208 ,288 } }, + { 96 ,{192 ,209 ,288 } }, + { 112 ,{224 ,243 ,336 } }, + { 112 ,{224 ,244 ,336 } }, + { 128 ,{256 ,278 ,384 } }, + { 128 ,{256 ,279 ,384 } }, + { 160 ,{320 ,348 ,480 } }, + { 160 ,{320 ,349 ,480 } }, + { 192 ,{384 ,417 ,576 } }, + { 192 ,{384 ,418 ,576 } }, + { 224 ,{448 ,487 ,672 } }, + { 224 ,{448 ,488 ,672 } }, + { 256 ,{512 ,557 ,768 } }, + { 256 ,{512 ,558 ,768 } }, + { 320 ,{640 ,696 ,960 } }, + { 320 ,{640 ,697 ,960 } }, + { 384 ,{768 ,835 ,1152 } }, + { 384 ,{768 ,836 ,1152 } }, + { 448 ,{896 ,975 ,1344 } }, + { 448 ,{896 ,976 ,1344 } }, + { 512 ,{1024 ,1114 ,1536 } }, + { 512 ,{1024 ,1115 ,1536 } }, + { 576 ,{1152 ,1253 ,1728 } }, + { 576 ,{1152 ,1254 ,1728 } }, + { 640 ,{1280 ,1393 ,1920 } }, + { 640 ,{1280 ,1394 ,1920 } }}; + +/* Parse a syncinfo structure, minus the sync word */ +void parse_syncinfo( ac3dec_thread_t * p_ac3dec ) +{ + /* Get crc1 - we don't actually use this data though */ + NeedBits( &(p_ac3dec->bit_stream), 16 ); + DumpBits( &(p_ac3dec->bit_stream), 16 ); + p_ac3dec->total_bits_read += 16; + + /* Get the sampling rate */ + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->syncinfo.fscod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); +// fprintf( stderr, "parse debug: fscod == %i\n", p_ac3dec->syncinfo.fscod ); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + + /* Get the frame size code */ + NeedBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->syncinfo.frmsizecod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 6)); +// fprintf( stderr, "parse debug: frmsizecod == %i\n", p_ac3dec->syncinfo.frmsizecod ); + DumpBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->total_bits_read += 6; + + p_ac3dec->syncinfo.bit_rate = frmsizecod_tbl[p_ac3dec->syncinfo.frmsizecod].bit_rate; +// fprintf( stderr, "parse debug: bit_rate == %i\n", p_ac3dec->syncinfo.bit_rate ); + p_ac3dec->syncinfo.frame_size = frmsizecod_tbl[p_ac3dec->syncinfo.frmsizecod].frm_size[p_ac3dec->syncinfo.fscod]; +// fprintf( stderr, "parse debug: frame_size == %i\n", p_ac3dec->syncinfo.frame_size ); +} + +/* + * This routine fills a bsi struct from the AC3 stream + */ +void parse_bsi( ac3dec_thread_t * p_ac3dec ) +{ + u32 i; + + /* Check the AC-3 version number */ + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->bsi.bsid = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + + /* Get the audio service provided by the steram */ + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->bsi.bsmod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + + /* Get the audio coding mode (ie how many channels)*/ + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->bsi.acmod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + /* Predecode the number of full bandwidth channels as we use this + * number a lot */ + p_ac3dec->bsi.nfchans = nfchans[p_ac3dec->bsi.acmod]; + + /* If it is in use, get the centre channel mix level */ + if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1)) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->bsi.cmixlev = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + /* If it is in use, get the surround channel mix level */ + if (p_ac3dec->bsi.acmod & 0x4) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->bsi.surmixlev = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + /* Get the dolby surround mode if in 2/0 mode */ + if(p_ac3dec->bsi.acmod == 0x2) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->bsi.dsurmod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + /* Is the low frequency effects channel on? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.lfeon = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + /* Get the dialogue normalization level */ + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->bsi.dialnorm = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + + /* Does compression gain exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.compre = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->bsi.compre) + { + /* Get compression gain */ + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->bsi.compr = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + + /* Does language code exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.langcode = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->bsi.langcode) + { + /* Get langauge code */ + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->bsi.langcod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + + /* Does audio production info exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.audprodie = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->bsi.audprodie) + { + /* Get mix level */ + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->bsi.mixlevel = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + + /* Get room type */ + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->bsi.roomtyp = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + /* If we're in dual mono mode then get some extra info */ + if (p_ac3dec->bsi.acmod ==0) + { + /* Get the dialogue normalization level two */ + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->bsi.dialnorm2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + + /* Does compression gain two exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.compr2e = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->bsi.compr2e) + { + /* Get compression gain two */ + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->bsi.compr2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + + /* Does language code two exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.langcod2e = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->bsi.langcod2e) + { + /* Get langauge code two */ + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->bsi.langcod2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + + /* Does audio production info two exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.audprodi2e = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->bsi.audprodi2e) + { + /* Get mix level two */ + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->bsi.mixlevel2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + + /* Get room type two */ + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->bsi.roomtyp2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + } + + /* Get the copyright bit */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.copyrightb = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + /* Get the original bit */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.origbs = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + /* Does timecode one exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.timecod1e = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->bsi.timecod1e) + { + NeedBits( &(p_ac3dec->bit_stream), 14 ); + p_ac3dec->bsi.timecod1 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 14)); + DumpBits( &(p_ac3dec->bit_stream), 14 ); + p_ac3dec->total_bits_read += 14; + } + + /* Does timecode two exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.timecod2e = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->bsi.timecod2e) + { + NeedBits( &(p_ac3dec->bit_stream), 14 ); + p_ac3dec->bsi.timecod2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 14)); + DumpBits( &(p_ac3dec->bit_stream), 14 ); + p_ac3dec->total_bits_read += 14; + } + + /* Does addition info exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->bsi.addbsie = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->bsi.addbsie) + { + /* Get how much info is there */ + NeedBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->bsi.addbsil = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 6)); + DumpBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->total_bits_read += 6; + + /* Get the additional info */ + for(i=0;i<(p_ac3dec->bsi.addbsil + 1);i++) + { + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->bsi.addbsi[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + } +} + +/* More pain inducing parsing */ +void parse_audblk( ac3dec_thread_t * p_ac3dec ) +{ + int i, j; + + for (i=0;i < p_ac3dec->bsi.nfchans; i++) + { + /* Is this channel an interleaved 256 + 256 block ? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.blksw[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + + for (i=0;i < p_ac3dec->bsi.nfchans; i++) + { + /* Should we dither this channel? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.dithflag[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + + /* Does dynamic range control exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.dynrnge = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->audblk.dynrnge) + { + /* Get dynamic range info */ + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->audblk.dynrng = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + + /* If we're in dual mono mode then get the second channel DR info */ + if (p_ac3dec->bsi.acmod == 0) + { + /* Does dynamic range control two exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.dynrng2e = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->audblk.dynrng2e) + { + /* Get dynamic range info */ + NeedBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->audblk.dynrng2 = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 8)); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + } + + /* Does coupling strategy exist? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.cplstre = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if (p_ac3dec->audblk.cplstre) + { + /* Is coupling turned on? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.cplinu = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if(p_ac3dec->audblk.cplinu) + { + for(i=0;i < p_ac3dec->bsi.nfchans; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.chincpl[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + if(p_ac3dec->bsi.acmod == 0x2) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.phsflginu = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cplbegf = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cplendf = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + p_ac3dec->audblk.ncplsubnd = (p_ac3dec->audblk.cplendf + 2) - p_ac3dec->audblk.cplbegf + 1; + + /* Calculate the start and end bins of the coupling channel */ + p_ac3dec->audblk.cplstrtmant = (p_ac3dec->audblk.cplbegf * 12) + 37 ; + p_ac3dec->audblk.cplendmant = ((p_ac3dec->audblk.cplendf + 3) * 12) + 37; + + /* The number of combined subbands is ncplsubnd minus each combined + * band */ + p_ac3dec->audblk.ncplbnd = p_ac3dec->audblk.ncplsubnd; + + for(i=1; i< p_ac3dec->audblk.ncplsubnd; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.cplbndstrc[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + p_ac3dec->audblk.ncplbnd -= p_ac3dec->audblk.cplbndstrc[i]; + } + } + } + + if(p_ac3dec->audblk.cplinu) + { + /* Loop through all the channels and get their coupling co-ords */ + for(i=0;i < p_ac3dec->bsi.nfchans;i++) + { + if(!p_ac3dec->audblk.chincpl[i]) + continue; + + /* Is there new coupling co-ordinate info? */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.cplcoe[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->audblk.cplcoe[i]) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.mstrcplco[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + for(j=0;j < p_ac3dec->audblk.ncplbnd; j++) + { + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cplcoexp[i][j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cplcomant[i][j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + } + } + } + + /* If we're in dual mono mode, there's going to be some phase info */ + if( (p_ac3dec->bsi.acmod == 0x2) && p_ac3dec->audblk.phsflginu && + (p_ac3dec->audblk.cplcoe[0] || p_ac3dec->audblk.cplcoe[1])) + { + for(j=0;j < p_ac3dec->audblk.ncplbnd; j++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.phsflg[j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + + } + } + + /* If we're in dual mono mode, there may be a rematrix strategy */ + if(p_ac3dec->bsi.acmod == 0x2) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.rematstr = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + if(p_ac3dec->audblk.rematstr) + { + if (p_ac3dec->audblk.cplinu == 0) + { + for(i = 0; i < 4; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + } + if((p_ac3dec->audblk.cplbegf > 2) && p_ac3dec->audblk.cplinu) + { + for(i = 0; i < 4; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + } + if((p_ac3dec->audblk.cplbegf <= 2) && p_ac3dec->audblk.cplinu) + { + for(i = 0; i < 3; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + } + if((p_ac3dec->audblk.cplbegf == 0) && p_ac3dec->audblk.cplinu) + for(i = 0; i < 2; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + + } + } + + if (p_ac3dec->audblk.cplinu) + { + /* Get the coupling channel exponent strategy */ + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.cplexpstr = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + + if(p_ac3dec->audblk.cplexpstr==0) + p_ac3dec->audblk.ncplgrps = 0; + else + p_ac3dec->audblk.ncplgrps = (p_ac3dec->audblk.cplendmant - p_ac3dec->audblk.cplstrtmant) / + (3 << (p_ac3dec->audblk.cplexpstr-1)); + + } + + for(i = 0; i < p_ac3dec->bsi.nfchans; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.chexpstr[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + /* Get the exponent strategy for lfe channel */ + if(p_ac3dec->bsi.lfeon) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.lfeexpstr = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + + /* Determine the bandwidths of all the fbw channels */ + for(i = 0; i < p_ac3dec->bsi.nfchans; i++) + { + u16 grp_size; + + if(p_ac3dec->audblk.chexpstr[i] != EXP_REUSE) + { + if (p_ac3dec->audblk.cplinu && p_ac3dec->audblk.chincpl[i]) + { + p_ac3dec->audblk.endmant[i] = p_ac3dec->audblk.cplstrtmant; + } + else + { + NeedBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->audblk.chbwcod[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 6)); + DumpBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->total_bits_read += 6; + p_ac3dec->audblk.endmant[i] = ((p_ac3dec->audblk.chbwcod[i] + 12) * 3) + 37; + } + + /* Calculate the number of exponent groups to fetch */ + grp_size = 3 * (1 << (p_ac3dec->audblk.chexpstr[i] - 1)); + p_ac3dec->audblk.nchgrps[i] = (p_ac3dec->audblk.endmant[i] - 1 + (grp_size - 3)) / grp_size; + } + } + + /* Get the coupling exponents if they exist */ + if(p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cplexpstr != EXP_REUSE)) + { + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cplabsexp = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + for(i=0;i< p_ac3dec->audblk.ncplgrps;i++) + { + NeedBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->audblk.cplexps[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 7)); + DumpBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->total_bits_read += 7; + } + } + + /* Get the fwb channel exponents */ + for(i=0;i < p_ac3dec->bsi.nfchans; i++) + { + if(p_ac3dec->audblk.chexpstr[i] != EXP_REUSE) + { + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.exps[i][0] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + for(j=1;j<=p_ac3dec->audblk.nchgrps[i];j++) + { + NeedBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->audblk.exps[i][j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 7)); + DumpBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->total_bits_read += 7; + } + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.gainrng[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + } + + /* Get the lfe channel exponents */ + if(p_ac3dec->bsi.lfeon && (p_ac3dec->audblk.lfeexpstr != EXP_REUSE)) + { + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.lfeexps[0] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->audblk.lfeexps[1] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 7)); + DumpBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->total_bits_read += 7; + NeedBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->audblk.lfeexps[2] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 7)); + DumpBits( &(p_ac3dec->bit_stream), 7 ); + p_ac3dec->total_bits_read += 7; + } + + /* Get the parametric bit allocation parameters */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.baie = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->audblk.baie) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.sdcycod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.fdcycod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.sgaincod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.dbpbcod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.floorcod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + + /* Get the SNR off set info if it exists */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.snroffste = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->audblk.snroffste) + { + NeedBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->audblk.csnroffst = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 6)); + DumpBits( &(p_ac3dec->bit_stream), 6 ); + p_ac3dec->total_bits_read += 6; + + if(p_ac3dec->audblk.cplinu) + { + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cplfsnroffst = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.cplfgaincod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + + for(i = 0;i < p_ac3dec->bsi.nfchans; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.fsnroffst[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.fgaincod[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + if(p_ac3dec->bsi.lfeon) + { + + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.lfefsnroffst = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.lfefgaincod = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + } + + /* Get coupling leakage info if it exists */ + if(p_ac3dec->audblk.cplinu) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.cplleake = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->audblk.cplleake) + { + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.cplfleak = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.cplsleak = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + } + + /* Get the delta bit alloaction info */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.deltbaie = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if(p_ac3dec->audblk.deltbaie) + { + if(p_ac3dec->audblk.cplinu) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.cpldeltbae = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + for(i = 0;i < p_ac3dec->bsi.nfchans; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->audblk.deltbae[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 2)); + DumpBits( &(p_ac3dec->bit_stream), 2 ); + p_ac3dec->total_bits_read += 2; + } + + if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cpldeltbae == DELTA_BIT_NEW)) + { + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.cpldeltnseg = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + for(i = 0;i < p_ac3dec->audblk.cpldeltnseg + 1; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->audblk.cpldeltoffst[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.cpldeltlen[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.cpldeltba[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + } + + for(i = 0;i < p_ac3dec->bsi.nfchans; i++) + { + if (p_ac3dec->audblk.deltbae[i] == DELTA_BIT_NEW) + { + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.deltnseg[i] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; +// if ( p_ac3dec->audblk.deltnseg[i] >= 8 ) +// fprintf( stderr, "parse debug: p_ac3dec->audblk.deltnseg[%i] == %i\n", i, p_ac3dec->audblk.deltnseg[i] ); + for(j = 0; j < p_ac3dec->audblk.deltnseg[i] + 1; j++) + { + NeedBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->audblk.deltoffst[i][j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 5)); + DumpBits( &(p_ac3dec->bit_stream), 5 ); + p_ac3dec->total_bits_read += 5; + NeedBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->audblk.deltlen[i][j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 4)); + DumpBits( &(p_ac3dec->bit_stream), 4 ); + p_ac3dec->total_bits_read += 4; + NeedBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->audblk.deltba[i][j] = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 3)); + DumpBits( &(p_ac3dec->bit_stream), 3 ); + p_ac3dec->total_bits_read += 3; + } + } + } + } + + /* Check to see if there's any dummy info to get */ + NeedBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->audblk.skiple = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 1)); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + if ( p_ac3dec->audblk.skiple ) + { + NeedBits( &(p_ac3dec->bit_stream), 9 ); + p_ac3dec->audblk.skipl = (u16)(p_ac3dec->bit_stream.fifo.buffer >> (32 - 9)); + DumpBits( &(p_ac3dec->bit_stream), 9 ); + p_ac3dec->total_bits_read += 9; + + for(i = 0; i < p_ac3dec->audblk.skipl ; i++) + { + NeedBits( &(p_ac3dec->bit_stream), 8 ); + DumpBits( &(p_ac3dec->bit_stream), 8 ); + p_ac3dec->total_bits_read += 8; + } + } +} + +void parse_auxdata( ac3dec_thread_t * p_ac3dec ) +{ + int i; + int skip_length; + + skip_length = (p_ac3dec->syncinfo.frame_size * 16) - p_ac3dec->total_bits_read - 17 - 1; +// fprintf( stderr, "parse debug: skip_length == %i\n", skip_length ); + + for ( i = 0; i < skip_length; i++ ) + { + NeedBits( &(p_ac3dec->bit_stream), 1 ); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + } + + //get the auxdata exists bit + NeedBits( &(p_ac3dec->bit_stream), 1 ); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + //Skip the CRC reserved bit + NeedBits( &(p_ac3dec->bit_stream), 1 ); + DumpBits( &(p_ac3dec->bit_stream), 1 ); + p_ac3dec->total_bits_read += 1; + + //Get the crc + NeedBits( &(p_ac3dec->bit_stream), 16 ); + DumpBits( &(p_ac3dec->bit_stream), 16 ); + p_ac3dec->total_bits_read += 16; +} diff --git a/src/ac3_decoder/ac3_rematrix.c b/src/ac3_decoder/ac3_rematrix.c new file mode 100644 index 0000000000..20b9bd2adb --- /dev/null +++ b/src/ac3_decoder/ac3_rematrix.c @@ -0,0 +1,75 @@ +#include /* getpid() */ + +#include /* "intf_msg.h" */ +#include /* malloc(), free() */ +#include /* "audio_output.h" */ +#include /* "input.h" */ + +#include "common.h" +#include "config.h" +#include "mtime.h" +#include "vlc_thread.h" +#include "debug.h" /* "input_netlist.h" */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "input.h" /* pes_packet_t */ +#include "input_netlist.h" /* input_NetlistFreePES() */ +#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */ + +#include "audio_output.h" + +#include "ac3_decoder.h" +#include "ac3_parse.h" +#include "ac3_exponent.h" +#include "ac3_bit_allocate.h" +#include "ac3_mantissa.h" +#include "ac3_rematrix.h" + +struct rematrix_band_s +{ + u32 start; + u32 end; +}; + +static struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}}; + +static __inline__ u32 min( u32 a, u32 b ) +{ + return( a < b ? a : b ); +} + +/* This routine simply does stereo rematixing for the 2 channel + * stereo mode */ +void rematrix( ac3dec_thread_t * p_ac3dec ) +{ + u32 num_bands; + u32 start; + u32 end; + u32 i,j; + float left,right; + + if(p_ac3dec->audblk.cplinu || p_ac3dec->audblk.cplbegf > 2) + num_bands = 4; + else if (p_ac3dec->audblk.cplbegf > 0) + num_bands = 3; + else + num_bands = 2; + + for(i=0;i < num_bands; i++) + { + if(!p_ac3dec->audblk.rematflg[i]) + continue; + + start = rematrix_band[i].start; + end = min(rematrix_band[i].end ,12 * p_ac3dec->audblk.cplbegf + 36); + + for(j=start;j < end; j++) + { + left = 0.5f * (p_ac3dec->coeffs.fbw[0][j] + p_ac3dec->coeffs.fbw[1][j]); + right = 0.5f * (p_ac3dec->coeffs.fbw[0][j] - p_ac3dec->coeffs.fbw[1][j]); + p_ac3dec->coeffs.fbw[0][j] = left; + p_ac3dec->coeffs.fbw[1][j] = right; + } + } +} diff --git a/src/input/input.c b/src/input/input.c index dd7b798c9b..c12d14f05d 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -349,6 +349,10 @@ static void EndThread( input_thread_t * p_input ) adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) ); break; + case AC3_AUDIO_ES: + ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) ); + break; + default: break; } @@ -979,20 +983,26 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input, PES fifo */ switch( p_es_descriptor->i_type ) { - case MPEG1_VIDEO_ES: - case MPEG2_VIDEO_ES: - p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo); - break; - case MPEG1_AUDIO_ES: - case MPEG2_AUDIO_ES: - p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo); - break; - default: - /* This should never happen. */ - intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n", - p_es_descriptor->i_id, p_es_descriptor->i_type); - p_fifo = NULL; - break; + case MPEG1_VIDEO_ES: + case MPEG2_VIDEO_ES: + p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo); + break; + + case MPEG1_AUDIO_ES: + case MPEG2_AUDIO_ES: + p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo); + break; + + case AC3_AUDIO_ES: + p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo); + break; + + default: + /* This should never happen */ + intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n", + p_es_descriptor->i_id, p_es_descriptor->i_type); + p_fifo = NULL; + break; } if( p_fifo != NULL ) diff --git a/src/input/input_ctrl.c b/src/input/input_ctrl.c index aad5a8ad38..53e84d6ae2 100644 --- a/src/input/input_ctrl.c +++ b/src/input/input_ctrl.c @@ -101,6 +101,17 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id ) /* Spawn the decoder. */ switch( p_input->p_es[i_es_loop].i_type ) { + case AC3_AUDIO_ES: + /* Spawn ac3 thread */ + if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) = + ac3dec_CreateThread(p_input)) == NULL ) + { + intf_ErrMsg( "Could not start ac3 decoder\n" ); + vlc_mutex_unlock( &p_input->es_lock ); + return( -1 ); + } + break; + case MPEG1_AUDIO_ES: case MPEG2_AUDIO_ES: /* Spawn audio thread. */ @@ -194,6 +205,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id ) /* Cancel the decoder. */ switch( p_input->pp_selected_es[i_selected_es_loop]->i_type ) { + case AC3_AUDIO_ES: + ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) ); + break; + case MPEG1_AUDIO_ES: case MPEG2_AUDIO_ES: adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) ); diff --git a/src/input/input_psi.c b/src/input/input_psi.c index 191e525dac..067c4726c8 100644 --- a/src/input/input_psi.c +++ b/src/input/input_psi.c @@ -218,6 +218,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section ) //intf_DbgMsg( "Section: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", (u8)p_psi_section->buffer[0], (u8)p_psi_section->buffer[1], (u8)p_psi_section->buffer[2], (u8)p_psi_section->buffer[3], (u8)p_psi_section->buffer[4], (u8)p_psi_section->buffer[5], (u8)p_psi_section->buffer[6], (u8)p_psi_section->buffer[7], (u8)p_psi_section->buffer[8], (u8)p_psi_section->buffer[9], (u8)p_psi_section->buffer[10], (u8)p_psi_section->buffer[11], (u8)p_psi_section->buffer[12], (u8)p_psi_section->buffer[13], (u8)p_psi_section->buffer[14], (u8)p_psi_section->buffer[15], (u8)p_psi_section->buffer[16], (u8)p_psi_section->buffer[17], (u8)p_psi_section->buffer[18], (u8)p_psi_section->buffer[19] ); /* Check the CRC validity if any CRC is carried */ +#if 0 if( p_psi_section->buffer[1] & 0x80 ) { if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) ) @@ -228,6 +229,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section ) return; } } +#endif /* If the section is not immediatly applicable, trash it (DVB drafts disallow transmission of such sections, so we didn't implement it) */ @@ -630,25 +632,37 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) { switch( p_input->p_es[i_es_loop].i_type ) { - case MPEG1_VIDEO_ES: - case MPEG2_VIDEO_ES: - if( p_main->b_video ) - { - /* Spawn a video thread */ - input_AddPgrmElem( p_input, - p_input->p_es[i_es_loop].i_id ); - } - break; - case MPEG1_AUDIO_ES: - case MPEG2_AUDIO_ES: - if( p_main->b_audio ) - { - /* Spawn an audio thread */ - input_AddPgrmElem( p_input, - p_input->p_es[i_es_loop].i_id ); - } - break; - default: + case MPEG1_VIDEO_ES: + case MPEG2_VIDEO_ES: + if( p_main->b_video ) + { + /* Spawn a video thread */ + input_AddPgrmElem( p_input, + p_input->p_es[i_es_loop].i_id ); + } + break; + + case AC3_AUDIO_ES: + if ( p_main->b_audio ) + { + /* Spawn an ac3 thread */ + input_AddPgrmElem( p_input, + p_input->p_es[i_es_loop].i_id ); + } + break; + + case MPEG1_AUDIO_ES: + case MPEG2_AUDIO_ES: + if( p_main->b_audio ) + { + /* Spawn an audio thread */ + input_AddPgrmElem( p_input, + p_input->p_es[i_es_loop].i_id ); + } + break; + + default: + break; } } #endif -- 2.39.2