diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-05-26 15:07:18 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-05-26 15:07:18 +0000 |
commit | 2bb1b8f3a4984075743b17fbe1d00b1af9917254 (patch) | |
tree | 06aa3a03497e938d80a7146013fef96324ef073c /src | |
parent | 65480cd3d11b465f0ede5f6c3d1b9f12e06dc98b (diff) | |
download | xine-lib-2bb1b8f3a4984075743b17fbe1d00b1af9917254.tar.gz xine-lib-2bb1b8f3a4984075743b17fbe1d00b1af9917254.tar.bz2 |
switch to walken's libac3 and minor bugfixes
CVS patchset: 83
CVS date: 2001/05/26 15:07:18
Diffstat (limited to 'src')
35 files changed, 2303 insertions, 3496 deletions
diff --git a/src/libac3/Makefile.am b/src/libac3/Makefile.am index 3071c7ae9..0e1d6d37a 100644 --- a/src/libac3/Makefile.am +++ b/src/libac3/Makefile.am @@ -7,16 +7,15 @@ libdir = $(XINE_PLUGINDIR) lib_LTLIBRARIES = xineplug_decode_ac3.la xineplug_decode_ac3_la_SOURCES = bitstream.c bit_allocate.c \ - decode.c coeff.c exponent.c parse.c crc.c rematrix.c \ - dither.c sanity_check.c srfft.c imdct.c downmix.c \ + coeff.c decode.c debug.c dither.c downmix.c imdct.c \ + imdct_mlib.c parse.c rematrix.c sanity_check.c stats.c \ xine_decoder.c xineplug_decode_ac3_la_LDFLAGS = -avoid-version -module -noinst_HEADERS = ac3.h ac3_internal.h bitstream.h \ - imdct.h coeff.h exponent.h bit_allocate.h parse.h \ - crc.h rematrix.h downmix.h dither.h \ - sanity_check.h srfft.h srfftp.h cmplx.h decode.h \ - bswap.h +noinst_HEADERS = ac3.h ac3_internal.h bit_allocate.h \ + bitstream.h coeff.h debug.h decode.h dither.h \ + downmix.h imdct.h parse.h rematrix.h \ + sanity_check.h stats.h ## ## Install header files (default=$includedir/xine) diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h index dcc125f85..07f41c0a0 100644 --- a/src/libac3/ac3.h +++ b/src/libac3/ac3.h @@ -22,33 +22,28 @@ * */ -#ifndef __AC3_H__ -#define __AC3_H__ - #include <inttypes.h> -#include "audio_out.h" - -#define AC3_DOLBY_SURR_ENABLE (1<<0) -#define AC3_ALTIVEC_ENABLE (1<<1) -#define AC3_3DNOW_ENABLE (1<<2) -#define AC3_MMX_ENABLE (1<<3) -#define AC3_SSE_ENABLE (1<<4) -typedef struct ac3_config_s { - // Bit flags that enable various things - uint32_t flags; - //Callback that points the decoder to new stream data - void (*fill_buffer_callback)(uint8_t **, uint8_t **); - // Number of discrete channels in final output (for downmixing) - uint16_t num_output_ch; - // Which channel of a dual mono stream to select - uint16_t dual_mono_ch_sel; +#define AC3_DOLBY_SURR_ENABLE 0x1 + +typedef struct ac3_config_s +{ + //Bit flags that enable various things + uint32_t flags; + //Callback that points the decoder to new stream data + void (* fill_buffer_callback) (uint8_t **, uint8_t **); + //Number of discrete channels in final output (for downmixing) + uint16_t num_output_ch; + //Which channel of a dual mono stream to select + uint16_t dual_mono_ch_sel; } ac3_config_t; -void ac3_init(ac3_config_t *,ao_functions_t*); - -size_t ac3_decode_data(uint8_t *data_start,uint8_t *data_end,uint32_t pts); - -void ac3_reset(void); +typedef struct ac3_frame_s +{ + uint32_t sampling_rate; + int16_t * audio_data; +} ac3_frame_t; -#endif +void ac3_init(void); +int ac3_frame_length(uint8_t * buf); +ac3_frame_t* ac3_decode_frame(uint8_t * buf); diff --git a/src/libac3/ac3_internal.h b/src/libac3/ac3_internal.h index cac0c7940..50d951547 100644 --- a/src/libac3/ac3_internal.h +++ b/src/libac3/ac3_internal.h @@ -25,11 +25,6 @@ #define inline #endif -#define FAST_ERROR -#ifdef FAST_ERROR -#include <setjmp.h> -#endif - /* Exponent strategy constants */ #define EXP_REUSE (0) #define EXP_D15 (1) @@ -45,15 +40,8 @@ /* samples work structure */ typedef float stream_samples_t[6][256]; -/* global config structure */ -extern ac3_config_t ac3_config; /* global error flag */ -#ifdef FAST_ERROR -extern jmp_buf error_jmp_mark; -#define HANDLE_ERROR() longjmp (error_jmp_mark, -1) -#else extern uint32_t error_flag; -#endif /* Everything you wanted to know about band structure */ /* @@ -80,273 +68,91 @@ extern uint32_t error_flag; * conditional fields. */ -typedef struct syncinfo_s -{ - uint32_t magic; - /* Sync word == 0x0B77 */ - uint16_t syncword; - /* crc for the first 5/8 of the sync block */ - /* uint16_t crc1; */ - /* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */ - uint16_t fscod; - /* Frame size code */ - uint16_t frmsizecod; - - /* Information not in the AC-3 bitstream, but derived */ - /* Frame size in 16 bit words */ - uint16_t frame_size; - /* Bit rate in kilobits */ - uint16_t bit_rate; - /* sampling rate in hertz */ - uint32_t sampling_rate; -} syncinfo_t; - -typedef struct bsi_s -{ - uint32_t magic; - /* Bit stream identification == 0x8 */ - uint16_t bsid; - /* Bit stream mode */ - uint16_t bsmod; - /* Audio coding mode */ - uint16_t acmod; - /* If we're using the centre channel then */ - /* centre mix level */ - uint16_t cmixlev; - /* If we're using the surround channel then */ - /* surround mix level */ - uint16_t surmixlev; - /* If we're in 2/0 mode then */ - /* Dolby surround mix level - NOT USED - */ - uint16_t dsurmod; - /* Low frequency effects on */ - uint16_t lfeon; - /* Dialogue Normalization level */ - uint16_t dialnorm; - /* Compression exists */ - uint16_t compre; - /* Compression level */ - uint16_t compr; - /* Language code exists */ - uint16_t langcode; - /* Language code */ - uint16_t langcod; - /* Audio production info exists*/ - uint16_t audprodie; - uint16_t mixlevel; - uint16_t roomtyp; - /* If we're in dual mono mode (acmod == 0) then extra stuff */ - uint16_t dialnorm2; - uint16_t compr2e; - uint16_t compr2; - uint16_t langcod2e; - uint16_t langcod2; - uint16_t audprodi2e; - uint16_t mixlevel2; - uint16_t roomtyp2; - /* Copyright bit */ - uint16_t copyrightb; - /* Original bit */ - uint16_t origbs; - /* Timecode 1 exists */ - uint16_t timecod1e; - /* Timecode 1 */ - uint16_t timecod1; - /* Timecode 2 exists */ - uint16_t timecod2e; - /* Timecode 2 */ - uint16_t timecod2; - /* Additional bit stream info exists */ - uint16_t addbsie; - /* Additional bit stream length - 1 (in bytes) */ - uint16_t addbsil; - /* Additional bit stream information (max 64 bytes) */ - uint8_t addbsi[64]; - - /* Information not in the AC-3 bitstream, but derived */ - /* Number of channels (excluding LFE) - * Derived from acmod */ - uint16_t nfchans; -} bsi_t; - +typedef struct ac3_state_s { + int nfchans; // number of channels, derived from acmod + + /* from syncinfo */ + uint8_t fscod; // sample rate + + /* from bsi */ + uint8_t acmod; // coded channels + uint8_t cmixlev; // centre channel mix level + uint8_t surmixlev; // surround channels mix level + uint8_t lfeon; // coded lfe channel +} ac3_state_t; + +typedef struct ac3_ba_s { + uint16_t fsnroffst; // fine SNR offset + uint16_t fgaincod; // fast gain + uint16_t deltbae; // delta bit allocation exists + uint16_t deltnseg; // number of delta bit segments + uint16_t deltoffst[8]; // delta bit offset + uint16_t deltlen[8]; // delta bit length + uint16_t deltba[8]; // delta bit value +} ac3_ba_t; /* more pain */ -typedef struct audblk_s -{ - uint32_t magic1; - /* block switch bit indexed by channel num */ - uint16_t blksw[5]; - /* dither enable bit indexed by channel num */ - uint16_t dithflag[5]; - /* dynamic range gain exists */ - uint16_t dynrnge; - /* dynamic range gain */ - uint16_t dynrng; - /* if acmod==0 then */ - /* dynamic range 2 gain exists */ - uint16_t dynrng2e; - /* dynamic range 2 gain */ - uint16_t dynrng2; - /* coupling strategy exists */ - uint16_t cplstre; - /* coupling in use */ - uint16_t cplinu; - /* channel coupled */ - uint16_t chincpl[5]; - /* if acmod==2 then */ - /* Phase flags in use */ - uint16_t phsflginu; - /* coupling begin frequency code */ - uint16_t cplbegf; - /* coupling end frequency code */ - uint16_t cplendf; - /* coupling band structure bits */ - uint16_t cplbndstrc[18]; - /* Do coupling co-ords exist for this channel? */ - uint16_t cplcoe[5]; - /* Master coupling co-ordinate */ - uint16_t mstrcplco[5]; - /* Per coupling band coupling co-ordinates */ - uint16_t cplcoexp[5][18]; - uint16_t cplcomant[5][18]; - /* Phase flags for dual mono */ - uint16_t phsflg[18]; - /* Is there a rematrixing strategy */ - uint16_t rematstr; - /* Rematrixing bits */ - uint16_t rematflg[4]; - /* Coupling exponent strategy */ - uint16_t cplexpstr; - /* Exponent strategy for full bandwidth channels */ - uint16_t chexpstr[5]; - /* Exponent strategy for lfe channel */ - uint16_t lfeexpstr; - /* Channel bandwidth for independent channels */ - uint16_t chbwcod[5]; - /* The absolute coupling exponent */ - uint16_t cplabsexp; - /* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */ - uint16_t cplexps[18 * 12 / 3]; - /* Sanity checking constant */ - uint32_t magic2; - /* fbw channel exponents */ - uint16_t exps[5][252 / 3]; - /* channel gain range */ - uint16_t gainrng[5]; - /* low frequency exponents */ - uint16_t lfeexps[3]; - - /* Bit allocation info */ - uint16_t baie; - /* Slow decay code */ - uint16_t sdcycod; - /* Fast decay code */ - uint16_t fdcycod; - /* Slow gain code */ - uint16_t sgaincod; - /* dB per bit code */ - uint16_t dbpbcod; - /* masking floor code */ - uint16_t floorcod; - - /* SNR offset info */ - uint16_t snroffste; - /* coarse SNR offset */ - uint16_t csnroffst; - /* coupling fine SNR offset */ - uint16_t cplfsnroffst; - /* coupling fast gain code */ - uint16_t cplfgaincod; - /* fbw fine SNR offset */ - uint16_t fsnroffst[5]; - /* fbw fast gain code */ - uint16_t fgaincod[5]; - /* lfe fine SNR offset */ - uint16_t lfefsnroffst; - /* lfe fast gain code */ - uint16_t lfefgaincod; +typedef struct audblk_s { + uint32_t magic1; + + // not reused between blocks + uint16_t blksw[5]; // imdct block transform switch + uint16_t dithflag[5]; // channel dither flag + + uint16_t cplinu; // coupling in use + uint16_t chincpl[5]; // channel coupled + uint16_t phsflginu; // phase flags in use (stereo only) + uint16_t cplbegf; // coupling begin frequency code + uint16_t cplendf; // coupling end frequency code + uint16_t cplbndstrc[18]; // coupling band structure + // derived information + uint16_t cplstrtmant; // coupling channel start mantissa + uint16_t cplendmant; // coupling channel end mantissa + uint16_t ncplsubnd; // number of coupling sub-bands + uint16_t ncplbnd; // number of coupling bands + + // should we simply have float cplco[5][18] instead of these 4 ? + uint8_t mstrcplco[5]; // per channel master coupling coordinate + uint8_t cplcoexp[5][18]; // per band coupling exponent + uint8_t cplcomant[5][18]; // per band coupling mantissa + uint8_t phsflg[18]; // per band phase flags for stereo + + uint16_t rematflg[4]; // stereo rematrixing + + uint16_t chbwcod[5]; // channel bandwidth for independant channels + + uint32_t magic2; + + uint16_t sdcycod; // slow decay + uint16_t fdcycod; // fast decay + uint16_t sgaincod; // slow gain + uint16_t dbpbcod; // dB per bit - encodes the dbknee value + uint16_t floorcod; // masking floor + + uint16_t csnroffst; // coarse SNR offset + ac3_ba_t cplba; // coupling bit allocation parameters + ac3_ba_t ba[5]; // channel bit allocation parameters + ac3_ba_t lfeba; // lfe bit allocation parameters + + uint16_t cplfleak; // coupling fast leak init + uint16_t cplsleak; // coupling slow leak init - /* Coupling leak info */ - uint16_t cplleake; - /* coupling fast leak initialization */ - uint16_t cplfleak; - /* coupling slow leak initialization */ - uint16_t cplsleak; - - /* delta bit allocation info */ - uint16_t deltbaie; - /* coupling delta bit allocation exists */ - uint16_t cpldeltbae; - /* fbw delta bit allocation exists */ - uint16_t deltbae[5]; - /* number of cpl delta bit segments */ - uint16_t cpldeltnseg; - /* coupling delta bit allocation offset */ - uint16_t cpldeltoffst[8]; - /* coupling delta bit allocation length */ - uint16_t cpldeltlen[8]; - /* coupling delta bit allocation length */ - uint16_t cpldeltba[8]; - /* number of delta bit segments */ - uint16_t deltnseg[5]; - /* fbw delta bit allocation offset */ - uint16_t deltoffst[5][8]; - /* fbw delta bit allocation length */ - uint16_t deltlen[5][8]; - /* fbw delta bit allocation length */ - uint16_t deltba[5][8]; - - /* skip length exists */ - uint16_t skiple; - /* skip length */ - uint16_t skipl; - //Removed Feb 2000 -ah - //added Jul 2000 ++dent - /* channel mantissas */ - uint16_t chmant[5][256]; - - /* coupling mantissas */ -// uint16_t cplmant[256]; - //Added Jun 2000 -MaXX - /* coupling floats */ - float cpl_flt[ 256 ]; - //Removed Feb 2000 -ah - //added Jul 2000 ++dent /* coupling mantissas */ - uint16_t lfemant[7]; + uint16_t cplmant[256]; /* -- Information not in the bitstream, but derived thereof -- */ - /* Number of coupling sub-bands */ - uint16_t ncplsubnd; - - /* Number of combined coupling sub-bands - * Derived from ncplsubnd and cplbndstrc */ - uint16_t ncplbnd; - - /* Number of exponent groups by channel - * Derived from strmant, endmant */ - uint16_t nchgrps[5]; - - /* Number of coupling exponent groups - * Derived from cplbegf, cplendf, cplexpstr */ - uint16_t ncplgrps; - /* End mantissa numbers of fbw channels */ uint16_t endmant[5]; - /* Start and end mantissa numbers for the coupling channel */ - uint16_t cplstrtmant; - uint16_t cplendmant; - /* Decoded exponent info */ - uint16_t fbw_exp[5][256]; - uint16_t cpl_exp[256]; - uint16_t lfe_exp[7]; + uint8_t fbw_exp[5][256]; + uint8_t cpl_exp[256]; + uint8_t lfe_exp[7]; /* Bit allocation pointer results */ uint16_t fbw_bap[5][256]; diff --git a/src/libac3/bit_allocate.c b/src/libac3/bit_allocate.c index 7a233a519..407626f08 100644 --- a/src/libac3/bit_allocate.c +++ b/src/libac3/bit_allocate.c @@ -21,32 +21,25 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <string.h> #include "ac3.h" #include "ac3_internal.h" +#include "bit_allocate.h" -static inline int16_t logadd(int16_t a,int16_t b); static int16_t calc_lowcomp(int16_t a,int16_t b0,int16_t b1,int16_t bin); static inline uint16_t min(int16_t a,int16_t b); static inline uint16_t max(int16_t a,int16_t b); -static void ba_compute_psd(int16_t start, int16_t end, int16_t exps[], - int16_t psd[], int16_t bndpsd[]); -static void ba_compute_excitation(int16_t start, int16_t end,int16_t fgain, - int16_t fastleak, int16_t slowleak, int16_t is_lfe, int16_t bndpsd[], - int16_t excite[]); static void ba_compute_mask(int16_t start, int16_t end, uint16_t fscod, - uint16_t deltbae, uint16_t deltnseg, uint16_t deltoffst[], uint16_t deltba[], - uint16_t deltlen[], int16_t excite[], int16_t mask[]); + uint16_t deltbae, uint16_t deltnseg, + uint16_t deltoffst[], uint16_t deltba[], + uint16_t deltlen[], int16_t excite[], + int16_t mask[]); static void ba_compute_bap(int16_t start, int16_t end, int16_t snroffset, - int16_t psd[], int16_t mask[], int16_t bap[]); + int8_t exp[], int16_t mask[], int16_t bap[]); /* Misc LUTs for bit allocation process */ @@ -60,450 +53,334 @@ static int16_t fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0 static int16_t bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, - 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, - 79, 85, 97, 109, 121, 133, 157, 181, 205, 229 }; + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, + 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, + 79, 85, 97, 109, 121, 133, 157, 181, 205, 229 }; static int16_t bndsz[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, - 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, - 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 }; + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, + 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 }; static int16_t masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29, - 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, - 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, - 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, - 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 }; + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29, + 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, + 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, + 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, + 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 }; static int16_t latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039, - 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032, - 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c, - 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026, - 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021, - 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c, - 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018, - 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015, - 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012, - 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f, - 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d, - 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b, - 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, - 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006, - 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005, - 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, - 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000}; + 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032, + 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c, + 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026, + 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021, + 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c, + 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018, + 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015, + 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012, + 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f, + 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d, + 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000}; static int16_t hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0, - 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, - 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, - 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, - 0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420, - 0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, - 0x0840, 0x0840 }, - - { 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0, - 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, - 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, - 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0, - 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0, - 0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, - 0x0840, 0x0840 }, - - { 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0, - 0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, - 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390, - 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330, - 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310, - 0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440, - 0x0450, 0x04e0 }}; + 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, + 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, + 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, + 0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420, + 0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, + 0x0840, 0x0840 }, + { 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0, + 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, + 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, + 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0, + 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0, + 0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, + 0x0840, 0x0840 }, + { 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0, + 0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, + 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390, + 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330, + 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310, + 0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440, + 0x0450, 0x04e0 }}; static int16_t baptab[] = { 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, - 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; static int16_t sdecay; static int16_t fdecay; static int16_t sgain; static int16_t dbknee; static int16_t floor; -static int16_t psd[256]; static int16_t bndpsd[256]; static int16_t excite[256]; static int16_t mask[256]; - -/** - * - **/ - static inline uint16_t max(int16_t a,int16_t b) { - return (a > b ? a : b); + return (a > b ? a : b); } - - -/** - * - **/ static inline uint16_t min(int16_t a,int16_t b) { - return (a < b ? a : b); + return (a < b ? a : b); } - -/** - * - **/ - -static inline int16_t logadd(int16_t a,int16_t b) -{ - int16_t c; - int16_t address; - - c = a - b; - address = min((abs(c) >> 1), 255); - - if (c >= 0) - return(a + latab[address]); - else - return(b + latab[address]); -} - - -/** - * - **/ - -void bit_allocate(uint16_t fscod, bsi_t *bsi, audblk_t *audblk) +void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, uint16_t start, + uint16_t end, int16_t fastleak, int16_t slowleak, + uint8_t * exp, uint16_t * bap, int is_lfe) { - uint16_t i; - int16_t fgain; - int16_t snroffset; - int16_t start; - int16_t end; - int16_t fastleak; - int16_t slowleak; - - /* Only perform bit_allocation if the exponents have changed or we - * have new sideband information */ - if (audblk->chexpstr[0] == 0 && audblk->chexpstr[1] == 0 && - audblk->chexpstr[2] == 0 && audblk->chexpstr[3] == 0 && - audblk->chexpstr[4] == 0 && audblk->cplexpstr == 0 && - audblk->lfeexpstr == 0 && audblk->baie == 0 && - audblk->snroffste == 0 && audblk->deltbaie == 0) - return; - - /* Do some setup before we do the bit alloc */ - sdecay = slowdec[audblk->sdcycod]; - fdecay = fastdec[audblk->fdcycod]; - sgain = slowgain[audblk->sgaincod]; - dbknee = dbpbtab[audblk->dbpbcod]; - floor = floortab[audblk->floorcod]; - - /* if all the SNR offset constants are zero then the whole block is zero */ - if(!audblk->csnroffst && !audblk->fsnroffst[0] && - !audblk->fsnroffst[1] && !audblk->fsnroffst[2] && - !audblk->fsnroffst[3] && !audblk->fsnroffst[4] && - !audblk->cplfsnroffst && !audblk->lfefsnroffst) { - memset(audblk->fbw_bap,0,sizeof(uint16_t) * 256 * 5); - memset(audblk->cpl_bap,0,sizeof(uint16_t) * 256); - memset(audblk->lfe_bap,0,sizeof(uint16_t) * 7); - return; + int16_t fgain; + uint16_t snroffset; + int i, j; + int bndstrt; + int lowcomp; + + /* Do some setup before we do the bit alloc */ + sdecay = slowdec[audblk->sdcycod]; + fdecay = fastdec[audblk->fdcycod]; + sgain = slowgain[audblk->sgaincod]; + dbknee = dbpbtab[audblk->dbpbcod]; + floor = floortab[audblk->floorcod]; + + fgain = fastgain[ba->fgaincod]; + snroffset = 64 * audblk->csnroffst + 4 * ba->fsnroffst - 960; + + i = start; + j = bndstrt = masktab[start]; + do { + int psd, lastbin; + + lastbin = min (bndtab[j] + bndsz[j], end); + psd = 128 * exp[i++]; + while (i < lastbin) { + int next, delta; + + next = 128 * exp[i++]; + delta = next - psd; + switch (delta >> 9) { + case -6: case -5: case -4: case -3: case -2: + psd = next; + break; + case -1: + psd = next - latab[(-delta) >> 1]; + break; + case 0: + psd -= latab[delta >> 1]; + break; + } } - - - for(i = 0; i < bsi->nfchans; i++) - { - start = 0; - end = audblk->endmant[i] ; - fgain = fastgain[audblk->fgaincod[i]]; - snroffset = (((audblk->csnroffst - 15) << 4) + audblk->fsnroffst[i]) << 2 ; - fastleak = 0; - slowleak = 0; - - ba_compute_psd(start, end, audblk->fbw_exp[i], psd, bndpsd); - - ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite); - - ba_compute_mask(start, end, fscod, audblk->deltbae[i], audblk->deltnseg[i], - audblk->deltoffst[i], audblk->deltba[i], audblk->deltlen[i], excite, mask); - - ba_compute_bap(start, end, snroffset, psd, mask, audblk->fbw_bap[i]); - } - - if(audblk->cplinu) { - start = audblk->cplstrtmant; - end = audblk->cplendmant; - fgain = fastgain[audblk->cplfgaincod]; - snroffset = (((audblk->csnroffst - 15) << 4) + audblk->cplfsnroffst) << 2 ; - fastleak = (audblk->cplfleak << 8) + 768; - slowleak = (audblk->cplsleak << 8) + 768; - - ba_compute_psd(start, end, audblk->cpl_exp, psd, bndpsd); - - ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite); - - ba_compute_mask(start, end, fscod, audblk->cpldeltbae, audblk->cpldeltnseg, - audblk->cpldeltoffst, audblk->cpldeltba, audblk->cpldeltlen, excite, mask); - - ba_compute_bap(start, end, snroffset, psd, mask, audblk->cpl_bap); - } - - if(bsi->lfeon) { - start = 0; - end = 7; - fgain = fastgain[audblk->lfefgaincod]; - snroffset = (((audblk->csnroffst - 15) << 4) + audblk->lfefsnroffst) << 2 ; - fastleak = 0; - slowleak = 0; - - ba_compute_psd(start, end, audblk->lfe_exp, psd, bndpsd); - - ba_compute_excitation(start, end , fgain, fastleak, slowleak, 1, bndpsd, excite); - - /* Perform no delta bit allocation for lfe */ - ba_compute_mask(start, end, fscod, 2, 0, 0, 0, 0, excite, mask); - - ba_compute_bap(start, end, snroffset, psd, mask, audblk->lfe_bap); + bndpsd[j++] = 3072 - psd; + } while (i < end); + + // j = bndend + j--; + + i = bndstrt; + lowcomp = 0; + if (i == 0) { // not the coupling channel + do { + if (i < j) { + if (bndpsd[i+1] == bndpsd[i] + 256) + lowcomp = 384; + else if (lowcomp && (bndpsd[i+1] < bndpsd[i])) + lowcomp -= 64; + } + excite[i++] = bndpsd[i] - fgain - lowcomp; + } while ((i < 3) || ((i < 7) && (bndpsd[i] < bndpsd[i-1]))); + fastleak = bndpsd[i-1] - fgain; + slowleak = bndpsd[i-1] - sgain; + + while (i < 7) { + if (i < j) { + if (bndpsd[i+1] == bndpsd[i] + 256) + lowcomp = 384; + else if (lowcomp && (bndpsd[i+1] < bndpsd[i])) + lowcomp -= 64; + } + fastleak -= fdecay; + if (fastleak < bndpsd[i] - fgain) + fastleak = bndpsd[i] - fgain; + slowleak -= sdecay; + if (slowleak < bndpsd[i] - sgain) + slowleak = bndpsd[i] - sgain; + excite[i++] = ((fastleak - lowcomp > slowleak) ? + fastleak - lowcomp : slowleak); } -} - - -/** - * - **/ - -static void ba_compute_psd(int16_t start, int16_t end, int16_t exps[], - int16_t psd[], int16_t bndpsd[]) -{ - int bin,j,k; - int16_t lastbin = 0; - - /* Map the exponents into dBs */ - for (bin=start; bin<end; bin++) { - psd[bin] = (3072 - (exps[bin] << 7)); + if (i > j) // lfe channel + goto done_excite; + + do { + if (bndpsd[i+1] == bndpsd[i] + 256) + lowcomp = 320; + else if (lowcomp && (bndpsd[i+1] < bndpsd[i])) + lowcomp -= 64; + fastleak -= fdecay; + if (fastleak < bndpsd[i] - fgain) + fastleak = bndpsd[i] - fgain; + slowleak -= sdecay; + if (slowleak < bndpsd[i] - sgain) + slowleak = bndpsd[i] - sgain; + excite[i++] = ((fastleak - lowcomp > slowleak) ? + fastleak - lowcomp : slowleak); + } while (i < 20); + + while (lowcomp > 128) { // two iterations maximum + lowcomp -= 128; + fastleak -= fdecay; + if (fastleak < bndpsd[i] - fgain) + fastleak = bndpsd[i] - fgain; + slowleak -= sdecay; + if (slowleak < bndpsd[i] - sgain) + slowleak = bndpsd[i] - sgain; + excite[i++] = ((fastleak - lowcomp > slowleak) ? + fastleak - lowcomp : slowleak); } - - /* Integrate the psd function over each bit allocation band */ - j = start; - k = masktab[start]; - - do { - lastbin = min(bndtab[k] + bndsz[k], end); - bndpsd[k] = psd[j]; - j++; - - for (; j < lastbin; j++) { - bndpsd[k] = logadd(bndpsd[k], psd[j]); - } - - k++; - } while (end > lastbin); -} - - -/** - * - **/ - -static void ba_compute_excitation(int16_t start, int16_t end,int16_t fgain, - int16_t fastleak, int16_t slowleak, int16_t is_lfe, int16_t bndpsd[], - int16_t excite[]) -{ - int bin; - int16_t bndstrt; - int16_t bndend; - int16_t lowcomp = 0; - int16_t begin = 0; - - /* Compute excitation function */ - bndstrt = masktab[start]; - bndend = masktab[end - 1] + 1; - - if (bndstrt == 0) { /* For fbw and lfe channels */ - lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0); - excite[0] = bndpsd[0] - fgain - lowcomp; - lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1); - excite[1] = bndpsd[1] - fgain - lowcomp; - begin = 7 ; - -// Note: Do not call calc_lowcomp() for the last band of the lfe channel,(bin=6) - for (bin = 2; bin < 7; bin++) { - if (!(is_lfe && (bin == 6))) - lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); - fastleak = bndpsd[bin] - fgain; - slowleak = bndpsd[bin] - sgain; - excite[bin] = fastleak - lowcomp; - - if (!(is_lfe && (bin == 6))) { - if (bndpsd[bin] <= bndpsd[bin+1]) { - begin = bin + 1 ; - break; - } - } - } - - for (bin = begin; bin < min(bndend, 22); bin++) { - if (!(is_lfe && (bin == 6))) - lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); - fastleak -= fdecay ; - fastleak = max(fastleak, bndpsd[bin] - fgain); - slowleak -= sdecay ; - slowleak = max(slowleak, bndpsd[bin] - sgain); - excite[bin] = max(fastleak - lowcomp, slowleak); - } - begin = 22; - } - else /* For coupling channel */ - begin = bndstrt; - - for (bin = begin; bin < bndend; bin++) { - fastleak -= fdecay; - fastleak = max(fastleak, bndpsd[bin] - fgain); - slowleak -= sdecay; - slowleak = max(slowleak, bndpsd[bin] - sgain); - excite[bin] = max(fastleak, slowleak) ; - } + } + + do { + fastleak -= fdecay; + if (fastleak < bndpsd[i] - fgain) + fastleak = bndpsd[i] - fgain; + slowleak -= sdecay; + if (slowleak < bndpsd[i] - sgain) + slowleak = bndpsd[i] - sgain; + excite[i++] = (fastleak > slowleak) ? fastleak : slowleak; + } while (i <= j); + +done_excite: + + ba_compute_mask(start, end, fscod, ba->deltbae, ba->deltnseg, + ba->deltoffst, ba->deltba, ba->deltlen, excite, mask); + ba_compute_bap(start, end, snroffset, exp, mask, bap); } -/** - * - **/ - static void ba_compute_mask(int16_t start, int16_t end, uint16_t fscod, - uint16_t deltbae, uint16_t deltnseg, uint16_t deltoffst[], uint16_t deltba[], - uint16_t deltlen[], int16_t excite[], int16_t mask[]) + uint16_t deltbae, uint16_t deltnseg, + uint16_t deltoffst[], uint16_t deltba[], + uint16_t deltlen[], int16_t excite[], + int16_t mask[]) { - int bin,k; - int16_t bndstrt; - int16_t bndend; - int16_t delta; + int bin,k; + int16_t bndstrt; + int16_t bndend; + int16_t delta; - bndstrt = masktab[start]; - bndend = masktab[end - 1] + 1; + bndstrt = masktab[start]; + bndend = masktab[end - 1] + 1; - /* Compute the masking curve */ + /* Compute the masking curve */ - for (bin = bndstrt; bin < bndend; bin++) { - if (bndpsd[bin] < dbknee) { - excite[bin] += ((dbknee - bndpsd[bin]) >> 2); - } - mask[bin] = max(excite[bin], hth[fscod][bin]); - } + for (bin = bndstrt; bin < bndend; bin++) { + if (bndpsd[bin] < dbknee) + excite[bin] += ((dbknee - bndpsd[bin]) >> 2); + mask[bin] = max(excite[bin], hth[fscod][bin]); + } - /* Perform delta bit modulation if necessary */ - if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) { - int16_t band = 0; - int16_t seg = 0; + /* Perform delta bit modulation if necessary */ + if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) { + int16_t band = 0; + int16_t seg = 0; - for (seg = 0; seg < deltnseg+1; seg++) { - band += deltoffst[seg]; - - if (deltba[seg] >= 4) { - delta = (deltba[seg] - 3) << 7; - } else { - delta = (deltba[seg] - 4) << 7; - } + for (seg = 0; seg < deltnseg+1; seg++) { + band += deltoffst[seg]; + if (deltba[seg] >= 4) + delta = (deltba[seg] - 3) << 7; + else + delta = (deltba[seg] - 4) << 7; - for (k = 0; k < deltlen[seg]; k++) { - mask[band] += delta; - band++; - } - } - } + for (k = 0; k < deltlen[seg]; k++) { + mask[band] += delta; + band++; + } + } + } } - -/** - * - **/ - static void ba_compute_bap(int16_t start, int16_t end, int16_t snroffset, - int16_t psd[], int16_t mask[], int16_t bap[]) + int8_t exps[], int16_t mask[], int16_t bap[]) { - int i,j,k; - int16_t lastbin = 0; - int16_t address = 0; - - /* Compute the bit allocation pointer for each bin */ - i = start; - j = masktab[start]; - - do { - lastbin = min(bndtab[j] + bndsz[j], end); - mask[j] -= snroffset; - mask[j] -= floor; + int i,j,k; + int16_t lastbin = 0; + int16_t address = 0; + + /* Compute the bit allocation pointer for each bin */ + i = start; + j = masktab[start]; + + do { + lastbin = min(bndtab[j] + bndsz[j], end); + mask[j] -= snroffset; + mask[j] -= floor; - if (mask[j] < 0) - mask[j] = 0; - - mask[j] &= 0x1fe0; - mask[j] += floor; - for (k = i; k < lastbin; k++) { - address = (psd[i] - mask[j]) >> 5; - address = min(63, max(0, address)); - bap[i] = baptab[address]; - i++; - } - j++; - } while (end > lastbin); + if (mask[j] < 0) + mask[j] = 0; + + mask[j] &= 0x1fe0; + mask[j] += floor; + for (k = i; k < lastbin; k++) { + address = (3072 - 128 * exps[i] - mask[j]) >> 5; + address = min(63, max(0, address)); + bap[i] = baptab[address]; + i++; + } + j++; + } while (end > lastbin); } - -/** - * - **/ - -static int16_t calc_lowcomp (int16_t a, int16_t b0, int16_t b1, int16_t bin) -{ - - if (bin < 7) { - if ((b0 + 256) == b1) - a = 384; - else if (b0 > b1) - a = max(0, a - 64); - } else if (bin < 20) { - if ((b0 + 256) == b1) - a = 320; - else if (b0 > b1) - a = max(0, a - 64) ; - } else - a = max(0, a - 128); +static int16_t calc_lowcomp(int16_t a,int16_t b0,int16_t b1,int16_t bin) +{ + if (bin < 7) { + if ((b0 + 256) == b1) + a = 384; + else if (b0 > b1) + a = max(0, a - 64); + } else if (bin < 20) { + if ((b0 + 256) == b1) + a = 320; + else if (b0 > b1) + a = max(0, a - 64) ; + } else + a = max(0, a - 128); - return(a); + return(a); } diff --git a/src/libac3/bit_allocate.h b/src/libac3/bit_allocate.h index a6a3c7703..cdf73414a 100644 --- a/src/libac3/bit_allocate.h +++ b/src/libac3/bit_allocate.h @@ -21,4 +21,6 @@ * */ -void bit_allocate(uint16_t fscod, bsi_t *bsi, audblk_t *audblk); +void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba, uint16_t start, + uint16_t end, int16_t fastleak, int16_t slowleak, + uint8_t * exp, uint16_t * bap, int ls_lfe); diff --git a/src/libac3/bitstream.c b/src/libac3/bitstream.c index 78ac0eca7..8d771965e 100644 --- a/src/libac3/bitstream.c +++ b/src/libac3/bitstream.c @@ -23,57 +23,54 @@ #include <stdlib.h> #include <stdio.h> -#include <inttypes.h> - -#include <bswap.h> -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include "ac3.h" #include "ac3_internal.h" #include "bitstream.h" +#define BUFFER_SIZE 4096 -uint32_t ac3bits_left = 0; -uint64_t ac3current_word; -uint64_t *buffer_start = 0; +static uint8_t *buffer_start; +uint32_t bits_left; +uint32_t current_word; -static inline uint64_t getdword (void) +void bitstream_set_ptr (uint8_t * buf) { - return be2me_64 (*buffer_start++); + buffer_start = buf; + bits_left = 0; } - -static inline void bitstream_fill_current (void) +static inline void +bitstream_fill_current() { - //ac3current_word = bswap_64 (*buffer_start++); - ac3current_word = getdword (); + current_word = *((uint32_t*)buffer_start)++; + current_word = swab32(current_word); } - -uint32_t bitstream_get_bh (uint32_t num_bits) +// +// The fast paths for _get is in the +// bitstream.h header file so it can be inlined. +// +// The "bottom half" of this routine is suffixed _bh +// +// -ah +// + +uint32_t +bitstream_get_bh(uint32_t num_bits) { - uint32_t result; + uint32_t result; - num_bits -= ac3bits_left; - result = (ac3current_word << (64 - ac3bits_left)) >> (64 - ac3bits_left); + num_bits -= bits_left; + result = (current_word << (32 - bits_left)) >> (32 - bits_left); - bitstream_fill_current(); + bitstream_fill_current(); - if(num_bits != 0) - result = (result << num_bits) | (ac3current_word >> (64 - num_bits)); + if(num_bits != 0) + result = (result << num_bits) | (current_word >> (32 - num_bits)); - ac3bits_left = 64 - num_bits; + bits_left = 32 - num_bits; - return result; -} - - -void bitstream_init (uint8_t *start) -{ - //initialize the start of the buffer - buffer_start = (uint64_t *) start; - ac3bits_left = 0; + return result; } diff --git a/src/libac3/bitstream.h b/src/libac3/bitstream.h index 392c7401c..84f3287c8 100644 --- a/src/libac3/bitstream.h +++ b/src/libac3/bitstream.h @@ -21,26 +21,48 @@ * */ +//My new and improved vego-matic endian swapping routine +//(stolen from the kernel) +#ifdef WORDS_BIGENDIAN -#include <inttypes.h> +# define swab32(x) (x) -extern uint32_t ac3bits_left; -extern uint64_t ac3current_word; +#else -void bitstream_init(uint8_t *start); -inline uint32_t bitstream_get_bh(uint32_t num_bits); +# if defined (__i386__) -static inline uint32_t bitstream_get (uint32_t num_bits) -{ - uint32_t result; - - if (num_bits < ac3bits_left) { - result = (ac3current_word << (64 - ac3bits_left)) >> (64 - num_bits); - ac3bits_left -= num_bits; - return result; +# define swab32(x) __i386_swab32(x) + static inline const uint32_t __i386_swab32(uint32_t x) + { + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; } - return bitstream_get_bh (num_bits); -} +# else + +# define swab32(x)\ +((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \ + (((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3])) + +# endif +#endif +extern uint32_t bits_left; +extern uint32_t current_word; +void bitstream_set_ptr (uint8_t * buf); +uint32_t bitstream_get_bh(uint32_t num_bits); + +static inline uint32_t +bitstream_get(uint32_t num_bits) +{ + uint32_t result; + + if(num_bits < bits_left) { + result = (current_word << (32 - bits_left)) >> (32 - num_bits); + bits_left -= num_bits; + return result; + } + + return bitstream_get_bh(num_bits); +} diff --git a/src/libac3/bswap.h b/src/libac3/bswap.h deleted file mode 100644 index 0fc325d64..000000000 --- a/src/libac3/bswap.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __BSWAP_H__ -#define __BSWAP_H__ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_BYTESWAP_H -#include <byteswap.h> -#else - -#include <inttypes.h> - -#ifdef WORDS_BIGENDIAN -// FIXME these need to actually swap ;) -#define bswap_16(x) (x) -#define bswap_32(x) (x) -#define bswap_64(x) (x) -#else -// This is wrong, 'cannot take address of ...' -#define bswap_16(x) ((((uint8_t*)&x)[2] << 8) \ - | (((uint8_t*)&x)[3])) - -// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc. -#define bswap_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) - -#define bswap_64(x) \ - (__extension__ \ - ({ union { __extension__ uint64_t __ll; \ - uint32_t __l[2]; } __w, __r; \ - __w.__ll = (x); \ - __r.__l[0] = bswap_32 (__w.__l[1]); \ - __r.__l[1] = bswap_32 (__w.__l[0]); \ - __r.__ll; })) -#endif - -#endif - -// be2me ... BigEndian to MachineEndian -// le2me ... LittleEndian to MachineEndian - -#ifdef WORDS_BIGENDIAN -#define be2me_16(x) (x) -#define be2me_32(x) (x) -#define be2me_64(x) (x) -#define le2me_16(x) bswap_16(x) -#define le2me_32(x) bswap_32(x) -#define le2me_64(x) bswap_64(x) -#else -#define be2me_16(x) bswap_16(x) -#define be2me_32(x) bswap_32(x) -#define be2me_64(x) bswap_64(x) -#define le2me_16(x) (x) -#define le2me_32(x) (x) -#define le2me_64(x) (x) -#endif - -#endif diff --git a/src/libac3/cmplx.h b/src/libac3/cmplx.h deleted file mode 100644 index a357fab38..000000000 --- a/src/libac3/cmplx.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __COMPLEX_H__ -#define __COMPLEX_H__ - -typedef struct complex { - float re; - float im; -} complex_t; - -#endif diff --git a/src/libac3/coeff.c b/src/libac3/coeff.c index 6c95f74a5..2913c18d4 100644 --- a/src/libac3/coeff.c +++ b/src/libac3/coeff.c @@ -21,9 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include <stdlib.h> #include <stdio.h> @@ -31,6 +28,7 @@ #include "ac3_internal.h" +#include "decode.h" #include "bitstream.h" #include "dither.h" #include "coeff.h" @@ -38,169 +36,37 @@ // //Lookup tables of 0.15 two's complement quantization values // -#define Q0 ((-2 << 15) / 3.0) -#define Q1 (0) -#define Q2 ((2 << 15) / 3.0) - -static const float q_1_0[ 32 ] = +static const uint16_t q_1[3] = { - Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, - Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, - Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, - 0,0,0,0,0 -}; + ( -2 << 15)/3, 0,( 2 << 15)/3 +}; -static const float q_1_1[ 32 ] = +static const uint16_t q_2[5] = { - Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, - Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, - Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, - 0,0,0,0,0 -}; + ( -4 << 15)/5,( -2 << 15)/5, 0, + ( 2 << 15)/5,( 4 << 15)/5 +}; -static const float q_1_2[ 32 ] = -{ - Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, - Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, - Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, - 0,0,0,0,0 -}; - -#undef Q0 -#undef Q1 -#undef Q2 - -#define Q0 ((-4 << 15) / 5.0) -#define Q1 ((-2 << 15) / 5.0) -#define Q2 (0) -#define Q3 ((2 << 15) / 5.0) -#define Q4 ((4 << 15) / 5.0) - -static const 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, - 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, - Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, - Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, - Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3, - Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3, - Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4, - Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4, - 0,0,0 -}; - -static const float q_2_1[ 128 ] = -{ - Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1, - Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3, - Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0, - Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2, - Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, - Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1, - Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3, - Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0, - Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2, - Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, - Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1, - Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3, - Q4,Q4,Q4,Q4,Q4,0,0,0 - }; - -static const float q_2_2[ 128 ] = - { - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, - Q0,Q1,Q2,Q3,Q4,0,0,0 -}; - -#undef Q0 -#undef Q1 -#undef Q2 -#undef Q3 -#undef Q4 - -static const float q_3[7] = +static const uint16_t q_3[7] = { - (-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0, 0.0, - ( 2 << 15)/7.0, ( 4 << 15)/7.0, ( 6 << 15)/7.0 + ( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, 0, + ( 2 << 15)/7,( 4 << 15)/7,( 6 << 15)/7 }; -#define Q0 ((-10 << 15) / 11.0) -#define Q1 ((-8 << 15) / 11.0) -#define Q2 ((-6 << 15) / 11.0) -#define Q3 ((-4 << 15) / 11.0) -#define Q4 ((-2 << 15) / 11.0) -#define Q5 (0) -#define Q6 ((2 << 15) / 11.0) -#define Q7 ((4 << 15) / 11.0) -#define Q8 ((6 << 15) / 11.0) -#define Q9 ((8 << 15) / 11.0) -#define QA ((10 << 15) / 11.0) - -static const float q_4_0[ 128 ] = +static const uint16_t q_4[11] = { - Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, - Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, - Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, - Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, - Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, - Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, - Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, - Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, - Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, - Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, - QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, - 0, 0, 0, 0, 0, 0, 0 - }; - -static const float q_4_1[ 128 ] = -{ - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, - 0, 0, 0, 0, 0, 0, 0 + (-10 << 15)/11,(-8 << 15)/11,(-6 << 15)/11, ( -4 << 15)/11,(-2 << 15)/11, 0, + ( 2 << 15)/11,( 4 << 15)/11,( 6 << 15)/11, ( 8 << 15)/11,(10 << 15)/11 }; -#undef Q0 -#undef Q1 -#undef Q2 -#undef Q3 -#undef Q4 -#undef Q5 -#undef Q6 -#undef Q7 -#undef Q8 -#undef Q9 -#undef QA - -static const float q_5[15] = +static const uint16_t q_5[15] = { - (-14 << 15)/15.0,(-12 << 15)/15.0,(-10 << 15)/15.0, - ( -8 << 15)/15.0,( -6 << 15)/15.0,( -4 << 15)/15.0, - ( -2 << 15)/15.0, 0.0 ,( 2 << 15)/15.0, - ( 4 << 15)/15.0,( 6 << 15)/15.0,( 8 << 15)/15.0, - ( 10 << 15)/15.0,( 12 << 15)/15.0,( 14 << 15)/15.0 -}; + (-14 << 15)/15,(-12 << 15)/15,(-10 << 15)/15, + ( -8 << 15)/15,( -6 << 15)/15,( -4 << 15)/15, + ( -2 << 15)/15, 0 ,( 2 << 15)/15, + ( 4 << 15)/15,( 6 << 15)/15,( 8 << 15)/15, + ( 10 << 15)/15,( 12 << 15)/15,( 14 << 15)/15 +}; // // Scale factors for convert_to_float @@ -238,200 +104,234 @@ static const uint32_t u32_scale_factors[25] = static float *scale_factor = (float*)u32_scale_factors; //These store the persistent state of the packed mantissas -static float q_1[2]; -static float q_2[2]; -static float q_4[1]; -static int32_t q_1_pointer; -static int32_t q_2_pointer; -static int32_t q_4_pointer; -static float __inline__ -coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp); +static uint16_t m_1[3]; +static uint16_t m_2[3]; +static uint16_t m_4[2]; +static uint16_t m_1_pointer; +static uint16_t m_2_pointer; +static uint16_t m_4_pointer; //Conversion from bap to number of bits in the mantissas //zeros account for cases 0,1,2,4 which are special cased -static uint16_t qnttztab[16] = -{ - 0, 0, 0, 3, - 0, 4, 5, 6, - 7, 8, 9, 10, - 11, 12, 14, 16 -}; +static uint16_t qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16}; -static void coeff_reset(void); -static float coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp); -static void coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch); +static void coeff_reset(void); +static int16_t coeff_get_mantissa(uint16_t bap, uint16_t dithflag); +static void coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch); -void coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples) +// +// Convert a 0.15 fixed point number into IEEE single +// precision floating point and scale by 2^-exp +// +static inline float +convert_to_float(uint16_t exp, int16_t mantissa) { - uint16_t i,j; - uint32_t done_cpl = 0; - - coeff_reset(); - - for(i=0; i< bsi->nfchans; i++) { - for(j=0; j < audblk->endmant[i]; j++) - samples[i][j] = coeff_get_float(audblk->fbw_bap[i][j], audblk->dithflag[i], audblk->fbw_exp[i][j]); - - if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) { - // ncplmant is equal to 12 * ncplsubnd - // Don't dither coupling channel until channel - // separation so that interchannel noise is uncorrelated - for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++) - audblk->cpl_flt[j] = coeff_get_float(audblk->cpl_bap[j],0, audblk->cpl_exp[j]); - done_cpl = 1; - } - } - - //uncouple the channel if necessary - if(audblk->cplinu) { - for(i=0; i< bsi->nfchans; i++) { - if(audblk->chincpl[i]) - coeff_uncouple_ch(samples[i],bsi,audblk,i); - } + float x; - } + //the scale by 2^-15 is built into the scale factor table + x = mantissa * scale_factor[exp]; - if(bsi->lfeon) { - // There are always 7 mantissas for lfe, no dither for lfe - for(j=0; j < 7 ; j++) - samples[5][j] = coeff_get_float(audblk->lfe_bap[j], 0, audblk->lfe_exp[j]); - } + return x; } - -/** - * Fetch a float from the bitstream - **/ - -static float inline coeff_get_float (uint16_t bap, uint16_t dithflag, uint16_t exp) +void +coeff_unpack(ac3_state_t *state, audblk_t *audblk, stream_samples_t samples) { - uint16_t dummy = 0; + uint16_t i,j; + uint32_t done_cpl = 0; + int16_t mantissa; - //If the bap is 0-5 then we have special cases to take care of - switch(bap) { - case 0: - if(dithflag) - return (dither_gen() * scale_factor[exp]); - return 0.0; + coeff_reset(); - case 1: - if (q_1_pointer >= 0) - return(q_1[q_1_pointer--] * scale_factor[exp]); + for(i=0; i< state->nfchans; i++) { + for(j=0; j < audblk->endmant[i]; j++) { + mantissa = coeff_get_mantissa(audblk->fbw_bap[i][j],audblk->dithflag[i]); + samples[i][j] = convert_to_float(audblk->fbw_exp[i][j],mantissa); + } - if ((dummy = bitstream_get (5)) > 26) - goto error; + if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) { + // ncplmant is equal to 12 * ncplsubnd + // Don't dither coupling channel until channel separation so that + // interchannel noise is uncorrelated + for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++) + audblk->cplmant[j] = coeff_get_mantissa(audblk->cpl_bap[j],0); + done_cpl = 1; + } + } - q_1[1] = q_1_1[dummy]; - q_1[0] = q_1_2[dummy]; - q_1_pointer = 1; + //uncouple the channel if necessary + if(audblk->cplinu) { + for(i=0; i< state->nfchans; i++) { + if(audblk->chincpl[i]) + coeff_uncouple_ch(samples[i],state,audblk,i); + } + } - return (q_1_0[dummy] * scale_factor[exp]); + if(state->lfeon) { + // There are always 7 mantissas for lfe, no dither for lfe + for(j=0; j < 7 ; j++) { + mantissa = coeff_get_mantissa(audblk->lfe_bap[j],0); + samples[5][j] = convert_to_float(audblk->lfe_exp[j],mantissa); + } + } +} - case 2: - if(q_2_pointer >= 0) - return (q_2[q_2_pointer--] * scale_factor[exp]); +// +//Fetch a mantissa from the bitstream +// +//The mantissa returned is a signed 0.15 fixed point number +// +static int16_t +coeff_get_mantissa(uint16_t bap, uint16_t dithflag) +{ + uint16_t mantissa; + uint16_t group_code; + + //If the bap is 0-5 then we have special cases to take care of + switch(bap) { + case 0: + if(dithflag) + mantissa = dither_gen(); + else + mantissa = 0; + break; + + case 1: + if(m_1_pointer > 2) { + group_code = bitstream_get(5); + + if(group_code > 26) + goto error; + + m_1[0] = group_code / 9; + m_1[1] = (group_code % 9) / 3; + m_1[2] = (group_code % 9) % 3; + m_1_pointer = 0; + } + mantissa = m_1[m_1_pointer++]; + mantissa = q_1[mantissa]; + break; + case 2: + + if(m_2_pointer > 2) { + group_code = bitstream_get(7); + + if(group_code > 124) + goto error; + + m_2[0] = group_code / 25; + m_2[1] = (group_code % 25) / 5 ; + m_2[2] = (group_code % 25) % 5 ; + m_2_pointer = 0; + } + mantissa = m_2[m_2_pointer++]; + mantissa = q_2[mantissa]; + break; - if ((dummy = bitstream_get (7)) > 124) - goto error; + case 3: + mantissa = bitstream_get(3); - q_2[1] = q_2_1[dummy]; - q_2[0] = q_2_2[dummy]; - q_2_pointer = 1; + if(mantissa > 6) + goto error; - return (q_2_0[dummy] * scale_factor[exp]); + mantissa = q_3[mantissa]; + break; - case 3: - if ((dummy = bitstream_get (3)) > 6) - goto error; + case 4: + if(m_4_pointer > 1) { + group_code = bitstream_get(7); - return (q_3[dummy] * scale_factor[exp]); + if(group_code > 120) + goto error; - case 4: - if(q_4_pointer >= 0) - return (q_4[q_4_pointer--] * scale_factor[exp]); + m_4[0] = group_code / 11; + m_4[1] = group_code % 11; + m_4_pointer = 0; + } + mantissa = m_4[m_4_pointer++]; + mantissa = q_4[mantissa]; + break; - if ((dummy = bitstream_get (7)) > 120) - goto error; + case 5: + mantissa = bitstream_get(4); - q_4[0] = q_4_1[dummy]; - q_4_pointer = 0; + if(mantissa > 14) + goto error; - return (q_4_0[dummy] * scale_factor[exp]); + mantissa = q_5[mantissa]; + break; - case 5: - if ((dummy = bitstream_get (4)) > 14) - goto error; + default: + mantissa = bitstream_get(qnttztab[bap]); + mantissa <<= 16 - qnttztab[bap]; + } - return (q_5[dummy] * scale_factor[exp]); + return mantissa; - default: - dummy = bitstream_get(qnttztab[bap]); - dummy <<= 16 - qnttztab[bap]; - return ((int16_t)dummy * scale_factor[exp]); - } -error: -#ifdef FAST_ERROR - HANDLE_ERROR (); -#else - if(!error_flag) - fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); - error_flag = 1; - - return 0.0; -#endif -} +error: + if(!error_flag) + fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); + error_flag = 1; -/** - * Reset the mantissa state - **/ + return 0; +} -static void coeff_reset(void) +// +// Reset the mantissa state +// +static void +coeff_reset(void) { - q_1_pointer = q_2_pointer = q_4_pointer = -1; + m_1[2] = m_1[1] = m_1[0] = 0; + m_2[2] = m_2[1] = m_2[0] = 0; + m_4[1] = m_4[0] = 0; + m_1_pointer = m_2_pointer = m_4_pointer = 3; } +// +// Uncouple the coupling channel into a fbw channel +// +static void +coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch) +{ + uint32_t bnd = 0; + uint32_t sub_bnd = 0; + uint32_t i,j; + float cpl_coord = 1.0; + uint32_t cpl_exp_tmp; + uint32_t cpl_mant_tmp; + int16_t mantissa; + + for(i=audblk->cplstrtmant;i<audblk->cplendmant;) { + if(!audblk->cplbndstrc[sub_bnd++]) { + cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; + if(audblk->cplcoexp[ch][bnd] == 15) + cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11; + else + cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10; + + cpl_coord = convert_to_float(cpl_exp_tmp,cpl_mant_tmp) * 8.0f; + + //Invert the phase for the right channel if necessary + if(state->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd]) + cpl_coord *= -1; + + bnd++; + } + + for(j=0;j < 12; j++) { + //Get new dither values for each channel if necessary, so + //the channels are uncorrelated + if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0) + mantissa = dither_gen(); + else + mantissa = audblk->cplmant[i]; -/** - * Uncouple the coupling channel into a fbw channel - **/ + samples[i] = cpl_coord * convert_to_float(audblk->cpl_exp[i],mantissa); -static void coeff_uncouple_ch (float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch) -{ - uint32_t bnd = 0; - uint32_t sub_bnd = 0; - uint32_t i,j; - float cpl_coord = 1.0; - uint32_t cpl_exp_tmp; - uint32_t cpl_mant_tmp; - - for (i=audblk->cplstrtmant;i<audblk->cplendmant;) { - if (!audblk->cplbndstrc[sub_bnd++]) { - cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; - if (audblk->cplcoexp[ch][bnd] == 15) - cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11; - else - cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10; - - cpl_coord = (cpl_mant_tmp * scale_factor[cpl_exp_tmp]) * 8.0f; - - //Invert the phase for the right channel if necessary - if(bsi->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd]) - cpl_coord *= -1; - - bnd++; - } - - for(j=0;j < 12; j++) { - // Get new dither values for each channel if necessary, - // so the channels are uncorrelated - if(audblk->dithflag[ch] && !audblk->cpl_bap[i]) - samples[i] = cpl_coord * (dither_gen() * scale_factor[audblk->cpl_exp[i]]); - else - samples[i] = cpl_coord * audblk->cpl_flt[i]; - - i++; - } + i++; } + } } diff --git a/src/libac3/coeff.h b/src/libac3/coeff.h index dc822a9bd..fd3e1a6d9 100644 --- a/src/libac3/coeff.h +++ b/src/libac3/coeff.h @@ -21,4 +21,4 @@ * */ -void coeff_unpack(bsi_t *bsi, audblk_t *audblk,stream_samples_t samples); +void coeff_unpack(ac3_state_t * state, audblk_t *audblk,stream_samples_t samples); diff --git a/src/libac3/crc.c b/src/libac3/crc.c deleted file mode 100644 index c8ee478b6..000000000 --- a/src/libac3/crc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * crc.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include "ac3.h" -#include "ac3_internal.h" - -#include <sys/time.h> - -#include "crc.h" - -static const uint16_t crc_lut[256] = -{ - 0x0000,0x8005,0x800f,0x000a,0x801b,0x001e,0x0014,0x8011, - 0x8033,0x0036,0x003c,0x8039,0x0028,0x802d,0x8027,0x0022, - 0x8063,0x0066,0x006c,0x8069,0x0078,0x807d,0x8077,0x0072, - 0x0050,0x8055,0x805f,0x005a,0x804b,0x004e,0x0044,0x8041, - 0x80c3,0x00c6,0x00cc,0x80c9,0x00d8,0x80dd,0x80d7,0x00d2, - 0x00f0,0x80f5,0x80ff,0x00fa,0x80eb,0x00ee,0x00e4,0x80e1, - 0x00a0,0x80a5,0x80af,0x00aa,0x80bb,0x00be,0x00b4,0x80b1, - 0x8093,0x0096,0x009c,0x8099,0x0088,0x808d,0x8087,0x0082, - 0x8183,0x0186,0x018c,0x8189,0x0198,0x819d,0x8197,0x0192, - 0x01b0,0x81b5,0x81bf,0x01ba,0x81ab,0x01ae,0x01a4,0x81a1, - 0x01e0,0x81e5,0x81ef,0x01ea,0x81fb,0x01fe,0x01f4,0x81f1, - 0x81d3,0x01d6,0x01dc,0x81d9,0x01c8,0x81cd,0x81c7,0x01c2, - 0x0140,0x8145,0x814f,0x014a,0x815b,0x015e,0x0154,0x8151, - 0x8173,0x0176,0x017c,0x8179,0x0168,0x816d,0x8167,0x0162, - 0x8123,0x0126,0x012c,0x8129,0x0138,0x813d,0x8137,0x0132, - 0x0110,0x8115,0x811f,0x011a,0x810b,0x010e,0x0104,0x8101, - 0x8303,0x0306,0x030c,0x8309,0x0318,0x831d,0x8317,0x0312, - 0x0330,0x8335,0x833f,0x033a,0x832b,0x032e,0x0324,0x8321, - 0x0360,0x8365,0x836f,0x036a,0x837b,0x037e,0x0374,0x8371, - 0x8353,0x0356,0x035c,0x8359,0x0348,0x834d,0x8347,0x0342, - 0x03c0,0x83c5,0x83cf,0x03ca,0x83db,0x03de,0x03d4,0x83d1, - 0x83f3,0x03f6,0x03fc,0x83f9,0x03e8,0x83ed,0x83e7,0x03e2, - 0x83a3,0x03a6,0x03ac,0x83a9,0x03b8,0x83bd,0x83b7,0x03b2, - 0x0390,0x8395,0x839f,0x039a,0x838b,0x038e,0x0384,0x8381, - 0x0280,0x8285,0x828f,0x028a,0x829b,0x029e,0x0294,0x8291, - 0x82b3,0x02b6,0x02bc,0x82b9,0x02a8,0x82ad,0x82a7,0x02a2, - 0x82e3,0x02e6,0x02ec,0x82e9,0x02f8,0x82fd,0x82f7,0x02f2, - 0x02d0,0x82d5,0x82df,0x02da,0x82cb,0x02ce,0x02c4,0x82c1, - 0x8243,0x0246,0x024c,0x8249,0x0258,0x825d,0x8257,0x0252, - 0x0270,0x8275,0x827f,0x027a,0x826b,0x026e,0x0264,0x8261, - 0x0220,0x8225,0x822f,0x022a,0x823b,0x023e,0x0234,0x8231, - 0x8213,0x0216,0x021c,0x8219,0x0208,0x820d,0x8207,0x0202 -}; - -static uint16_t state; - - -void crc_init(void) -{ - state = 0; -} - - -inline void crc_process_byte (uint8_t data) -{ - state = crc_lut[data ^ (state>>8)] ^ (state<<8); -} - - -void crc_process_frame (uint8_t *data,uint32_t num_bytes) -{ - uint32_t i; - - for(i=0; i<num_bytes; i++) - crc_process_byte (data[i]); -} - - -int crc_validate(void) -{ - return (state == 0); -} diff --git a/src/libac3/debug.c b/src/libac3/debug.c new file mode 100644 index 000000000..b7d6a3b08 --- /dev/null +++ b/src/libac3/debug.c @@ -0,0 +1,58 @@ +/* + * + * debug.c + * + * Copyright (C) Aaron Holtzman - May 1999 + * + * This file is part of ac3dec, a free Dolby AC-3 stream decoder. + * + * ac3dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ac3dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#include "debug.h" + +static int debug_level = -1; + +// Determine is debug output is required. +// We could potentially have multiple levels of debug info +int debug_is_on(void) +{ + char *env_var; + + if(debug_level < 0) + { + env_var = getenv("AC3_DEBUG"); + + if (env_var) + { + debug_level = 1; + } + else + debug_level = 0; + } + + return debug_level; +} + +//If you don't have gcc, then ya don't get debug output +#ifndef __GNUC__ +void dprintf(char fmt[],...) +{ + int foo = 0; +} +#endif + diff --git a/src/libac3/exponent.h b/src/libac3/debug.h index 06c59db03..f45cb5b1a 100644 --- a/src/libac3/exponent.h +++ b/src/libac3/debug.h @@ -1,5 +1,6 @@ -/* - * exponent.h +/* + * + * debug.h * * Copyright (C) Aaron Holtzman - May 1999 * @@ -21,8 +22,16 @@ * */ -#define UNPACK_FBW 1 -#define UNPACK_CPL 2 -#define UNPACK_LFE 4 +int debug_is_on(void); -void exponent_unpack( bsi_t *bsi, audblk_t *audblk); +#ifdef __GNUC__ +#define dprintf(format,args...)\ +{\ + if (debug_is_on())\ + {\ + fprintf(stderr,format,## args);\ + }\ +} +#else +void dprintf(char fmt[],...); +#endif diff --git a/src/libac3/decode.c b/src/libac3/decode.c index 96ee6c1a3..db0068b8d 100644 --- a/src/libac3/decode.c +++ b/src/libac3/decode.c @@ -22,296 +22,115 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> -#include <unistd.h> #include <errno.h> #include <string.h> #include <sys/time.h> - +#include <inttypes.h> #include "ac3.h" #include "ac3_internal.h" #include "bitstream.h" -#include "downmix.h" -#include "srfft.h" #include "imdct.h" -#include "exponent.h" #include "coeff.h" #include "bit_allocate.h" #include "parse.h" -#include "crc.h" +#include "stats.h" #include "rematrix.h" #include "sanity_check.h" - -#include "audio_out.h" -#include "metronom.h" -#include "attributes.h" - +#include "downmix.h" +#include "debug.h" //our global config structure -ac3_config_t ac3_config; -#ifdef FAST_ERROR -jmp_buf error_jmp_mark; -#else uint32_t error_flag = 0; -#endif static audblk_t audblk; -static bsi_t bsi; -static syncinfo_t syncinfo; +static ac3_state_t state; static uint32_t frame_count = 0; -static uint32_t is_output_initialized = 0; +static uint32_t done_banner; +static ac3_frame_t frame; //the floating point samples for one audblk static stream_samples_t samples; //the integer samples for the entire frame (with enough space for 2 ch out) //if this size change, be sure to change the size when muting -static int16_t s16_samples[2 * 6 * 256] __attribute__ ((aligned(16))); - -/* output buffer for spdiv output */ -static int16_t s16_samples_out[4 * 6 * 256] __attribute__ ((aligned(16))); - -static ao_functions_t *ac3_output; +static int16_t s16_samples[2 * 6 * 256]; -// downmix stuff -static float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 }; -static float smixlev_lut[4] = { 0.707, 0.500, 0.0 , 0.500 }; -static dm_par_t dm_par; - -//Storage for the syncframe -#define BUFFER_MAX_SIZE 4096 -static uint8_t buffer[BUFFER_MAX_SIZE]; -static uint32_t buffer_size = 0;; - -static uint32_t decode_buffer_syncframe (syncinfo_t *syncinfo, uint8_t **start, uint8_t *end) +void +ac3_init(void) { - uint8_t *cur = *start; - uint16_t syncword = syncinfo->syncword; - uint32_t ret = 0; - - // - // Find an ac3 sync frame. - // - while (syncword != 0x0b77) { - if (cur >= end) - goto done; - syncword = (syncword << 8) + *cur++; - } + imdct_init(); + sanity_check_init(&state,&audblk); - //need the next 3 bytes to decide how big the frame is - while (buffer_size < 3) { - if(cur >= end) - goto done; - buffer[buffer_size++] = *cur++; - } - - parse_syncinfo (syncinfo,buffer); - - while (buffer_size < syncinfo->frame_size * 2 - 2) { - if(cur >= end) - goto done; - - buffer[buffer_size++] = *cur++; - } - -#if 0 - // Check the crc over the entire frame - crc_init(); - crc_process_frame (buffer, syncinfo->frame_size * 2 - 2); - - if (!crc_validate()) { -#ifndef FAST_ERROR - error_flag = 1; -#endif - fprintf(stderr,"** CRC failed - skipping frame **\n"); - goto done; - } -#endif - - // - //if we got to this point, we found a valid ac3 frame to decode - // - - if ((ac3_config.flags & AO_CAP_MODE_AC3) == 0) { - bitstream_init (buffer); - //get rid of the syncinfo struct as we already parsed it - bitstream_get (24); - } - - //reset the syncword for next time - syncword = 0xffff; - buffer_size = 0; - ret = 1; - -done: - syncinfo->syncword = syncword; - *start = cur; - return ret; + frame.audio_data = s16_samples; } - -void inline decode_mute (void) +int ac3_frame_length(uint8_t * buf) { - //mute the frame - memset (s16_samples, 0, sizeof(int16_t) * 256 * 2 * 6); -#ifndef FAST_ERROR - error_flag = 0; -#endif -} - - -void ac3_init(ac3_config_t *config ,ao_functions_t *foo) -{ - memcpy(&ac3_config,config,sizeof(ac3_config_t)); - ac3_output = foo; - - imdct_init (); - /* downmix_init (); */ - sanity_check_init (&syncinfo,&bsi,&audblk); - memset(s16_samples_out,0,4 * 6 * 256); - -} - -void ac3_reset () -{ - printf ("ac3_reset\n"); -#ifndef FAST_ERROR - error_flag = 0; -#endif - - frame_count = 0; - is_output_initialized = 0; - - buffer_size = 0; - syncinfo.syncword = 0; - imdct_init(); - sanity_check_init(&syncinfo,&bsi,&audblk); + int dummy; + return parse_syncinfo (buf, &dummy, &dummy); } -size_t ac3_decode_data (uint8_t *data_start, uint8_t *data_end, uint32_t pts_) +ac3_frame_t* +ac3_decode_frame(uint8_t * buf) { - uint32_t i; + uint32_t i; + int dummy; -#ifdef FAST_ERROR - if (setjmp (error_jmp_mark) < 0) { - imdct_init (); - sanity_check_init(&syncinfo,&bsi,&audblk); - return 0; - } -#endif - - while (decode_buffer_syncframe (&syncinfo, &data_start, data_end)) { + if (!parse_syncinfo (buf, &frame.sampling_rate, &dummy)) + goto error; -#ifndef FAST_ERROR - if (error_flag) - goto error; -#endif + dprintf("(decode) begin frame %d\n",frame_count++); - if ((ac3_config.flags & AO_CAP_MODE_AC3) == 0) { - parse_bsi (&bsi); + if (parse_bsi (&state, buf)) + goto error; - // compute downmix parameters - // downmix to two channels for now - dm_par.clev = 0.0; dm_par.slev = 0.0; dm_par.unit = 1.0; - if (bsi.acmod & 0x1) // have center - dm_par.clev = cmixlev_lut[bsi.cmixlev]; + if (!done_banner) { + stats_print_banner (&state); + done_banner = 1; + } - if (bsi.acmod & 0x4) // have surround channels - dm_par.slev = smixlev_lut[bsi.surmixlev]; + for(i=0; i < 6; i++) { + //Initialize freq/time sample storage + memset(samples,0,sizeof(float) * 256 * (state.nfchans + state.lfeon)); - dm_par.unit /= 1.0 + dm_par.clev + dm_par.slev; - dm_par.clev *= dm_par.unit; - dm_par.slev *= dm_par.unit; + // Extract most of the audblk info from the bitstream + // (minus the mantissas + if (parse_audblk (&state, &audblk)) + goto error; - for(i=0; i < 6; i++) { - //Initialize freq/time sample storage - memset (samples, 0, sizeof(float) * 256 * (bsi.nfchans + bsi.lfeon)); + // Figure out how many bits per mantissa + //bit_allocate(&state,&audblk); - // Extract most of the audblk info from the bitstream - // (minus the mantissas - parse_audblk (&bsi,&audblk); + // Extract the mantissas from the stream and + // generate floating point frequency coefficients + coeff_unpack(&state,&audblk,samples); + if(error_flag) + goto error; - // Take the differential exponent data and turn it into - // absolute exponents - exponent_unpack (&bsi,&audblk); -#ifndef FAST_ERROR - if (error_flag) - goto error; -#endif + if(state.acmod == 0x2) + rematrix(&audblk,samples); - // Figure out how many bits per mantissa - bit_allocate (syncinfo.fscod,&bsi,&audblk); + // Convert the frequency samples into time samples + imdct(&state,&audblk,samples); - // Extract the mantissas from the stream and - // generate floating point frequency coefficients - coeff_unpack (&bsi,&audblk,samples); -#ifndef FAST_ERROR - if (error_flag) - goto error; -#endif + // Downmix into the requested number of channels + // and convert floating point to int16_t + downmix(&state,samples,&s16_samples[i * 2 * 256]); - if (bsi.acmod == 0x2) - rematrix (&audblk,samples); + sanity_check(&state,&audblk); + if(error_flag) + goto error; + } - // Convert the frequency samples into time samples - imdct (&bsi,&audblk,samples, &s16_samples[i * 2 * 256], &dm_par); + return &frame; - // Downmix into the requested number of channels - // and convert floating point to int16_t - // downmix(&bsi,samples,&s16_samples[i * 2 * 256]); - - if (sanity_check(&syncinfo,&bsi,&audblk) < 0) - sanity_check_init (&syncinfo,&bsi,&audblk); - - continue; - } - } - else { - s16_samples_out[0] = 0xf872; //spdif syncword - s16_samples_out[1] = 0x4e1f; // ............. - s16_samples_out[2] = 0x0001; // AC3 data - s16_samples_out[3] = syncinfo.frame_size * 16; - s16_samples_out[4] = 0x0b77; // AC3 syncwork - - // ac3 seems to be swabbed data - swab(buffer,&s16_samples_out[5], syncinfo.frame_size * 2 ); - - } - - if (!is_output_initialized) { - ac3_output->open (ac3_output, 16, syncinfo.sampling_rate, - (ac3_config.flags & AO_CAP_MODE_AC3) ? AO_CAP_MODE_AC3 : AO_CAP_MODE_STEREO); - is_output_initialized = 1; - } - - if ((ac3_config.flags & AO_CAP_MODE_AC3) == 0) { - ac3_output->write_audio_data(ac3_output, - s16_samples, 256*6, pts_); - } - else { - ac3_output->write_audio_data(ac3_output, - s16_samples_out, 6 * 256, pts_); - } - - pts_ = 0; - -#ifndef FAST_ERROR error: - - //find a new frame - decode_mute (); //RMB CHECK -#endif - } -#ifdef FAST_ERROR - decode_mute (); -#endif + //mute the frame + memset(s16_samples,0,sizeof(int16_t) * 256 * 2 * 6); - return 0; + error_flag = 0; + return &frame; } - diff --git a/src/libac3/dither.c b/src/libac3/dither.c index 07fa2f596..8b7ef3427 100644 --- a/src/libac3/dither.c +++ b/src/libac3/dither.c @@ -21,9 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include <stdlib.h> #include <stdio.h> @@ -94,24 +91,24 @@ uint16_t lfsr_state = 1; uint16_t dither_gen(void) { - int i; - uint32_t state; + int i; + uint32_t state; - //explicitly bring the state into a local var as gcc > 3.0? - //doesn't know how to optimize out the stores - state = lfsr_state; + //explicitly bring the state into a local var as gcc > 3.0? + //doesn't know how to optimize out the stores + state = lfsr_state; - //Generate eight pseudo random bits - for(i=0;i<8;i++) { - state <<= 1; + //Generate eight pseudo random bits + for(i=0;i<8;i++) { + state <<= 1; - if(state & 0x10000) - state ^= 0xa011; - } + if(state & 0x10000) + state ^= 0xa011; + } - lfsr_state = state; + lfsr_state = state; - return (((((int32_t)state<<8)>>8) * (int32_t) (0.707106 * 256.0))>>16); + return (((((int32_t)state<<8)>>8) * (int32_t) (0.707106 * 256.0))>>16); } #endif diff --git a/src/libac3/dither.h b/src/libac3/dither.h index abb9f518e..1a605ee14 100644 --- a/src/libac3/dither.h +++ b/src/libac3/dither.h @@ -27,11 +27,11 @@ extern const uint16_t dither_lut[256]; static inline uint16_t dither_gen(void) { - int16_t state; + int16_t state; - state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8); + state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8); - lfsr_state = (uint16_t) state; + lfsr_state = (uint16_t) state; - return ((state * (int32_t) (0.707106 * 256.0))>>8); + return ((state * (int32_t) (0.707106 * 256.0))>>8); } diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c index df71d5e3d..a50b045be 100644 --- a/src/libac3/downmix.c +++ b/src/libac3/downmix.c @@ -1,7 +1,10 @@ /* - * imdct.c + * + * downmix.c * - * Copyright (C) Aaron Holtzman - May 1999 + * Copyright (C) Aaron Holtzman - Sept 1999 + * + * Originally based on code by Yuqing Deng. * * This file is part of ac3dec, a free Dolby AC-3 stream decoder. * @@ -22,137 +25,396 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include <math.h> - #include "ac3.h" #include "ac3_internal.h" + +#include "decode.h" #include "downmix.h" +#include "debug.h" -void downmix_3f_2r_to_2ch (float *samples, dm_par_t *dm_par) + +//Pre-scaled downmix coefficients +static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 }; +static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 }; + +static void +downmix_3f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) { - int i; - float *left, *right, *center, *left_sur, *right_sur; - float left_tmp, right_tmp; - - left = samples; - right = samples + 256 * 2; - center = samples + 256; - left_sur = samples + 256 * 3; - right_sur = samples + 256 * 4; - - for (i=0; i < 256; i++) { - left_tmp = dm_par->unit * *left + dm_par->clev * *center + dm_par->slev * *left_sur++; - right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++; - *left++ = left_tmp; - *center++ = right_tmp; + uint32_t j; + float right_tmp; + float left_tmp; + float clev,slev; + float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; + + left = samples[0]; + centre = samples[1]; + right = samples[2]; + left_sur = samples[3]; + right_sur = samples[4]; + + clev = cmixlev_lut[state->cmixlev]; + slev = smixlev_lut[state->surmixlev]; + + 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++; + + s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); + s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); } } - -void downmix_2f_2r_to_2ch (float *samples, dm_par_t *dm_par) +static void +downmix_2f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) { - int i; - float *left, *right, *left_sur, *right_sur; - float left_tmp, right_tmp; - - left = &samples[0]; - right = &samples[256]; - left_sur = &samples[512]; - right_sur = &samples[768]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left + dm_par->slev * *left_sur++; - right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++; - *left++ = left_tmp; - *right++ = right_tmp; + uint32_t j; + float right_tmp; + float left_tmp; + float slev; + float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0; + + left = samples[0]; + right = samples[1]; + left_sur = samples[2]; + right_sur = samples[3]; + + slev = smixlev_lut[state->surmixlev]; + + for (j = 0; j < 256; j++) + { + left_tmp = 0.4142f * *left++ + slev * *left_sur++; + right_tmp= 0.4142f * *right++ + slev * *right_sur++; + + s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); + s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); } } - -void downmix_3f_1r_to_2ch (float *samples, dm_par_t *dm_par) +static void +downmix_3f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) { - int i; - float *left, *right, *center, *right_sur; - float left_tmp, right_tmp; - - left = &samples[0]; - right = &samples[512]; - center = &samples[256]; - right_sur = &samples[768]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left + dm_par->clev * *center - dm_par->slev * *right_sur; - right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++; - *left++ = left_tmp; - *center++ = right_tmp; + uint32_t j; + float right_tmp; + float left_tmp; + float clev,slev; + float *centre = 0, *left = 0, *right = 0, *sur = 0; + + left = samples[0]; + centre = samples[1]; + right = samples[2]; + //Mono surround + sur = samples[3]; + + clev = cmixlev_lut[state->cmixlev]; + slev = smixlev_lut[state->surmixlev]; + + for (j = 0; j < 256; j++) + { + left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *sur; + right_tmp= 0.4142f * *right++ + clev * *centre + slev * *sur++; + + s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); + s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); } } -void downmix_2f_1r_to_2ch (float *samples, dm_par_t *dm_par) +static void +downmix_2f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) { - int i; - float *left, *right, *right_sur; - float left_tmp, right_tmp; - - left = &samples[0]; - right = &samples[256]; - right_sur = &samples[512]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left - dm_par->slev * *right_sur; - right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++; - *left++ = left_tmp; - *right++ = right_tmp; + uint32_t j; + float right_tmp; + float left_tmp; + float slev; + float *left = 0, *right = 0, *sur = 0; + + left = samples[0]; + right = samples[1]; + //Mono surround + sur = samples[2]; + + slev = smixlev_lut[state->surmixlev]; + + for (j = 0; j < 256; j++) + { + left_tmp = 0.4142f * *left++ + slev * *sur; + right_tmp= 0.4142f * *right++ + slev * *sur++; + + s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); + s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); } } +static void +downmix_3f_0r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) +{ + uint32_t j; + float right_tmp; + float left_tmp; + float clev; + float *centre = 0, *left = 0, *right = 0; + + left = samples[0]; + centre = samples[1]; + right = samples[2]; -void downmix_3f_0r_to_2ch (float *samples, dm_par_t *dm_par) + clev = cmixlev_lut[state->cmixlev]; + + for (j = 0; j < 256; j++) + { + left_tmp = 0.4142f * *left++ + clev * *centre; + right_tmp= 0.4142f * *right++ + clev * *centre++; + + s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f); + s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f); + } +} + +static void +downmix_2f_0r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) { - int i; - float *left, *right, *center; - float left_tmp, right_tmp; - - left = &samples[0]; - center = &samples[256]; - right = &samples[512]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left + dm_par->clev * *center; - right_tmp= dm_par->unit * *right++ + dm_par->clev * *center; - *left++ = left_tmp; - *center++ = right_tmp; + uint32_t j; + float *left = 0, *right = 0; + + left = samples[0]; + right = samples[1]; + + for (j = 0; j < 256; j++) + { + s16_samples[j * 2 ] = (int16_t) (*left++ * 32767.0f); + s16_samples[j * 2 + 1] = (int16_t) (*right++ * 32767.0f); } } -void stream_sample_2ch_to_s16 (int16_t *s16_samples, float *left, float *right) +static void +downmix_1f_0r_to_2ch(float *centre,int16_t *s16_samples) { - int i; + uint32_t j; + float tmp; + + //Mono program! - for (i=0; i < 256; i++) { - *s16_samples++ = (int16_t) *left++; - *s16_samples++ = (int16_t) *right++; + for (j = 0; j < 256; j++) + { + tmp = 32767.0f * 0.7071f * *centre++; + + s16_samples[j * 2 ] = s16_samples[j * 2 + 1] = (int16_t) tmp; } } +// +// Downmix into 2 or 4 channels (4 ch isn't in quite yet) +// +// The downmix function names have the following format +// +// downmix_Xf_Yr_to_[2|4]ch[_dolby] +// +// where X = number of front channels +// Y = number of rear channels +// [2|4] = number of output channels +// [_dolby] = with or without dolby surround mix +// -void stream_sample_1ch_to_s16 (int16_t *s16_samples, float *center) +void downmix(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples) { - int i; - float tmp; + if(state->acmod > 7) + dprintf("(downmix) invalid acmod number\n"); + +#if 0 + // + //There are two main cases, with or without Dolby Surround + // + if(ac3_config.flags & AC3_DOLBY_SURR_ENABLE) + { + fprintf(stderr,"Dolby Surround Mixes not currently enabled\n"); + exit(1); + } +#endif + + //Non-Dolby surround downmixes + switch(state->acmod) + { + // 3/2 + case 7: + downmix_3f_2r_to_2ch(state, samples,s16_samples); + break; + + // 2/2 + case 6: + downmix_2f_2r_to_2ch(state, samples,s16_samples); + break; + + // 3/1 + case 5: + downmix_3f_1r_to_2ch(state, samples,s16_samples); + break; + + // 2/1 + case 4: + downmix_2f_1r_to_2ch(state, samples,s16_samples); + break; + + // 3/0 + case 3: + downmix_3f_0r_to_2ch(state, samples,s16_samples); + break; - for (i=0; i < 256; i++) { - *s16_samples++ = tmp = (int16_t) (0.7071f * *center++); - *s16_samples++ = tmp; + case 2: + downmix_2f_0r_to_2ch(state, samples,s16_samples); + break; + + // 1/0 + case 1: + downmix_1f_0r_to_2ch(samples[0],s16_samples); + break; + + // 1+1 + case 0: +#if 0 + downmix_1f_0r_to_2ch(samples[ac3_config.dual_mono_ch_sel],s16_samples); +#endif + break; } } + +#if 0 + + //the dolby mixes lay here for the time being + switch(state->acmod) + { + // 3/2 + case 7: + left = samples[0]; + centre = samples[1]; + right = samples[2]; + left_sur = samples[3]; + right_sur = samples[4]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++; + left_tmp = -1 * right_tmp; + right_tmp += 0.3204f * *right++ + 0.2265f * *centre; + left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; + + samples[1][j] = right_tmp; + samples[0][j] = left_tmp; + } + + break; + + // 2/2 + case 6: + left = samples[0]; + right = samples[1]; + left_sur = samples[2]; + right_sur = samples[3]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++; + left_tmp = -1 * right_tmp; + right_tmp += 0.3204f * *right++; + left_tmp += 0.3204f * *left++ ; + + samples[1][j] = right_tmp; + samples[0][j] = left_tmp; + } + break; + + // 3/1 + case 5: + left = samples[0]; + centre = samples[1]; + right = samples[2]; + //Mono surround + right_sur = samples[3]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.2265f * *right_sur++; + left_tmp = -1 * right_tmp; + right_tmp += 0.3204f * *right++ + 0.2265f * *centre; + left_tmp += 0.3204f * *left++ + 0.2265f * *centre++; + + samples[1][j] = right_tmp; + samples[0][j] = left_tmp; + } + break; + + // 2/1 + case 4: + left = samples[0]; + right = samples[1]; + //Mono surround + right_sur = samples[2]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.2265f * *right_sur++; + left_tmp = -1 * right_tmp; + right_tmp += 0.3204f * *right++; + left_tmp += 0.3204f * *left++; + + samples[1][j] = right_tmp; + samples[0][j] = left_tmp; + } + break; + + // 3/0 + case 3: + left = samples[0]; + centre = samples[1]; + right = samples[2]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.3204f * *right++ + 0.2265f * *centre; + left_tmp = 0.3204f * *left++ + 0.2265f * *centre++; + + samples[1][j] = right_tmp; + samples[0][j] = left_tmp; + } + break; + + // 2/0 + case 2: + //Do nothing! + break; + + // 1/0 + case 1: + //Mono program! + right = samples[0]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.7071f * *right++; + + samples[1][j] = right_tmp; + samples[0][j] = right_tmp; + } + + break; + + // 1+1 + case 0: + //Dual mono, output selected by user + right = samples[ac3_config.dual_mono_ch_sel]; + + for (j = 0; j < 256; j++) + { + right_tmp = 0.7071f * *right++; + + samples[1][j] = right_tmp; + samples[0][j] = right_tmp; + } + break; +#endif diff --git a/src/libac3/downmix.h b/src/libac3/downmix.h index 7e6dea014..525980afb 100644 --- a/src/libac3/downmix.h +++ b/src/libac3/downmix.h @@ -25,19 +25,4 @@ * */ -typedef struct dm_par_s { - float unit; - float clev; - float slev; -} dm_par_t; - -void downmix_3f_2r_to_2ch (float *samples, dm_par_t * dm_par); -void downmix_3f_1r_to_2ch (float *samples, dm_par_t * dm_par); -void downmix_2f_2r_to_2ch (float *samples, dm_par_t * dm_par); -void downmix_2f_1r_to_2ch (float *samples, dm_par_t * dm_par); -void downmix_3f_0r_to_2ch (float *samples, dm_par_t * dm_par); - -void stream_sample_2ch_to_s16 (int16_t *s16_samples, float *left, float *right); -void stream_sample_1ch_to_s16 (int16_t *s16_samples, float *center); - - +void downmix(ac3_state_t * state, stream_samples_t stream_samples,int16_t *s16_samples); diff --git a/src/libac3/exponent.c b/src/libac3/exponent.c deleted file mode 100644 index ebb35abd7..000000000 --- a/src/libac3/exponent.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * exponent.c - * - * Copyright (C) Aaron Holtzman - May 1999 - * - * This file is part of ac3dec, a free Dolby AC-3 stream decoder. - * - * ac3dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * ac3dec is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include "ac3.h" -#include "ac3_internal.h" - - -#include "exponent.h" - - -static inline void exp_unpack_ch(uint16_t type,uint16_t expstr,uint16_t ngrps,uint16_t initial_exp, uint16_t exps[], uint16_t *dest); - - -/** - * - **/ - -void exponent_unpack( bsi_t *bsi, audblk_t *audblk) -{ - uint16_t i; - - for(i=0; i< bsi->nfchans; i++) - exp_unpack_ch(UNPACK_FBW, audblk->chexpstr[i], audblk->nchgrps[i], audblk->exps[i][0], &audblk->exps[i][1], audblk->fbw_exp[i]); - - if(audblk->cplinu) - exp_unpack_ch(UNPACK_CPL, audblk->cplexpstr, audblk->ncplgrps, audblk->cplabsexp << 1, audblk->cplexps, &audblk->cpl_exp[audblk->cplstrtmant]); - - if(bsi->lfeon) - exp_unpack_ch(UNPACK_LFE, audblk->lfeexpstr, 2, audblk->lfeexps[0], &audblk->lfeexps[1], audblk->lfe_exp); -} - - -/** - * - **/ - -static inline void exp_unpack_ch(uint16_t type,uint16_t expstr,uint16_t ngrps,uint16_t initial_exp, - uint16_t exps[], uint16_t *dest) -{ - uint16_t i,j; - int16_t exp_acc; - int16_t exp_1,exp_2,exp_3; - - if (expstr == EXP_REUSE) - return; - - /* Handle the initial absolute exponent */ - exp_acc = initial_exp; - j = 0; - - /* In the case of a fbw channel then the initial absolute values is - * also an exponent */ - if(type != UNPACK_CPL) - dest[j++] = exp_acc; - - /* Loop through the groups and fill the dest array appropriately */ - for(i=0; i< ngrps; i++) { - if(exps[i] > 124) - goto error; - - exp_1 = exps[i] / 25; - exp_2 = (exps[i] - (exp_1 * 25)) / 5; - exp_3 = exps[i] - (exp_1 * 25) - (exp_2 * 5) ; - - exp_acc += (exp_1 - 2); - - switch(expstr) { - case EXP_D45: - dest[j++] = exp_acc; - dest[j++] = exp_acc; - case EXP_D25: - dest[j++] = exp_acc; - case EXP_D15: - dest[j++] = exp_acc; - } - - exp_acc += (exp_2 - 2); - - switch(expstr) { - case EXP_D45: - dest[j++] = exp_acc; - dest[j++] = exp_acc; - case EXP_D25: - dest[j++] = exp_acc; - case EXP_D15: - dest[j++] = exp_acc; - } - - exp_acc += (exp_3 - 2); - - switch(expstr) { - case EXP_D45: - dest[j++] = exp_acc; - dest[j++] = exp_acc; - case EXP_D25: - dest[j++] = exp_acc; - case EXP_D15: - dest[j++] = exp_acc; - } - } - - return; -error: -#ifdef FAST_ERROR - HANDLE_ERROR (); -#else - if (!error_flag) - fprintf (stderr,"** Invalid exponent - skipping frame **\n"); - error_flag = 1; -#endif -} - diff --git a/src/libac3/imdct.c b/src/libac3/imdct.c index a055f3399..a2e83d423 100644 --- a/src/libac3/imdct.c +++ b/src/libac3/imdct.c @@ -22,9 +22,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include <stdlib.h> #include <stdio.h> @@ -32,31 +30,78 @@ #include "ac3.h" #include "ac3_internal.h" -#include "downmix.h" + +#include "decode.h" #include "imdct.h" -#include "srfft.h" + +void imdct_do_256(float data[],float delay[]); +void imdct_do_512(float data[],float delay[]); + +void imdct_do_256_mlib(float data[],float delay[]); +void imdct_do_512_mlib(float data[],float delay[]); + +typedef struct complex_s +{ + float real; + float imag; +} complex_t; + #define N 512 -/* static complex_t buf[128]; */ -//static complex_t buf[128] __attribute__((aligned(16))); -complex_t buf[128] __attribute__((aligned(16))); -/* Delay buffer for time domain interleaving */ -static float delay[6][256]; -static float delay1[6][256]; +/* 128 point bit-reverse LUT */ +static uint8_t bit_reverse_512[] = { + 0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, + 0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78, + 0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74, + 0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c, + 0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72, + 0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a, + 0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76, + 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e, + 0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71, + 0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79, + 0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75, + 0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d, + 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73, + 0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b, + 0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77, + 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f}; + +static uint8_t bit_reverse_256[] = { + 0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38, + 0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c, + 0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a, + 0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e, + 0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39, + 0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d, + 0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b, + 0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f}; + +static complex_t buf[128]; + +/* Twiddle factor LUT */ +static complex_t *w[7]; +static complex_t w_1[1]; +static complex_t w_2[2]; +static complex_t w_4[4]; +static complex_t w_8[8]; +static complex_t w_16[16]; +static complex_t w_32[32]; +static complex_t w_64[64]; /* Twiddle factors for IMDCT */ -static float xcos1[128] __attribute__((aligned(16))); -static float xsin1[128] __attribute__((aligned(16))); - -/* more twiddle factors for IMDCT */ +static float xcos1[128]; +static float xsin1[128]; static float xcos2[64]; static float xsin2[64]; +/* Delay buffer for time domain interleaving */ +static float delay[6][256]; + /* Windowing function for Modified DCT - Thank you acroread */ -//static float window[] = { -float window[] = { +float imdct_window[] = { 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130, 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443, 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061, @@ -88,574 +133,326 @@ float window[] = { 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993, 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999, 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, - 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 -}; - -//static const int pm128[128] = -const int pm128[128] = -{ - 0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120, - 4, 20, 36, 52, 68, 84, 100, 116, 12, 28, 44, 60, 76, 92, 108, 124, - 2, 18, 34, 50, 66, 82, 98, 114, 10, 42, 74, 106, 26, 58, 90, 122, - 6, 22, 38, 54, 70, 86, 102, 118, 14, 46, 78, 110, 30, 62, 94, 126, - 1, 17, 33, 49, 65, 81, 97, 113, 9, 41, 73, 105, 25, 57, 89, 121, - 5, 21, 37, 53, 69, 85, 101, 117, 13, 29, 45, 61, 77, 93, 109, 125, - 3, 19, 35, 51, 67, 83, 99, 115, 11, 43, 75, 107, 27, 59, 91, 123, - 7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127 -}; - -static const int pm64[64] = -{ - 0, 8, 16, 24, 32, 40, 48, 56, - 4, 20, 36, 52, 12, 28, 44, 60, - 2, 10, 18, 26, 34, 42, 50, 58, - 6, 14, 22, 30, 38, 46, 54, 62, - 1, 9, 17, 25, 33, 41, 49, 57, - 5, 21, 37, 53, 13, 29, 45, 61, - 3, 11, 19, 27, 35, 43, 51, 59, - 7, 23, 39, 55, 15, 31, 47, 63 -}; - - -void imdct_init (void) - { - int i; - float scale = 255.99609372; - - /* Twiddle factors to turn IFFT into IMDCT */ - - for (i=0; i < 128; i++) { - xcos1[i] = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale; - xsin1[i] = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale; - } + 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 }; - // More twiddle factors to turn IFFT into IMDCT */ - for (i=0; i < 64; i++) { - xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale; - xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale; - } -} - -void imdct_do_256 (float data[],float delay[]) +static inline void swap_cmplx(complex_t *a, complex_t *b) { - int i, j, k; - int p, q; + complex_t tmp; - float tmp_a_i; - float tmp_a_r; + tmp = *a; + *a = *b; + *b = tmp; +} - float *data_ptr; - float *delay_ptr; - float *window_ptr; - complex_t *buf1, *buf2; - buf1 = &buf[0]; - buf2 = &buf[64]; +static inline complex_t cmplx_mult(complex_t a, complex_t b) +{ + complex_t ret; -// Pre IFFT complex multiply plus IFFT complex conjugate - for (k=0; k<64; k++) { - /* X1[k] = X[2*k] */ - /* X2[k] = X[2*k+1] */ + ret.real = a.real * b.real - a.imag * b.imag; + ret.imag = a.real * b.imag + a.imag * b.real; - j = pm64[k]; - p = 2 * (128-2*j-1); - q = 2 * (2 * j); + return ret; +} - /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */ - buf1[k].re = data[p] * xcos2[j] - data[q] * xsin2[j]; - buf1[k].im = -1.0f * (data[q] * xcos2[j] + data[p] * xsin2[j]); - /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */ - buf2[k].re = data[p + 1] * xcos2[j] - data[q + 1] * xsin2[j]; - buf2[k].im = -1.0f * ( data[q + 1] * xcos2[j] + data[p + 1] * xsin2[j]); - } +void imdct_init(void) +{ + int i,k; + complex_t angle_step; + complex_t current_angle; - fft_64p(&buf1[0]); - fft_64p(&buf2[0]); - -#ifdef DEBUG - //DEBUG FFT -#if 0 - printf ("Post FFT, buf1\n"); - for (i=0; i < 64; i++) - printf("%d %f %f\n", i, buf_1[i].re, buf_1[i].im); - printf ("Post FFT, buf2\n"); - for (i=0; i < 64; i++) - printf("%d %f %f\n", i, buf_2[i].re, buf_2[i].im); -#endif +#ifdef LIBAC3_MLIB + return; #endif - - // Post IFFT complex multiply - for( i=0; i < 64; i++) { - tmp_a_r = buf1[i].re; - tmp_a_i = -buf1[i].im; - buf1[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); - buf1[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]); - tmp_a_r = buf2[i].re; - tmp_a_i = -buf2[i].im; - buf2[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); - buf2[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]); - } - - data_ptr = data; - delay_ptr = delay; - window_ptr = window; - - /* Window and convert to real valued signal */ - for(i=0; i< 64; i++) { - *data_ptr++ = -buf1[i].im * *window_ptr++ + *delay_ptr++; - *data_ptr++ = buf1[64-i-1].re * *window_ptr++ + *delay_ptr++; - } - - for(i=0; i< 64; i++) { - *data_ptr++ = -buf1[i].re * *window_ptr++ + *delay_ptr++; - *data_ptr++ = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++; - } + /* Twiddle factors to turn IFFT into IMDCT */ + for( i=0; i < 128; i++) { + xcos1[i] = -cos(2.0f * M_PI * (8*i+1)/(8*N)) ; + xsin1[i] = -sin(2.0f * M_PI * (8*i+1)/(8*N)) ; + } - delay_ptr = delay; - - for(i=0; i< 64; i++) { - *delay_ptr++ = -buf2[i].re * *--window_ptr; - *delay_ptr++ = buf2[64-i-1].im * *--window_ptr; - } - - for(i=0; i< 64; i++) { - *delay_ptr++ = buf2[i].im * *--window_ptr; - *delay_ptr++ = -buf2[64-i-1].re * *--window_ptr; + /* More twiddle factors to turn IFFT into IMDCT */ + for( i=0; i < 64; i++) { + xcos2[i] = -cos(2.0f * M_PI * (8*i+1)/(4*N)) ; + xsin2[i] = -sin(2.0f * M_PI * (8*i+1)/(4*N)) ; + } + + /* Canonical twiddle factors for FFT */ + w[0] = w_1; + w[1] = w_2; + w[2] = w_4; + w[3] = w_8; + w[4] = w_16; + w[5] = w_32; + w[6] = w_64; + + for( i = 0; i < 7; i++) { + angle_step.real = cos(-2.0 * M_PI / (1 << (i+1))); + angle_step.imag = sin(-2.0 * M_PI / (1 << (i+1))); + + current_angle.real = 1.0; + current_angle.imag = 0.0; + + for (k = 0; k < 1 << i; k++) { + w[i][k] = current_angle; + current_angle = cmplx_mult(current_angle,angle_step); } + } } - -/** - * - **/ - -void imdct_do_256_nol (float data[], float delay[]) +void +imdct_do_512(float data[],float delay[]) { - int i, j, k; - int p, q; - - float tmp_a_i; - float tmp_a_r; - - float *data_ptr; - float *delay_ptr; - float *window_ptr; - - complex_t *buf1, *buf2; - - buf1 = &buf[0]; - buf2 = &buf[64]; - - /* Pre IFFT complex multiply plus IFFT cmplx conjugate */ - for(k=0; k<64; k++) { - /* X1[k] = X[2*k] */ - /* X2[k] = X[2*k+1] */ - j = pm64[k]; - p = 2 * (128-2*j-1); - q = 2 * (2 * j); - - /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */ - buf1[k].re = data[p] * xcos2[j] - data[q] * xsin2[j]; - buf1[k].im = -1.0f * (data[q] * xcos2[j] + data[p] * xsin2[j]); - /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */ - buf2[k].re = data[p + 1] * xcos2[j] - data[q + 1] * xsin2[j]; - buf2[k].im = -1.0f * ( data[q + 1] * xcos2[j] + data[p + 1] * xsin2[j]); - } - - - fft_64p(&buf1[0]); - fft_64p(&buf2[0]); - -#ifdef DEBUG - //DEBUG FFT -#if 0 - printf("Post FFT, buf1\n"); - for (i=0; i < 64; i++) - printf("%d %f %f\n", i, buf_1[i].re, buf_1[i].im); - printf("Post FFT, buf2\n"); - for (i=0; i < 64; i++) - printf("%d %f %f\n", i, buf_2[i].re, buf_2[i].im); -#endif -#endif - - /* Post IFFT complex multiply */ - for( i=0; i < 64; i++) { - /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ - tmp_a_r = buf1[i].re; - tmp_a_i = -buf1[i].im; - buf1[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); - buf1[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]); - /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */ - tmp_a_r = buf2[i].re; - tmp_a_i = -buf2[i].im; - buf2[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); - buf2[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]); - } - - data_ptr = data; - delay_ptr = delay; - window_ptr = window; - - /* Window and convert to real valued signal, no overlap */ - for(i=0; i< 64; i++) { - *data_ptr++ = -buf1[i].im * *window_ptr++; - *data_ptr++ = buf1[64-i-1].re * *window_ptr++; - } - - for(i=0; i< 64; i++) { - *data_ptr++ = -buf1[i].re * *window_ptr++ + *delay_ptr++; - *data_ptr++ = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++; - } - - delay_ptr = delay; - - for(i=0; i< 64; i++) { - *delay_ptr++ = -buf2[i].re * *--window_ptr; - *delay_ptr++ = buf2[64-i-1].im * *--window_ptr; - } - - for(i=0; i< 64; i++) { - *delay_ptr++ = buf2[i].im * *--window_ptr; - *delay_ptr++ = -buf2[64-i-1].re * *--window_ptr; + int i,k; + int p,q; + int m; + int two_m; + int two_m_plus_one; + + float tmp_a_i; + float tmp_a_r; + float tmp_b_i; + float tmp_b_r; + + float *data_ptr; + float *delay_ptr; + float *window_ptr; + + // + // 512 IMDCT with source and dest data in 'data' + // + + // Pre IFFT complex multiply plus IFFT cmplx conjugate + for( i=0; i < 128; i++) { + /* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */ + buf[i].real = (data[256-2*i-1] * xcos1[i]) - (data[2*i] * xsin1[i]); + buf[i].imag = -1.0 * ((data[2*i] * xcos1[i]) + (data[256-2*i-1] * xsin1[i])); + } + + //Bit reversed shuffling + for(i=0; i<128; i++) { + k = bit_reverse_512[i]; + if (k < i) + swap_cmplx(&buf[i],&buf[k]); + } + + /* FFT Merge */ + for (m=0; m < 7; m++) { + if(m) + two_m = (1 << m); + else + two_m = 1; + + two_m_plus_one = (1 << (m+1)); + + for(k = 0; k < two_m; k++) { + for(i = 0; i < 128; i += two_m_plus_one) { + p = k + i; + q = p + two_m; + tmp_a_r = buf[p].real; + tmp_a_i = buf[p].imag; + tmp_b_r = buf[q].real * w[m][k].real - buf[q].imag * w[m][k].imag; + tmp_b_i = buf[q].imag * w[m][k].real + buf[q].real * w[m][k].imag; + buf[p].real = tmp_a_r + tmp_b_r; + buf[p].imag = tmp_a_i + tmp_b_i; + buf[q].real = tmp_a_r - tmp_b_r; + buf[q].imag = tmp_a_i - tmp_b_i; + } } + } + + /* Post IFFT complex multiply plus IFFT complex conjugate*/ + for( i=0; i < 128; i++) { + /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ + tmp_a_r = buf[i].real; + tmp_a_i = -1.0 * buf[i].imag; + buf[i].real =(tmp_a_r * xcos1[i]) - (tmp_a_i * xsin1[i]); + buf[i].imag =(tmp_a_r * xsin1[i]) + (tmp_a_i * xcos1[i]); + } + + data_ptr = data; + delay_ptr = delay; + window_ptr = imdct_window; + + /* Window and convert to real valued signal */ + for(i=0; i< 64; i++) { + *data_ptr++ = 2.0f * (-buf[64+i].imag * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf[64-i-1].real * *window_ptr++ + *delay_ptr++); + } + + for(i=0; i< 64; i++) { + *data_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf[128-i-1].imag * *window_ptr++ + *delay_ptr++); + } + + /* The trailing edge of the window goes into the delay line */ + delay_ptr = delay; + + for(i=0; i< 64; i++) { + *delay_ptr++ = -buf[64+i].real * *--window_ptr; + *delay_ptr++ = buf[64-i-1].imag * *--window_ptr; + } + + for(i=0; i<64; i++) { + *delay_ptr++ = buf[i].imag * *--window_ptr; + *delay_ptr++ = -buf[128-i-1].real * *--window_ptr; + } } -//FIXME remove - for timing code -///#include <sys/time.h> -//FIXME remove - - -void imdct_do_512 (float data[], float delay[]) +void +imdct_do_256(float data[],float delay[]) { - int i, j; - float tmp_a_r, tmp_a_i; - float *data_ptr; - float *delay_ptr; - float *window_ptr; - -// 512 IMDCT with source and dest data in 'data' -// Pre IFFT complex multiply plus IFFT complex conjugate - - for( i=0; i < 128; i++) { - j = pm128[i]; - //a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]); - //c = data[2*j] * xcos1[j]; - //b = data[256-2*j-1] * xsin1[j]; - //buf1[i].re = a - b + c; - //buf1[i].im = b + c; - buf[i].re = (data[256-2*j-1] * xcos1[j]) - (data[2*j] * xsin1[j]); - buf[i].im = -1.0 * (data[2*j] * xcos1[j] + data[256-2*j-1] * xsin1[j]); - } - - fft_128p (&buf[0]); - -// Post IFFT complex multiply plus IFFT complex conjugate - for (i=0; i < 128; i++) { - tmp_a_r = buf[i].re; - tmp_a_i = buf[i].im; - //a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]); - //b = tmp_a_r * xsin1[j]; - //c = tmp_a_i * xcos1[j]; - //buf[j].re = a - b + c; - //buf[j].im = b + c; - buf[i].re =(tmp_a_r * xcos1[i]) + (tmp_a_i * xsin1[i]); - buf[i].im =(tmp_a_r * xsin1[i]) - (tmp_a_i * xcos1[i]); + int i,k; + int p,q; + int m; + int two_m; + int two_m_plus_one; + + float tmp_a_i; + float tmp_a_r; + float tmp_b_i; + float tmp_b_r; + + float *data_ptr; + float *delay_ptr; + float *window_ptr; + + complex_t *buf_1, *buf_2; + + buf_1 = &buf[0]; + buf_2 = &buf[64]; + + /* Pre IFFT complex multiply plus IFFT cmplx conjugate */ + for(k=0; k<64; k++) { + /* X1[k] = X[2*k] */ + /* X2[k] = X[2*k+1] */ + + p = 2 * (128-2*k-1); + q = 2 * (2 * k); + + /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */ + buf_1[k].real = data[p] * xcos2[k] - data[q] * xsin2[k]; + buf_1[k].imag = -1.0f * (data[q] * xcos2[k] + data[p] * xsin2[k]); + /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */ + buf_2[k].real = data[p + 1] * xcos2[k] - data[q + 1] * xsin2[k]; + buf_2[k].imag = -1.0f * ( data[q + 1] * xcos2[k] + data[p + 1] * xsin2[k]); + } + + //IFFT Bit reversed shuffling + for(i=0; i<64; i++) { + k = bit_reverse_256[i]; + if (k < i) { + swap_cmplx(&buf_1[i],&buf_1[k]); + swap_cmplx(&buf_2[i],&buf_2[k]); } + } - data_ptr = data; - delay_ptr = delay; - window_ptr = window; - -// Window and convert to real valued signal - for (i=0; i< 64; i++) { - *data_ptr++ = -buf[64+i].im * *window_ptr++ + *delay_ptr++; - *data_ptr++ = buf[64-i-1].re * *window_ptr++ + *delay_ptr++; - } + /* FFT Merge */ + for (m=0; m < 6; m++) { + two_m = (1 << m); + two_m_plus_one = (1 << (m+1)); - for(i=0; i< 64; i++) { - *data_ptr++ = -buf[i].re * *window_ptr++ + *delay_ptr++; - *data_ptr++ = buf[128-i-1].im * *window_ptr++ + *delay_ptr++; + //FIXME + if(m) + two_m = (1 << m); + else + two_m = 1; + + for(k = 0; k < two_m; k++) { + for(i = 0; i < 64; i += two_m_plus_one) { + p = k + i; + q = p + two_m; + //Do block 1 + tmp_a_r = buf_1[p].real; + tmp_a_i = buf_1[p].imag; + tmp_b_r = buf_1[q].real * w[m][k].real - buf_1[q].imag * w[m][k].imag; + tmp_b_i = buf_1[q].imag * w[m][k].real + buf_1[q].real * w[m][k].imag; + buf_1[p].real = tmp_a_r + tmp_b_r; + buf_1[p].imag = tmp_a_i + tmp_b_i; + buf_1[q].real = tmp_a_r - tmp_b_r; + buf_1[q].imag = tmp_a_i - tmp_b_i; + + //Do block 2 + tmp_a_r = buf_2[p].real; + tmp_a_i = buf_2[p].imag; + tmp_b_r = buf_2[q].real * w[m][k].real - buf_2[q].imag * w[m][k].imag; + tmp_b_i = buf_2[q].imag * w[m][k].real + buf_2[q].real * w[m][k].imag; + buf_2[p].real = tmp_a_r + tmp_b_r; + buf_2[p].imag = tmp_a_i + tmp_b_i; + buf_2[q].real = tmp_a_r - tmp_b_r; + buf_2[q].imag = tmp_a_i - tmp_b_i; + } } + } + + /* Post IFFT complex multiply */ + for( i=0; i < 64; i++) { + /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ + tmp_a_r = buf_1[i].real; + tmp_a_i = -buf_1[i].imag; + buf_1[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); + buf_1[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]); + /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */ + tmp_a_r = buf_2[i].real; + tmp_a_i = -buf_2[i].imag; + buf_2[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]); + buf_2[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]); + } + + data_ptr = data; + delay_ptr = delay; + window_ptr = imdct_window; + + /* Window and convert to real valued signal */ + for(i=0; i< 64; i++) { + *data_ptr++ = 2.0f * (-buf_1[i].imag * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf_1[64-i-1].real * *window_ptr++ + *delay_ptr++); + } + + for(i=0; i< 64; i++) { + *data_ptr++ = 2.0f * (-buf_1[i].real * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf_1[64-i-1].imag * *window_ptr++ + *delay_ptr++); + } + + delay_ptr = delay; -// The trailing edge of the window goes into the delay line - delay_ptr = delay; - - for(i=0; i< 64; i++) { - *delay_ptr++ = -buf[64+i].re * *--window_ptr; - *delay_ptr++ = buf[64-i-1].im * *--window_ptr; - } + for(i=0; i< 64; i++) { + *delay_ptr++ = -buf_2[i].real * *--window_ptr; + *delay_ptr++ = buf_2[64-i-1].imag * *--window_ptr; + } - for(i=0; i<64; i++) { - *delay_ptr++ = buf[i].im * *--window_ptr; - *delay_ptr++ = -buf[128-i-1].re * *--window_ptr; - } + for(i=0; i< 64; i++) { + *delay_ptr++ = buf_2[i].imag * *--window_ptr; + *delay_ptr++ = -buf_2[64-i-1].real * *--window_ptr; + } } +void +imdct(ac3_state_t *state,audblk_t *audblk, stream_samples_t samples) { + int i; -void imdct_do_512_nol (float data[], float delay[]) -{ - int i, j; - - float tmp_a_i; - float tmp_a_r; - - float *data_ptr; - float *delay_ptr; - float *window_ptr; - - // - // 512 IMDCT with source and dest data in 'data' - // - - // Pre IFFT complex multiply plus IFFT cmplx conjugate - - for( i=0; i < 128; i++) { - /* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) */ - j = pm128[i]; - //a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]); - //c = data[2*j] * xcos1[j]; - //b = data[256-2*j-1] * xsin1[j]; - //buf1[i].re = a - b + c; - - //buf1[i].im = b + c; - buf[i].re = (data[256-2*j-1] * xcos1[j]) - (data[2*j] * xsin1[j]); - buf[i].im = -1.0 * (data[2*j] * xcos1[j] + data[256-2*j-1] * xsin1[j]); - } - - fft_128p (&buf[0]); - - /* Post IFFT complex multiply plus IFFT complex conjugate*/ - for (i=0; i < 128; i++) { - /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ - /* int j1 = i; */ - tmp_a_r = buf[i].re; - tmp_a_i = buf[i].im; - //a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]); - //b = tmp_a_r * xsin1[j]; - //c = tmp_a_i * xcos1[j]; - //buf[j].re = a - b + c; - //buf[j].im = b + c; - buf[i].re =(tmp_a_r * xcos1[i]) + (tmp_a_i * xsin1[i]); - buf[i].im =(tmp_a_r * xsin1[i]) - (tmp_a_i * xcos1[i]); - } - - data_ptr = data; - delay_ptr = delay; - window_ptr = window; - - /* Window and convert to real valued signal, no overlap here*/ - for (i=0; i< 64; i++) { - *data_ptr++ = -buf[64+i].im * *window_ptr++; - *data_ptr++ = buf[64-i-1].re * *window_ptr++; - } - - for(i=0; i< 64; i++) { - *data_ptr++ = -buf[i].re * *window_ptr++; - *data_ptr++ = buf[128-i-1].im * *window_ptr++; - } - - /* The trailing edge of the window goes into the delay line */ - delay_ptr = delay; - - for(i=0; i< 64; i++) { - *delay_ptr++ = -buf[64+i].re * *--window_ptr; - *delay_ptr++ = buf[64-i-1].im * *--window_ptr; - } - - for(i=0; i<64; i++) { - *delay_ptr++ = buf[i].im * *--window_ptr; - *delay_ptr++ = -buf[128-i-1].re * *--window_ptr; - } -} - -void imdct (bsi_t *bsi,audblk_t *audblk, stream_samples_t samples, int16_t *s16_samples, dm_par_t* dm_par) -{ - int i; - int doable = 0; - float *center=NULL, *left, *right, *left_sur, *right_sur; - float *delay_left, *delay_right; - float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl; - float right_tmp, left_tmp; - void (*do_imdct)(float data[], float deley[]); - - // test if dm in frequency is doable - if (!(doable = audblk->blksw[0])) - do_imdct = imdct_do_512; +#ifdef LIBAC3_MLIB + for(i=0; i<state->nfchans;i++) { + if(audblk->blksw[i]) + imdct_do_256_mlib(samples[i],delay[i]); else - do_imdct = imdct_do_256; - - // downmix in the frequency domain if all the channels - // use the same imdct - for (i=0; i < bsi->nfchans; i++) { - if (doable != audblk->blksw[i]) { - do_imdct = NULL; - break; - } - } + imdct_do_512_mlib(samples[i],delay[i]); + } + return; +#endif - if (do_imdct) { - //dowmix first and imdct - switch(bsi->acmod) { - case 7: // 3/2 - downmix_3f_2r_to_2ch (samples[0], dm_par); - break; - case 6: // 2/2 - downmix_2f_2r_to_2ch (samples[0], dm_par); - break; - case 5: // 3/1 - downmix_3f_1r_to_2ch (samples[0], dm_par); - break; - case 4: // 2/1 - downmix_2f_1r_to_2ch (samples[0], dm_par); - break; - case 3: // 3/0 - downmix_3f_0r_to_2ch (samples[0], dm_par); - break; - case 2: - break; - default: // 1/0 - if (bsi->acmod == 1) - center = samples[0]; - else if (bsi->acmod == 0) - center = samples[ac3_config.dual_mono_ch_sel]; - do_imdct(center, delay[0]); // no downmix - - stream_sample_1ch_to_s16 (s16_samples, center); - - return; - //goto done; - break; - } - - do_imdct (samples[0], delay[0]); - do_imdct (samples[1], delay[1]); - stream_sample_2ch_to_s16(s16_samples, samples[0], samples[1]); - - } else { //imdct and then dowmix - // delay and samples should be saved and mixed - //fprintf(stderr, "time domain downmix\n"); - for (i=0; i<bsi->nfchans; i++) { - if (audblk->blksw[i]) - imdct_do_256_nol (samples[i],delay1[i]); - else - imdct_do_512_nol (samples[i],delay1[i]); - } - - // mix the sample, overlap - switch(bsi->acmod) { - case 7: // 3/2 - left = samples[0]; - center = samples[1]; - right = samples[2]; - left_sur = samples[3]; - right_sur = samples[4]; - delay_left = delay[0]; - delay_right = delay[1]; - delay1_left = delay1[0]; - delay1_center = delay1[1]; - delay1_right = delay1[2]; - delay1_sl = delay1[3]; - delay1_sr = delay1[4]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left++ + dm_par->clev * *center + dm_par->slev * *left_sur++; - right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++ + dm_par->slev * *right_sur++; - *s16_samples++ = (int16_t)(left_tmp + *delay_left); - *s16_samples++ = (int16_t)(right_tmp + *delay_right); - *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center + dm_par->slev * *delay1_sl++; - *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++ + dm_par->slev * *delay1_sr++; - } - break; - case 6: // 2/2 - left = samples[0]; - right = samples[1]; - left_sur = samples[2]; - right_sur = samples[3]; - delay_left = delay[0]; - delay_right = delay[1]; - delay1_left = delay1[0]; - delay1_right = delay1[1]; - delay1_sl = delay1[2]; - delay1_sr = delay1[3]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left++ + dm_par->slev * *left_sur++; - right_tmp= dm_par->unit * *right++ + dm_par->slev * *right_sur++; - *s16_samples++ = (int16_t)(left_tmp + *delay_left); - *s16_samples++ = (int16_t)(right_tmp + *delay_right); - *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->slev * *delay1_sl++; - *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->slev * *delay1_sr++; - } - break; - case 5: // 3/1 - left = samples[0]; - center = samples[1]; - right = samples[2]; - right_sur = samples[3]; - delay_left = delay[0]; - delay_right = delay[1]; - delay1_left = delay1[0]; - delay1_center = delay1[1]; - delay1_right = delay1[2]; - delay1_sl = delay1[3]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left++ + dm_par->clev * *center - dm_par->slev * *right_sur; - right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++ + dm_par->slev * *right_sur++; - *s16_samples++ = (int16_t)(left_tmp + *delay_left); - *s16_samples++ = (int16_t)(right_tmp + *delay_right); - *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center + dm_par->slev * *delay1_sl; - *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++ + dm_par->slev * *delay1_sl++; - } - break; - case 4: // 2/1 - left = samples[0]; - right = samples[1]; - right_sur = samples[2]; - delay_left = delay[0]; - delay_right = delay[1]; - delay1_left = delay1[0]; - delay1_right = delay1[1]; - delay1_sl = delay1[2]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left++ - dm_par->slev * *right_sur; - right_tmp= dm_par->unit * *right++ + dm_par->slev * *right_sur++; - *s16_samples++ = (int16_t)(left_tmp + *delay_left); - *s16_samples++ = (int16_t)(right_tmp + *delay_right); - *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->slev * *delay1_sl; - *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->slev * *delay1_sl++; - } - break; - case 3: // 3/0 - left = samples[0]; - center = samples[1]; - right = samples[2]; - delay_left = delay[0]; - delay_right = delay[1]; - delay1_left = delay1[0]; - delay1_center = delay1[1]; - delay1_right = delay1[2]; - - for (i = 0; i < 256; i++) { - left_tmp = dm_par->unit * *left++ + dm_par->clev * *center; - right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++; - *s16_samples++ = (int16_t)(left_tmp + *delay_left); - *s16_samples++ = (int16_t)(right_tmp + *delay_right); - *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center; - *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++; - } - break; - case 2: // copy to output - for (i = 0; i < 256; i++) { - *s16_samples++ = (int16_t)samples[0][i]; - *s16_samples++ = (int16_t)samples[1][i]; - } - break; - } - } + for(i=0; i<state->nfchans;i++) { + if(audblk->blksw[i]) + imdct_do_256(samples[i],delay[i]); + else + imdct_do_512(samples[i],delay[i]); + } + + //XXX We don't bother with the IMDCT for the LFE as it's currently + //unused. + //if (state->lfeon) + // imdct_do_512(coeffs->lfe,samples->channel[5],delay[5]); + // } - diff --git a/src/libac3/imdct.h b/src/libac3/imdct.h index 8a4479375..c6b3325a9 100644 --- a/src/libac3/imdct.h +++ b/src/libac3/imdct.h @@ -22,15 +22,5 @@ * */ -#include "cmplx.h" - +void imdct(ac3_state_t *state,audblk_t *audblk, stream_samples_t samples); void imdct_init(void); - -void imdct (bsi_t *bsi,audblk_t *audblk, stream_samples_t samples, - int16_t *s16_samples, dm_par_t *dm_par); - -void fft_64p (complex_t *); -void imdct_do_512 (float data[],float delay[]); -void imdct_do_512_nol (float data[], float delay[]); -void imdct_do_256 (float data[],float delay[]); - diff --git a/src/libac3/imdct_mlib.c b/src/libac3/imdct_mlib.c new file mode 100644 index 000000000..eca0139ee --- /dev/null +++ b/src/libac3/imdct_mlib.c @@ -0,0 +1,143 @@ +/* + * imdct_mlib.c + * Copyright (C) 2001 Håkan Hjort <d95hjort@dtek.chalmers.se> + * + * This file is part of ac3dec, a free Dolby AC-3 stream decoder. + * + * ac3dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ac3dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "config.h" + +#ifdef LIBAC3_MLIB + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include <mlib_types.h> +#include <mlib_status.h> +#include <mlib_signal.h> + + +extern float imdct_window[]; + +void +imdct_do_512_mlib(float data[], float delay[]) +{ + float *buf_real; + float *buf_imag; + float *data_ptr; + float *delay_ptr; + float *window_ptr; + float tmp[256] __attribute__ ((__aligned__ (16))); + int i; + + memcpy(tmp, data, 256 * sizeof(float)); + if(mlib_SignalIMDCT_F32(tmp) != MLIB_SUCCESS) { + fprintf(stderr, "mediaLib failure\n"); + exit(-1); + } + + buf_real = tmp; + buf_imag = tmp + 128; + data_ptr = data; + delay_ptr = delay; + window_ptr = imdct_window; + + /* Window and convert to real valued signal */ + for(i=0; i< 64; i++) + { + *data_ptr++ = 2.0f * (-buf_imag[64+i] * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf_real[64-i-1] * *window_ptr++ + *delay_ptr++); + } + + for(i=0; i< 64; i++) + { + *data_ptr++ = 2.0f * (-buf_real[i] * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf_imag[128-i-1] * *window_ptr++ + *delay_ptr++); + } + + /* The trailing edge of the window goes into the delay line */ + delay_ptr = delay; + + for(i=0; i< 64; i++) + { + *delay_ptr++ = -buf_real[64+i] * *--window_ptr; + *delay_ptr++ = buf_imag[64-i-1] * *--window_ptr; + } + + for(i=0; i<64; i++) + { + *delay_ptr++ = buf_imag[i] * *--window_ptr; + *delay_ptr++ = -buf_real[128-i-1] * *--window_ptr; + } +} + +void +imdct_do_256_mlib(float data[], float delay[]) +{ + float *buf1_real, *buf1_imag; + float *buf2_real, *buf2_imag; + float *data_ptr; + float *delay_ptr; + float *window_ptr; + float tmp[256] __attribute__ ((__aligned__ (16))); + int i; + + memcpy(tmp, data, 256 * sizeof(float)); + if(mlib_SignalIMDCT_F32(tmp) != MLIB_SUCCESS) { + fprintf(stderr, "mediaLib failure\n"); + exit(-1); + } + + buf1_real = tmp; + buf1_imag = tmp + 64; + buf2_real = tmp + 128; + buf2_imag = tmp + 128 + 64; + data_ptr = data; + delay_ptr = delay; + window_ptr = imdct_window; + + /* Window and convert to real valued signal */ + for(i=0; i< 64; i++) + { + *data_ptr++ = 2.0f * (-buf1_imag[i] * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf1_real[64-i-1] * *window_ptr++ + *delay_ptr++); + } + + for(i=0; i< 64; i++) + { + *data_ptr++ = 2.0f * (-buf1_real[i] * *window_ptr++ + *delay_ptr++); + *data_ptr++ = 2.0f * ( buf1_imag[64-i-1] * *window_ptr++ + *delay_ptr++); + } + + delay_ptr = delay; + + for(i=0; i< 64; i++) + { + *delay_ptr++ = -buf2_real[i] * *--window_ptr; + *delay_ptr++ = buf2_imag[64-i-1] * *--window_ptr; + } + + for(i=0; i< 64; i++) + { + *delay_ptr++ = buf2_imag[i] * *--window_ptr; + *delay_ptr++ = -buf2_real[64-i-1] * *--window_ptr; + } +} + +#endif diff --git a/src/libac3/parse.c b/src/libac3/parse.c index 47ed3b407..0596eaa49 100644 --- a/src/libac3/parse.c +++ b/src/libac3/parse.c @@ -22,463 +22,393 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> +#include <string.h> #include "ac3.h" #include "ac3_internal.h" - #include "bitstream.h" -#include "crc.h" +#include "stats.h" +#include "debug.h" #include "parse.h" +#include "bit_allocate.h" -/* Misc LUT */ -static const uint16_t nfchans[8] = {2,1,2,3,3,4,4,5}; +static const uint8_t nfchans[8] = {2, 1, 2, 3, 3, 4, 4, 5}; -struct frmsize_s -{ - uint16_t bit_rate; - uint16_t frm_size[3]; -}; - -static const struct frmsize_s frmsizecod_tbl[64] = -{ - { 32 ,{64 ,69 ,96 } }, - { 32 ,{64 ,70 ,96 } }, - { 40 ,{80 ,87 ,120 } }, - { 40 ,{80 ,88 ,120 } }, - { 48 ,{96 ,104 ,144 } }, - { 48 ,{96 ,105 ,144 } }, - { 56 ,{112 ,121 ,168 } }, - { 56 ,{112 ,122 ,168 } }, - { 64 ,{128 ,139 ,192 } }, - { 64 ,{128 ,140 ,192 } }, - { 80 ,{160 ,174 ,240 } }, - { 80 ,{160 ,175 ,240 } }, - { 96 ,{192 ,208 ,288 } }, - { 96 ,{192 ,209 ,288 } }, - { 112 ,{224 ,243 ,336 } }, - { 112 ,{224 ,244 ,336 } }, - { 128 ,{256 ,278 ,384 } }, - { 128 ,{256 ,279 ,384 } }, - { 160 ,{320 ,348 ,480 } }, - { 160 ,{320 ,349 ,480 } }, - { 192 ,{384 ,417 ,576 } }, - { 192 ,{384 ,418 ,576 } }, - { 224 ,{448 ,487 ,672 } }, - { 224 ,{448 ,488 ,672 } }, - { 256 ,{512 ,557 ,768 } }, - { 256 ,{512 ,558 ,768 } }, - { 320 ,{640 ,696 ,960 } }, - { 320 ,{640 ,697 ,960 } }, - { 384 ,{768 ,835 ,1152 } }, - { 384 ,{768 ,836 ,1152 } }, - { 448 ,{896 ,975 ,1344 } }, - { 448 ,{896 ,976 ,1344 } }, - { 512 ,{1024 ,1114 ,1536 } }, - { 512 ,{1024 ,1115 ,1536 } }, - { 576 ,{1152 ,1253 ,1728 } }, - { 576 ,{1152 ,1254 ,1728 } }, - { 640 ,{1280 ,1393 ,1920 } }, - { 640 ,{1280 ,1394 ,1920 } } -}; - -/* Parse a syncinfo structure, minus the sync word */ -void parse_syncinfo(syncinfo_t *syncinfo, uint8_t *data) +int parse_syncinfo (uint8_t * buf, int * sample_rate, int * bit_rate) { - // - // We need to read in the entire syncinfo struct (0x0b77 + 24 bits) - // in order to determine how big the frame is - // - - // Get the sampling rate - syncinfo->fscod = (data[2] >> 6) & 0x3; - - if(syncinfo->fscod == 3) { - //invalid sampling rate code -#ifndef FAST_ERROR - error_flag = 1; -#endif - return; - } - else if(syncinfo->fscod == 2) - syncinfo->sampling_rate = 32000; - else if(syncinfo->fscod == 1) - syncinfo->sampling_rate = 44100; - else - syncinfo->sampling_rate = 48000; - - // Get the frame size code - syncinfo->frmsizecod = data[2] & 0x3f; - - // Calculate the frame size and bitrate - syncinfo->frame_size = - frmsizecod_tbl[syncinfo->frmsizecod].frm_size[syncinfo->fscod]; - syncinfo->bit_rate = frmsizecod_tbl[syncinfo->frmsizecod].bit_rate; - + static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, + 128, 160, 192, 224, 256, 320, 384, 448, + 512, 576, 640}; + int frmsizecod; + int bitrate; + + if ((buf[0] != 0x0b) || (buf[1] != 0x77)) // syncword + return 0; + + frmsizecod = buf[4] & 63; + if (frmsizecod >= 38) + return 0; + *bit_rate = bitrate = rate [frmsizecod >> 1]; + + switch (buf[4] & 0xc0) { + case 0: // 48 KHz + *sample_rate = 48000; + return 4 * bitrate; + case 0x40: + *sample_rate = 44100; + return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); + case 0x80: + *sample_rate = 32000; + return 6 * bitrate; + default: + return 0; + } } - -/** - * This routine fills a bsi struct from the AC3 stream - **/ - -void parse_bsi(bsi_t *bsi) +int parse_bsi (ac3_state_t * state, uint8_t * buf) { - /* Check the AC-3 version number */ - bsi->bsid = bitstream_get(5); - - /* Get the audio service provided by the steram */ - bsi->bsmod = bitstream_get(3); - - /* Get the audio coding mode (ie how many channels)*/ - bsi->acmod = bitstream_get(3); - /* Predecode the number of full bandwidth channels as we use this - * number a lot */ - bsi->nfchans = nfchans[bsi->acmod]; - - /* If it is in use, get the centre channel mix level */ - if ((bsi->acmod & 0x1) && (bsi->acmod != 0x1)) - bsi->cmixlev = bitstream_get(2); - - /* If it is in use, get the surround channel mix level */ - if (bsi->acmod & 0x4) - bsi->surmixlev = bitstream_get(2); - - /* Get the dolby surround mode if in 2/0 mode */ - if(bsi->acmod == 0x2) - bsi->dsurmod= bitstream_get(2); - - /* Is the low frequency effects channel on? */ - bsi->lfeon = bitstream_get(1); - - /* Get the dialogue normalization level */ - bsi->dialnorm = bitstream_get(5); + int chaninfo; - /* Does compression gain exist? */ - if ((bsi->compre = bitstream_get(1))) { - /* Get compression gain */ - bsi->compr = bitstream_get(8); - } + state->fscod = buf[4] >> 6; - /* Does language code exist? */ - if ((bsi->langcode = bitstream_get(1))) { - /* Get langauge code */ - bsi->langcod = bitstream_get(8); - } + if (buf[5] >= 0x48) // bsid >= 9 + return 1; - /* Does audio production info exist? */ - if ((bsi->audprodie = bitstream_get(1))) { - /* Get mix level */ - bsi->mixlevel = bitstream_get(5); + state->acmod = buf[6] >> 5; + state->nfchans = nfchans[state->acmod]; - /* Get room type */ - bsi->roomtyp = bitstream_get(2); - } + bitstream_set_ptr (buf + 6); + bitstream_get (3); // skip acmod we already parsed - /* If we're in dual mono mode then get some extra info */ - if (!bsi->acmod) { - /* Get the dialogue normalization level two */ - bsi->dialnorm2 = bitstream_get(5); + if ((state->acmod & 0x1) && (state->acmod != 0x1)) + state->cmixlev = bitstream_get (2); - /* Does compression gain two exist? */ - if ((bsi->compr2e = bitstream_get(1))) { - /* Get compression gain two */ - bsi->compr2 = bitstream_get(8); - } + if (state->acmod & 0x4) + state->surmixlev = bitstream_get (2); - /* Does language code two exist? */ - if ((bsi->langcod2e = bitstream_get(1))) { - /* Get langauge code two */ - bsi->langcod2 = bitstream_get(8); - } - - /* Does audio production info two exist? */ - if ((bsi->audprodi2e = bitstream_get(1))) { - /* Get mix level two */ - bsi->mixlevel2 = bitstream_get(5); - - /* Get room type two */ - bsi->roomtyp2 = bitstream_get(2); - } - } + if (state->acmod == 0x2) + bitstream_get (2); // dsurmod - /* Get the copyright bit */ - bsi->copyrightb = bitstream_get(1); + state->lfeon = bitstream_get (1); - /* Get the original bit */ - bsi->origbs = bitstream_get(1); - - /* Does timecode one exist? */ - if ((bsi->timecod1e = bitstream_get(1))) - bsi->timecod1 = bitstream_get(14); + chaninfo = (state->acmod) ? 0 : 1; + do { + bitstream_get (5); // dialnorm + if (bitstream_get (1)) // compre + bitstream_get (8); // compr + if (bitstream_get (1)) // langcode + bitstream_get (8); // langcod + if (bitstream_get (1)) // audprodie + bitstream_get (7); // mixlevel + roomtyp + } while (chaninfo--); - /* Does timecode two exist? */ - if ((bsi->timecod2e = bitstream_get(1))) - bsi->timecod2 = bitstream_get(14); + bitstream_get (2); // copyrightb + origbs - /* Does addition info exist? */ - if ((bsi->addbsie = bitstream_get(1))) { - uint32_t i; + if (bitstream_get (1)) // timecod1e + bitstream_get (14); // timecod1 + if (bitstream_get (1)) // timecod2e + bitstream_get (14); // timecod2 - /* Get how much info is there */ - bsi->addbsil = bitstream_get(6); + if (bitstream_get (1)) { // addbsie + int addbsil; - /* Get the additional info */ - for(i=0;i<(bsi->addbsil + 1);i++) - bsi->addbsi[i] = bitstream_get(8); - } + addbsil = bitstream_get (6); + do { + bitstream_get (8); // addbsi + } while (addbsil--); + } + stats_print_bsi(state); + return 0; } - -/* More pain inducing parsing */ -void parse_audblk(bsi_t *bsi,audblk_t *audblk) +static int parse_exponents (int expstr, int ngrps, uint8_t exponent, + uint8_t * dest) { - int i,j; - - for (i=0; i < bsi->nfchans; i++) { - /* Is this channel an interleaved 256 + 256 block ? */ - audblk->blksw[i] = bitstream_get(1); + int exps; + int8_t exp_1, exp_2, exp_3; + + while (ngrps--) { + exps = bitstream_get (7); + if (exps >= 125) + return 1; + + exp_1 = exps / 25; + exp_2 = (exps - (exp_1 * 25)) / 5; + exp_3 = exps - (exp_1 * 25) - (exp_2 * 5) ; + + exponent += (exp_1 - 2); + if (exponent > 24) + return 1; + + switch (expstr) { + case EXP_D45: + *(dest++) = exponent; + *(dest++) = exponent; + case EXP_D25: + *(dest++) = exponent; + case EXP_D15: + *(dest++) = exponent; } - for (i=0;i < bsi->nfchans; i++) { - /* Should we dither this channel? */ - audblk->dithflag[i] = bitstream_get(1); + exponent += (exp_2 - 2); + if (exponent > 24) + return 1; + + switch (expstr) { + case EXP_D45: + *(dest++) = exponent; + *(dest++) = exponent; + case EXP_D25: + *(dest++) = exponent; + case EXP_D15: + *(dest++) = exponent; } - /* Does dynamic range control exist? */ - if ((audblk->dynrnge = bitstream_get(1))) { - /* Get dynamic range info */ - audblk->dynrng = bitstream_get(8); + exponent += (exp_3 - 2); + if (exponent > 24) + return 1; + + switch (expstr) { + case EXP_D45: + *(dest++) = exponent; + *(dest++) = exponent; + case EXP_D25: + *(dest++) = exponent; + case EXP_D15: + *(dest++) = exponent; } + } - /* If we're in dual mono mode then get the second channel DR info */ - if (bsi->acmod == 0) { - /* Does dynamic range control two exist? */ - if ((audblk->dynrng2e = bitstream_get(1))) { - /* Get dynamic range info */ - audblk->dynrng2 = bitstream_get(8); - } - } - - /* Does coupling strategy exist? */ - if ((audblk->cplstre = bitstream_get(1))) { - /* Is coupling turned on? */ - if ((audblk->cplinu = bitstream_get(1))) { - for(i=0;i < bsi->nfchans; i++) - audblk->chincpl[i] = bitstream_get(1); - if(bsi->acmod == 0x2) - audblk->phsflginu = bitstream_get(1); - audblk->cplbegf = bitstream_get(4); - audblk->cplendf = bitstream_get(4); - audblk->ncplsubnd = (audblk->cplendf + 2) - audblk->cplbegf + 1; - - /* Calculate the start and end bins of the coupling channel */ - audblk->cplstrtmant = (audblk->cplbegf * 12) + 37 ; - audblk->cplendmant = ((audblk->cplendf + 3) * 12) + 37; - - /* The number of combined subbands is ncplsubnd minus each combined - * band */ - audblk->ncplbnd = audblk->ncplsubnd; - - for(i=1; i< audblk->ncplsubnd; i++) { - audblk->cplbndstrc[i] = bitstream_get(1); - audblk->ncplbnd -= audblk->cplbndstrc[i]; - } - } - } + return 0; +} - if(audblk->cplinu) { - /* Loop through all the channels and get their coupling co-ords */ - for(i=0;i < bsi->nfchans;i++) { - if(!audblk->chincpl[i]) - continue; - - /* Is there new coupling co-ordinate info? */ - if ((audblk->cplcoe[i] = bitstream_get(1))) { - audblk->mstrcplco[i] = bitstream_get(2); - for(j=0;j < audblk->ncplbnd; j++) { - audblk->cplcoexp[i][j] = bitstream_get(4); - audblk->cplcomant[i][j] = bitstream_get(4); - } - } - } +static inline int zero_snr_offsets (ac3_state_t * state, audblk_t * audblk) +{ + int i; + + if ((audblk->csnroffst) || + (audblk->cplinu && audblk->cplba.fsnroffst) || + (state->lfeon && audblk->lfeba.fsnroffst)) + return 0; + for (i = 0; i < state->nfchans; i++) + if (audblk->ba[i].fsnroffst) + return 0; + return 1; +} - /* If we're in dual mono mode, there's going to be some phase info */ - if( (bsi->acmod == 0x2) && audblk->phsflginu && - (audblk->cplcoe[0] || audblk->cplcoe[1])) { - for(j=0;j < audblk->ncplbnd; j++) - audblk->phsflg[j] = bitstream_get(1); +int parse_audblk (ac3_state_t * state, audblk_t * audblk) +{ + int i, chaninfo; + uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc; - } - } + for (i = 0; i < state->nfchans; i++) + audblk->blksw[i] = bitstream_get (1); - /* If we're in dual mono mode, there may be a rematrix strategy */ - if(bsi->acmod == 0x2) { - if ((audblk->rematstr = bitstream_get(1))) { - if (!audblk->cplinu) { - for(i = 0; i < 4; i++) - audblk->rematflg[i] = bitstream_get(1); - } - if((audblk->cplbegf > 2) && audblk->cplinu) { - for(i = 0; i < 4; i++) - audblk->rematflg[i] = bitstream_get(1); - } - if((audblk->cplbegf <= 2) && audblk->cplinu) { - for(i = 0; i < 3; i++) - audblk->rematflg[i] = bitstream_get(1); - } - if((audblk->cplbegf == 0) && audblk->cplinu) - for(i = 0; i < 2; i++) - audblk->rematflg[i] = bitstream_get(1); + for (i = 0; i < state->nfchans; i++) + audblk->dithflag[i] = bitstream_get (1); - } - } + chaninfo = (state->acmod) ? 0 : 1; + do { + if (bitstream_get (1)) // dynrnge + bitstream_get (8); // dynrng + } while (chaninfo--); + if (bitstream_get (1)) { // cplstre + audblk->cplinu = bitstream_get (1); if (audblk->cplinu) { - /* Get the coupling channel exponent strategy */ - audblk->cplexpstr = bitstream_get(2); - audblk->ncplgrps = (audblk->cplendmant - audblk->cplstrtmant) / - (((audblk->cplexpstr-1)>=0)?(3 << (audblk->cplexpstr-1)):(3 >> (-(audblk->cplexpstr-1)))); + for (i = 0; i < state->nfchans; i++) + audblk->chincpl[i] = bitstream_get (1); + if (state->acmod == 0x2) + audblk->phsflginu = bitstream_get (1); + audblk->cplbegf = bitstream_get (4); + audblk->cplendf = bitstream_get (4); + + audblk->cplstrtmant = audblk->cplbegf * 12 + 37; + audblk->cplendmant = audblk->cplendf * 12 + 73; + audblk->ncplsubnd = audblk->cplendf + 3 - audblk->cplbegf; + audblk->ncplbnd = audblk->ncplsubnd; + + for(i = 1; i< audblk->ncplsubnd; i++) { + audblk->cplbndstrc[i] = bitstream_get (1); + audblk->ncplbnd -= audblk->cplbndstrc[i]; + } } - - for(i = 0; i < bsi->nfchans; i++) - audblk->chexpstr[i] = bitstream_get(2); - - /* Get the exponent strategy for lfe channel */ - if(bsi->lfeon) - audblk->lfeexpstr = bitstream_get(1); - - /* Determine the bandwidths of all the fbw channels */ - for(i = 0; i < bsi->nfchans; i++) { - uint16_t grp_size; - - if(audblk->chexpstr[i] != EXP_REUSE) { - if (audblk->cplinu && audblk->chincpl[i]) { - audblk->endmant[i] = audblk->cplstrtmant; - } else { - audblk->chbwcod[i] = bitstream_get(6); - audblk->endmant[i] = ((audblk->chbwcod[i] + 12) * 3) + 37; - } - - /* Calculate the number of exponent groups to fetch */ - grp_size = 3 * (1 << (audblk->chexpstr[i] - 1)); - audblk->nchgrps[i] = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size; + } + + if (audblk->cplinu) { + int j, cplcoe; + + cplcoe = 0; + for (i = 0; i < state->nfchans; i++) + if (audblk->chincpl[i]) + if (bitstream_get (1)) { // cplcoe + cplcoe = 1; + audblk->mstrcplco[i] = bitstream_get (2); + for (j = 0; j < audblk->ncplbnd; j++) { + audblk->cplcoexp[i][j] = bitstream_get (4); + audblk->cplcomant[i][j] = bitstream_get (4); + } } + if ((state->acmod == 0x2) && audblk->phsflginu && cplcoe) + for (j = 0; j < audblk->ncplbnd; j++) + audblk->phsflg[j] = bitstream_get (1); + } + + if ((state->acmod == 0x2) && (bitstream_get (1))) { // rematstr + if ((audblk->cplbegf > 2) || (audblk->cplinu == 0)) + for (i = 0; i < 4; i++) + audblk->rematflg[i] = bitstream_get (1); + else if ((audblk->cplbegf == 0) && audblk->cplinu) + for (i = 0; i < 2; i++) + audblk->rematflg[i] = bitstream_get (1); + else if ((audblk->cplbegf <= 2) && audblk->cplinu) + for(i = 0; i < 3; i++) + audblk->rematflg[i] = bitstream_get (1); + } + + cplexpstr = EXP_REUSE; + lfeexpstr = EXP_REUSE; + if (audblk->cplinu) + cplexpstr = bitstream_get (2); + for (i = 0; i < state->nfchans; i++) + chexpstr[i] = bitstream_get (2); + if (state->lfeon) + lfeexpstr = bitstream_get (1); + + for (i = 0; i < state->nfchans; i++) + if (chexpstr[i] != EXP_REUSE) { + if (audblk->cplinu && audblk->chincpl[i]) + audblk->endmant[i] = audblk->cplstrtmant; + else { + audblk->chbwcod[i] = bitstream_get (6); + audblk->endmant[i] = ((audblk->chbwcod[i] + 12) * 3) + 37; + } } - /* Get the coupling exponents if they exist */ - if(audblk->cplinu && (audblk->cplexpstr != EXP_REUSE)) { - audblk->cplabsexp = bitstream_get(4); - for(i=0;i< audblk->ncplgrps;i++) - audblk->cplexps[i] = bitstream_get(7); + do_bit_alloc = 0; + + if (cplexpstr != EXP_REUSE) { + int cplabsexp, ncplgrps; + + do_bit_alloc = 1; + ncplgrps = ((audblk->cplendmant - audblk->cplstrtmant) / + (3 << (cplexpstr - 1))); + cplabsexp = bitstream_get (4) << 1; + if (parse_exponents (cplexpstr, ncplgrps, cplabsexp, + audblk->cpl_exp + audblk->cplstrtmant)) + return 1; + } + for (i = 0; i < state->nfchans; i++) + if (chexpstr[i] != EXP_REUSE) { + int grp_size, nchgrps; + + do_bit_alloc = 1; + grp_size = 3 * (1 << (chexpstr[i] - 1)); + nchgrps = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size; + audblk->fbw_exp[i][0] = bitstream_get (4); + if (parse_exponents (chexpstr[i], nchgrps, audblk->fbw_exp[i][0], + audblk->fbw_exp[i] + 1)) + return 1; + bitstream_get (2); // gainrng } - - /* Get the fwb channel exponents */ - for(i=0;i < bsi->nfchans; i++) { - if(audblk->chexpstr[i] != EXP_REUSE) { - audblk->exps[i][0] = bitstream_get(4); - for(j=1;j<=audblk->nchgrps[i];j++) - audblk->exps[i][j] = bitstream_get(7); - audblk->gainrng[i] = bitstream_get(2); - } + if (lfeexpstr != EXP_REUSE) { + do_bit_alloc = 1; + audblk->lfe_exp[0] = bitstream_get (4); + if (parse_exponents (lfeexpstr, 2, audblk->lfe_exp[0], + audblk->lfe_exp + 1)) + return 1; + } + + if (bitstream_get (1)) { // baie + do_bit_alloc = 1; + audblk->sdcycod = bitstream_get (2); + audblk->fdcycod = bitstream_get (2); + audblk->sgaincod = bitstream_get (2); + audblk->dbpbcod = bitstream_get (2); + audblk->floorcod = bitstream_get (3); + } + if (bitstream_get (1)) { //snroffste + do_bit_alloc = 1; + audblk->csnroffst = bitstream_get (6); + if (audblk->cplinu) { + audblk->cplba.fsnroffst = bitstream_get (4); + audblk->cplba.fgaincod = bitstream_get (3); } - - /* Get the lfe channel exponents */ - if(bsi->lfeon && (audblk->lfeexpstr != EXP_REUSE)) { - audblk->lfeexps[0] = bitstream_get(4); - audblk->lfeexps[1] = bitstream_get(7); - audblk->lfeexps[2] = bitstream_get(7); + for (i = 0; i < state->nfchans; i++) { + audblk->ba[i].fsnroffst = bitstream_get (4); + audblk->ba[i].fgaincod = bitstream_get (3); } - - /* Get the parametric bit allocation parameters */ - audblk->baie = bitstream_get(1); - - if(audblk->baie) { - audblk->sdcycod = bitstream_get(2); - audblk->fdcycod = bitstream_get(2); - audblk->sgaincod = bitstream_get(2); - audblk->dbpbcod = bitstream_get(2); - audblk->floorcod = bitstream_get(3); + if (state->lfeon) { + audblk->lfeba.fsnroffst = bitstream_get (4); + audblk->lfeba.fgaincod = bitstream_get (3); } - - /* Get the SNR off set info if it exists */ - audblk->snroffste = bitstream_get(1); - - if(audblk->snroffste) { - audblk->csnroffst = bitstream_get(6); - - if(audblk->cplinu) { - audblk->cplfsnroffst = bitstream_get(4); - audblk->cplfgaincod = bitstream_get(3); - } - - for(i = 0;i < bsi->nfchans; i++) { - audblk->fsnroffst[i] = bitstream_get(4); - audblk->fgaincod[i] = bitstream_get(3); - } - if(bsi->lfeon) { - - audblk->lfefsnroffst = bitstream_get(4); - audblk->lfefgaincod = bitstream_get(3); - } + } + if ((audblk->cplinu) && (bitstream_get (1))) { // cplleake + do_bit_alloc = 1; + audblk->cplfleak = bitstream_get (3); + audblk->cplsleak = bitstream_get (3); + } + + if (bitstream_get (1)) { // deltbaie + do_bit_alloc = 1; + if (audblk->cplinu) + audblk->cplba.deltbae = bitstream_get (2); + for (i = 0; i < state->nfchans; i++) + audblk->ba[i].deltbae = bitstream_get (2); + if (audblk->cplinu && (audblk->cplba.deltbae == DELTA_BIT_NEW)) { + audblk->cplba.deltnseg = bitstream_get (3); + for (i = 0; i < audblk->cplba.deltnseg + 1; i++) { + audblk->cplba.deltoffst[i] = bitstream_get (5); + audblk->cplba.deltlen[i] = bitstream_get (4); + audblk->cplba.deltba[i] = bitstream_get (3); + } } - - /* Get coupling leakage info if it exists */ - if(audblk->cplinu) { - audblk->cplleake = bitstream_get(1); - - if(audblk->cplleake) { - audblk->cplfleak = bitstream_get(3); - audblk->cplsleak = bitstream_get(3); + for (i = 0; i < state->nfchans; i++) { + if (audblk->ba[i].deltbae == DELTA_BIT_NEW) { + int j; + audblk->ba[i].deltnseg = bitstream_get (3); + for (j = 0; j < audblk->ba[i].deltnseg + 1; j++) { + audblk->ba[i].deltoffst[j] = bitstream_get (5); + audblk->ba[i].deltlen[j] = bitstream_get (4); + audblk->ba[i].deltba[j] = bitstream_get (3); } + } } - - /* Get the delta bit alloaction info */ - audblk->deltbaie = bitstream_get(1); - - if(audblk->deltbaie) { - if(audblk->cplinu) - audblk->cpldeltbae = bitstream_get(2); - - for(i = 0;i < bsi->nfchans; i++) - audblk->deltbae[i] = bitstream_get(2); - - if (audblk->cplinu && (audblk->cpldeltbae == DELTA_BIT_NEW)) { - audblk->cpldeltnseg = bitstream_get(3); - for(i = 0;i < audblk->cpldeltnseg + 1; i++) { - audblk->cpldeltoffst[i] = bitstream_get(5); - audblk->cpldeltlen[i] = bitstream_get(4); - audblk->cpldeltba[i] = bitstream_get(3); - } - } - - for(i = 0;i < bsi->nfchans; i++) { - if (audblk->deltbae[i] == DELTA_BIT_NEW) { - audblk->deltnseg[i] = bitstream_get(3); - for(j = 0; j < audblk->deltnseg[i] + 1; j++) { - audblk->deltoffst[i][j] = bitstream_get(5); - audblk->deltlen[i][j] = bitstream_get(4); - audblk->deltba[i][j] = bitstream_get(3); - } - } - } + } + + if (do_bit_alloc) { + if (zero_snr_offsets (state, audblk)) { + memset (audblk->cpl_bap, 0, sizeof (audblk->cpl_bap)); + memset (audblk->fbw_bap, 0, sizeof (audblk->fbw_bap)); + memset (audblk->lfe_bap, 0, sizeof (audblk->lfe_bap)); + } else { + if (audblk->cplinu) + bit_allocate (state->fscod, audblk, &audblk->cplba, + audblk->cplstrtmant, audblk->cplendmant, + (audblk->cplfleak << 8) + 768, + (audblk->cplsleak << 8) + 768, + audblk->cpl_exp, audblk->cpl_bap, 0); + for (i = 0; i < state->nfchans; i++) + bit_allocate (state->fscod, audblk, audblk->ba + i, 0, + audblk->endmant[i], 0, 0, + audblk->fbw_exp[i], audblk->fbw_bap[i], 0); + if (state->lfeon) { + audblk->lfeba.deltbae = DELTA_BIT_NONE; + bit_allocate (state->fscod, audblk, &audblk->lfeba, 0, 7, 0, 0, + audblk->lfe_exp, audblk->lfe_bap, 1); + } } + } - /* Check to see if there's any dummy info to get */ - if((audblk->skiple = bitstream_get(1))) { - uint16_t skip_data; - - audblk->skipl = bitstream_get(9); - - for (i = 0; i < audblk->skipl; i++) { - skip_data = bitstream_get(8); - } - } + if (bitstream_get (1)) { // skiple + i = bitstream_get (9); // skipl + while (i--) + bitstream_get (8); + } + stats_print_audblk(state,audblk); + return 0; } diff --git a/src/libac3/parse.h b/src/libac3/parse.h index 6264fea1d..39b5d8a2a 100644 --- a/src/libac3/parse.h +++ b/src/libac3/parse.h @@ -21,6 +21,6 @@ * */ -void parse_syncinfo(syncinfo_t *syncinfo,uint8_t *data); -void parse_audblk(bsi_t *bsi,audblk_t *audblk); -void parse_bsi(bsi_t *bsi); +int parse_syncinfo(uint8_t * buf, int * sample_rate, int * bit_rate); +int parse_audblk(ac3_state_t *state,audblk_t *audblk); +int parse_bsi(ac3_state_t *state, uint8_t * buf); diff --git a/src/libac3/rematrix.c b/src/libac3/rematrix.c index 95ce0117c..7098f0526 100644 --- a/src/libac3/rematrix.c +++ b/src/libac3/rematrix.c @@ -22,74 +22,60 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include "ac3.h" #include "ac3_internal.h" +#include "decode.h" #include "rematrix.h" - struct rematrix_band_s { - uint32_t start; - uint32_t end; -} rematrix_band[] = { - {13, 24}, - {25, 36}, - {37, 60}, - {61, 252} + uint32_t start; + uint32_t end; }; +struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}}; -/** - * - **/ +static inline uint32_t min(uint32_t a,uint32_t b); -inline uint32_t min (uint32_t a, uint32_t b) +static inline uint32_t +min(uint32_t a,uint32_t b) { - return (a < b) ? a : b; + return (a < b ? a : b); } - -/** - * This routine simply does stereo remartixing for the 2 channel - * stereo mode - **/ - -void rematrix (audblk_t *audblk, stream_samples_t samples) +/* This routine simply does stereo rematixing for the 2 channel + * stereo mode */ +void rematrix(audblk_t *audblk, stream_samples_t samples) { - uint32_t num_bands; - uint32_t start; - uint32_t end; - int i,j; - - if (!audblk->cplinu || audblk->cplbegf > 2) - num_bands = 4; - else if (audblk->cplbegf > 0) - num_bands = 3; - else - num_bands = 2; - - for (i=0; i < num_bands; i++) { - if (!audblk->rematflg[i]) - continue; - - start = rematrix_band[i].start; - end = min (rematrix_band[i].end ,12 * audblk->cplbegf + 36); + uint32_t num_bands; + uint32_t start; + uint32_t end; + uint32_t i,j; + float left,right; + + if(!audblk->cplinu || audblk->cplbegf > 2) + num_bands = 4; + else if (audblk->cplbegf > 0) + num_bands = 3; + else + num_bands = 2; + + for(i=0;i < num_bands; i++) { + if(!audblk->rematflg[i]) + continue; + + start = rematrix_band[i].start; + end = min(rematrix_band[i].end ,12 * audblk->cplbegf + 36); - for (j=start;j < end; j++) { - float left,right; - - left = samples[0][j] + samples[1][j]; - right = samples[0][j] - samples[1][j]; - samples[0][j] = left; - samples[1][j] = right; - } + for(j=start;j < end; j++) { + left = samples[0][j] + samples[1][j]; + right = samples[0][j] - samples[1][j]; + samples[0][j] = left; + samples[1][j] = right; } + } } diff --git a/src/libac3/sanity_check.c b/src/libac3/sanity_check.c index ef0af0bd2..199fe6b4c 100644 --- a/src/libac3/sanity_check.c +++ b/src/libac3/sanity_check.c @@ -21,10 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include <stdlib.h> #include <stdio.h> #include "ac3.h" @@ -32,97 +28,90 @@ #include "sanity_check.h" -/** - * - **/ - -void sanity_check_init(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk) +void +sanity_check_init(ac3_state_t * state, audblk_t *audblk) { - syncinfo->magic = AC3_MAGIC_NUMBER; - bsi->magic = AC3_MAGIC_NUMBER; - audblk->magic1 = AC3_MAGIC_NUMBER; - audblk->magic2 = AC3_MAGIC_NUMBER; - audblk->magic3 = AC3_MAGIC_NUMBER; + audblk->magic1 = AC3_MAGIC_NUMBER; + audblk->magic2 = AC3_MAGIC_NUMBER; + audblk->magic3 = AC3_MAGIC_NUMBER; } - -/** - * - **/ - -int sanity_check(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk) +void +sanity_check(ac3_state_t * state, audblk_t *audblk) { int i; - if(syncinfo->magic != AC3_MAGIC_NUMBER) { - fprintf(stderr,"\n** Sanity check failed -- syncinfo magic number **"); - return -1; - } - - if(bsi->magic != AC3_MAGIC_NUMBER) { - fprintf(stderr,"\n** Sanity check failed -- bsi magic number **"); - return -1; - } - - if(audblk->magic1 != AC3_MAGIC_NUMBER) { + if(audblk->magic1 != AC3_MAGIC_NUMBER) + { fprintf(stderr,"\n** Sanity check failed -- audblk magic number 1 **"); - return -1; + error_flag = 1; } - if(audblk->magic2 != AC3_MAGIC_NUMBER) { + if(audblk->magic2 != AC3_MAGIC_NUMBER) + { fprintf(stderr,"\n** Sanity check failed -- audblk magic number 2 **"); - return -1; + error_flag = 1; } - if(audblk->magic3 != AC3_MAGIC_NUMBER) { + if(audblk->magic3 != AC3_MAGIC_NUMBER) + { fprintf(stderr,"\n** Sanity check failed -- audblk magic number 3 **"); - return -1; + error_flag = 1; } - for(i = 0;i < 5 ; i++) { + for(i = 0;i < 5 ; i++) + { if (audblk->fbw_exp[i][255] !=0 || audblk->fbw_exp[i][254] !=0 || - audblk->fbw_exp[i][253] !=0) { + audblk->fbw_exp[i][253] !=0) + { fprintf(stderr,"\n** Sanity check failed -- fbw_exp out of bounds **"); - return -1; + error_flag = 1; } if (audblk->fbw_bap[i][255] !=0 || audblk->fbw_bap[i][254] !=0 || - audblk->fbw_bap[i][253] !=0) { + audblk->fbw_bap[i][253] !=0) + { fprintf(stderr,"\n** Sanity check failed -- fbw_bap out of bounds **"); - return -1; + error_flag = 1; } } if (audblk->cpl_exp[255] !=0 || audblk->cpl_exp[254] !=0 || - audblk->cpl_exp[253] !=0) { + audblk->cpl_exp[253] !=0) + { fprintf(stderr,"\n** Sanity check failed -- cpl_exp out of bounds **"); - return -1; + error_flag = 1; } if (audblk->cpl_bap[255] !=0 || audblk->cpl_bap[254] !=0 || - audblk->cpl_bap[253] !=0) { + audblk->cpl_bap[253] !=0) + { fprintf(stderr,"\n** Sanity check failed -- cpl_bap out of bounds **"); - return -1; + error_flag = 1; } - if (audblk->cpl_flt[255] !=0 || audblk->cpl_flt[254] !=0 || - audblk->cpl_flt[253] !=0) { + if (audblk->cplmant[255] !=0 || audblk->cplmant[254] !=0 || + audblk->cplmant[253] !=0) + { fprintf(stderr,"\n** Sanity check failed -- cpl_mant out of bounds **"); - return -1; + error_flag = 1; } - if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2))) { + if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2))) + { fprintf(stderr,"\n** Sanity check failed -- cpl params inconsistent **"); - return -1; + error_flag = 1; } - for(i=0; i < bsi->nfchans; i++) { - if((audblk->chincpl[i] == 0) && (audblk->chbwcod[i] > 60)) { + for(i=0; i < state->nfchans; i++) + { + if((audblk->chincpl[i] == 0) && (audblk->chbwcod[i] > 60)) + { fprintf(stderr,"\n** Sanity check failed -- chbwcod too big **"); - return -1; + error_flag = 1; } } - return 0; + return; } diff --git a/src/libac3/sanity_check.h b/src/libac3/sanity_check.h index ead9399c9..e098aebce 100644 --- a/src/libac3/sanity_check.h +++ b/src/libac3/sanity_check.h @@ -23,5 +23,5 @@ #define AC3_MAGIC_NUMBER 0xdeadbeef -void sanity_check_init (syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk); -int sanity_check (syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk); +void sanity_check_init(ac3_state_t * state, audblk_t *audblk); +void sanity_check(ac3_state_t * state, audblk_t *audblk); diff --git a/src/libac3/srfft.c b/src/libac3/srfft.c deleted file mode 100644 index 308fc2ccc..000000000 --- a/src/libac3/srfft.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * srfft.c - * - * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000 - * - * 64 and 128 point split radix fft for ac3dec - * - * The algorithm is desribed in the book: - * "Computational Frameworks of the Fast Fourier Transform". - * - * The ideas and the the organization of code borrowed from djbfft written by - * D. J. Bernstein <djb@cr.py.to>. djbff can be found at - * http://cr.yp.to/djbfft.html. - * - * srfft.c is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * srfft.c is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> - -#include "srfft.h" -#include "srfftp.h" - -void fft_8 (complex_t *x); - -void fft_4(complex_t *x) -{ - /* delta_p = 1 here */ - /* x[k] = sum_{i=0..3} x[i] * w^{i*k}, w=e^{-2*pi/4} - */ - - register float yt_r, yt_i, yb_r, yb_i, u_r, u_i, vi_r, vi_i; - - yt_r = x[0].re; - yb_r = yt_r - x[2].re; - yt_r += x[2].re; - - u_r = x[1].re; - vi_i = x[3].re - u_r; - u_r += x[3].re; - - u_i = x[1].im; - vi_r = u_i - x[3].im; - u_i += x[3].im; - - yt_i = yt_r; - yt_i += u_r; - x[0].re = yt_i; - yt_r -= u_r; - x[2].re = yt_r; - yt_i = yb_r; - yt_i += vi_r; - x[1].re = yt_i; - yb_r -= vi_r; - x[3].re = yb_r; - - yt_i = x[0].im; - yb_i = yt_i - x[2].im; - yt_i += x[2].im; - - yt_r = yt_i; - yt_r += u_i; - x[0].im = yt_r; - yt_i -= u_i; - x[2].im = yt_i; - yt_r = yb_i; - yt_r += vi_i; - x[1].im = yt_r; - yb_i -= vi_i; - x[3].im = yb_i; -} - - -void fft_8 (complex_t *x) -{ - /* delta_p = diag{1, sqrt(i)} here */ - /* x[k] = sum_{i=0..7} x[i] * w^{i*k}, w=e^{-2*pi/8} - */ - register float wT1_r, wT1_i, wB1_r, wB1_i, wT2_r, wT2_i, wB2_r, wB2_i; - - wT1_r = x[1].re; - wT1_i = x[1].im; - wB1_r = x[3].re; - wB1_i = x[3].im; - - x[1] = x[2]; - x[2] = x[4]; - x[3] = x[6]; - fft_4(&x[0]); - - - /* x[0] x[4] */ - wT2_r = x[5].re; - wT2_r += x[7].re; - wT2_r += wT1_r; - wT2_r += wB1_r; - wT2_i = wT2_r; - wT2_r += x[0].re; - wT2_i = x[0].re - wT2_i; - x[0].re = wT2_r; - x[4].re = wT2_i; - - wT2_i = x[5].im; - wT2_i += x[7].im; - wT2_i += wT1_i; - wT2_i += wB1_i; - wT2_r = wT2_i; - wT2_r += x[0].im; - wT2_i = x[0].im - wT2_i; - x[0].im = wT2_r; - x[4].im = wT2_i; - - /* x[2] x[6] */ - wT2_r = x[5].im; - wT2_r -= x[7].im; - wT2_r += wT1_i; - wT2_r -= wB1_i; - wT2_i = wT2_r; - wT2_r += x[2].re; - wT2_i = x[2].re - wT2_i; - x[2].re = wT2_r; - x[6].re = wT2_i; - - wT2_i = x[5].re; - wT2_i -= x[7].re; - wT2_i += wT1_r; - wT2_i -= wB1_r; - wT2_r = wT2_i; - wT2_r += x[2].im; - wT2_i = x[2].im - wT2_i; - x[2].im = wT2_i; - x[6].im = wT2_r; - - - /* x[1] x[5] */ - wT2_r = wT1_r; - wT2_r += wB1_i; - wT2_r -= x[5].re; - wT2_r -= x[7].im; - wT2_i = wT1_i; - wT2_i -= wB1_r; - wT2_i -= x[5].im; - wT2_i += x[7].re; - - wB2_r = wT2_r; - wB2_r += wT2_i; - wT2_i -= wT2_r; - wB2_r *= HSQRT2; - wT2_i *= HSQRT2; - wT2_r = wB2_r; - wB2_r += x[1].re; - wT2_r = x[1].re - wT2_r; - - wB2_i = x[5].re; - x[1].re = wB2_r; - x[5].re = wT2_r; - - wT2_r = wT2_i; - wT2_r += x[1].im; - wT2_i = x[1].im - wT2_i; - wB2_r = x[5].im; - x[1].im = wT2_r; - x[5].im = wT2_i; - - /* x[3] x[7] */ - wT1_r -= wB1_i; - wT1_i += wB1_r; - wB1_r = wB2_i - x[7].im; - wB1_i = wB2_r + x[7].re; - wT1_r -= wB1_r; - wT1_i -= wB1_i; - wB1_r = wT1_r + wT1_i; - wB1_r *= HSQRT2; - wT1_i -= wT1_r; - wT1_i *= HSQRT2; - wB2_r = x[3].re; - wB2_i = wB2_r + wT1_i; - wB2_r -= wT1_i; - x[3].re = wB2_i; - x[7].re = wB2_r; - wB2_i = x[3].im; - wB2_r = wB2_i + wB1_r; - wB2_i -= wB1_r; - x[3].im = wB2_i; - x[7].im = wB2_r; -} - - -void fft_asmb(int k, complex_t *x, complex_t *wTB, - const complex_t *d, const complex_t *d_3) -{ - register complex_t *x2k, *x3k, *x4k, *wB; - register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i; - - x2k = x + 2 * k; - x3k = x2k + 2 * k; - x4k = x3k + 2 * k; - wB = wTB + 2 * k; - - TRANSZERO(x[0],x2k[0],x3k[0],x4k[0]); - TRANS(x[1],x2k[1],x3k[1],x4k[1],wTB[1],wB[1],d[1],d_3[1]); - - --k; - for(;;) { - TRANS(x[2],x2k[2],x3k[2],x4k[2],wTB[2],wB[2],d[2],d_3[2]); - TRANS(x[3],x2k[3],x3k[3],x4k[3],wTB[3],wB[3],d[3],d_3[3]); - if (!--k) break; - x += 2; - x2k += 2; - x3k += 2; - x4k += 2; - d += 2; - d_3 += 2; - wTB += 2; - wB += 2; - } - -} - -void fft_asmb16(complex_t *x, complex_t *wTB) -{ - register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i; - int k = 2; - - /* transform x[0], x[8], x[4], x[12] */ - TRANSZERO(x[0],x[4],x[8],x[12]); - - /* transform x[1], x[9], x[5], x[13] */ - TRANS(x[1],x[5],x[9],x[13],wTB[1],wTB[5],delta16[1],delta16_3[1]); - - /* transform x[2], x[10], x[6], x[14] */ - TRANSHALF_16(x[2],x[6],x[10],x[14]); - - /* transform x[3], x[11], x[7], x[15] */ - TRANS(x[3],x[7],x[11],x[15],wTB[3],wTB[7],delta16[3],delta16_3[3]); - -} - - -void fft_64p (complex_t *a) -{ - fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]); - fft_asmb16(&a[0], &a[8]); - - fft_8(&a[16]), fft_8(&a[24]); - fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]); - - fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]); - fft_asmb16(&a[32], &a[40]); - - fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]); - fft_asmb16(&a[48], &a[56]); - - fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]); -} - - -void fft_128p (complex_t *a) -{ - fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]); - fft_asmb16(&a[0], &a[8]); - - fft_8(&a[16]), fft_8(&a[24]); - fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]); - - fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]); - fft_asmb16(&a[32], &a[40]); - - fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]); - fft_asmb16(&a[48], &a[56]); - - fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]); - - fft_8(&a[64]); fft_4(&a[72]); fft_4(&a[76]); - /* fft_16(&a[64]); */ - fft_asmb16(&a[64], &a[72]); - - fft_8(&a[80]); fft_8(&a[88]); - - /* fft_32(&a[64]); */ - fft_asmb(4, &a[64], &a[80],&delta32[0], &delta32_3[0]); - - fft_8(&a[96]); fft_4(&a[104]), fft_4(&a[108]); - /* fft_16(&a[96]); */ - fft_asmb16(&a[96], &a[104]); - - fft_8(&a[112]), fft_8(&a[120]); - /* fft_32(&a[96]); */ - fft_asmb(4, &a[96], &a[112], &delta32[0], &delta32_3[0]); - - /* fft_128(&a[0]); */ - fft_asmb(16, &a[0], &a[64], &delta128[0], &delta128_3[0]); -} diff --git a/src/libac3/srfft.h b/src/libac3/srfft.h deleted file mode 100644 index ca85deda1..000000000 --- a/src/libac3/srfft.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * srfft.h - * - * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000 - * - * 64 and 128 point split radix fft for ac3dec - * - * The algorithm is desribed in the book: - * "Computational Frameworks of the Fast Fourier Transform". - * - * The ideas and the the organization of code borrowed from djbfft written by - * D. J. Bernstein <djb@cr.py.to>. djbff can be found at - * http://cr.yp.to/djbfft.html. - * - * srfft.h is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * srfft.h is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef SRFFT_H__ -#define SRFFT_H__ - -#include "cmplx.h" - -void fft_64p (complex_t *x); -void fft_128p (complex_t *x); - -#endif /* SRFFT_H__ */ diff --git a/src/libac3/srfftp.h b/src/libac3/srfftp.h deleted file mode 100644 index 6f4471530..000000000 --- a/src/libac3/srfftp.h +++ /dev/null @@ -1,305 +0,0 @@ - -/* - * srfftp.h - * - * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000 - * - * 64 and 128 point split radix fft for ac3dec - * - * The algorithm is desribed in the book: - * "Computational Frameworks of the Fast Fourier Transform". - * - * The ideas and the the organization of code borrowed from djbfft written by - * D. J. Bernstein <djb@cr.py.to>. djbff can be found at - * http://cr.yp.to/djbfft.html. - * - * srfftp.h is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * srfftp.h is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef SRFFTP_H__ -#define SRFFTP_H__ - -#include "cmplx.h" - -static complex_t delta16[4] = - { {1.00000000000000, 0.00000000000000}, - {0.92387953251129, -0.38268343236509}, - {0.70710678118655, -0.70710678118655}, - {0.38268343236509, -0.92387953251129}}; - -static complex_t delta16_3[4] = - { {1.00000000000000, 0.00000000000000}, - {0.38268343236509, -0.92387953251129}, - {-0.70710678118655, -0.70710678118655}, - {-0.92387953251129, 0.38268343236509}}; - -static complex_t delta32[8] = - { {1.00000000000000, 0.00000000000000}, - {0.98078528040323, -0.19509032201613}, - {0.92387953251129, -0.38268343236509}, - {0.83146961230255, -0.55557023301960}, - {0.70710678118655, -0.70710678118655}, - {0.55557023301960, -0.83146961230255}, - {0.38268343236509, -0.92387953251129}, - {0.19509032201613, -0.98078528040323}}; - -static complex_t delta32_3[8] = - { {1.00000000000000, 0.00000000000000}, - {0.83146961230255, -0.55557023301960}, - {0.38268343236509, -0.92387953251129}, - {-0.19509032201613, -0.98078528040323}, - {-0.70710678118655, -0.70710678118655}, - {-0.98078528040323, -0.19509032201613}, - {-0.92387953251129, 0.38268343236509}, - {-0.55557023301960, 0.83146961230255}}; - -static complex_t delta64[16] = - { {1.00000000000000, 0.00000000000000}, - {0.99518472667220, -0.09801714032956}, - {0.98078528040323, -0.19509032201613}, - {0.95694033573221, -0.29028467725446}, - {0.92387953251129, -0.38268343236509}, - {0.88192126434836, -0.47139673682600}, - {0.83146961230255, -0.55557023301960}, - {0.77301045336274, -0.63439328416365}, - {0.70710678118655, -0.70710678118655}, - {0.63439328416365, -0.77301045336274}, - {0.55557023301960, -0.83146961230255}, - {0.47139673682600, -0.88192126434835}, - {0.38268343236509, -0.92387953251129}, - {0.29028467725446, -0.95694033573221}, - {0.19509032201613, -0.98078528040323}, - {0.09801714032956, -0.99518472667220}}; - -static complex_t delta64_3[16] = - { {1.00000000000000, 0.00000000000000}, - {0.95694033573221, -0.29028467725446}, - {0.83146961230255, -0.55557023301960}, - {0.63439328416365, -0.77301045336274}, - {0.38268343236509, -0.92387953251129}, - {0.09801714032956, -0.99518472667220}, - {-0.19509032201613, -0.98078528040323}, - {-0.47139673682600, -0.88192126434836}, - {-0.70710678118655, -0.70710678118655}, - {-0.88192126434835, -0.47139673682600}, - {-0.98078528040323, -0.19509032201613}, - {-0.99518472667220, 0.09801714032956}, - {-0.92387953251129, 0.38268343236509}, - {-0.77301045336274, 0.63439328416365}, - {-0.55557023301960, 0.83146961230255}, - {-0.29028467725446, 0.95694033573221}}; - -static complex_t delta128[32] = - { {1.00000000000000, 0.00000000000000}, - {0.99879545620517, -0.04906767432742}, - {0.99518472667220, -0.09801714032956}, - {0.98917650996478, -0.14673047445536}, - {0.98078528040323, -0.19509032201613}, - {0.97003125319454, -0.24298017990326}, - {0.95694033573221, -0.29028467725446}, - {0.94154406518302, -0.33688985339222}, - {0.92387953251129, -0.38268343236509}, - {0.90398929312344, -0.42755509343028}, - {0.88192126434836, -0.47139673682600}, - {0.85772861000027, -0.51410274419322}, - {0.83146961230255, -0.55557023301960}, - {0.80320753148064, -0.59569930449243}, - {0.77301045336274, -0.63439328416365}, - {0.74095112535496, -0.67155895484702}, - {0.70710678118655, -0.70710678118655}, - {0.67155895484702, -0.74095112535496}, - {0.63439328416365, -0.77301045336274}, - {0.59569930449243, -0.80320753148064}, - {0.55557023301960, -0.83146961230255}, - {0.51410274419322, -0.85772861000027}, - {0.47139673682600, -0.88192126434835}, - {0.42755509343028, -0.90398929312344}, - {0.38268343236509, -0.92387953251129}, - {0.33688985339222, -0.94154406518302}, - {0.29028467725446, -0.95694033573221}, - {0.24298017990326, -0.97003125319454}, - {0.19509032201613, -0.98078528040323}, - {0.14673047445536, -0.98917650996478}, - {0.09801714032956, -0.99518472667220}, - {0.04906767432742, -0.99879545620517}}; - -static complex_t delta128_3[32] = - { {1.00000000000000, 0.00000000000000}, - {0.98917650996478, -0.14673047445536}, - {0.95694033573221, -0.29028467725446}, - {0.90398929312344, -0.42755509343028}, - {0.83146961230255, -0.55557023301960}, - {0.74095112535496, -0.67155895484702}, - {0.63439328416365, -0.77301045336274}, - {0.51410274419322, -0.85772861000027}, - {0.38268343236509, -0.92387953251129}, - {0.24298017990326, -0.97003125319454}, - {0.09801714032956, -0.99518472667220}, - {-0.04906767432742, -0.99879545620517}, - {-0.19509032201613, -0.98078528040323}, - {-0.33688985339222, -0.94154406518302}, - {-0.47139673682600, -0.88192126434836}, - {-0.59569930449243, -0.80320753148065}, - {-0.70710678118655, -0.70710678118655}, - {-0.80320753148065, -0.59569930449243}, - {-0.88192126434835, -0.47139673682600}, - {-0.94154406518302, -0.33688985339222}, - {-0.98078528040323, -0.19509032201613}, - {-0.99879545620517, -0.04906767432742}, - {-0.99518472667220, 0.09801714032956}, - {-0.97003125319454, 0.24298017990326}, - {-0.92387953251129, 0.38268343236509}, - {-0.85772861000027, 0.51410274419322}, - {-0.77301045336274, 0.63439328416365}, - {-0.67155895484702, 0.74095112535496}, - {-0.55557023301960, 0.83146961230255}, - {-0.42755509343028, 0.90398929312344}, - {-0.29028467725446, 0.95694033573221}, - {-0.14673047445536, 0.98917650996478}}; - -#define HSQRT2 0.707106781188; - -#define TRANSZERO(A0,A4,A8,A12) { \ - u_r = wTB[0].re; \ - v_i = u_r - wTB[k*2].re; \ - u_r += wTB[k*2].re; \ - u_i = wTB[0].im; \ - v_r = wTB[k*2].im - u_i; \ - u_i += wTB[k*2].im; \ - a_r = A0.re; \ - a_i = A0.im; \ - a1_r = a_r; \ - a1_r += u_r; \ - A0.re = a1_r; \ - a_r -= u_r; \ - A8.re = a_r; \ - a1_i = a_i; \ - a1_i += u_i; \ - A0.im = a1_i; \ - a_i -= u_i; \ - A8.im = a_i; \ - a1_r = A4.re; \ - a1_i = A4.im; \ - a_r = a1_r; \ - a_r -= v_r; \ - A4.re = a_r; \ - a1_r += v_r; \ - A12.re = a1_r; \ - a_i = a1_i; \ - a_i -= v_i; \ - A4.im = a_i; \ - a1_i += v_i; \ - A12.im = a1_i; \ - } - -#define TRANSHALF_16(A2,A6,A10,A14) {\ - u_r = wTB[2].re; \ - a_r = u_r; \ - u_i = wTB[2].im; \ - u_r += u_i; \ - u_i -= a_r; \ - a_r = wTB[6].re; \ - a1_r = a_r; \ - a_i = wTB[6].im; \ - a_r = a_i - a_r; \ - a_i += a1_r; \ - v_i = u_r - a_r; \ - u_r += a_r; \ - v_r = u_i + a_i; \ - u_i -= a_i; \ - v_i *= HSQRT2; \ - v_r *= HSQRT2; \ - u_r *= HSQRT2; \ - u_i *= HSQRT2; \ - a_r = A2.re; \ - a_i = A2.im; \ - a1_r = a_r; \ - a1_r += u_r; \ - A2.re = a1_r; \ - a_r -= u_r; \ - A10.re = a_r; \ - a1_i = a_i; \ - a1_i += u_i; \ - A2.im = a1_i; \ - a_i -= u_i; \ - A10.im = a_i; \ - a1_r = A6.re; \ - a1_i = A6.im; \ - a_r = a1_r; \ - a1_r += v_r; \ - A6.re = a1_r; \ - a_r -= v_r; \ - A14.re = a_r; \ - a_i = a1_i; \ - a1_i -= v_i; \ - A6.im = a1_i; \ - a_i += v_i; \ - A14.im = a_i; \ - } - -#define TRANS(A1,A5,A9,A13,WT,WB,D,D3) { \ - u_r = WT.re; \ - a_r = u_r; \ - a_r *= D.im; \ - u_r *= D.re; \ - a_i = WT.im; \ - a1_i = a_i; \ - a1_i *= D.re; \ - a_i *= D.im; \ - u_r -= a_i; \ - u_i = a_r; \ - u_i += a1_i; \ - a_r = WB.re; \ - a1_r = a_r; \ - a1_r *= D3.re; \ - a_r *= D3.im; \ - a_i = WB.im; \ - a1_i = a_i; \ - a_i *= D3.re; \ - a1_i *= D3.im; \ - a1_r -= a1_i; \ - a_r += a_i; \ - v_i = u_r - a1_r; \ - u_r += a1_r; \ - v_r = a_r - u_i; \ - u_i += a_r; \ - a_r = A1.re; \ - a_i = A1.im; \ - a1_r = a_r; \ - a1_r += u_r; \ - A1.re = a1_r; \ - a_r -= u_r; \ - A9.re = a_r; \ - a1_i = a_i; \ - a1_i += u_i; \ - A1.im = a1_i; \ - a_i -= u_i; \ - A9.im = a_i; \ - a1_r = A5.re; \ - a1_i = A5.im; \ - a_r = a1_r; \ - a1_r -= v_r; \ - A5.re = a1_r; \ - a_r += v_r; \ - A13.re = a_r; \ - a_i = a1_i; \ - a1_i -= v_i; \ - A5.im = a1_i; \ - a_i += v_i; \ - A13.im = a_i; \ - } - -#endif diff --git a/src/libac3/stats.c b/src/libac3/stats.c new file mode 100644 index 000000000..7f73ceb62 --- /dev/null +++ b/src/libac3/stats.c @@ -0,0 +1,107 @@ +/* + * stats.c + * + * Copyright (C) Aaron Holtzman - May 1999 + * + * This file is part of ac3dec, a free Dolby AC-3 stream decoder. + * + * ac3dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ac3dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include "config.h" +#include "ac3.h" +#include "ac3_internal.h" + + +#include "decode.h" +#include "stats.h" +#include "debug.h" + + +struct mixlev_s +{ + float clev; + char *desc; +}; + +static const struct mixlev_s cmixlev_tbl[4] = +{ + {0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"}, + {0.500, "(-6.0 dB)"}, {1.0, "Invalid"} +}; + +static const struct mixlev_s smixlev_tbl[4] = +{ + {0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"}, + { 0.0, "off "}, { 1.0, "Invalid"} +}; + +void stats_print_banner(ac3_state_t * state) +{ + fprintf(stdout,"%d.%d Mode\n",state->nfchans,state->lfeon); +} + +void stats_print_syncinfo(ac3_state_t * state) +{ + dprintf("(syncinfo) "); + + switch (state->fscod) + { + case 2: + dprintf("32 KHz "); + break; + case 1: + dprintf("44.1 KHz "); + break; + case 0: + dprintf("48 KHz "); + break; + default: + dprintf("Invalid sampling rate "); + break; + } +} + +void stats_print_bsi(ac3_state_t * state) +{ + dprintf("(bsi) "); + dprintf(" %d.%d Mode ",state->nfchans,state->lfeon); + if ((state->acmod & 0x1) && (state->acmod != 0x1)) + dprintf(" Centre Mix Level %s ",cmixlev_tbl[state->cmixlev].desc); + if (state->acmod & 0x4) + dprintf(" Sur Mix Level %s ",smixlev_tbl[state->cmixlev].desc); + dprintf("\n"); + +} + +char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "}; + +void stats_print_audblk(ac3_state_t * state,audblk_t *audblk) +{ + uint32_t i; + + dprintf("(audblk) "); + dprintf("%s ",audblk->cplinu ? "cpl on " : "cpl off"); + dprintf("%s ",audblk->phsflginu? "phsflg " : " "); + dprintf("["); + for(i=0;i<state->nfchans;i++) + dprintf("%1d",audblk->blksw[i]); + dprintf("]"); + + dprintf("\n"); +} diff --git a/src/libac3/crc.h b/src/libac3/stats.h index 16489656c..a87911888 100644 --- a/src/libac3/crc.h +++ b/src/libac3/stats.h @@ -1,5 +1,5 @@ /* - * crc.h + * stats.h * * Copyright (C) Aaron Holtzman - May 1999 * @@ -20,8 +20,8 @@ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ - -int crc_validate(void); -void crc_init(void); -void crc_process_byte(uint8_t data); -void crc_process_frame(uint8_t *data,uint32_t num_bytes); + +void stats_print_syncinfo(ac3_state_t * state); +void stats_print_bsi(ac3_state_t * state); +void stats_print_audblk(ac3_state_t * state,audblk_t *audblk); +void stats_print_banner(ac3_state_t * state); diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c index 5d1486f05..b11987299 100644 --- a/src/libac3/xine_decoder.c +++ b/src/libac3/xine_decoder.c @@ -17,13 +17,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.1 2001/04/29 16:40:33 guenter Exp $ + * $Id: xine_decoder.c,v 1.2 2001/05/26 15:07:18 guenter Exp $ * * stuff needed to turn libac3 into a xine decoder plugin */ /* - * FIXME: libac3 uses global variables (that are written) + * FIXME: libac3 uses global variables (that are written to) */ @@ -34,10 +34,23 @@ #include "buffer.h" #include "xine_internal.h" +#define FRAME_SIZE 4096 typedef struct ac3dec_decoder_s { audio_decoder_t audio_decoder; - ac3_config_t ac3c; /* FIXME - global variables, see above */ + + uint32_t pts; + + uint8_t frame_buffer[FRAME_SIZE]; + uint8_t *frame_ptr; + int sync_todo; + int frame_length, frame_todo; + uint16_t syncword; + + ao_functions_t *audio_out; + int output_sampling_rate; + int output_open; + } ac3dec_decoder_t; int ac3dec_can_handle (audio_decoder_t *this_gen, int buf_type) { @@ -49,21 +62,109 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; - ac3_init (&this->ac3c, audio_out); + this->audio_out = audio_out; + ac3_init (); + this->syncword = 0; + this->sync_todo = 6; + this->output_open = 0; } void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - /* ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;*/ - ac3_decode_data (buf->content, buf->content + buf->size, - buf->PTS); + ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; + + uint8_t *current = buf->content; + uint8_t *end = buf->content + buf->size; + ac3_frame_t *ac3_frame; + int sampling_rate; + + uint8_t byte; + + this->pts = buf->PTS; + + while (current != end) { + + while (1) { + byte = *current++; + + if (this->sync_todo>0) { + + /* search and collect syncinfo */ + + if (this->syncword != 0x0b77) { + this->syncword = (this->syncword << 8) | byte; + + if (this->syncword == 0x0b77) { + + this->frame_buffer[0] = 0x0b; + this->frame_buffer[1] = 0x77; + + this->sync_todo = 4; + this->frame_ptr = this->frame_buffer+2; + } + } else { + *this->frame_ptr++ = byte; + this->sync_todo--; + + if (this->sync_todo==0) { + this->frame_length = ac3_frame_length (this->frame_buffer); + this->frame_todo = this->frame_length - 6; + } + + } + } else { + + *this->frame_ptr++ = byte; + this->frame_todo--; + + if (this->frame_todo == 0) + break; + } + + if (current == end) + return ; + } + + /* now, decode this frame */ + + ac3_frame = ac3_decode_frame (this->frame_buffer); + + /* output audio */ + + if (!this->output_open + || (ac3_frame->sampling_rate != this->output_sampling_rate) ) { + + if (this->output_open) + this->audio_out->close (this->audio_out); + + this->output_open = (this->audio_out->open (this->audio_out, 16, + ac3_frame->sampling_rate, + AO_CAP_MODE_STEREO) == 1); + this->output_sampling_rate = ac3_frame->sampling_rate; + } + + if (this->output_open) { + this->audio_out->write_audio_data (this->audio_out, + ac3_frame->audio_data, + 256*6, + this->pts); + this->pts = 0; + } + + /* done with frame, prepare for next one */ + + this->syncword = 0; + this->sync_todo = 6; + + } } void ac3dec_close (audio_decoder_t *this_gen) { - /* ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; */ + ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; - ac3_reset (); + if (this->output_open) + this->audio_out->close (this->audio_out); } static char *ac3dec_get_id(void) { @@ -79,11 +180,6 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t * this = (ac3dec_decoder_t *) malloc (sizeof (ac3dec_decoder_t)); - this->ac3c.flags = 0; - this->ac3c.fill_buffer_callback = NULL; - this->ac3c.num_output_ch = 2; /* FIXME */ - this->ac3c.dual_mono_ch_sel = 0; - this->audio_decoder.interface_version = 1; this->audio_decoder.can_handle = ac3dec_can_handle; this->audio_decoder.init = ac3dec_init; diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c index 95c04e79f..0207425df 100644 --- a/src/libmpeg2/slice.c +++ b/src/libmpeg2/slice.c @@ -1007,12 +1007,13 @@ static inline void slice_intra_DCT (picture_t * picture, int cc, static inline void slice_non_intra_DCT (picture_t * picture, uint8_t * dest, int stride) { - memset (picture->DCTblock, 0, 64 * sizeof (int16_t)); + if (!picture->skip_non_intra_dct) + memset (picture->DCTblock, 0, 64 * sizeof (int16_t)); if (picture->mpeg1) get_mpeg1_non_intra_block (picture); else get_non_intra_block (picture); - if (!picture->skip_non_intra_dct) + if (!picture->skip_non_intra_dct) idct_block_add (picture->DCTblock, dest, stride); } |