Browse Source

Created a small&clean public interface for the ac3 decoder (see ac3_decoder.h)


			
			
				pull/2/head
			
			
		
Michel Lespinasse 26 years ago
parent
commit
a5e77c46eb
  1. 610
      include/ac3_decoder.h
  2. 3
      include/ac3_decoder_thread.h
  3. 239
      src/ac3_decoder/ac3_bit_allocate.c
  4. 1
      src/ac3_decoder/ac3_bit_allocate.h
  5. 18
      src/ac3_decoder/ac3_bit_stream.h
  6. 51
      src/ac3_decoder/ac3_decoder.c
  7. 137
      src/ac3_decoder/ac3_decoder_thread.c
  8. 585
      src/ac3_decoder/ac3_downmix.c
  9. 1
      src/ac3_decoder/ac3_downmix.h
  10. 62
      src/ac3_decoder/ac3_exponent.c
  11. 1
      src/ac3_decoder/ac3_exponent.h
  12. 108
      src/ac3_decoder/ac3_imdct.c
  13. 2
      src/ac3_decoder/ac3_imdct.h
  14. 36
      src/ac3_decoder/ac3_internal.h
  15. 265
      src/ac3_decoder/ac3_mantissa.c
  16. 1
      src/ac3_decoder/ac3_mantissa.h
  17. 701
      src/ac3_decoder/ac3_parse.c
  18. 5
      src/ac3_decoder/ac3_parse.h
  19. 21
      src/ac3_decoder/ac3_rematrix.c
  20. 1
      src/ac3_decoder/ac3_rematrix.h
  21. 2
      src/input/input.c

610
include/ac3_decoder.h

@ -1,19 +1,38 @@
/***************************************************************************** /*****************************************************************************
* ac3_decoder.h : ac3 decoder thread interface * ac3_decoder.h : ac3 decoder interface
* (c)1999 VideoLAN * (c)1999 VideoLAN
*****************************************************************************/ *****************************************************************************/
/* Exponent strategy constants */ /**** ac3 decoder API - public ac3 decoder structures */
#define EXP_REUSE (0)
#define EXP_D15 (1)
#define EXP_D25 (2)
#define EXP_D45 (3)
/* Delta bit allocation constants */ typedef struct ac3dec_s ac3dec_t;
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1) typedef struct ac3_sync_info_s {
#define DELTA_BIT_NONE (2) int sample_rate; /* sample rate in Hz */
#define DELTA_BIT_RESERVED (3) int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */
} ac3_sync_info_t;
typedef struct ac3_byte_stream_s {
u8 * p_byte;
u8 * p_end;
void * info;
} ac3_byte_stream_t;
/**** ac3 decoder API - functions publically provided by the ac3 decoder ****/
int ac3_init (ac3dec_t * p_ac3dec);
int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info);
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer);
static ac3_byte_stream_t * ac3_byte_stream (ac3dec_t * p_ac3dec);
/**** ac3 decoder API - user functions to be provided to the ac3 decoder ****/
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream);
/**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/
/**** ac3 decoder internal structures ****/
/* The following structures are filled in by their corresponding parse_* /* The following structures are filled in by their corresponding parse_*
* functions. See http://www.atsc.org/Standards/A52/a_52.pdf for * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
@ -21,268 +40,262 @@
* conditional fields. * conditional fields.
*/ */
typedef struct syncinfo_s typedef struct syncinfo_s {
{ /* Sync word == 0x0B77 */
/* Sync word == 0x0B77 */ /* u16 syncword; */
/* u16 syncword; */ /* crc for the first 5/8 of the sync block */
/* crc for the first 5/8 of the sync block */ /* u16 crc1; */
/* u16 crc1; */ /* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
/* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */ u16 fscod;
u16 fscod; /* Frame size code */
/* Frame size code */ u16 frmsizecod;
u16 frmsizecod;
/* Information not in the AC-3 bitstream, but derived */
/* Information not in the AC-3 bitstream, but derived */ /* Frame size in 16 bit words */
/* Frame size in 16 bit words */ u16 frame_size;
u16 frame_size; /* Bit rate in kilobits */
/* Bit rate in kilobits */ //u16 bit_rate;
u16 bit_rate;
} syncinfo_t; } syncinfo_t;
typedef struct bsi_s typedef struct bsi_s {
{ /* Bit stream identification == 0x8 */
/* Bit stream identification == 0x8 */ u16 bsid;
u16 bsid; /* Bit stream mode */
/* Bit stream mode */ u16 bsmod;
u16 bsmod; /* Audio coding mode */
/* Audio coding mode */ u16 acmod;
u16 acmod; /* If we're using the centre channel then */
/* If we're using the centre channel then */ /* centre mix level */
/* centre mix level */ u16 cmixlev;
u16 cmixlev; /* If we're using the surround channel then */
/* If we're using the surround channel then */ /* surround mix level */
/* surround mix level */ u16 surmixlev;
u16 surmixlev; /* If we're in 2/0 mode then */
/* If we're in 2/0 mode then */ /* Dolby surround mix level - NOT USED - */
/* Dolby surround mix level - NOT USED - */ u16 dsurmod;
u16 dsurmod; /* Low frequency effects on */
/* Low frequency effects on */ u16 lfeon;
u16 lfeon; /* Dialogue Normalization level */
/* Dialogue Normalization level */ u16 dialnorm;
u16 dialnorm; /* Compression exists */
/* Compression exists */ u16 compre;
u16 compre; /* Compression level */
/* Compression level */ u16 compr;
u16 compr; /* Language code exists */
/* Language code exists */ u16 langcode;
u16 langcode; /* Language code */
/* Language code */ u16 langcod;
u16 langcod; /* Audio production info exists*/
/* Audio production info exists*/ u16 audprodie;
u16 audprodie; u16 mixlevel;
u16 mixlevel; u16 roomtyp;
u16 roomtyp; /* If we're in dual mono mode (acmod == 0) then extra stuff */
/* If we're in dual mono mode (acmod == 0) then extra stuff */ u16 dialnorm2;
u16 dialnorm2; u16 compr2e;
u16 compr2e; u16 compr2;
u16 compr2; u16 langcod2e;
u16 langcod2e; u16 langcod2;
u16 langcod2; u16 audprodi2e;
u16 audprodi2e; u16 mixlevel2;
u16 mixlevel2; u16 roomtyp2;
u16 roomtyp2; /* Copyright bit */
/* Copyright bit */ u16 copyrightb;
u16 copyrightb; /* Original bit */
/* Original bit */ u16 origbs;
u16 origbs; /* Timecode 1 exists */
/* Timecode 1 exists */ u16 timecod1e;
u16 timecod1e; /* Timecode 1 */
/* Timecode 1 */ u16 timecod1;
u16 timecod1; /* Timecode 2 exists */
/* Timecode 2 exists */ u16 timecod2e;
u16 timecod2e; /* Timecode 2 */
/* Timecode 2 */ u16 timecod2;
u16 timecod2; /* Additional bit stream info exists */
/* Additional bit stream info exists */ u16 addbsie;
u16 addbsie; /* Additional bit stream length - 1 (in bytes) */
/* Additional bit stream length - 1 (in bytes) */ u16 addbsil;
u16 addbsil; /* Additional bit stream information (max 64 bytes) */
/* Additional bit stream information (max 64 bytes) */ u8 addbsi[64];
u8 addbsi[64];
/* Information not in the AC-3 bitstream, but derived */
/* Information not in the AC-3 bitstream, but derived */ /* Number of channels (excluding LFE)
/* Number of channels (excluding LFE) * Derived from acmod */
* Derived from acmod */ u16 nfchans;
u16 nfchans;
} bsi_t; } bsi_t;
/* more pain */ /* more pain */
typedef struct audblk_s typedef struct audblk_s {
{ /* block switch bit indexed by channel num */
/* block switch bit indexed by channel num */ u16 blksw[5];
u16 blksw[5]; /* dither enable bit indexed by channel num */
/* dither enable bit indexed by channel num */ u16 dithflag[5];
u16 dithflag[5]; /* dynamic range gain exists */
/* dynamic range gain exists */ u16 dynrnge;
u16 dynrnge; /* dynamic range gain */
/* dynamic range gain */ u16 dynrng;
u16 dynrng; /* if acmod==0 then */
/* if acmod==0 then */ /* dynamic range 2 gain exists */
/* dynamic range 2 gain exists */ u16 dynrng2e;
u16 dynrng2e; /* dynamic range 2 gain */
/* dynamic range 2 gain */ u16 dynrng2;
u16 dynrng2; /* coupling strategy exists */
/* coupling strategy exists */ u16 cplstre;
u16 cplstre; /* coupling in use */
/* coupling in use */ u16 cplinu;
u16 cplinu; /* channel coupled */
/* channel coupled */ u16 chincpl[5];
u16 chincpl[5]; /* if acmod==2 then */
/* if acmod==2 then */ /* Phase flags in use */
/* Phase flags in use */ u16 phsflginu;
u16 phsflginu; /* coupling begin frequency code */
/* coupling begin frequency code */ u16 cplbegf;
u16 cplbegf; /* coupling end frequency code */
/* coupling end frequency code */ u16 cplendf;
u16 cplendf; /* coupling band structure bits */
/* coupling band structure bits */ u16 cplbndstrc[18];
u16 cplbndstrc[18]; /* Do coupling co-ords exist for this channel? */
/* Do coupling co-ords exist for this channel? */ u16 cplcoe[5];
u16 cplcoe[5]; /* Master coupling co-ordinate */
/* Master coupling co-ordinate */ u16 mstrcplco[5];
u16 mstrcplco[5]; /* Per coupling band coupling co-ordinates */
/* Per coupling band coupling co-ordinates */ u16 cplcoexp[5][18];
u16 cplcoexp[5][18]; u16 cplcomant[5][18];
u16 cplcomant[5][18]; /* Phase flags for dual mono */
/* Phase flags for dual mono */ u16 phsflg[18];
u16 phsflg[18]; /* Is there a rematrixing strategy */
/* Is there a rematrixing strategy */ u16 rematstr;
u16 rematstr; /* Rematrixing bits */
/* Rematrixing bits */ u16 rematflg[4];
u16 rematflg[4]; /* Coupling exponent strategy */
/* Coupling exponent strategy */ u16 cplexpstr;
u16 cplexpstr; /* Exponent strategy for full bandwidth channels */
/* Exponent strategy for full bandwidth channels */ u16 chexpstr[5];
u16 chexpstr[5]; /* Exponent strategy for lfe channel */
/* Exponent strategy for lfe channel */ u16 lfeexpstr;
u16 lfeexpstr; /* Channel bandwidth for independent channels */
/* Channel bandwidth for independent channels */ u16 chbwcod[5];
u16 chbwcod[5]; /* The absolute coupling exponent */
/* The absolute coupling exponent */ u16 cplabsexp;
u16 cplabsexp; /* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */ u16 cplexps[18 * 12 / 3];
u16 cplexps[18 * 12 / 3]; /* Sanity checking constant */
/* Sanity checking constant */ u32 magic2;
u32 magic2; /* fbw channel exponents */
/* fbw channel exponents */ u16 exps[5][252 / 3];
u16 exps[5][252 / 3]; /* channel gain range */
/* channel gain range */ u16 gainrng[5];
u16 gainrng[5]; /* low frequency exponents */
/* low frequency exponents */ u16 lfeexps[3];
u16 lfeexps[3];
/* Bit allocation info */
/* Bit allocation info */ u16 baie;
u16 baie; /* Slow decay code */
/* Slow decay code */ u16 sdcycod;
u16 sdcycod; /* Fast decay code */
/* Fast decay code */ u16 fdcycod;
u16 fdcycod; /* Slow gain code */
/* Slow gain code */ u16 sgaincod;
u16 sgaincod; /* dB per bit code */
/* dB per bit code */ u16 dbpbcod;
u16 dbpbcod; /* masking floor code */
/* masking floor code */ u16 floorcod;
u16 floorcod;
/* SNR offset info */
/* SNR offset info */ u16 snroffste;
u16 snroffste; /* coarse SNR offset */
/* coarse SNR offset */ u16 csnroffst;
u16 csnroffst; /* coupling fine SNR offset */
/* coupling fine SNR offset */ u16 cplfsnroffst;
u16 cplfsnroffst; /* coupling fast gain code */
/* coupling fast gain code */ u16 cplfgaincod;
u16 cplfgaincod; /* fbw fine SNR offset */
/* fbw fine SNR offset */ u16 fsnroffst[5];
u16 fsnroffst[5]; /* fbw fast gain code */
/* fbw fast gain code */ u16 fgaincod[5];
u16 fgaincod[5]; /* lfe fine SNR offset */
/* lfe fine SNR offset */ u16 lfefsnroffst;
u16 lfefsnroffst; /* lfe fast gain code */
/* lfe fast gain code */ u16 lfefgaincod;
u16 lfefgaincod;
/* Coupling leak info */
/* Coupling leak info */ u16 cplleake;
u16 cplleake; /* coupling fast leak initialization */
/* coupling fast leak initialization */ u16 cplfleak;
u16 cplfleak; /* coupling slow leak initialization */
/* coupling slow leak initialization */ u16 cplsleak;
u16 cplsleak;
/* delta bit allocation info */
/* delta bit allocation info */ u16 deltbaie;
u16 deltbaie; /* coupling delta bit allocation exists */
/* coupling delta bit allocation exists */ u16 cpldeltbae;
u16 cpldeltbae; /* fbw delta bit allocation exists */
/* fbw delta bit allocation exists */ u16 deltbae[5];
u16 deltbae[5]; /* number of cpl delta bit segments */
/* number of cpl delta bit segments */ u16 cpldeltnseg;
u16 cpldeltnseg; /* coupling delta bit allocation offset */
/* coupling delta bit allocation offset */ u16 cpldeltoffst[8];
u16 cpldeltoffst[8]; /* coupling delta bit allocation length */
/* coupling delta bit allocation length */ u16 cpldeltlen[8];
u16 cpldeltlen[8]; /* coupling delta bit allocation length */
/* coupling delta bit allocation length */ u16 cpldeltba[8];
u16 cpldeltba[8]; /* number of delta bit segments */
/* number of delta bit segments */ u16 deltnseg[5];
u16 deltnseg[5]; /* fbw delta bit allocation offset */
/* fbw delta bit allocation offset */ u16 deltoffst[5][8];
u16 deltoffst[5][8]; /* fbw delta bit allocation length */
/* fbw delta bit allocation length */ u16 deltlen[5][8];
u16 deltlen[5][8]; /* fbw delta bit allocation length */
/* fbw delta bit allocation length */ u16 deltba[5][8];
u16 deltba[5][8];
/* skip length exists */
/* skip length exists */ u16 skiple;
u16 skiple; /* skip length */
/* skip length */ u16 skipl;
u16 skipl;
/* channel mantissas */
/* channel mantissas */ // u16 chmant[5][256];
// u16 chmant[5][256];
/* coupling mantissas */
/* coupling mantissas */ float cplfbw[ 256 ];
float cplfbw[ 256 ]; // u16 cplmant[256];
// u16 cplmant[256];
/* coupling mantissas */
/* coupling mantissas */ // u16 lfemant[7];
// u16 lfemant[7];
/* -- Information not in the bitstream, but derived thereof -- */
/* -- Information not in the bitstream, but derived thereof -- */
/* Number of coupling sub-bands */
/* Number of coupling sub-bands */ u16 ncplsubnd;
u16 ncplsubnd;
/* Number of combined coupling sub-bands
/* Number of combined coupling sub-bands * Derived from ncplsubnd and cplbndstrc */
* Derived from ncplsubnd and cplbndstrc */ u16 ncplbnd;
u16 ncplbnd;
/* Number of exponent groups by channel
/* Number of exponent groups by channel * Derived from strmant, endmant */
* Derived from strmant, endmant */ u16 nchgrps[5];
u16 nchgrps[5];
/* Number of coupling exponent groups
/* Number of coupling exponent groups * Derived from cplbegf, cplendf, cplexpstr */
* Derived from cplbegf, cplendf, cplexpstr */ u16 ncplgrps;
u16 ncplgrps;
/* End mantissa numbers of fbw channels */
/* End mantissa numbers of fbw channels */ u16 endmant[5];
u16 endmant[5];
/* Start and end mantissa numbers for the coupling channel */
/* Start and end mantissa numbers for the coupling channel */ u16 cplstrtmant;
u16 cplstrtmant; u16 cplendmant;
u16 cplendmant;
/* Decoded exponent info */
/* Decoded exponent info */ u16 fbw_exp[5][256];
u16 fbw_exp[5][256]; u16 cpl_exp[256];
u16 cpl_exp[256]; u16 lfe_exp[7];
u16 lfe_exp[7];
/* Bit allocation pointer results */
/* Bit allocation pointer results */ u16 fbw_bap[5][256];
u16 fbw_bap[5][256]; /* FIXME?? figure out exactly how many entries there should be (253-37?) */
/* FIXME?? figure out exactly how many entries there should be (253-37?) */ u16 cpl_bap[256];
u16 cpl_bap[256]; u16 lfe_bap[7];
u16 lfe_bap[7];
} audblk_t; } audblk_t;
/* Everything you wanted to know about band structure */ /* Everything you wanted to know about band structure */
@ -304,66 +317,45 @@ typedef struct audblk_s
* approximate a 1/6 octave scale. * approximate a 1/6 octave scale.
*/ */
typedef struct stream_coeffs_s typedef struct stream_coeffs_s {
{ float fbw[5][256];
float fbw[5][256]; float lfe[256];
float lfe[256];
} stream_coeffs_t; } stream_coeffs_t;
typedef struct stream_samples_s typedef struct stream_samples_s {
{ float channel[6][256];
float channel[6][256];
} stream_samples_t; } stream_samples_t;
#define AC3DEC_FRAME_SIZE (2*256) typedef struct ac3_bit_stream_s {
/*****************************************************************************
* ac3dec_frame_t
*****************************************************************************/
typedef s16 ac3dec_frame_t[ AC3DEC_FRAME_SIZE ];
typedef struct ac3_byte_stream_s
{
u8 * p_byte;
u8 * p_end;
void * info;
} ac3_byte_stream_t;
typedef struct ac3_bit_stream_s
{
u32 buffer; u32 buffer;
int i_available; int i_available;
ac3_byte_stream_t byte_stream; ac3_byte_stream_t byte_stream;
unsigned int total_bits_read; /* temporary */ unsigned int total_bits_read; /* temporary */
} ac3_bit_stream_t; } ac3_bit_stream_t;
/***************************************************************************** struct ac3dec_s {
* ac3dec_t : ac3 decoder descriptor
*****************************************************************************/
typedef struct ac3dec_s
{
/* /*
* Input properties * Input properties
*/ */
/* The bit stream structure handles the PES stream at the bit level */ /* The bit stream structure handles the PES stream at the bit level */
ac3_bit_stream_t bit_stream; ac3_bit_stream_t bit_stream;
/* /*
* Decoder properties * Decoder properties
*/ */
syncinfo_t syncinfo; syncinfo_t syncinfo;
bsi_t bsi; bsi_t bsi;
audblk_t audblk; audblk_t audblk;
stream_coeffs_t coeffs;
stream_samples_t samples;
} ac3dec_t; stream_coeffs_t coeffs;
stream_samples_t samples;
};
int ac3_audio_block (ac3dec_t * p_ac3dec, s16 * buffer); /**** ac3 decoder inline functions ****/
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream); static ac3_byte_stream_t * ac3_byte_stream (ac3dec_t * p_ac3dec)
{
return &(p_ac3dec->bit_stream.byte_stream);
}

3
include/ac3_decoder_thread.h

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* ac3_decoder.h : ac3 decoder thread interface * ac3_decoder_thread.h : ac3 decoder thread interface
* (c)1999 VideoLAN * (c)1999 VideoLAN
*****************************************************************************/ *****************************************************************************/
@ -21,6 +21,7 @@ typedef struct ac3dec_thread_s
decoder_fifo_t fifo; /* stores the PES stream data */ decoder_fifo_t fifo; /* stores the PES stream data */
input_thread_t * p_input; input_thread_t * p_input;
ts_packet_t * p_ts; ts_packet_t * p_ts;
int sync_ptr; /* sync ptr from ac3 magic header */
/* /*
* Decoder properties * Decoder properties

239
src/ac3_decoder/ac3_bit_allocate.c

@ -1,25 +1,26 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_bit_allocate.h" #include "ac3_internal.h"
/* /*
static inline s16 logadd(s16 a,s16 b); static inline s16 logadd (s16 a, s16 b);
static s16 calc_lowcomp(s16 a,s16 b0,s16 b1,s16 bin); static s16 calc_lowcomp (s16 a, s16 b0, s16 b1, s16 bin);
static inline u16 min(s16 a,s16 b); static inline u16 min (s16 a, s16 b);
static inline u16 max(s16 a,s16 b); static inline u16 max (s16 a, s16 b);
*/ */
static void ba_compute_psd(s16 start, s16 end, s16 exps[], static void ba_compute_psd (s16 start, s16 end, s16 exps[],
s16 psd[], s16 bndpsd[]); s16 psd[], s16 bndpsd[]);
static void ba_compute_excitation(s16 start, s16 end,s16 fgain, static void ba_compute_excitation (s16 start, s16 end, s16 fgain,
s16 fastleak, s16 slowleak, s16 is_lfe, s16 bndpsd[], s16 fastleak, s16 slowleak, s16 is_lfe,
s16 excite[]); s16 bndpsd[], s16 excite[]);
static void ba_compute_mask(s16 start, s16 end, u16 fscod, static void ba_compute_mask (s16 start, s16 end, u16 fscod,
u16 deltbae, u16 deltnseg, u16 deltoffst[], u16 deltba[], u16 deltbae, u16 deltnseg, u16 deltoffst[],
u16 deltlen[], s16 excite[], s16 mask[]); u16 deltba[], u16 deltlen[], s16 excite[],
static void ba_compute_bap(s16 start, s16 end, s16 snroffset, s16 mask[]);
s16 psd[], s16 mask[], s16 bap[]); static void ba_compute_bap (s16 start, s16 end, s16 snroffset,
s16 psd[], s16 mask[], s16 bap[]);
/* Misc LUTs for bit allocation process */ /* Misc LUTs for bit allocation process */
@ -31,7 +32,6 @@ static s16 dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
static u16 floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 }; static u16 floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
static s16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 }; static s16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
static s16 bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, static s16 bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
@ -136,53 +136,46 @@ static s16 bndpsd[256];
static s16 excite[256]; static s16 excite[256];
static s16 mask[256]; static s16 mask[256];
static __inline__ u16 max( s16 a, s16 b ) static __inline__ u16 max (s16 a, s16 b)
{ {
return( a > b ? a : b ); return (a > b ? a : b);
} }
static __inline__ u16 min( s16 a, s16 b ) static __inline__ u16 min (s16 a, s16 b)
{ {
return( a < b ? a : b ); return (a < b ? a : b);
} }
static __inline__ s16 logadd( s16 a, s16 b ) static __inline__ s16 logadd (s16 a, s16 b)
{ {
s16 c; s16 c;
if ( (c = a - b) >= 0 ) if ((c = a - b) >= 0) {
{ return (a + latab[min(((c) >> 1), 255)]);
return( a + latab[min(((c) >> 1), 255)] ); } else {
} return (b + 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 ) static __inline__ s16 calc_lowcomp (s16 a, s16 b0, s16 b1, s16 bin)
{ {
if (bin < 7) if (bin < 7) {
{
if ((b0 + 256) == b1) if ((b0 + 256) == b1)
a = 384; a = 384;
else if (b0 > b1) else if (b0 > b1)
a = max(0, a - 64); a = max(0, a - 64);
} } else if (bin < 20) {
else if (bin < 20)
{
if ((b0 + 256) == b1) if ((b0 + 256) == b1)
a = 320; a = 320;
else if (b0 > b1) else if (b0 > b1)
a = max(0, a - 64) ; a = max(0, a - 64) ;
} } else
else
a = max(0, a - 128); a = max(0, a - 128);
return(a); return a;
} }
void bit_allocate( ac3dec_t * p_ac3dec ) void bit_allocate (ac3dec_t * p_ac3dec)
{ {
u16 i; u16 i;
s16 fgain; s16 fgain;
@ -195,10 +188,10 @@ void bit_allocate( ac3dec_t * p_ac3dec )
/* Only perform bit_allocation if the exponents have changed or we /* Only perform bit_allocation if the exponents have changed or we
* have new sideband information */ * have new sideband information */
if (p_ac3dec->audblk.chexpstr[0] == 0 && p_ac3dec->audblk.chexpstr[1] == 0 && 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[2] == 0 && p_ac3dec->audblk.chexpstr[3] == 0 &&
p_ac3dec->audblk.chexpstr[4] == 0 && p_ac3dec->audblk.cplexpstr == 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.lfeexpstr == 0 && p_ac3dec->audblk.baie == 0 &&
p_ac3dec->audblk.snroffste == 0 && p_ac3dec->audblk.deltbaie == 0) p_ac3dec->audblk.snroffste == 0 && p_ac3dec->audblk.deltbaie == 0)
return; return;
/* Do some setup before we do the bit alloc */ /* Do some setup before we do the bit alloc */
@ -209,19 +202,17 @@ void bit_allocate( ac3dec_t * p_ac3dec )
floor = floortab[p_ac3dec->audblk.floorcod]; floor = floortab[p_ac3dec->audblk.floorcod];
/* if all the SNR offset constants are zero then the whole block is zero */ /* if all the SNR offset constants are zero then the whole block is zero */
if(!p_ac3dec->audblk.csnroffst && !p_ac3dec->audblk.fsnroffst[0] && if (!p_ac3dec->audblk.csnroffst && !p_ac3dec->audblk.fsnroffst[0] &&
!p_ac3dec->audblk.fsnroffst[1] && !p_ac3dec->audblk.fsnroffst[2] && !p_ac3dec->audblk.fsnroffst[1] && !p_ac3dec->audblk.fsnroffst[2] &&
!p_ac3dec->audblk.fsnroffst[3] && !p_ac3dec->audblk.fsnroffst[4] && !p_ac3dec->audblk.fsnroffst[3] && !p_ac3dec->audblk.fsnroffst[4] &&
!p_ac3dec->audblk.cplfsnroffst && !p_ac3dec->audblk.lfefsnroffst) !p_ac3dec->audblk.cplfsnroffst && !p_ac3dec->audblk.lfefsnroffst) {
{
memset(p_ac3dec->audblk.fbw_bap,0,sizeof(u16) * 256 * 5); 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.cpl_bap,0,sizeof(u16) * 256);
memset(p_ac3dec->audblk.lfe_bap,0,sizeof(u16) * 7); memset(p_ac3dec->audblk.lfe_bap,0,sizeof(u16) * 7);
return; return;
} }
for(i = 0; i < p_ac3dec->bsi.nfchans; i++) for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
{
start = 0; start = 0;
end = p_ac3dec->audblk.endmant[i] ; end = p_ac3dec->audblk.endmant[i] ;
fgain = fastgain[p_ac3dec->audblk.fgaincod[i]]; fgain = fastgain[p_ac3dec->audblk.fgaincod[i]];
@ -229,17 +220,23 @@ void bit_allocate( ac3dec_t * p_ac3dec )
fastleak = 0; fastleak = 0;
slowleak = 0; slowleak = 0;
ba_compute_psd(start, end, p_ac3dec->audblk.fbw_exp[i], psd, bndpsd); ba_compute_psd (start, end, p_ac3dec->audblk.fbw_exp[i], psd, bndpsd);
ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite); ba_compute_excitation (start, end , fgain, fastleak, slowleak, 0,
bndpsd, excite);
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_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]); ba_compute_bap (start, end, snroffset, psd, mask,
p_ac3dec->audblk.fbw_bap[i]);
} }
if(p_ac3dec->audblk.cplinu) if (p_ac3dec->audblk.cplinu) {
{
start = p_ac3dec->audblk.cplstrtmant; start = p_ac3dec->audblk.cplstrtmant;
end = p_ac3dec->audblk.cplendmant; end = p_ac3dec->audblk.cplendmant;
fgain = fastgain[p_ac3dec->audblk.cplfgaincod]; fgain = fastgain[p_ac3dec->audblk.cplfgaincod];
@ -247,17 +244,23 @@ void bit_allocate( ac3dec_t * p_ac3dec )
fastleak = (p_ac3dec->audblk.cplfleak << 8) + 768; fastleak = (p_ac3dec->audblk.cplfleak << 8) + 768;
slowleak = (p_ac3dec->audblk.cplsleak << 8) + 768; slowleak = (p_ac3dec->audblk.cplsleak << 8) + 768;
ba_compute_psd(start, end, p_ac3dec->audblk.cpl_exp, psd, bndpsd); 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_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_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); ba_compute_bap (start, end, snroffset, psd, mask,
p_ac3dec->audblk.cpl_bap);
} }
if(p_ac3dec->bsi.lfeon) if (p_ac3dec->bsi.lfeon) {
{
start = 0; start = 0;
end = 7; end = 7;
fgain = fastgain[p_ac3dec->audblk.lfefgaincod]; fgain = fastgain[p_ac3dec->audblk.lfefgaincod];
@ -265,26 +268,28 @@ void bit_allocate( ac3dec_t * p_ac3dec )
fastleak = 0; fastleak = 0;
slowleak = 0; slowleak = 0;
ba_compute_psd(start, end, p_ac3dec->audblk.lfe_exp, psd, bndpsd); 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_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_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); ba_compute_bap (start, end, snroffset, psd, mask,
p_ac3dec->audblk.lfe_bap);
} }
} }
static void ba_compute_psd(s16 start, s16 end, s16 exps[], static void ba_compute_psd (s16 start, s16 end, s16 exps[], s16 psd[],
s16 psd[], s16 bndpsd[]) s16 bndpsd[])
{ {
int bin,i,j,k; int bin,i,j,k;
s16 lastbin = 0; s16 lastbin = 0;
/* Map the exponents into dBs */ /* Map the exponents into dBs */
for (bin=start; bin<end; bin++) for (bin=start; bin<end; bin++) {
{
psd[bin] = (3072 - (exps[bin] << 7)); psd[bin] = (3072 - (exps[bin] << 7));
} }
@ -292,14 +297,12 @@ static void ba_compute_psd(s16 start, s16 end, s16 exps[],
j = start; j = start;
k = masktab[start]; k = masktab[start];
do do {
{
lastbin = min(bndtab[k] + bndsz[k], end); lastbin = min(bndtab[k] + bndsz[k], end);
bndpsd[k] = psd[j]; bndpsd[k] = psd[j];
j++; j++;
for (i = j; i < lastbin; i++) for (i = j; i < lastbin; i++) {
{
bndpsd[k] = logadd(bndpsd[k], psd[j]); bndpsd[k] = logadd(bndpsd[k], psd[j]);
j++; j++;
} }
@ -308,9 +311,9 @@ static void ba_compute_psd(s16 start, s16 end, s16 exps[],
} while (end > lastbin); } while (end > lastbin);
} }
static void ba_compute_excitation(s16 start, s16 end,s16 fgain, static void ba_compute_excitation (s16 start, s16 end,s16 fgain, s16 fastleak,
s16 fastleak, s16 slowleak, s16 is_lfe, s16 bndpsd[], s16 slowleak, s16 is_lfe, s16 bndpsd[],
s16 excite[]) s16 excite[])
{ {
int bin; int bin;
s16 bndstrt; s16 bndstrt;
@ -322,8 +325,7 @@ static void ba_compute_excitation(s16 start, s16 end,s16 fgain,
bndstrt = masktab[start]; bndstrt = masktab[start];
bndend = masktab[end - 1] + 1; bndend = masktab[end - 1] + 1;
if (bndstrt == 0) /* For fbw and lfe channels */ if (bndstrt == 0) { /* For fbw and lfe channels */
{
lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0); lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0);
excite[0] = bndpsd[0] - fgain - lowcomp; excite[0] = bndpsd[0] - fgain - lowcomp;
lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1); lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
@ -331,43 +333,36 @@ static void ba_compute_excitation(s16 start, s16 end,s16 fgain,
begin = 7 ; begin = 7 ;
/* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */ /* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
for (bin = 2; bin < 7; bin++) for (bin = 2; bin < 7; bin++) {
{
if (!(is_lfe && (bin == 6))) if (!(is_lfe && (bin == 6)))
lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); lowcomp = calc_lowcomp (lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
fastleak = bndpsd[bin] - fgain; fastleak = bndpsd[bin] - fgain;
slowleak = bndpsd[bin] - sgain; slowleak = bndpsd[bin] - sgain;
excite[bin] = fastleak - lowcomp; excite[bin] = fastleak - lowcomp;
if (!(is_lfe && (bin == 6))) if (!(is_lfe && (bin == 6))) {
{ if (bndpsd[bin] <= bndpsd[bin+1]) {
if (bndpsd[bin] <= bndpsd[bin+1])
{
begin = bin + 1 ; begin = bin + 1 ;
break; break;
} }
} }
} }
for (bin = begin; bin < min(bndend, 22); bin++) for (bin = begin; bin < min(bndend, 22); bin++) {
{
if (!(is_lfe && (bin == 6))) if (!(is_lfe && (bin == 6)))
lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); lowcomp = calc_lowcomp (lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
fastleak -= fdecay ; fastleak -= fdecay ;
fastleak = max(fastleak, bndpsd[bin] - fgain); fastleak = max(fastleak, bndpsd[bin] - fgain);
slowleak -= sdecay ; slowleak -= sdecay ;
slowleak = max(slowleak, bndpsd[bin] - sgain); slowleak = max(slowleak, bndpsd[bin] - sgain);
excite[bin] = max(fastleak - lowcomp, slowleak); excite[bin] = max(fastleak - lowcomp, slowleak);
} }
begin = 22; begin = 22;
} } else { /* For coupling channel */
else /* For coupling channel */
{
begin = bndstrt; begin = bndstrt;
} }
for (bin = begin; bin < bndend; bin++) for (bin = begin; bin < bndend; bin++) {
{
fastleak -= fdecay; fastleak -= fdecay;
fastleak = max(fastleak, bndpsd[bin] - fgain); fastleak = max(fastleak, bndpsd[bin] - fgain);
slowleak -= sdecay; slowleak -= sdecay;
@ -376,9 +371,9 @@ static void ba_compute_excitation(s16 start, s16 end,s16 fgain,
} }
} }
static void ba_compute_mask(s16 start, s16 end, u16 fscod, static void ba_compute_mask (s16 start, s16 end, u16 fscod, u16 deltbae,
u16 deltbae, u16 deltnseg, u16 deltoffst[], u16 deltba[], u16 deltnseg, u16 deltoffst[], u16 deltba[],
u16 deltlen[], s16 excite[], s16 mask[]) u16 deltlen[], s16 excite[], s16 mask[])
{ {
int bin,k; int bin,k;
s16 bndstrt; s16 bndstrt;
@ -389,43 +384,35 @@ static void ba_compute_mask(s16 start, s16 end, u16 fscod,
bndend = masktab[end - 1] + 1; bndend = masktab[end - 1] + 1;
/* Compute the masking curve */ /* Compute the masking curve */
for (bin = bndstrt; bin < bndend; bin++) for (bin = bndstrt; bin < bndend; bin++) {
{ if (bndpsd[bin] < dbknee) {
if (bndpsd[bin] < dbknee)
{
excite[bin] += ((dbknee - bndpsd[bin]) >> 2); excite[bin] += ((dbknee - bndpsd[bin]) >> 2);
} }
mask[bin] = max(excite[bin], hth[fscod][bin]); mask[bin] = max(excite[bin], hth[fscod][bin]);
} }
/* Perform delta bit modulation if necessary */ /* Perform delta bit modulation if necessary */
if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) {
{
s16 band = 0; s16 band = 0;
s16 seg = 0; s16 seg = 0;
for (seg = 0; seg < deltnseg+1; seg++) for (seg = 0; seg < deltnseg+1; seg++) {
{
band += deltoffst[seg]; band += deltoffst[seg];
if (deltba[seg] >= 4) if (deltba[seg] >= 4) {
{
delta = (deltba[seg] - 3) << 7; delta = (deltba[seg] - 3) << 7;
} } else {
else
{
delta = (deltba[seg] - 4) << 7; delta = (deltba[seg] - 4) << 7;
} }
for (k = 0; k < deltlen[seg]; k++) for (k = 0; k < deltlen[seg]; k++) {
{ mask[band] += delta;
mask[band] += delta; band++;
band++;
} }
} }
} }
} }
static void ba_compute_bap(s16 start, s16 end, s16 snroffset, static void ba_compute_bap (s16 start, s16 end, s16 snroffset, s16 psd[],
s16 psd[], s16 mask[], s16 bap[]) s16 mask[], s16 bap[])
{ {
int i,j,k; int i,j,k;
s16 lastbin = 0; s16 lastbin = 0;
@ -435,8 +422,7 @@ static void ba_compute_bap(s16 start, s16 end, s16 snroffset,
i = start; i = start;
j = masktab[start]; j = masktab[start];
do do {
{
lastbin = min(bndtab[j] + bndsz[j], end); lastbin = min(bndtab[j] + bndsz[j], end);
mask[j] -= snroffset; mask[j] -= snroffset;
mask[j] -= floor; mask[j] -= floor;
@ -446,8 +432,7 @@ static void ba_compute_bap(s16 start, s16 end, s16 snroffset,
mask[j] &= 0x1fe0; mask[j] &= 0x1fe0;
mask[j] += floor; mask[j] += floor;
for (k = i; k < lastbin; k++) for (k = i; k < lastbin; k++) {
{
address = (psd[i] - mask[j]) >> 5; address = (psd[i] - mask[j]) >> 5;
address = min(63, max(0, address)); address = min(63, max(0, address));
bap[i] = baptab[address]; bap[i] = baptab[address];

1
src/ac3_decoder/ac3_bit_allocate.h

@ -1 +0,0 @@
void bit_allocate( ac3dec_t * );

18
src/ac3_decoder/ac3_bit_stream.h

@ -9,18 +9,6 @@ static __inline__ u8 GetByte (ac3_byte_stream_t * p_byte_stream)
return *(p_byte_stream->p_byte++); return *(p_byte_stream->p_byte++);
} }
/*****************************************************************************
* NeedBits : reads i_bits new bits in the bit stream and stores them in the
* bit buffer
*****************************************************************************
* - i_bits must be less or equal 32 !
* - There is something important to notice with that function : if the number
* of bits available in the bit buffer when calling NeedBits() is greater than
* 24 (i_available > 24) but less than the number of needed bits
* (i_available < i_bits), the byte returned by GetByte() will be shifted with
* a negative value and the number of bits available in the bit buffer will be
* set to more than 32 !
*****************************************************************************/
static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits) static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{ {
while (p_bit_stream->i_available < i_bits) { while (p_bit_stream->i_available < i_bits) {
@ -30,12 +18,6 @@ static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
} }
} }
/*****************************************************************************
* DumpBits : removes i_bits bits from the bit buffer
*****************************************************************************
* - i_bits <= i_available
* - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
*****************************************************************************/
static __inline__ void DumpBits (ac3_bit_stream_t * p_bit_stream, int i_bits) static __inline__ void DumpBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{ {
p_bit_stream->buffer <<= i_bits; p_bit_stream->buffer <<= i_bits;

51
src/ac3_decoder/ac3_decoder.c

@ -1,23 +1,36 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_parse.h" #include "ac3_internal.h"
#include "ac3_exponent.h"
#include "ac3_bit_allocate.h" int ac3_init (ac3dec_t * p_ac3dec)
#include "ac3_mantissa.h" {
#include "ac3_rematrix.h" //p_ac3dec->bit_stream.buffer = 0;
#include "ac3_imdct.h" p_ac3dec->bit_stream.i_available = 0;
#include "ac3_downmix.h"
int ac3_audio_block (ac3dec_t * p_ac3dec, s16 * buffer)
{
parse_audblk( p_ac3dec );
if (exponent_unpack( p_ac3dec ))
return 1;
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->bsi.acmod == 0x2 )
rematrix( p_ac3dec );
imdct( p_ac3dec );
downmix( p_ac3dec, buffer );
return 0; return 0;
}
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
{
int i;
parse_bsi (p_ac3dec);
for (i = 0; i < 6; i++) {
parse_audblk (p_ac3dec);
if (exponent_unpack (p_ac3dec))
return 1;
bit_allocate (p_ac3dec);
mantissa_unpack (p_ac3dec);
if (p_ac3dec->bsi.acmod == 0x2)
rematrix (p_ac3dec);
imdct (p_ac3dec);
downmix (p_ac3dec, buffer);
buffer += 2*256;
} }
parse_auxdata (p_ac3dec);
return 0;
}

137
src/ac3_decoder/ac3_decoder_thread.c

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* ac3_decoder.c: ac3 decoder thread * ac3_decoder_thread.c: ac3 decoder thread
* (c)1999 VideoLAN * (c)1999 VideoLAN
*****************************************************************************/ *****************************************************************************/
@ -42,8 +42,9 @@
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_decoder_thread.h" #include "ac3_decoder_thread.h"
#include "ac3_parse.h"
#include "ac3_imdct.h" #define AC3DEC_FRAME_SIZE (2*1536)
typedef s16 ac3dec_frame_t[ AC3DEC_FRAME_SIZE ];
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
@ -84,10 +85,12 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
vlc_cond_init( &p_ac3dec->fifo.data_wait ); vlc_cond_init( &p_ac3dec->fifo.data_wait );
p_ac3dec->fifo.i_start = 0; p_ac3dec->fifo.i_start = 0;
p_ac3dec->fifo.i_end = 0; p_ac3dec->fifo.i_end = 0;
/* Initialize the ac3 decoder structures */
ac3_init (&p_ac3dec->ac3_decoder);
/* Initialize the bit stream structure */ /* Initialize the bit stream structure */
p_ac3dec->p_input = p_input; p_ac3dec->p_input = p_input;
p_ac3dec->ac3_decoder.bit_stream.buffer = 0;
p_ac3dec->ac3_decoder.bit_stream.i_available = 0;
/* /*
* Initialize the output properties * Initialize the output properties
@ -95,8 +98,6 @@ 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) )
{ {
@ -131,25 +132,13 @@ void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec )
/* Following functions are local */ /* Following functions are local */
/*****************************************************************************
* decode_find_sync()
*****************************************************************************/
static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
{
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{
if (! (ac3_test_sync (&p_ac3dec->ac3_decoder)))
return 0;
}
return( -1 );
}
/***************************************************************************** /*****************************************************************************
* InitThread : initialize an ac3 decoder thread * InitThread : initialize an ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
static int InitThread( ac3dec_thread_t * p_ac3dec ) static int InitThread( ac3dec_thread_t * p_ac3dec )
{ {
aout_fifo_t aout_fifo; aout_fifo_t aout_fifo;
ac3_byte_stream_t * byte_stream;
intf_DbgMsg( "ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec ); intf_DbgMsg( "ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec );
@ -166,11 +155,12 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock ); vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
} }
p_ac3dec->p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts; p_ac3dec->p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.p_byte = byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
byte_stream->p_byte =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start; p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.p_end = byte_stream->p_end =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end; p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.info = p_ac3dec; byte_stream->info = p_ac3dec;
vlc_mutex_unlock( &p_ac3dec->fifo.data_lock ); vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO; aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
@ -194,6 +184,8 @@ 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 sync;
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() );
msleep( INPUT_PTS_DELAY ); msleep( INPUT_PTS_DELAY );
@ -204,13 +196,44 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->b_error = 1; p_ac3dec->b_error = 1;
} }
sync = 0;
p_ac3dec->sync_ptr = 0;
/* ac3 decoder thread's main loop */ /* ac3 decoder thread's main loop */
/* FIXME : do we have enough room to store the decoded frames ?? */ /* FIXME : do we have enough room to store the decoded frames ?? */
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) ) while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{ {
int i; s16 * buffer;
ac3_sync_info_t sync_info;
decode_find_sync( p_ac3dec ); if (!sync) { /* have to find a synchro point */
int ptr;
ac3_byte_stream_t * p_byte_stream;
p_byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
/* first read till next ac3 magic header */
do {
ac3_byte_stream_next (p_byte_stream);
} while ((!p_ac3dec->sync_ptr) &&
(!p_ac3dec->b_die) &&
(!p_ac3dec->b_error));
/* skip the specified number of bytes */
ptr = p_ac3dec->sync_ptr;
while (--ptr && (!p_ac3dec->b_die) && (!p_ac3dec->b_error)) {
if (p_byte_stream->p_byte >= p_byte_stream->p_end) {
ac3_byte_stream_next (p_byte_stream);
}
p_byte_stream->p_byte++;
}
/* we are in sync now */
sync = 1;
p_ac3dec->sync_ptr = 0;
}
if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts ) if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts )
{ {
@ -222,46 +245,25 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE; p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
} }
parse_syncinfo( &p_ac3dec->ac3_decoder ); if (ac3_sync_frame (&p_ac3dec->ac3_decoder, &sync_info)) {
switch ( p_ac3dec->ac3_decoder.syncinfo.fscod ) sync = 0;
{ goto bad_frame;
case 0: }
p_ac3dec->p_aout_fifo->l_rate = 48000;
break;
case 1:
p_ac3dec->p_aout_fifo->l_rate = 44100;
break;
case 2:
p_ac3dec->p_aout_fifo->l_rate = 32000;
break;
default: /* XXX?? */
fprintf( stderr, "ac3dec debug: invalid fscod\n" );
continue;
}
parse_bsi( &p_ac3dec->ac3_decoder );
for (i = 0; i < 6; i++) p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate;
{
s16 * buffer;
buffer = ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ]; buffer = ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ];
if (ac3_audio_block (&p_ac3dec->ac3_decoder, buffer)) if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) {
goto bad_frame; sync = 0;
goto bad_frame;
}
if (i) vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock );
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE; p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock ); vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
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 );
vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
}
parse_auxdata( &p_ac3dec->ac3_decoder );
bad_frame: bad_frame:
} }
@ -333,9 +335,11 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
/* We are looking for the next TS packet that contains real data, /* We are looking for the next TS packet that contains real data,
* and not just a PES header */ * and not just a PES header */
do { do {
/* We were reading the last TS packet of this PES packet... It's /* We were reading the last TS packet of this PES packet... It's
* time to jump to the next PES packet */ * time to jump to the next PES packet */
if (p_ac3dec->p_ts->p_next_ts == NULL) { if (p_ac3dec->p_ts->p_next_ts == NULL) {
int ptr;
/* We are going to read/write the start and end indexes of the /* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable, * decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before */ * that's why we need to take the lock before */
@ -368,6 +372,13 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
/* The next byte could be found in the next PES packet */ /* The next byte could be found in the next PES packet */
p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts; p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
/* parse ac3 magic header */
ptr = p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+2];
ptr <<= 8;
ptr |= p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+3];
p_ac3dec->sync_ptr = ptr;
p_ac3dec->p_ts->i_payload_start += 4;
/* We can release the fifo's data lock */ /* We can release the fifo's data lock */
vlc_mutex_unlock (&p_ac3dec->fifo.data_lock); vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
} }

585
src/ac3_decoder/ac3_downmix.c

@ -1,11 +1,10 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_downmix.h" #include "ac3_internal.h"
#define NORM 16384 #define NORM 16384
typedef struct prefs_s typedef struct prefs_s {
{
u16 use_dolby_surround; u16 use_dolby_surround;
u16 dual_mono_channel_select; u16 dual_mono_channel_select;
} prefs_t; } prefs_t;
@ -20,7 +19,7 @@ static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 };
* to reduce complexity. Realistically, there aren't many machines around * to reduce complexity. Realistically, there aren't many machines around
* with > 2 channel output anyways */ * with > 2 channel output anyways */
void downmix( ac3dec_t * p_ac3dec, s16 * out_buf ) void downmix (ac3dec_t * p_ac3dec, s16 * out_buf)
{ {
int j; int j;
float right_tmp; float right_tmp;
@ -29,347 +28,255 @@ void downmix( ac3dec_t * p_ac3dec, s16 * out_buf )
float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
/* /*
if(p_ac3dec->bsi.acmod > 7) if (p_ac3dec->bsi.acmod > 7)
dprintf("(downmix) invalid acmod number\n"); dprintf("(downmix) invalid acmod number\n");
*/ */
/* There are two main cases, with or without Dolby Surround */ /* There are two main cases, with or without Dolby Surround */
if(global_prefs.use_dolby_surround) if (global_prefs.use_dolby_surround) {
{ switch(p_ac3dec->bsi.acmod) {
switch(p_ac3dec->bsi.acmod) case 7: /* 3/2 */
{ left = p_ac3dec->samples.channel[0];
/* 3/2 */ centre = p_ac3dec->samples.channel[1];
case 7: right = p_ac3dec->samples.channel[2];
left = p_ac3dec->samples.channel[0]; left_sur = p_ac3dec->samples.channel[3];
centre = p_ac3dec->samples.channel[1]; right_sur = p_ac3dec->samples.channel[4];
right = p_ac3dec->samples.channel[2];
left_sur = p_ac3dec->samples.channel[3]; for (j = 0; j < 256; j++) {
right_sur = p_ac3dec->samples.channel[4]; right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
left_tmp = -1 * right_tmp;
for ( j = 0; j < 256; j++ ) right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
{ left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
left_tmp = -1 * right_tmp; *(out_buf++) = left_tmp * NORM;
right_tmp += 0.3204f * *right++ + 0.2265f * *centre; *(out_buf++) = right_tmp * NORM;
left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; }
break;
*(out_buf++) = left_tmp * NORM;
*(out_buf++) = right_tmp * NORM; case 6: /* 2/2 */
/* left = p_ac3dec->samples.channel[0];
p_ac3dec->samples.channel[1][j] = right_tmp; right = p_ac3dec->samples.channel[1];
p_ac3dec->samples.channel[0][j] = left_tmp; left_sur = p_ac3dec->samples.channel[2];
*/ right_sur = p_ac3dec->samples.channel[3];
}
break; for (j = 0; j < 256; j++) {
right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
/* 2/2 */ left_tmp = -1 * right_tmp;
case 6: right_tmp += 0.3204f * *right++;
left = p_ac3dec->samples.channel[0]; left_tmp += 0.3204f * *left++ ;
right = p_ac3dec->samples.channel[1];
left_sur = p_ac3dec->samples.channel[2]; *(out_buf++) = left_tmp * NORM;
right_sur = p_ac3dec->samples.channel[3]; *(out_buf++) = right_tmp * NORM;
}
for (j = 0; j < 256; j++) break;
{
right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++; case 5: /* 3/1 */
left_tmp = -1 * right_tmp; left = p_ac3dec->samples.channel[0];
right_tmp += 0.3204f * *right++; centre = p_ac3dec->samples.channel[1];
left_tmp += 0.3204f * *left++ ; right = p_ac3dec->samples.channel[2];
/* Mono surround */
*(out_buf++) = left_tmp * NORM; right_sur = p_ac3dec->samples.channel[3];
*(out_buf++) = right_tmp * NORM;
/* for (j = 0; j < 256; j++) {
p_ac3dec->samples.channel[1][j] = right_tmp; right_tmp = 0.2265f * *right_sur++;
p_ac3dec->samples.channel[0][j] = left_tmp; left_tmp = - right_tmp;
*/ right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
} left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
break;
*(out_buf++) = left_tmp * NORM;
/* 3/1 */ *(out_buf++) = right_tmp * NORM;
case 5: }
left = p_ac3dec->samples.channel[0]; break;
centre = p_ac3dec->samples.channel[1];
right = p_ac3dec->samples.channel[2]; case 4: /* 2/1 */
/* Mono surround */ left = p_ac3dec->samples.channel[0];
right_sur = p_ac3dec->samples.channel[3]; right = p_ac3dec->samples.channel[1];
/* Mono surround */
for (j = 0; j < 256; j++) right_sur = p_ac3dec->samples.channel[2];
{
right_tmp = 0.2265f * *right_sur++; for (j = 0; j < 256; j++) {
left_tmp = - right_tmp; right_tmp = 0.2265f * *right_sur++;
right_tmp += 0.3204f * *right++ + 0.2265f * *centre; left_tmp = - right_tmp;
left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; right_tmp += 0.3204f * *right++;
left_tmp += 0.3204f * *left++;
*(out_buf++) = left_tmp * NORM;
*(out_buf++) = right_tmp * NORM; *(out_buf++) = left_tmp * NORM;
/* *(out_buf++) = right_tmp * NORM;
p_ac3dec->samples.channel[1][j] = right_tmp; }
p_ac3dec->samples.channel[0][j] = left_tmp; break;
*/
} case 3: /* 3/0 */
break; left = p_ac3dec->samples.channel[0];
centre = p_ac3dec->samples.channel[1];
/* 2/1 */ right = p_ac3dec->samples.channel[2];
case 4:
left = p_ac3dec->samples.channel[0]; for (j = 0; j < 256; j++) {
right = p_ac3dec->samples.channel[1]; right_tmp = 0.3204f * *right++ + 0.2265f * *centre;
/* Mono surround */ left_tmp = 0.3204f * *left++ + 0.2265f * *centre++;
right_sur = p_ac3dec->samples.channel[2];
*(out_buf++) = left_tmp * NORM;
for (j = 0; j < 256; j++) *(out_buf++) = right_tmp * NORM;
{ }
right_tmp = 0.2265f * *right_sur++; break;
left_tmp = - right_tmp;
right_tmp += 0.3204f * *right++; case 2: /* 2/0 */
left_tmp += 0.3204f * *left++; left = p_ac3dec->samples.channel[0];
right = p_ac3dec->samples.channel[1];
*(out_buf++) = left_tmp * NORM;
*(out_buf++) = right_tmp * NORM; for (j = 0; j < 256; j++) {
/* *(out_buf++) = *(left++) * NORM;
p_ac3dec->samples.channel[1][j] = right_tmp; *(out_buf++) = *(right++) * NORM;
p_ac3dec->samples.channel[0][j] = left_tmp; }
*/ break;
}
break; case 1: /* 1/0 */
/* Mono program! */
/* 3/0 */ right = p_ac3dec->samples.channel[0];
case 3:
left = p_ac3dec->samples.channel[0]; for (j = 0; j < 256; j++) {
centre = p_ac3dec->samples.channel[1]; right_tmp = 0.7071f * *right++;
right = p_ac3dec->samples.channel[2];
*(out_buf++) = right_tmp * NORM;
for (j = 0; j < 256; j++) *(out_buf++) = right_tmp * NORM;
{ }
right_tmp = 0.3204f * *right++ + 0.2265f * *centre; break;
left_tmp = 0.3204f * *left++ + 0.2265f * *centre++;
case 0: /* 1+1 */
*(out_buf++) = left_tmp * NORM; /* Dual mono, output selected by user */
*(out_buf++) = right_tmp * NORM; right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
/*
p_ac3dec->samples.channel[1][j] = right_tmp; for (j = 0; j < 256; j++) {
p_ac3dec->samples.channel[0][j] = left_tmp; right_tmp = 0.7071f * *right++;
*/
} *(out_buf++) = right_tmp * NORM;
break; *(out_buf++) = right_tmp * NORM;
}
/* 2/0 */ break;
case 2:
left = p_ac3dec->samples.channel[0];
right = p_ac3dec->samples.channel[1];
for ( j = 0; j < 256; j++ )
{
*(out_buf++) = *(left++) * NORM;
*(out_buf++) = *(right++) * NORM;
}
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 * NORM;
*(out_buf++) = right_tmp * NORM;
/*
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 * NORM;
*(out_buf++) = right_tmp * NORM;
/*
p_ac3dec->samples.channel[1][j] = right_tmp;
p_ac3dec->samples.channel[0][j] = right_tmp;
*/
}
break;
} }
} } else {
else
{
/* Non-Dolby surround downmixes */ /* Non-Dolby surround downmixes */
switch(p_ac3dec->bsi.acmod) switch(p_ac3dec->bsi.acmod) {
{ case 7: /* 3/2 */
/* 3/2 */ left = p_ac3dec->samples.channel[0];
case 7: centre = p_ac3dec->samples.channel[1];
left = p_ac3dec->samples.channel[0]; right = p_ac3dec->samples.channel[2];
centre = p_ac3dec->samples.channel[1]; left_sur = p_ac3dec->samples.channel[3];
right = p_ac3dec->samples.channel[2]; right_sur = p_ac3dec->samples.channel[4];
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];
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++;
for (j = 0; j < 256; j++) left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *left_sur++;
{
right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur++; *(out_buf++) = left_tmp * NORM;
left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *left_sur++; *(out_buf++) = right_tmp * NORM;
}
*(out_buf++) = left_tmp * NORM; break;
*(out_buf++) = right_tmp * NORM;
/* case 6: /* 2/2 */
p_ac3dec->samples.channel[1][j] = right_tmp; left = p_ac3dec->samples.channel[0];
p_ac3dec->samples.channel[0][j] = left_tmp; right = p_ac3dec->samples.channel[1];
*/ left_sur = p_ac3dec->samples.channel[2];
} right_sur = p_ac3dec->samples.channel[3];
break;
slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
/* 2/2 */
case 6: for (j = 0; j < 256; j++) {
left = p_ac3dec->samples.channel[0]; right_tmp= 0.4142f * *right++ + slev * *right_sur++;
right = p_ac3dec->samples.channel[1]; left_tmp = 0.4142f * *left++ + slev * *left_sur++;
left_sur = p_ac3dec->samples.channel[2];
right_sur = p_ac3dec->samples.channel[3]; *(out_buf++) = left_tmp * NORM;
*(out_buf++) = right_tmp * NORM;
slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; }
break;
for (j = 0; j < 256; j++)
{ case 5: /* 3/1 */
right_tmp= 0.4142f * *right++ + slev * *right_sur++; left = p_ac3dec->samples.channel[0];
left_tmp = 0.4142f * *left++ + slev * *left_sur++; centre = p_ac3dec->samples.channel[1];
right = p_ac3dec->samples.channel[2];
*(out_buf++) = left_tmp * NORM; /* Mono surround */
*(out_buf++) = right_tmp * NORM; right_sur = p_ac3dec->samples.channel[3];
/*
p_ac3dec->samples.channel[1][j] = right_tmp; clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
p_ac3dec->samples.channel[0][j] = left_tmp; slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
*/
} for (j = 0; j < 256; j++) {
break; right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur;
left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *right_sur++;
/* 3/1 */
case 5: *(out_buf++) = left_tmp * NORM;
left = p_ac3dec->samples.channel[0]; *(out_buf++) = right_tmp * NORM;
centre = p_ac3dec->samples.channel[1]; }
right = p_ac3dec->samples.channel[2]; break;
/* Mono surround */
right_sur = p_ac3dec->samples.channel[3]; case 4: /* 2/1 */
left = p_ac3dec->samples.channel[0];
clev = cmixlev_lut[p_ac3dec->bsi.cmixlev]; right = p_ac3dec->samples.channel[1];
slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; /* Mono surround */
right_sur = p_ac3dec->samples.channel[2];
for (j = 0; j < 256; j++)
{ slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur;
left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *right_sur++; for (j = 0; j < 256; j++) {
right_tmp= 0.4142f * *right++ + slev * *right_sur;
*(out_buf++) = left_tmp * NORM; left_tmp = 0.4142f * *left++ + slev * *right_sur++;
*(out_buf++) = right_tmp * NORM;
/* *(out_buf++) = left_tmp * NORM;
p_ac3dec->samples.channel[1][j] = right_tmp; *(out_buf++) = right_tmp * NORM;
p_ac3dec->samples.channel[0][j] = left_tmp; }
*/ break;
}
break; case 3: /* 3/0 */
left = p_ac3dec->samples.channel[0];
/* 2/1 */ centre = p_ac3dec->samples.channel[1];
case 4: right = p_ac3dec->samples.channel[2];
left = p_ac3dec->samples.channel[0];
right = p_ac3dec->samples.channel[1]; clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
/* Mono surround */
right_sur = p_ac3dec->samples.channel[2]; for (j = 0; j < 256; j++) {
right_tmp= 0.4142f * *right++ + clev * *centre;
slev = smixlev_lut[p_ac3dec->bsi.surmixlev]; left_tmp = 0.4142f * *left++ + clev * *centre++;
for (j = 0; j < 256; j++) *(out_buf++) = left_tmp * NORM;
{ *(out_buf++) = right_tmp * NORM;
right_tmp= 0.4142f * *right++ + slev * *right_sur; }
left_tmp = 0.4142f * *left++ + slev * *right_sur++; break;
*(out_buf++) = left_tmp * NORM; case 2: /* 2/0 */
*(out_buf++) = right_tmp * NORM; left = p_ac3dec->samples.channel[0];
/* right = p_ac3dec->samples.channel[1];
p_ac3dec->samples.channel[1][j] = right_tmp;
p_ac3dec->samples.channel[0][j] = left_tmp; for (j = 0; j < 256; j++) {
*/ *(out_buf++) = *(left++) * NORM;
} *(out_buf++) = *(right++) * NORM;
break; }
break;
/* 3/0 */
case 3: case 1: /* 1/0 */
left = p_ac3dec->samples.channel[0]; /* Mono program! */
centre = p_ac3dec->samples.channel[1]; right = p_ac3dec->samples.channel[0];
right = p_ac3dec->samples.channel[2];
for (j = 0; j < 256; j++) {
clev = cmixlev_lut[p_ac3dec->bsi.cmixlev]; right_tmp = 0.7071f * *right++;
for (j = 0; j < 256; j++) *(out_buf++) = right_tmp * NORM;
{ *(out_buf++) = right_tmp * NORM;
right_tmp= 0.4142f * *right++ + clev * *centre; }
left_tmp = 0.4142f * *left++ + clev * *centre++; break;
*(out_buf++) = left_tmp * NORM; case 0: /* 1+1 */
*(out_buf++) = right_tmp * NORM; /* Dual mono, output selected by user */
/* right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
p_ac3dec->samples.channel[1][j] = right_tmp;
p_ac3dec->samples.channel[0][j] = left_tmp; for (j = 0; j < 256; j++) {
*/ right_tmp = 0.7071f * *right++;
}
break; *(out_buf++) = right_tmp * NORM;
*(out_buf++) = right_tmp * NORM;
case 2: }
left = p_ac3dec->samples.channel[0]; break;
right = p_ac3dec->samples.channel[1];
for ( j = 0; j < 256; j++ )
{
*(out_buf++) = *(left++) * NORM;
*(out_buf++) = *(right++) * NORM;
}
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 * NORM;
*(out_buf++) = right_tmp * NORM;
/*
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 * NORM;
*(out_buf++) = right_tmp * NORM;
/*
p_ac3dec->samples.channel[1][j] = right_tmp;
p_ac3dec->samples.channel[0][j] = right_tmp;
*/
}
break;
} }
} }
} }

1
src/ac3_decoder/ac3_downmix.h

@ -1 +0,0 @@
void downmix( ac3dec_t *, s16 * );

62
src/ac3_decoder/ac3_exponent.c

@ -3,7 +3,7 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_bit_stream.h" #include "ac3_bit_stream.h"
#include "ac3_exponent.h" #include "ac3_internal.h"
static const s16 exps_1[128] = static const s16 exps_1[128] =
{ -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, { -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,
@ -33,13 +33,14 @@ static const s16 exps_3[128] =
#define UNPACK_CPL 2 #define UNPACK_CPL 2
#define UNPACK_LFE 4 #define UNPACK_LFE 4
static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, u16 ngrps, u16 initial_exp, u16 exps[], u16 * dest ) static __inline__ int exp_unpack_ch (ac3dec_t * p_ac3dec, u16 type,
u16 expstr, u16 ngrps, u16 initial_exp,
u16 exps[], u16 * dest)
{ {
u16 i,j; u16 i,j;
s16 exp_acc; s16 exp_acc;
if ( expstr == EXP_REUSE ) if (expstr == EXP_REUSE) {
{
return 0; return 0;
} }
@ -49,20 +50,16 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
/* In the case of a fbw channel then the initial absolute values is /* In the case of a fbw channel then the initial absolute values is
* also an exponent */ * also an exponent */
if ( type != UNPACK_CPL ) if (type != UNPACK_CPL) {
{
dest[j++] = exp_acc; dest[j++] = exp_acc;
} }
/* Loop through the groups and fill the dest array appropriately */ /* Loop through the groups and fill the dest array appropriately */
switch ( expstr ) switch (expstr) {
{
case EXP_D15: /* 1 */ case EXP_D15: /* 1 */
for ( i = 0; i < ngrps; i++ ) for (i = 0; i < ngrps; i++) {
{ if (exps[i] > 124) {
if ( exps[i] > 124 ) fprintf (stderr, "ac3dec debug: invalid exponent\n");
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1; return 1;
} }
exp_acc += (exps_1[exps[i]] /*- 2*/); exp_acc += (exps_1[exps[i]] /*- 2*/);
@ -75,11 +72,9 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
break; break;
case EXP_D25: /* 2 */ case EXP_D25: /* 2 */
for ( i = 0; i < ngrps; i++ ) for (i = 0; i < ngrps; i++) {
{ if (exps[i] > 124) {
if ( exps[i] > 124 ) fprintf (stderr, "ac3dec debug: invalid exponent\n");
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1; return 1;
} }
exp_acc += (exps_1[exps[i]] /*- 2*/); exp_acc += (exps_1[exps[i]] /*- 2*/);
@ -95,11 +90,9 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
break; break;
case EXP_D45: /* 3 */ case EXP_D45: /* 3 */
for ( i = 0; i < ngrps; i++ ) for (i = 0; i < ngrps; i++) {
{ if (exps[i] > 124) {
if ( exps[i] > 124 ) fprintf (stderr, "ac3dec debug: invalid exponent\n");
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1; return 1;
} }
exp_acc += (exps_1[exps[i]] /*- 2*/); exp_acc += (exps_1[exps[i]] /*- 2*/);
@ -124,36 +117,33 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
return 0; return 0;
} }
int exponent_unpack( ac3dec_t * p_ac3dec ) int exponent_unpack (ac3dec_t * p_ac3dec)
{ {
u16 i; u16 i;
for ( i = 0; i < p_ac3dec->bsi.nfchans; i++ ) for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
{ if (exp_unpack_ch (p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
if (exp_unpack_ch( p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
p_ac3dec->audblk.nchgrps[i], p_ac3dec->audblk.nchgrps[i],
p_ac3dec->audblk.exps[i][0], p_ac3dec->audblk.exps[i][0],
&p_ac3dec->audblk.exps[i][1], &p_ac3dec->audblk.exps[i][1],
p_ac3dec->audblk.fbw_exp[i] )) p_ac3dec->audblk.fbw_exp[i]))
return 1; return 1;
} }
if ( p_ac3dec->audblk.cplinu ) if (p_ac3dec->audblk.cplinu) {
{ if (exp_unpack_ch (p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
if (exp_unpack_ch( p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
p_ac3dec->audblk.ncplgrps, p_ac3dec->audblk.ncplgrps,
p_ac3dec->audblk.cplabsexp << 1, p_ac3dec->audblk.cplabsexp << 1,
p_ac3dec->audblk.cplexps, p_ac3dec->audblk.cplexps,
&p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant] )) &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]))
return 1; return 1;
} }
if ( p_ac3dec->bsi.lfeon ) if (p_ac3dec->bsi.lfeon) {
{ if (exp_unpack_ch (p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
if (exp_unpack_ch( p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
2, p_ac3dec->audblk.lfeexps[0], 2, p_ac3dec->audblk.lfeexps[0],
&p_ac3dec->audblk.lfeexps[1], &p_ac3dec->audblk.lfeexps[1],
p_ac3dec->audblk.lfe_exp )) p_ac3dec->audblk.lfe_exp))
return 1; return 1;
} }

1
src/ac3_decoder/ac3_exponent.h

@ -1 +0,0 @@
int exponent_unpack( ac3dec_t * );

108
src/ac3_decoder/ac3_imdct.c

@ -2,13 +2,12 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_imdct.h" #include "ac3_internal.h"
void imdct_do_256(float x[],float y[],float delay[]); void imdct_do_256(float x[],float y[],float delay[]);
void imdct_do_512(float x[],float y[],float delay[]); void imdct_do_512(float x[],float y[],float delay[]);
typedef struct complex_s typedef struct complex_s {
{
float real; float real;
float imag; float imag;
} complex_t; } complex_t;
@ -119,22 +118,21 @@ static __inline__ complex_t cmplx_mult(complex_t a, complex_t b)
return ret; return ret;
} }
void imdct_init(void) static void imdct_init(void) __attribute__ ((__constructor__));
static void imdct_init(void)
{ {
int i,k; int i,k;
complex_t angle_step; complex_t angle_step;
complex_t current_angle; complex_t current_angle;
/* Twiddle factors to turn IFFT into IMDCT */ /* Twiddle factors to turn IFFT into IMDCT */
for( i=0; i < N/4; i++) for (i=0; i < N/4; i++) {
{
xcos1[i] = -cos(2 * M_PI * (8*i+1)/(8*N)) ; xcos1[i] = -cos(2 * M_PI * (8*i+1)/(8*N)) ;
xsin1[i] = -sin(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 */ /* More twiddle factors to turn IFFT into IMDCT */
for( i=0; i < N/8; i++) for (i=0; i < N/8; i++) {
{
xcos2[i] = -cos(2 * M_PI * (8*i+1)/(4*N)) ; xcos2[i] = -cos(2 * M_PI * (8*i+1)/(4*N)) ;
xsin2[i] = -sin(2 * M_PI * (8*i+1)/(4*N)) ; xsin2[i] = -sin(2 * M_PI * (8*i+1)/(4*N)) ;
} }
@ -148,29 +146,26 @@ void imdct_init(void)
w[5] = w_32; w[5] = w_32;
w[6] = w_64; w[6] = w_64;
for( i = 0; i < 7; i++) for (i = 0; i < 7; i++) {
{
angle_step.real = cos(-2.0f * M_PI / (1 << (i+1))); angle_step.real = cos(-2.0f * M_PI / (1 << (i+1)));
angle_step.imag = sin(-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.real = 1.0f;
current_angle.imag = 0.0f; current_angle.imag = 0.0f;
for (k = 0; k < 1 << i; k++) for (k = 0; k < 1 << i; k++) {
{
w[i][k] = current_angle; w[i][k] = current_angle;
current_angle = cmplx_mult(current_angle,angle_step); current_angle = cmplx_mult(current_angle,angle_step);
} }
} }
} }
void imdct( ac3dec_t * p_ac3dec ) void imdct (ac3dec_t * p_ac3dec)
{ {
int i; int i;
for(i=0; i<p_ac3dec->bsi.nfchans;i++) for (i=0; i<p_ac3dec->bsi.nfchans;i++) {
{ if (p_ac3dec->audblk.blksw[i])
if(p_ac3dec->audblk.blksw[i])
imdct_do_256(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]); imdct_do_256(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]);
else else
imdct_do_512(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]); imdct_do_512(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]);
@ -202,31 +197,26 @@ imdct_do_512(float x[],float y[],float delay[])
float *window_ptr; float *window_ptr;
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for( i=0; i < N/4; i++) for (i=0; i < N/4; i++) {
{
/* z[i] = (X[N/2-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[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].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])); buf[i].imag = -((x[2*i] * xcos1[i]) + (x[N/2-2*i-1] * xsin1[i]));
} }
/* Bit reversed shuffling */ /* Bit reversed shuffling */
for(i=0; i<N/4; i++) for (i=0; i<N/4; i++) {
{
k = bit_reverse_512[i]; k = bit_reverse_512[i];
if (k < i) if (k < i)
swap_cmplx(&buf[i],&buf[k]); swap_cmplx(&buf[i],&buf[k]);
} }
/* FFT Merge */ /* FFT Merge */
for (m=0; m < 7; m++) for (m=0; m < 7; m++) {
{
two_m = (1 << m); two_m = (1 << m);
two_m_plus_one = (1 << (m+1)); two_m_plus_one = (1 << (m+1));
for(k = 0; k < two_m; k++) for (k = 0; k < two_m; k++) {
{ for (i = 0; i < 128; i += two_m_plus_one) {
for(i = 0; i < 128; i += two_m_plus_one)
{
p = k + i; p = k + i;
q = p + two_m; q = p + two_m;
tmp_a_r = buf[p].real; tmp_a_r = buf[p].real;
@ -237,48 +227,42 @@ imdct_do_512(float x[],float y[],float delay[])
buf[p].imag = tmp_a_i + tmp_b_i; buf[p].imag = tmp_a_i + tmp_b_i;
buf[q].real = tmp_a_r - tmp_b_r; buf[q].real = tmp_a_r - tmp_b_r;
buf[q].imag = tmp_a_i - tmp_b_i; buf[q].imag = tmp_a_i - tmp_b_i;
} }
} }
} }
/* Post IFFT complex multiply plus IFFT complex conjugate*/ /* Post IFFT complex multiply plus IFFT complex conjugate*/
for( i=0; i < N/4; i++) for (i=0; i < N/4; i++) {
{
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
tmp_a_r = buf[i].real; tmp_a_r = buf[i].real;
tmp_a_i = - buf[i].imag; tmp_a_i = - buf[i].imag;
buf[i].real =(tmp_a_r * xcos1[i]) - (tmp_a_i * xsin1[i]); 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]); buf[i].imag =(tmp_a_r * xsin1[i]) + (tmp_a_i * xcos1[i]);
} }
y_ptr = y; y_ptr = y;
delay_ptr = delay; delay_ptr = delay;
window_ptr = window; window_ptr = window;
/* Window and convert to real valued signal */ /* Window and convert to real valued signal */
for(i=0; i<N/8; i++) 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].imag * *window_ptr++ + *delay_ptr++);
*y_ptr++ = 2.0f * ( buf[N/8-i-1].real * *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++) for (i=0; i<N/8; i++) {
{
*y_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++); *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++); *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 */ /* The trailing edge of the window goes into the delay line */
delay_ptr = delay; delay_ptr = delay;
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
*delay_ptr++ = -buf[N/8+i].real * *--window_ptr; *delay_ptr++ = -buf[N/8+i].real * *--window_ptr;
*delay_ptr++ = buf[N/8-i-1].imag * *--window_ptr; *delay_ptr++ = buf[N/8-i-1].imag * *--window_ptr;
} }
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
*delay_ptr++ = buf[i].imag * *--window_ptr; *delay_ptr++ = buf[i].imag * *--window_ptr;
*delay_ptr++ = -buf[N/4-i-1].real * *--window_ptr; *delay_ptr++ = -buf[N/4-i-1].real * *--window_ptr;
} }
@ -304,8 +288,7 @@ imdct_do_256(float x[],float y[],float delay[])
buf_2 = &buf[64]; buf_2 = &buf[64];
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for(k=0; k<N/8; k++) for (k=0; k<N/8; k++) {
{
/* X1[k] = X[2*k] */ /* X1[k] = X[2*k] */
/* X2[k] = X[2*k+1] */ /* X2[k] = X[2*k+1] */
@ -321,26 +304,21 @@ imdct_do_256(float x[],float y[],float delay[])
} }
/* IFFT Bit reversed shuffling */ /* IFFT Bit reversed shuffling */
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
k = bit_reverse_256[i]; k = bit_reverse_256[i];
if (k < i) if (k < i) {
{
swap_cmplx(&buf_1[i],&buf_1[k]); swap_cmplx(&buf_1[i],&buf_1[k]);
swap_cmplx(&buf_2[i],&buf_2[k]); swap_cmplx(&buf_2[i],&buf_2[k]);
} }
} }
/* FFT Merge */ /* FFT Merge */
for (m=0; m < 6; m++) for (m=0; m < 6; m++) {
{
two_m = (1 << m); two_m = (1 << m);
two_m_plus_one = (1 << (m+1)); two_m_plus_one = (1 << (m+1));
for(k = 0; k < two_m; k++) for (k = 0; k < two_m; k++) {
{ for (i = 0; i < 64; i += two_m_plus_one) {
for(i = 0; i < 64; i += two_m_plus_one)
{
p = k + i; p = k + i;
q = p + two_m; q = p + two_m;
/* Do block 1 */ /* Do block 1 */
@ -362,29 +340,26 @@ imdct_do_256(float x[],float y[],float delay[])
buf_2[p].imag = tmp_a_i + tmp_b_i; buf_2[p].imag = tmp_a_i + tmp_b_i;
buf_2[q].real = tmp_a_r - tmp_b_r; buf_2[q].real = tmp_a_r - tmp_b_r;
buf_2[q].imag = tmp_a_i - tmp_b_i; buf_2[q].imag = tmp_a_i - tmp_b_i;
} }
} }
} }
/* Post IFFT complex multiply */ /* Post IFFT complex multiply */
for( i=0; i < N/8; i++) for (i=0; i < N/8; i++) {
{
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
tmp_a_r = buf_1[i].real; tmp_a_r = buf_1[i].real;
tmp_a_i = - buf_1[i].imag; tmp_a_i = - buf_1[i].imag;
buf_1[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); 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]); buf_1[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
/* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */ /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
tmp_a_r = buf_2[i].real; tmp_a_r = buf_2[i].real;
tmp_a_i = - buf_2[i].imag; tmp_a_i = - buf_2[i].imag;
buf_2[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); 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]); buf_2[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
} }
/* Window and convert to real valued signal */ /* Window and convert to real valued signal */
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
y[2*i] = -buf_1[i].imag * window[2*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[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] = -buf_1[i].real * window[N/4+2*i];
@ -396,8 +371,7 @@ imdct_do_256(float x[],float y[],float delay[])
} }
/* Overlap and add */ /* Overlap and add */
for(i=0; i<N/2; i++) for (i=0; i<N/2; i++) {
{
y[i] = 2 * (y[i] + delay[i]); y[i] = 2 * (y[i] + delay[i]);
delay[i] = y[N/2+i]; delay[i] = y[N/2+i];
} }

2
src/ac3_decoder/ac3_imdct.h

@ -1,2 +0,0 @@
void imdct( ac3dec_t * p_ac3dec );
void imdct_init( void );

36
src/ac3_decoder/ac3_internal.h

@ -0,0 +1,36 @@
/* 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)
/* ac3_bit_allocate.c */
void bit_allocate (ac3dec_t *);
/* ac3_downmix.c */
void downmix (ac3dec_t *, s16 *);
/* ac3_exponent.c */
int exponent_unpack (ac3dec_t *);
/* ac3_imdct.c */
void imdct (ac3dec_t * p_ac3dec);
/* ac3_mantissa.c */
void mantissa_unpack (ac3dec_t *);
/* ac3_parse.c */
int ac3_test_sync (ac3dec_t *);
void parse_syncinfo (ac3dec_t *);
void parse_bsi (ac3dec_t *);
void parse_audblk (ac3dec_t *);
void parse_auxdata (ac3dec_t *);
/* ac3_rematrix.c */
void rematrix (ac3dec_t *);

265
src/ac3_decoder/ac3_mantissa.c

@ -2,12 +2,12 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_mantissa.h" #include "ac3_internal.h"
#include "ac3_bit_stream.h" #include "ac3_bit_stream.h"
#define Q0 ((-2 << 15) / 3) #define Q0 ((-2 << 15) / 3.0)
#define Q1 (0) #define Q1 (0)
#define Q2 ((2 << 15) / 3) #define Q2 ((2 << 15) / 3.0)
static float q_1_0[ 32 ] = { Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, static float q_1_0[ 32 ] = { Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
@ -24,11 +24,11 @@ static float q_1_2[ 32 ] = { Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
#undef Q1 #undef Q1
#undef Q2 #undef Q2
#define Q0 ((-4 << 15) / 5) #define Q0 ((-4 << 15) / 5.0)
#define Q1 ((-2 << 15) / 5) #define Q1 ((-2 << 15) / 5.0)
#define Q2 (0) #define Q2 (0)
#define Q3 ((2 << 15) / 5) #define Q3 ((2 << 15) / 5.0)
#define Q4 ((4 << 15) / 5) #define Q4 ((4 << 15) / 5.0)
static float q_2_0[ 128 ] = static float q_2_0[ 128 ] =
{ Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, { Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
@ -56,17 +56,17 @@ static float q_2_2[ 128 ] =
#undef Q3 #undef Q3
#undef Q4 #undef Q4
#define Q0 ((-10 << 15) / 11) #define Q0 ((-10 << 15) / 11.0)
#define Q1 ((-8 << 15) / 11) #define Q1 ((-8 << 15) / 11.0)
#define Q2 ((-6 << 15) / 11) #define Q2 ((-6 << 15) / 11.0)
#define Q3 ((-4 << 15) / 11) #define Q3 ((-4 << 15) / 11.0)
#define Q4 ((-2 << 15) / 11) #define Q4 ((-2 << 15) / 11.0)
#define Q5 (0) #define Q5 (0)
#define Q6 ((2 << 15) / 11) #define Q6 ((2 << 15) / 11.0)
#define Q7 ((4 << 15) / 11) #define Q7 ((4 << 15) / 11.0)
#define Q8 ((6 << 15) / 11) #define Q8 ((6 << 15) / 11.0)
#define Q9 ((8 << 15) / 11) #define Q9 ((8 << 15) / 11.0)
#define QA ((10 << 15) / 11) #define QA ((10 << 15) / 11.0)
static float q_4_0[ 128 ] = { Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, static float q_4_0[ 128 ] = { Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
@ -105,15 +105,16 @@ static float q_4_1[ 128 ] = { Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
/* Lookup tables of 0.16 two's complement quantization values */ /* Lookup tables of 0.16 two's complement quantization values */
static float q_3[7] = { (-6 << 15)/7, (-4 << 15)/7, (-2 << 15)/7, static float q_3[8] = { (-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0,
0 , ( 2 << 15)/7, ( 4 << 15)/7, 0 , (2 << 15)/7.0, (4 << 15)/7.0,
( 6 << 15)/7}; (6 << 15)/7.0, 0 };
static float q_5[15] = { (-14 << 15)/15, (-12 << 15)/15, (-10 << 15)/15, static float q_5[16] = { (-14 << 15)/15.0, (-12 << 15)/15.0, (-10 << 15)/15.0,
( -8 << 15)/15, ( -6 << 15)/15, ( -4 << 15)/15, (-8 << 15)/15.0, (-6 << 15)/15.0, (-4 << 15)/15.0,
( -2 << 15)/15, 0 , ( 2 << 15)/15, (-2 << 15)/15.0, 0 , (2 << 15)/15.0,
( 4 << 15)/15, ( 6 << 15)/15, ( 8 << 15)/15, (4 << 15)/15.0, (6 << 15)/15.0, (8 << 15)/15.0,
( 10 << 15)/15, ( 12 << 15)/15, ( 14 << 15)/15}; (10 << 15)/15.0, (12 << 15)/15.0, (14 << 15)/15.0,
0 };
/* These store the persistent state of the packed mantissas */ /* These store the persistent state of the packed mantissas */
static float q_1[2]; static float q_1[2];
@ -157,112 +158,103 @@ static float exp_lut[ 25 ] =
}; };
/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */ /* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */
static __inline__ float float_get( ac3dec_t * p_ac3dec, u16 bap, u16 exp ) static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
{ {
u32 group_code; u32 group_code;
/* If the bap is 0-5 then we have special cases to take care of */ /* If the bap is 0-5 then we have special cases to take care of */
switch ( bap ) switch (bap) {
{ case 0:
case 0: return (0); /* FIXME dither */
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.buffer >> (32 - 5);
DumpBits( &(p_ac3dec->bit_stream), 5 );
if ( group_code > 26 ) case 1:
{ if (q_1_pointer >= 0) {
fprintf( stderr, "ac3dec debug: invalid mantissa\n" ); return (q_1[q_1_pointer--] * exp_lut[exp]);
} }
q_1[ 1 ] = q_1_1[ group_code ]; NeedBits (&(p_ac3dec->bit_stream), 5);
q_1[ 0 ] = q_1_2[ group_code ]; group_code = p_ac3dec->bit_stream.buffer >> (32 - 5);
DumpBits (&(p_ac3dec->bit_stream), 5);
if (group_code >= 27) {
fprintf (stderr, "ac3dec debug: invalid mantissa\n");
}
q_1_pointer = 1; q_1[ 1 ] = q_1_1[ group_code ];
q_1[ 0 ] = q_1_2[ group_code ];
return( q_1_0[group_code] * exp_lut[exp] ); q_1_pointer = 1;
case 2: return (q_1_0[group_code] * exp_lut[exp]);
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.buffer >> (32 - 7);
DumpBits( &(p_ac3dec->bit_stream), 7 );
if ( group_code > 124 ) case 2:
{ if (q_2_pointer >= 0) {
fprintf( stderr, "ac3dec debug: invalid mantissa\n" ); return (q_2[q_2_pointer--] * exp_lut[exp]);
} }
NeedBits (&(p_ac3dec->bit_stream), 7);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 7);
DumpBits (&(p_ac3dec->bit_stream), 7);
q_2[ 1 ] = q_2_1[ group_code ]; if (group_code >= 125) {
q_2[ 0 ] = q_2_2[ group_code ]; fprintf (stderr, "ac3dec debug: invalid mantissa\n");
}
q_2_pointer = 1; q_2[ 1 ] = q_2_1[ group_code ];
q_2[ 0 ] = q_2_2[ group_code ];
return( q_2_0[ group_code ] * exp_lut[exp] ); q_2_pointer = 1;
case 3: return (q_2_0[ group_code ] * exp_lut[exp]);
NeedBits( &(p_ac3dec->bit_stream), 3 );
group_code = p_ac3dec->bit_stream.buffer >> (32 - 3);
DumpBits( &(p_ac3dec->bit_stream), 3 );
if ( group_code > 6 ) case 3:
{ NeedBits (&(p_ac3dec->bit_stream), 3);
fprintf( stderr, "ac3dec debug: invalid mantissa\n" ); group_code = p_ac3dec->bit_stream.buffer >> (32 - 3);
} DumpBits (&(p_ac3dec->bit_stream), 3);
return( q_3[group_code] * exp_lut[exp] ); if (group_code >= 7) {
fprintf (stderr, "ac3dec debug: invalid mantissa\n");
}
case 4: return (q_3[group_code] * exp_lut[exp]);
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.buffer >> (32 - 7);
DumpBits( &(p_ac3dec->bit_stream), 7 );
if ( group_code > 120 ) case 4:
{ if (q_4_pointer >= 0) {
fprintf( stderr, "ac3dec debug: invalid mantissa\n" ); return (q_4[q_4_pointer--] * exp_lut[exp]);
} }
NeedBits (&(p_ac3dec->bit_stream), 7);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 7);
DumpBits (&(p_ac3dec->bit_stream), 7);
q_4[ 0 ] = q_4_1[ group_code ]; if (group_code >= 121) {
fprintf (stderr, "ac3dec debug: invalid mantissa\n");
}
q_4_pointer = 0; q_4[ 0 ] = q_4_1[ group_code ];
return( q_4_0[ group_code ] * exp_lut[exp] ); q_4_pointer = 0;
case 5: return (q_4_0[ group_code ] * exp_lut[exp]);
NeedBits( &(p_ac3dec->bit_stream), 4 );
group_code = p_ac3dec->bit_stream.buffer >> (32 - 4);
DumpBits( &(p_ac3dec->bit_stream), 4 );
if ( group_code > 14 ) case 5:
{ NeedBits (&(p_ac3dec->bit_stream), 4);
fprintf( stderr, "ac3dec debug: invalid mantissa\n" ); group_code = p_ac3dec->bit_stream.buffer >> (32 - 4);
} DumpBits (&(p_ac3dec->bit_stream), 4);
return( q_5[group_code] * exp_lut[exp] ); if (group_code >= 15) {
fprintf (stderr, "ac3dec debug: invalid mantissa\n");
}
default: return (q_5[group_code] * exp_lut[exp]);
NeedBits( &(p_ac3dec->bit_stream), qnttztab[bap] );
group_code = (((s32)(p_ac3dec->bit_stream.buffer)) >> (32 - qnttztab[bap])) << (16 - qnttztab[bap]);
DumpBits( &(p_ac3dec->bit_stream), qnttztab[bap] );
return( ((s32)group_code) * exp_lut[exp] ); default:
NeedBits (&(p_ac3dec->bit_stream), qnttztab[bap]);
group_code = (((s32)(p_ac3dec->bit_stream.buffer)) >> (32 - qnttztab[bap])) << (16 - qnttztab[bap]);
DumpBits (&(p_ac3dec->bit_stream), qnttztab[bap]);
return (((s32)group_code) * exp_lut[exp]);
} }
} }
static __inline__ void uncouple_channel( ac3dec_t * p_ac3dec, u32 ch ) static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch)
{ {
u32 bnd = 0; u32 bnd = 0;
u32 i,j; u32 i,j;
@ -270,12 +262,10 @@ static __inline__ void uncouple_channel( ac3dec_t * p_ac3dec, u32 ch )
u32 cpl_exp_tmp; u32 cpl_exp_tmp;
u32 cpl_mant_tmp; u32 cpl_mant_tmp;
for(i=p_ac3dec->audblk.cplstrtmant;i<p_ac3dec->audblk.cplendmant;) for (i = p_ac3dec->audblk.cplstrtmant; i < p_ac3dec->audblk.cplendmant;) {
{ if (!p_ac3dec->audblk.cplbndstrc[bnd]) {
if(!p_ac3dec->audblk.cplbndstrc[bnd])
{
cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] + 3 * p_ac3dec->audblk.mstrcplco[ch]; cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] + 3 * p_ac3dec->audblk.mstrcplco[ch];
if(p_ac3dec->audblk.cplcoexp[ch][bnd] == 15) if (p_ac3dec->audblk.cplcoexp[ch][bnd] == 15)
cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 12; cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 12;
else else
cpl_mant_tmp = ((0x10) | p_ac3dec->audblk.cplcomant[ch][bnd]) << 11; cpl_mant_tmp = ((0x10) | p_ac3dec->audblk.cplcomant[ch][bnd]) << 11;
@ -284,15 +274,14 @@ static __inline__ void uncouple_channel( ac3dec_t * p_ac3dec, u32 ch )
} }
bnd++; bnd++;
for(j=0;j < 12; j++) for (j=0;j < 12; j++) {
{
p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i]; p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i];
i++; i++;
} }
} }
} }
void mantissa_unpack( ac3dec_t * p_ac3dec ) void mantissa_unpack (ac3dec_t * p_ac3dec)
{ {
int i, j; int i, j;
@ -300,58 +289,44 @@ void mantissa_unpack( ac3dec_t * p_ac3dec )
q_2_pointer = -1; q_2_pointer = -1;
q_4_pointer = -1; q_4_pointer = -1;
if ( p_ac3dec->audblk.cplinu ) if (p_ac3dec->audblk.cplinu) {
{
/* 1 */ /* 1 */
for ( i = 0; !p_ac3dec->audblk.chincpl[i]; i++ ) for (i = 0; !p_ac3dec->audblk.chincpl[i]; i++) {
{ for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) {
for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]);
{
p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] );
} }
} }
/* 2 */ /* 2 */
for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) {
{ p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]);
p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] );
} }
for ( j = p_ac3dec->audblk.cplstrtmant; j < p_ac3dec->audblk.cplendmant; j++ ) for (j = p_ac3dec->audblk.cplstrtmant; j < p_ac3dec->audblk.cplendmant; j++) {
{ p_ac3dec->audblk.cplfbw[j] = float_get (p_ac3dec, p_ac3dec->audblk.cpl_bap[j], p_ac3dec->audblk.cpl_exp[j]);
p_ac3dec->audblk.cplfbw[j] = float_get( p_ac3dec, p_ac3dec->audblk.cpl_bap[j], p_ac3dec->audblk.cpl_exp[j] );
} }
uncouple_channel( p_ac3dec, i ); uncouple_channel (p_ac3dec, i);
/* 3 */ /* 3 */
for ( i++; i < p_ac3dec->bsi.nfchans; i++ ) for (i++; i < p_ac3dec->bsi.nfchans; i++) {
{ for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) {
for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ ) p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]);
{
p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] );
} }
if ( p_ac3dec->audblk.chincpl[i] ) if (p_ac3dec->audblk.chincpl[i]) {
{ uncouple_channel (p_ac3dec, i);
uncouple_channel( p_ac3dec, i );
} }
} }
} } else {
else for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
{ for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) {
for ( i = 0; i < p_ac3dec->bsi.nfchans; i++ ) p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]);
{
for ( j = 0; j < p_ac3dec->audblk.endmant[i]; j++ )
{
p_ac3dec->coeffs.fbw[i][j] = float_get( p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j] );
} }
} }
} }
if ( p_ac3dec->bsi.lfeon ) if (p_ac3dec->bsi.lfeon) {
{
/* There are always 7 mantissas for lfe, no dither for lfe */ /* There are always 7 mantissas for lfe, no dither for lfe */
for ( j = 0; j < 7; j++ ) for (j = 0; j < 7; j++) {
{ p_ac3dec->coeffs.lfe[j] = float_get (p_ac3dec, p_ac3dec->audblk.lfe_bap[j], p_ac3dec->audblk.lfe_exp[j]);
p_ac3dec->coeffs.lfe[j] = float_get( p_ac3dec, p_ac3dec->audblk.lfe_bap[j], p_ac3dec->audblk.lfe_exp[j] );
} }
} }
} }

1
src/ac3_decoder/ac3_mantissa.h

@ -1 +0,0 @@
void mantissa_unpack( ac3dec_t * );

701
src/ac3_decoder/ac3_parse.c

File diff suppressed because it is too large

5
src/ac3_decoder/ac3_parse.h

@ -1,5 +0,0 @@
int ac3_test_sync (ac3dec_t *);
void parse_syncinfo( ac3dec_t * );
void parse_bsi( ac3dec_t * );
void parse_audblk( ac3dec_t * );
void parse_auxdata( ac3dec_t * );

21
src/ac3_decoder/ac3_rematrix.c

@ -1,23 +1,22 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_rematrix.h" #include "ac3_internal.h"
struct rematrix_band_s struct rematrix_band_s {
{
u32 start; u32 start;
u32 end; u32 end;
}; };
static struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}}; static struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}};
static __inline__ u32 min( u32 a, u32 b ) static __inline__ u32 min (u32 a, u32 b)
{ {
return( a < b ? a : b ); return (a < b ? a : b);
} }
/* This routine simply does stereo rematixing for the 2 channel /* This routine simply does stereo rematixing for the 2 channel
* stereo mode */ * stereo mode */
void rematrix( ac3dec_t * p_ac3dec ) void rematrix (ac3dec_t * p_ac3dec)
{ {
u32 num_bands; u32 num_bands;
u32 start; u32 start;
@ -25,23 +24,21 @@ void rematrix( ac3dec_t * p_ac3dec )
u32 i,j; u32 i,j;
float left,right; float left,right;
if(p_ac3dec->audblk.cplinu || p_ac3dec->audblk.cplbegf > 2) if (p_ac3dec->audblk.cplinu || p_ac3dec->audblk.cplbegf > 2)
num_bands = 4; num_bands = 4;
else if (p_ac3dec->audblk.cplbegf > 0) else if (p_ac3dec->audblk.cplbegf > 0)
num_bands = 3; num_bands = 3;
else else
num_bands = 2; num_bands = 2;
for(i=0;i < num_bands; i++) for (i=0;i < num_bands; i++) {
{ if (!p_ac3dec->audblk.rematflg[i])
if(!p_ac3dec->audblk.rematflg[i])
continue; continue;
start = rematrix_band[i].start; start = rematrix_band[i].start;
end = min(rematrix_band[i].end ,12 * p_ac3dec->audblk.cplbegf + 36); end = min(rematrix_band[i].end ,12 * p_ac3dec->audblk.cplbegf + 36);
for(j=start;j < end; j++) for (j=start;j < end; j++) {
{
left = 0.5f * (p_ac3dec->coeffs.fbw[0][j] + p_ac3dec->coeffs.fbw[1][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]); 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[0][j] = left;

1
src/ac3_decoder/ac3_rematrix.h

@ -1 +0,0 @@
void rematrix( ac3dec_t * );

2
src/input/input.c

@ -1074,8 +1074,10 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
break; break;
case AC3_AUDIO_ES: case AC3_AUDIO_ES:
#if 0
/* we skip 4 bytes at the beginning of the AC3 payload */ /* we skip 4 bytes at the beginning of the AC3 payload */
p_ts->i_payload_start += 4; p_ts->i_payload_start += 4;
#endif
p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo); p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break; break;

Loading…
Cancel
Save