summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-05-26 15:07:18 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-05-26 15:07:18 +0000
commit2bb1b8f3a4984075743b17fbe1d00b1af9917254 (patch)
tree06aa3a03497e938d80a7146013fef96324ef073c /src
parent65480cd3d11b465f0ede5f6c3d1b9f12e06dc98b (diff)
downloadxine-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')
-rw-r--r--src/libac3/Makefile.am13
-rw-r--r--src/libac3/ac3.h45
-rw-r--r--src/libac3/ac3_internal.h334
-rw-r--r--src/libac3/bit_allocate.c687
-rw-r--r--src/libac3/bit_allocate.h4
-rw-r--r--src/libac3/bitstream.c63
-rw-r--r--src/libac3/bitstream.h52
-rw-r--r--src/libac3/bswap.h60
-rw-r--r--src/libac3/cmplx.h9
-rw-r--r--src/libac3/coeff.c524
-rw-r--r--src/libac3/coeff.h2
-rw-r--r--src/libac3/crc.c100
-rw-r--r--src/libac3/debug.c58
-rw-r--r--src/libac3/debug.h (renamed from src/libac3/exponent.h)21
-rw-r--r--src/libac3/decode.c299
-rw-r--r--src/libac3/dither.c29
-rw-r--r--src/libac3/dither.h8
-rw-r--r--src/libac3/downmix.c450
-rw-r--r--src/libac3/downmix.h17
-rw-r--r--src/libac3/exponent.c138
-rw-r--r--src/libac3/imdct.c903
-rw-r--r--src/libac3/imdct.h12
-rw-r--r--src/libac3/imdct_mlib.c143
-rw-r--r--src/libac3/parse.c734
-rw-r--r--src/libac3/parse.h6
-rw-r--r--src/libac3/rematrix.c86
-rw-r--r--src/libac3/sanity_check.c97
-rw-r--r--src/libac3/sanity_check.h4
-rw-r--r--src/libac3/srfft.c309
-rw-r--r--src/libac3/srfft.h39
-rw-r--r--src/libac3/srfftp.h305
-rw-r--r--src/libac3/stats.c107
-rw-r--r--src/libac3/stats.h (renamed from src/libac3/crc.h)12
-rw-r--r--src/libac3/xine_decoder.c124
-rw-r--r--src/libmpeg2/slice.c5
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);
}