]> git.sesse.net Git - vlc/commitdiff
* Modification de l'input afin de spawner un d�codeur ac3 lorsqu'un tel flux
authorMichel Kaempf <maxx@videolan.org>
Tue, 18 Jan 2000 13:55:43 +0000 (13:55 +0000)
committerMichel Kaempf <maxx@videolan.org>
Tue, 18 Jan 2000 13:55:43 +0000 (13:55 +0000)
est d�tect� ;

* Impl�mentation du d�codeur ac3 ;

* Il est rewlz(ac3dec) - 2h00 :-)

21 files changed:
Makefile
include/ac3_bit_allocate.h [new file with mode: 0644]
include/ac3_decoder.h
include/ac3_downmix.h [new file with mode: 0644]
include/ac3_exponent.h [new file with mode: 0644]
include/ac3_imdct.h [new file with mode: 0644]
include/ac3_mantissa.h [new file with mode: 0644]
include/ac3_parse.h [new file with mode: 0644]
include/ac3_rematrix.h [new file with mode: 0644]
include/input.h
src/ac3_decoder/ac3_bit_allocate.c [new file with mode: 0644]
src/ac3_decoder/ac3_decoder.c
src/ac3_decoder/ac3_downmix.c [new file with mode: 0644]
src/ac3_decoder/ac3_exponent.c [new file with mode: 0644]
src/ac3_decoder/ac3_imdct.c [new file with mode: 0644]
src/ac3_decoder/ac3_mantissa.c [new file with mode: 0644]
src/ac3_decoder/ac3_parse.c [new file with mode: 0644]
src/ac3_decoder/ac3_rematrix.c [new file with mode: 0644]
src/input/input.c
src/input/input_ctrl.c
src/input/input_psi.c

index ba68aabfa0744bef5940418c59c8048e48a146b5..50e8121f729b7f346cf6b12b9196684247d451e5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -176,7 +176,14 @@ video_output_obj =                 video_output/video_output.o \
                                                video_output/video_$(video).o \
                                                video_output/video_yuv_c.o
 
-ac3_decoder_obj =              ac3_decoder/ac3_decoder.o
+ac3_decoder_obj =              ac3_decoder/ac3_decoder.o \
+                                               ac3_decoder/ac3_parse.o \
+                                               ac3_decoder/ac3_exponent.o \
+                                               ac3_decoder/ac3_bit_allocate.o \
+                                               ac3_decoder/ac3_mantissa.o \
+                                               ac3_decoder/ac3_rematrix.o \
+                                               ac3_decoder/ac3_imdct.o \
+                                               ac3_decoder/ac3_downmix.o
 
 audio_decoder_obj =            audio_decoder/audio_decoder.o \
                                                audio_decoder/audio_math.o
diff --git a/include/ac3_bit_allocate.h b/include/ac3_bit_allocate.h
new file mode 100644 (file)
index 0000000..9332be6
--- /dev/null
@@ -0,0 +1 @@
+void bit_allocate( ac3dec_thread_t * );
index fb4add8af4b281c9f96a303f3cabdce2d5031f2a..7f367b4f4f2fbf4eb4dcd4cfe83e894ca01ebc61 100644 (file)
@@ -3,6 +3,320 @@
  * (c)1999 VideoLAN
  *****************************************************************************/
 
+/* Exponent strategy constants */
+#define EXP_REUSE       (0)
+#define EXP_D15         (1)
+#define EXP_D25         (2)
+#define EXP_D45         (3)
+
+/* Delta bit allocation constants */
+#define DELTA_BIT_REUSE         (0)
+#define DELTA_BIT_NEW           (1)
+#define DELTA_BIT_NONE          (2)
+#define DELTA_BIT_RESERVED      (3)
+
+/* The following structures are filled in by their corresponding parse_*
+ * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
+ * full details on each field. Indented fields are used to denote
+ * conditional fields.
+ */
+
+typedef struct syncinfo_s
+{
+       /* Sync word == 0x0B77 */
+       /* u16   syncword; */
+       /* crc for the first 5/8 of the sync block */
+       /* u16   crc1; */
+       /* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
+       u16             fscod;  
+       /* Frame size code */
+       u16             frmsizecod;
+
+       /* Information not in the AC-3 bitstream, but derived */
+       /* Frame size in 16 bit words */
+       u16 frame_size;
+       /* Bit rate in kilobits */
+       u16 bit_rate;
+
+} syncinfo_t;
+
+typedef struct bsi_s
+{
+       /* Bit stream identification == 0x8 */
+       u16 bsid;       
+       /* Bit stream mode */
+       u16 bsmod;
+       /* Audio coding mode */
+       u16 acmod;
+       /* If we're using the centre channel then */
+               /* centre mix level */
+               u16 cmixlev;
+       /* If we're using the surround channel then */
+               /* surround mix level */
+               u16 surmixlev;
+       /* If we're in 2/0 mode then */
+               /* Dolby surround mix level - NOT USED - */
+               u16 dsurmod;
+       /* Low frequency effects on */
+       u16 lfeon;
+       /* Dialogue Normalization level */
+       u16 dialnorm;
+       /* Compression exists */
+       u16 compre;
+               /* Compression level */
+               u16 compr;
+       /* Language code exists */
+       u16 langcode;
+               /* Language code */
+               u16 langcod;
+       /* Audio production info exists*/
+       u16 audprodie;
+               u16 mixlevel;
+               u16 roomtyp;
+       /* If we're in dual mono mode (acmod == 0) then extra stuff */
+               u16 dialnorm2;
+               u16 compr2e;
+                       u16 compr2;
+               u16 langcod2e;
+                       u16 langcod2;
+               u16 audprodi2e;
+                       u16 mixlevel2;
+                       u16 roomtyp2;
+       /* Copyright bit */
+       u16 copyrightb;
+       /* Original bit */
+       u16 origbs;
+       /* Timecode 1 exists */
+       u16 timecod1e;
+               /* Timecode 1 */
+               u16 timecod1;
+       /* Timecode 2 exists */
+       u16 timecod2e;
+               /* Timecode 2 */
+               u16 timecod2;
+       /* Additional bit stream info exists */
+       u16 addbsie;
+               /* Additional bit stream length - 1 (in bytes) */
+               u16 addbsil;
+               /* Additional bit stream information (max 64 bytes) */
+               u8      addbsi[64];
+
+       /* Information not in the AC-3 bitstream, but derived */
+       /* Number of channels (excluding LFE)
+        * Derived from acmod */
+       u16 nfchans;
+
+} bsi_t;
+
+/* more pain */
+typedef struct audblk_s
+{
+       /* block switch bit indexed by channel num */
+       u16 blksw[5];
+       /* dither enable bit indexed by channel num */
+       u16 dithflag[5];
+       /* dynamic range gain exists */
+       u16 dynrnge;
+               /* dynamic range gain */
+               u16 dynrng;
+       /* if acmod==0 then */
+       /* dynamic range 2 gain exists */
+       u16 dynrng2e;
+               /* dynamic range 2 gain */
+               u16 dynrng2;
+       /* coupling strategy exists */
+       u16 cplstre;
+               /* coupling in use */
+               u16 cplinu;
+                       /* channel coupled */
+                       u16 chincpl[5];
+                       /* if acmod==2 then */
+                               /* Phase flags in use */
+                               u16 phsflginu;
+                       /* coupling begin frequency code */
+                       u16 cplbegf;
+                       /* coupling end frequency code */
+                       u16 cplendf;
+                       /* coupling band structure bits */
+                       u16 cplbndstrc[18];
+                       /* Do coupling co-ords exist for this channel? */
+                       u16 cplcoe[5];
+                       /* Master coupling co-ordinate */
+                       u16 mstrcplco[5];
+                       /* Per coupling band coupling co-ordinates */
+                       u16 cplcoexp[5][18];
+                       u16     cplcomant[5][18];
+                       /* Phase flags for dual mono */
+                       u16 phsflg[18];
+       /* Is there a rematrixing strategy */
+       u16 rematstr;
+               /* Rematrixing bits */
+               u16 rematflg[4];
+       /* Coupling exponent strategy */
+       u16 cplexpstr;
+       /* Exponent strategy for full bandwidth channels */
+       u16 chexpstr[5];
+       /* Exponent strategy for lfe channel */
+       u16 lfeexpstr;
+       /* Channel bandwidth for independent channels */
+       u16 chbwcod[5];
+               /* The absolute coupling exponent */
+               u16 cplabsexp;
+               /* Coupling channel exponents (D15 mode gives 18 * 12 /3  encoded exponents */
+               u16 cplexps[18 * 12 / 3];
+       /* Sanity checking constant */
+       u32     magic2;
+       /* fbw channel exponents */
+       u16 exps[5][252 / 3];
+       /* channel gain range */
+       u16 gainrng[5];
+       /* low frequency exponents */
+       u16 lfeexps[3];
+
+       /* Bit allocation info */
+       u16 baie;
+               /* Slow decay code */
+               u16 sdcycod;
+               /* Fast decay code */
+               u16 fdcycod;
+               /* Slow gain code */
+               u16 sgaincod;
+               /* dB per bit code */
+               u16 dbpbcod;
+               /* masking floor code */
+               u16 floorcod;
+
+       /* SNR offset info */
+       u16 snroffste;
+               /* coarse SNR offset */
+               u16 csnroffst;
+               /* coupling fine SNR offset */
+               u16 cplfsnroffst;
+               /* coupling fast gain code */
+               u16 cplfgaincod;
+               /* fbw fine SNR offset */
+               u16 fsnroffst[5];
+               /* fbw fast gain code */
+               u16 fgaincod[5];
+               /* lfe fine SNR offset */
+               u16 lfefsnroffst;
+               /* lfe fast gain code */
+               u16 lfefgaincod;
+       
+       /* Coupling leak info */
+       u16 cplleake;
+               /* coupling fast leak initialization */
+               u16 cplfleak;
+               /* coupling slow leak initialization */
+               u16 cplsleak;
+       
+       /* delta bit allocation info */
+       u16 deltbaie;
+               /* coupling delta bit allocation exists */
+               u16 cpldeltbae;
+               /* fbw delta bit allocation exists */
+               u16 deltbae[5];
+               /* number of cpl delta bit segments */
+               u16 cpldeltnseg;
+                       /* coupling delta bit allocation offset */
+                       u16 cpldeltoffst[8];
+                       /* coupling delta bit allocation length */
+                       u16 cpldeltlen[8];
+                       /* coupling delta bit allocation length */
+                       u16 cpldeltba[8];
+               /* number of delta bit segments */
+               u16 deltnseg[5];
+                       /* fbw delta bit allocation offset */
+                       u16 deltoffst[5][8];
+                       /* fbw delta bit allocation length */
+                       u16 deltlen[5][8];
+                       /* fbw delta bit allocation length */
+                       u16 deltba[5][8];
+
+       /* skip length exists */
+       u16 skiple;
+               /* skip length */
+               u16 skipl;
+
+       /* channel mantissas */
+//     u16     chmant[5][256];
+
+       /* coupling mantissas */
+       float cplfbw[ 256 ];
+//     u16     cplmant[256];
+
+       /* coupling mantissas */
+//     u16     lfemant[7];
+
+       /*  -- Information not in the bitstream, but derived thereof  -- */
+
+       /* Number of coupling sub-bands */
+       u16 ncplsubnd;
+
+       /* Number of combined coupling sub-bands
+        * Derived from ncplsubnd and cplbndstrc */
+       u16 ncplbnd;
+
+       /* Number of exponent groups by channel
+        * Derived from strmant, endmant */
+       u16 nchgrps[5];
+
+       /* Number of coupling exponent groups
+        * Derived from cplbegf, cplendf, cplexpstr */
+       u16 ncplgrps;
+                       
+       /* End mantissa numbers of fbw channels */
+       u16 endmant[5];
+
+       /* Start and end mantissa numbers for the coupling channel */
+       u16 cplstrtmant;
+       u16 cplendmant;
+
+       /* Decoded exponent info */
+       u16 fbw_exp[5][256];
+       u16 cpl_exp[256];
+       u16 lfe_exp[7];
+
+       /* Bit allocation pointer results */
+       u16 fbw_bap[5][256];
+       //FIXME figure out exactly how many entries there should be (253-37?) 
+       u16 cpl_bap[256];
+       u16 lfe_bap[7];
+
+} audblk_t;
+
+/* Everything you wanted to know about band structure */
+/*
+ * The entire frequency domain is represented by 256 real
+ * floating point fourier coefficients. Only the lower 253
+ * coefficients are actually utilized however. We use arrays
+ * of 256 to be efficient in some cases.
+ *
+ * The 5 full bandwidth channels (fbw) can have their higher
+ * frequencies coupled together. These coupled channels then
+ * share their high frequency components.
+ *
+ * This coupling band is broken up into 18 sub-bands starting
+ * at mantissa number 37. Each sub-band is 12 bins wide.
+ *
+ * There are 50 bit allocation sub-bands which cover the entire
+ * frequency range. The sub-bands are of non-uniform width, and
+ * approximate a 1/6 octave scale.
+ */
+
+typedef struct stream_coeffs_s
+{
+       float fbw[5][256];
+       float lfe[256];
+
+} stream_coeffs_t;
+
+typedef struct stream_samples_s
+{
+       float channel[6][256];
+
+} stream_samples_t;
+
 #define AC3DEC_FRAME_SIZE (2*256)
 
 /*****************************************************************************
@@ -34,6 +348,13 @@ typedef struct ac3dec_thread_s
      */
     unsigned int        total_bits_read;
 
+    syncinfo_t          syncinfo;
+    bsi_t               bsi;
+    audblk_t            audblk;
+
+    stream_coeffs_t     coeffs;
+    stream_samples_t    samples;
+
     /*
      * Output properties
      */
diff --git a/include/ac3_downmix.h b/include/ac3_downmix.h
new file mode 100644 (file)
index 0000000..41e135a
--- /dev/null
@@ -0,0 +1 @@
+void downmix( ac3dec_thread_t *, s16 * );
diff --git a/include/ac3_exponent.h b/include/ac3_exponent.h
new file mode 100644 (file)
index 0000000..0ff520f
--- /dev/null
@@ -0,0 +1,5 @@
+#define UNPACK_FBW  1
+#define UNPACK_CPL  2
+#define UNPACK_LFE  4
+
+void exponent_unpack( ac3dec_thread_t * );
diff --git a/include/ac3_imdct.h b/include/ac3_imdct.h
new file mode 100644 (file)
index 0000000..c2c11d8
--- /dev/null
@@ -0,0 +1,2 @@
+void imdct( ac3dec_thread_t * p_ac3dec );
+void imdct_init( void );
diff --git a/include/ac3_mantissa.h b/include/ac3_mantissa.h
new file mode 100644 (file)
index 0000000..fa93fe4
--- /dev/null
@@ -0,0 +1 @@
+void mantissa_unpack( ac3dec_thread_t * );
diff --git a/include/ac3_parse.h b/include/ac3_parse.h
new file mode 100644 (file)
index 0000000..00d0f57
--- /dev/null
@@ -0,0 +1,4 @@
+void parse_syncinfo( ac3dec_thread_t * );
+void parse_bsi( ac3dec_thread_t * );
+void parse_audblk( ac3dec_thread_t * );
+void parse_auxdata( ac3dec_thread_t * );
diff --git a/include/ac3_rematrix.h b/include/ac3_rematrix.h
new file mode 100644 (file)
index 0000000..7d49300
--- /dev/null
@@ -0,0 +1 @@
+void rematrix( ac3dec_thread_t * );
index 743c27656d97b9ffdb289eb501a60dd2882b0e25..140cf2ef9dee9517b36f3d1422dcbbc65c0ca589 100644 (file)
@@ -164,7 +164,7 @@ typedef struct
 #define MPEG2_VIDEO_ES          0x02
 #define MPEG1_AUDIO_ES          0x03
 #define MPEG2_AUDIO_ES          0x04
-
+#define AC3_AUDIO_ES            0x81
 
 /******************************************************************************
  * program_descriptor_t
diff --git a/src/ac3_decoder/ac3_bit_allocate.c b/src/ac3_decoder/ac3_bit_allocate.c
new file mode 100644 (file)
index 0000000..6dfc3c9
--- /dev/null
@@ -0,0 +1,485 @@
+#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
+}
index 043a4baa35921bd78af77eca4df1080dc666af35..6cc6d9c017641f866d0df23e9e91e3ae498a80a5 100644 (file)
@@ -6,6 +6,10 @@
 /*****************************************************************************
  * 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
@@ -85,6 +96,8 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
     p_ac3dec->p_aout = p_input->p_aout;
     p_ac3dec->p_aout_fifo = NULL;
 
+    imdct_init();
+
     /* Spawn the ac3 decoder thread */
     if ( vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec) )
     {
@@ -177,6 +190,10 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
  *****************************************************************************/
 static void RunThread( ac3dec_thread_t * p_ac3dec )
 {
+    int i;
+    mtime_t mdate = 0;
+    byte_t byte;
+
     intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() );
 
     /* Initializing the ac3 decoder thread */
@@ -185,14 +202,39 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
         p_ac3dec->b_error = 1;
     }
 
+    i = open( "/tmp/taxi.ac3", O_WRONLY|O_CREAT|O_TRUNC );
     /* ac3 decoder thread's main loop */
     while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
     {
-        if ( decode_find_sync(p_ac3dec) == 0 )
+           byte = GetByte( &(p_ac3dec->bit_stream) );
+           write( i, &byte, 1 );
+#if 0
+        decode_find_sync( p_ac3dec );
+       parse_syncinfo( p_ac3dec );
+       parse_bsi( p_ac3dec );
+        for ( i = 0; i < 6; i++ )
         {
-            fprintf( stderr, "ac3dec debug: decode_find_sync() == 0\n" );
+            parse_audblk( p_ac3dec );
+            exponent_unpack( p_ac3dec );
+            bit_allocate( p_ac3dec );
+            mantissa_unpack( p_ac3dec );
+            if ( p_ac3dec->bsi.acmod == 0x2 )
+            {
+                rematrix( p_ac3dec );
+            }
+            imdct( p_ac3dec );
+
+           vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
+           downmix( p_ac3dec, ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ] );
+           p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = mdate;
+           p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+           vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
+           mdate += 5333;
         }
+        parse_auxdata( p_ac3dec );
+#endif
     }
+    close( i );
 
     /* If b_error is set, the ac3 decoder thread enters the error loop */
     if ( p_ac3dec->b_error )
diff --git a/src/ac3_decoder/ac3_downmix.c b/src/ac3_decoder/ac3_downmix.c
new file mode 100644 (file)
index 0000000..aa643ac
--- /dev/null
@@ -0,0 +1,394 @@
+#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;
+               }
+       }
+}
diff --git a/src/ac3_decoder/ac3_exponent.c b/src/ac3_decoder/ac3_exponent.c
new file mode 100644 (file)
index 0000000..c6154a0
--- /dev/null
@@ -0,0 +1,126 @@
+#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);
+}
diff --git a/src/ac3_decoder/ac3_imdct.c b/src/ac3_decoder/ac3_imdct.c
new file mode 100644 (file)
index 0000000..ea24bb2
--- /dev/null
@@ -0,0 +1,425 @@
+#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]; 
+       }
+}
diff --git a/src/ac3_decoder/ac3_mantissa.c b/src/ac3_decoder/ac3_mantissa.c
new file mode 100644 (file)
index 0000000..80580fc
--- /dev/null
@@ -0,0 +1,481 @@
+#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
+               }
+       }
+}
diff --git a/src/ac3_decoder/ac3_parse.c b/src/ac3_decoder/ac3_parse.c
new file mode 100644 (file)
index 0000000..e34568a
--- /dev/null
@@ -0,0 +1,892 @@
+#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;
+}
diff --git a/src/ac3_decoder/ac3_rematrix.c b/src/ac3_decoder/ac3_rematrix.c
new file mode 100644 (file)
index 0000000..20b9bd2
--- /dev/null
@@ -0,0 +1,75 @@
+#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;
+               }
+       }
+}
index dd7b798c9bfa5967cbaa48b78287f7e189d42232..c12d14f05df085f0cad5012efbbd8159ec550c16 100644 (file)
@@ -349,6 +349,10 @@ static void EndThread( input_thread_t * p_input )
                     adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) );
                     break;
 
+                case AC3_AUDIO_ES:
+                    ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
+                    break;
+
                 default:
                     break;
             }
@@ -979,20 +983,26 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
                PES fifo */
             switch( p_es_descriptor->i_type )
             {
-            case MPEG1_VIDEO_ES:
-            case MPEG2_VIDEO_ES:
-                p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-                break;
-            case MPEG1_AUDIO_ES:
-            case MPEG2_AUDIO_ES:
-                p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-                break;
-            default:
-                /* This should never happen. */
-                intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
-                            p_es_descriptor->i_id, p_es_descriptor->i_type);
-                p_fifo = NULL;
-                break;
+                case MPEG1_VIDEO_ES:
+                case MPEG2_VIDEO_ES:
+                    p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
+                    break;
+
+                case MPEG1_AUDIO_ES:
+                case MPEG2_AUDIO_ES:
+                    p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
+                    break;
+
+                case AC3_AUDIO_ES:
+                    p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
+                    break;
+
+                default:
+                    /* This should never happen */
+                    intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
+                        p_es_descriptor->i_id, p_es_descriptor->i_type);
+                    p_fifo = NULL;
+                    break;
             }
 
             if( p_fifo != NULL )
index aad5a8ad3821fd5e34d3aa6819d550514a58e66e..53e84d6ae25f65258fb65e3dc53acecded6a102a 100644 (file)
@@ -101,6 +101,17 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
                 /* Spawn the decoder. */
                 switch( p_input->p_es[i_es_loop].i_type )
                 {
+                    case AC3_AUDIO_ES:
+                        /* Spawn ac3 thread */
+                        if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
+                            ac3dec_CreateThread(p_input)) == NULL )
+                        {
+                            intf_ErrMsg( "Could not start ac3 decoder\n" );
+                            vlc_mutex_unlock( &p_input->es_lock );
+                            return( -1 );
+                        }
+                        break;
+
                     case MPEG1_AUDIO_ES:
                     case MPEG2_AUDIO_ES:
                         /* Spawn audio thread. */
@@ -194,6 +205,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
                 /* Cancel the decoder. */
                 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
                 {
+                    case AC3_AUDIO_ES:
+                        ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
+                        break;
+
                     case MPEG1_AUDIO_ES:
                     case MPEG2_AUDIO_ES:
                         adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
index 191e525dac53b780551f1a1987b45706955996da..067c4726c82143dcc7aa46c905a1c61d63433faa 100644 (file)
@@ -218,6 +218,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
   //intf_DbgMsg( "Section: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", (u8)p_psi_section->buffer[0], (u8)p_psi_section->buffer[1], (u8)p_psi_section->buffer[2], (u8)p_psi_section->buffer[3], (u8)p_psi_section->buffer[4], (u8)p_psi_section->buffer[5], (u8)p_psi_section->buffer[6], (u8)p_psi_section->buffer[7], (u8)p_psi_section->buffer[8], (u8)p_psi_section->buffer[9], (u8)p_psi_section->buffer[10], (u8)p_psi_section->buffer[11], (u8)p_psi_section->buffer[12], (u8)p_psi_section->buffer[13], (u8)p_psi_section->buffer[14], (u8)p_psi_section->buffer[15], (u8)p_psi_section->buffer[16], (u8)p_psi_section->buffer[17], (u8)p_psi_section->buffer[18], (u8)p_psi_section->buffer[19] );
 
   /* Check the CRC validity if any CRC is carried */
+#if 0
   if( p_psi_section->buffer[1] & 0x80 )
   {
     if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) )
@@ -228,6 +229,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
       return;
     }
   }
+#endif
   
   /* If the section is not immediatly applicable, trash it (DVB drafts disallow
      transmission of such sections, so we didn't implement it) */
@@ -630,25 +632,37 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
               {
                   switch( p_input->p_es[i_es_loop].i_type )
                   {
-                  case MPEG1_VIDEO_ES:
-                  case MPEG2_VIDEO_ES:
-                      if( p_main->b_video )
-                      {
-                           /* Spawn a video thread */
-                           input_AddPgrmElem( p_input,
-                                              p_input->p_es[i_es_loop].i_id );
-                      }
-                      break;
-                  case MPEG1_AUDIO_ES:
-                  case MPEG2_AUDIO_ES:
-                      if( p_main->b_audio )
-                      {
-                          /* Spawn an audio thread */
-                          input_AddPgrmElem( p_input,
-                                             p_input->p_es[i_es_loop].i_id );
-                      }
-                      break;
-                  default:
+                      case MPEG1_VIDEO_ES:
+                      case MPEG2_VIDEO_ES:
+                          if( p_main->b_video )
+                          {
+                              /* Spawn a video thread */
+                              input_AddPgrmElem( p_input,
+                                  p_input->p_es[i_es_loop].i_id );
+                          }
+                          break;
+
+                      case AC3_AUDIO_ES:
+                          if ( p_main->b_audio )
+                          {
+                              /* Spawn an ac3 thread */
+                              input_AddPgrmElem( p_input,
+                                  p_input->p_es[i_es_loop].i_id );
+                              }
+                          break;
+
+                      case MPEG1_AUDIO_ES:
+                      case MPEG2_AUDIO_ES:
+                          if( p_main->b_audio )
+                          {
+                              /* Spawn an audio thread */
+                              input_AddPgrmElem( p_input,
+                                  p_input->p_es[i_es_loop].i_id );
+                          }
+                          break;
+
+                      default:
+                          break;
                   }
               }
 #endif