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
--- /dev/null
+void bit_allocate( ac3dec_thread_t * );
* (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)
/*****************************************************************************
*/
unsigned int total_bits_read;
+ syncinfo_t syncinfo;
+ bsi_t bsi;
+ audblk_t audblk;
+
+ stream_coeffs_t coeffs;
+ stream_samples_t samples;
+
/*
* Output properties
*/
--- /dev/null
+void downmix( ac3dec_thread_t *, s16 * );
--- /dev/null
+#define UNPACK_FBW 1
+#define UNPACK_CPL 2
+#define UNPACK_LFE 4
+
+void exponent_unpack( ac3dec_thread_t * );
--- /dev/null
+void imdct( ac3dec_thread_t * p_ac3dec );
+void imdct_init( void );
--- /dev/null
+void mantissa_unpack( ac3dec_thread_t * );
--- /dev/null
+void parse_syncinfo( ac3dec_thread_t * );
+void parse_bsi( ac3dec_thread_t * );
+void parse_audblk( ac3dec_thread_t * );
+void parse_auxdata( ac3dec_thread_t * );
--- /dev/null
+void rematrix( ac3dec_thread_t * );
#define MPEG2_VIDEO_ES 0x02
#define MPEG1_AUDIO_ES 0x03
#define MPEG2_AUDIO_ES 0x04
-
+#define AC3_AUDIO_ES 0x81
/******************************************************************************
* program_descriptor_t
--- /dev/null
+#include <unistd.h> /* getpid() */
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <stdlib.h> /* malloc(), free() */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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<end; bin++)
+ {
+ psd[bin] = (3072 - (exps[bin] << 7));
+ }
+
+ /* Integrate the psd function over each bit allocation band */
+ j = start;
+ k = masktab[start];
+
+ do
+ {
+ lastbin = min(bndtab[k] + bndsz[k], end);
+ bndpsd[k] = psd[j];
+ j++;
+
+ for (i = j; i < lastbin; i++)
+ {
+ bndpsd[k] = logadd(bndpsd[k], psd[j]);
+ j++;
+ }
+
+ k++;
+ } while (end > 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
+}
/*****************************************************************************
* Preamble
*****************************************************************************/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
#include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */
#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
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) )
{
*****************************************************************************/
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 */
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 )
--- /dev/null
+#include <unistd.h> /* getpid() */
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <stdlib.h> /* malloc(), free() */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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;
+ }
+ }
+}
--- /dev/null
+#include <unistd.h> /* getpid() */
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <stdlib.h> /* malloc(), free() */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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);
+}
--- /dev/null
+#include <unistd.h> /* getpid() */
+
+#include <math.h>
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <stdlib.h> /* malloc(), free() */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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; i<p_ac3dec->bsi.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<N/4; i++)
+ {
+ k = bit_reverse_512[i];
+ if (k < i)
+ swap_cmplx(&buf[i],&buf[k]);
+ }
+
+ /* FFT Merge */
+ for (m=0; m < 7; m++)
+ {
+ two_m = (1 << m);
+ two_m_plus_one = (1 << (m+1));
+
+ for(k = 0; k < two_m; k++)
+ {
+ for(i = 0; i < 128; i += two_m_plus_one)
+ {
+ p = k + i;
+ q = p + two_m;
+ tmp_a_r = buf[p].real;
+ tmp_a_i = buf[p].imag;
+ tmp_b_r = buf[q].real * w[m][k].real - buf[q].imag * w[m][k].imag;
+ tmp_b_i = buf[q].imag * w[m][k].real + buf[q].real * w[m][k].imag;
+ buf[p].real = tmp_a_r + tmp_b_r;
+ buf[p].imag = tmp_a_i + tmp_b_i;
+ buf[q].real = tmp_a_r - tmp_b_r;
+ buf[q].imag = tmp_a_i - tmp_b_i;
+
+ }
+ }
+ }
+
+ /* Post IFFT complex multiply plus IFFT complex conjugate*/
+ for( i=0; i < N/4; i++)
+ {
+ /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
+ tmp_a_r = buf[i].real;
+ tmp_a_i = - buf[i].imag;
+ buf[i].real =(tmp_a_r * xcos1[i]) - (tmp_a_i * xsin1[i]);
+ buf[i].imag =(tmp_a_r * xsin1[i]) + (tmp_a_i * xcos1[i]);
+ }
+
+ y_ptr = y;
+ delay_ptr = delay;
+ window_ptr = window;
+ /* Window and convert to real valued signal */
+ for(i=0; i<N/8; i++)
+ {
+ *y_ptr++ = 2.0f * (-buf[N/8+i].imag * *window_ptr++ + *delay_ptr++);
+ *y_ptr++ = 2.0f * ( buf[N/8-i-1].real * *window_ptr++ + *delay_ptr++);
+ }
+
+ for(i=0; i<N/8; i++)
+ {
+ *y_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++);
+ *y_ptr++ = 2.0f * ( buf[N/4-i-1].imag * *window_ptr++ + *delay_ptr++);
+ }
+
+ /* The trailing edge of the window goes into the delay line */
+ delay_ptr = delay;
+
+ for(i=0; i<N/8; i++)
+ {
+ *delay_ptr++ = -buf[N/8+i].real * *--window_ptr;
+ *delay_ptr++ = buf[N/8-i-1].imag * *--window_ptr;
+ }
+
+ for(i=0; i<N/8; i++)
+ {
+ *delay_ptr++ = buf[i].imag * *--window_ptr;
+ *delay_ptr++ = -buf[N/4-i-1].real * *--window_ptr;
+ }
+}
+
+void
+imdct_do_256(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;
+
+ complex_t *buf_1, *buf_2;
+
+ buf_1 = &buf[0];
+ buf_2 = &buf[64];
+
+ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+ for(k=0; k<N/8; k++)
+ {
+ /* X1[k] = X[2*k] */
+ /* X2[k] = X[2*k+1] */
+
+ p = 2 * (N/4-2*k-1);
+ q = 2 * (2 * k);
+
+ /* Z1[k] = (X1[N/4-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
+ buf_1[k].real = x[p] * xcos2[k] - x[q] * xsin2[k];
+ buf_1[k].imag = - (x[q] * xcos2[k] + x[p] * xsin2[k]);
+ /* Z2[k] = (X2[N/4-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
+ buf_2[k].real = x[p + 1] * xcos2[k] - x[q + 1] * xsin2[k];
+ buf_2[k].imag = - (x[q + 1] * xcos2[k] + x[p + 1] * xsin2[k]);
+ }
+
+ //IFFT Bit reversed shuffling
+ for(i=0; i<N/8; i++)
+ {
+ k = bit_reverse_256[i];
+ if (k < i)
+ {
+ swap_cmplx(&buf_1[i],&buf_1[k]);
+ swap_cmplx(&buf_2[i],&buf_2[k]);
+ }
+ }
+
+ /* FFT Merge */
+ for (m=0; m < 6; m++)
+ {
+ two_m = (1 << m);
+ two_m_plus_one = (1 << (m+1));
+
+ for(k = 0; k < two_m; k++)
+ {
+ for(i = 0; i < 64; i += two_m_plus_one)
+ {
+ p = k + i;
+ q = p + two_m;
+ //Do block 1
+ tmp_a_r = buf_1[p].real;
+ tmp_a_i = buf_1[p].imag;
+ tmp_b_r = buf_1[q].real * w[m][k].real - buf_1[q].imag * w[m][k].imag;
+ tmp_b_i = buf_1[q].imag * w[m][k].real + buf_1[q].real * w[m][k].imag;
+ buf_1[p].real = tmp_a_r + tmp_b_r;
+ buf_1[p].imag = tmp_a_i + tmp_b_i;
+ buf_1[q].real = tmp_a_r - tmp_b_r;
+ buf_1[q].imag = tmp_a_i - tmp_b_i;
+
+ //Do block 2
+ tmp_a_r = buf_2[p].real;
+ tmp_a_i = buf_2[p].imag;
+ tmp_b_r = buf_2[q].real * w[m][k].real - buf_2[q].imag * w[m][k].imag;
+ tmp_b_i = buf_2[q].imag * w[m][k].real + buf_2[q].real * w[m][k].imag;
+ buf_2[p].real = tmp_a_r + tmp_b_r;
+ buf_2[p].imag = tmp_a_i + tmp_b_i;
+ buf_2[q].real = tmp_a_r - tmp_b_r;
+ buf_2[q].imag = tmp_a_i - tmp_b_i;
+
+ }
+ }
+ }
+
+ /* Post IFFT complex multiply */
+ for( i=0; i < N/8; i++)
+ {
+ /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
+ tmp_a_r = buf_1[i].real;
+ tmp_a_i = - buf_1[i].imag;
+ buf_1[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
+ buf_1[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
+ /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
+ tmp_a_r = buf_2[i].real;
+ tmp_a_i = - buf_2[i].imag;
+ buf_2[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
+ buf_2[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
+ }
+
+ /* Window and convert to real valued signal */
+ for(i=0; i<N/8; i++)
+ {
+ y[2*i] = -buf_1[i].imag * window[2*i];
+ y[2*i+1] = buf_1[N/8-i-1].real * window[2*i+1];
+ y[N/4+2*i] = -buf_1[i].real * window[N/4+2*i];
+ y[N/4+2*i+1] = buf_1[N/8-i-1].imag * window[N/4+2*i+1];
+ y[N/2+2*i] = -buf_2[i].real * window[N/2-2*i-1];
+ y[N/2+2*i+1] = buf_2[N/8-i-1].imag * window[N/2-2*i-2];
+ y[3*N/4+2*i] = buf_2[i].imag * window[N/4-2*i-1];
+ y[3*N/4+2*i+1] = -buf_2[N/8-i-1].real * window[N/4-2*i-2];
+ }
+
+ /* Overlap and add */
+ for(i=0; i<N/2; i++)
+ {
+ y[i] = 2 * (y[i] + delay[i]);
+ delay[i] = y[N/2+i];
+ }
+}
--- /dev/null
+#include <unistd.h> /* getpid() */
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <stdlib.h> /* malloc(), free() */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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;i<p_ac3dec->audblk.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
+ }
+ }
+}
--- /dev/null
+#include <stdio.h> /* "intf_msg.h" */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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;
+}
--- /dev/null
+#include <unistd.h> /* getpid() */
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <stdlib.h> /* malloc(), free() */
+#include <sys/soundcard.h> /* "audio_output.h" */
+#include <sys/uio.h> /* "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;
+ }
+ }
+}
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;
}
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 )
/* 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. */
/* 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) );
//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) )
return;
}
}
+#endif
/* If the section is not immediatly applicable, trash it (DVB drafts disallow
transmission of such sections, so we didn't implement it) */
{
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