Commit 6bc7ac7c authored by Michel Kaempf's avatar Michel Kaempf

* Modification de l'input afin de spawner un d�codeur ac3 lorsqu'un tel flux

est d�tect� ;

* Impl�mentation du d�codeur ac3 ;

* Il est rewlz(ac3dec) - 2h00 :-)
parent b9dc0c52
...@@ -176,7 +176,14 @@ video_output_obj = video_output/video_output.o \ ...@@ -176,7 +176,14 @@ video_output_obj = video_output/video_output.o \
video_output/video_$(video).o \ video_output/video_$(video).o \
video_output/video_yuv_c.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_obj = audio_decoder/audio_decoder.o \
audio_decoder/audio_math.o audio_decoder/audio_math.o
......
void bit_allocate( ac3dec_thread_t * );
...@@ -3,6 +3,320 @@ ...@@ -3,6 +3,320 @@
* (c)1999 VideoLAN * (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) #define AC3DEC_FRAME_SIZE (2*256)
/***************************************************************************** /*****************************************************************************
...@@ -34,6 +348,13 @@ typedef struct ac3dec_thread_s ...@@ -34,6 +348,13 @@ typedef struct ac3dec_thread_s
*/ */
unsigned int total_bits_read; unsigned int total_bits_read;
syncinfo_t syncinfo;
bsi_t bsi;
audblk_t audblk;
stream_coeffs_t coeffs;
stream_samples_t samples;
/* /*
* Output properties * Output properties
*/ */
......
void downmix( ac3dec_thread_t *, s16 * );
#define UNPACK_FBW 1
#define UNPACK_CPL 2
#define UNPACK_LFE 4
void exponent_unpack( ac3dec_thread_t * );
void imdct( ac3dec_thread_t * p_ac3dec );
void imdct_init( void );
void mantissa_unpack( ac3dec_thread_t * );
void parse_syncinfo( ac3dec_thread_t * );
void parse_bsi( ac3dec_thread_t * );
void parse_audblk( ac3dec_thread_t * );
void parse_auxdata( ac3dec_thread_t * );
void rematrix( ac3dec_thread_t * );
...@@ -164,7 +164,7 @@ typedef struct ...@@ -164,7 +164,7 @@ typedef struct
#define MPEG2_VIDEO_ES 0x02 #define MPEG2_VIDEO_ES 0x02
#define MPEG1_AUDIO_ES 0x03 #define MPEG1_AUDIO_ES 0x03
#define MPEG2_AUDIO_ES 0x04 #define MPEG2_AUDIO_ES 0x04
#define AC3_AUDIO_ES 0x81
/****************************************************************************** /******************************************************************************
* program_descriptor_t * program_descriptor_t
......
#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
}
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> /* getpid() */ #include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */ #include <stdio.h> /* "intf_msg.h" */
...@@ -28,6 +32,13 @@ ...@@ -28,6 +32,13 @@
#include "audio_output.h" #include "audio_output.h"
#include "ac3_decoder.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 * Local prototypes
...@@ -85,6 +96,8 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) ...@@ -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 = p_input->p_aout;
p_ac3dec->p_aout_fifo = NULL; p_ac3dec->p_aout_fifo = NULL;
imdct_init();
/* Spawn the ac3 decoder thread */ /* Spawn the ac3 decoder thread */
if ( vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec) ) 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 ) ...@@ -177,6 +190,10 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
*****************************************************************************/ *****************************************************************************/
static void RunThread( 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() ); intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() );
/* Initializing the ac3 decoder thread */ /* Initializing the ac3 decoder thread */
...@@ -185,14 +202,39 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) ...@@ -185,14 +202,39 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->b_error = 1; p_ac3dec->b_error = 1;
} }
i = open( "/tmp/taxi.ac3", O_WRONLY|O_CREAT|O_TRUNC );
/* ac3 decoder thread's main loop */ /* ac3 decoder thread's main loop */
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) ) 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 b_error is set, the ac3 decoder thread enters the error loop */
if ( p_ac3dec->b_error ) if ( p_ac3dec->b_error )
......
#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;
}
}
}
#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);
}
#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];
}
}
#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
}
}
}
#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;
}
#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;
}
}
}
...@@ -349,6 +349,10 @@ static void EndThread( input_thread_t * p_input ) ...@@ -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) ); adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) );
break; break;
case AC3_AUDIO_ES:
ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
break;
default: default:
break; break;
} }
...@@ -979,20 +983,26 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input, ...@@ -979,20 +983,26 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
PES fifo */ PES fifo */
switch( p_es_descriptor->i_type ) switch( p_es_descriptor->i_type )
{ {
case MPEG1_VIDEO_ES: case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES: case MPEG2_VIDEO_ES:
p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo); p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
break; break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case MPEG1_AUDIO_ES:
p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo); case MPEG2_AUDIO_ES:
break; p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
default: break;
/* This should never happen. */
intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n", case AC3_AUDIO_ES:
p_es_descriptor->i_id, p_es_descriptor->i_type); p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
p_fifo = NULL; break;
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 ) if( p_fifo != NULL )
......
...@@ -101,6 +101,17 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id ) ...@@ -101,6 +101,17 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
/* Spawn the decoder. */ /* Spawn the decoder. */
switch( p_input->p_es[i_es_loop].i_type ) 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 MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case MPEG2_AUDIO_ES:
/* Spawn audio thread. */ /* Spawn audio thread. */
...@@ -194,6 +205,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id ) ...@@ -194,6 +205,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
/* Cancel the decoder. */ /* Cancel the decoder. */
switch( p_input->pp_selected_es[i_selected_es_loop]->i_type ) 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 MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case MPEG2_AUDIO_ES:
adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) ); adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
......
...@@ -218,6 +218,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section ) ...@@ -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] ); //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 */ /* Check the CRC validity if any CRC is carried */
#if 0
if( p_psi_section->buffer[1] & 0x80 ) if( p_psi_section->buffer[1] & 0x80 )
{ {
if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) ) 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 ) ...@@ -228,6 +229,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
return; return;
} }
} }
#endif
/* If the section is not immediatly applicable, trash it (DVB drafts disallow /* If the section is not immediatly applicable, trash it (DVB drafts disallow
transmission of such sections, so we didn't implement it) */ 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 ) ...@@ -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 ) switch( p_input->p_es[i_es_loop].i_type )
{ {
case MPEG1_VIDEO_ES: case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES: case MPEG2_VIDEO_ES:
if( p_main->b_video ) if( p_main->b_video )
{ {
/* Spawn a video thread */ /* Spawn a video thread */
input_AddPgrmElem( p_input, input_AddPgrmElem( p_input,
p_input->p_es[i_es_loop].i_id ); p_input->p_es[i_es_loop].i_id );
} }
break; break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case AC3_AUDIO_ES:
if( p_main->b_audio ) if ( p_main->b_audio )
{ {
/* Spawn an audio thread */ /* Spawn an ac3 thread */
input_AddPgrmElem( p_input, input_AddPgrmElem( p_input,
p_input->p_es[i_es_loop].i_id ); p_input->p_es[i_es_loop].i_id );
} }
break; break;
default:
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 #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment