summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--liba52/Makefile3
-rw-r--r--liba52/a52.h72
-rw-r--r--liba52/a52_internal.h89
-rw-r--r--liba52/bit_allocate.c25
-rw-r--r--liba52/bitstream.c53
-rw-r--r--liba52/bitstream.h45
-rw-r--r--liba52/downmix.c24
-rw-r--r--liba52/imdct.c1016
-rw-r--r--liba52/imdct_3dnow.h2
-rw-r--r--liba52/liba52_changes.diff2028
-rw-r--r--liba52/mm_accel.h4
-rw-r--r--liba52/parse.c417
-rw-r--r--liba52/tables.h10
-rw-r--r--libmpcodecs/ad_liba52.c23
14 files changed, 1521 insertions, 2290 deletions
diff --git a/liba52/Makefile b/liba52/Makefile
index 9ddd8e6284..9296b32284 100644
--- a/liba52/Makefile
+++ b/liba52/Makefile
@@ -9,12 +9,11 @@ SRCS = crc.c \
bitstream.c \
downmix.c \
imdct.c \
- imdct_mlib.c \
parse.c \
OBJS = $(SRCS:.c=.o)
-CFLAGS = $(MLIB_INC) $(OPTFLAGS) -I..
+CFLAGS = $(OPTFLAGS) -I..
.SUFFIXES: .c .o
diff --git a/liba52/a52.h b/liba52/a52.h
index f87abe9851..5c7a3d8656 100644
--- a/liba52/a52.h
+++ b/liba52/a52.h
@@ -1,6 +1,6 @@
/*
* a52.h
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -34,69 +34,7 @@ typedef float sample_t;
typedef double sample_t;
#endif
-typedef struct a52_ba_s {
- uint16_t fsnroffst; /* fine SNR offset */
- uint16_t fgaincod; /* fast gain */
- uint16_t deltbae; /* delta bit allocation exists */
- int8_t deltba[50]; /* per-band delta bit allocation */
-} a52_ba_t;
-
-typedef struct a52_state_s {
- uint8_t fscod; /* sample rate */
- uint8_t halfrate; /* halfrate factor */
- uint8_t acmod; /* coded channels */
- sample_t clev; /* centre channel mix level */
- sample_t slev; /* surround channels mix level */
- uint8_t lfeon; /* coded lfe channel */
-
- int output; /* type of output */
- sample_t level; /* output level */
- sample_t bias; /* output bias */
-
- int dynrnge; /* apply dynamic range */
- sample_t dynrng; /* dynamic range */
- void * dynrngdata; /* dynamic range callback funtion and data */
- sample_t (* dynrngcall) (sample_t range, void * dynrngdata);
-
- uint16_t cplinu; /* coupling in use */
- uint16_t chincpl[5]; /* channel coupled */
- uint16_t phsflginu; /* phase flags in use (stereo only) */
- uint16_t cplbndstrc[18]; /* coupling band structure */
- uint16_t cplstrtmant; /* coupling channel start mantissa */
- uint16_t cplendmant; /* coupling channel end mantissa */
- sample_t cplco[5][18]; /* coupling coordinates */
-
- /* derived information */
- uint16_t cplstrtbnd; /* coupling start band (for bit allocation) */
- uint16_t ncplbnd; /* number of coupling bands */
-
- uint16_t rematflg[4]; /* stereo rematrixing */
-
- uint16_t endmant[5]; /* channel end mantissa */
-
- uint8_t cpl_exp[256]; /* decoded coupling channel exponents */
- uint8_t fbw_exp[5][256]; /* decoded channel exponents */
- uint8_t lfe_exp[7]; /* decoded lfe channel exponents */
-
- 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 */
- a52_ba_t cplba; /* coupling bit allocation parameters */
- a52_ba_t ba[5]; /* channel bit allocation parameters */
- a52_ba_t lfeba; /* lfe bit allocation parameters */
-
- uint16_t cplfleak; /* coupling fast leak init */
- uint16_t cplsleak; /* coupling slow leak init */
-
- /* derived bit allocation information */
- int8_t fbw_bap[5][256];
- int8_t cpl_bap[256];
- int8_t lfe_bap[7];
-} a52_state_t;
+typedef struct a52_state_s a52_state_t;
#define A52_CHANNEL 0
#define A52_MONO 1
@@ -114,14 +52,16 @@ typedef struct a52_state_s {
#define A52_LFE 16
#define A52_ADJUST_LEVEL 32
-sample_t * a52_init (uint32_t mm_accel);
+a52_state_t * a52_init (uint32_t mm_accel);
+sample_t * a52_samples (a52_state_t * state);
int a52_syncinfo (uint8_t * buf, int * flags,
int * sample_rate, int * bit_rate);
int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
sample_t * level, sample_t bias);
void a52_dynrng (a52_state_t * state,
sample_t (* call) (sample_t, void *), void * data);
-int a52_block (a52_state_t * state, sample_t * samples);
+int a52_block (a52_state_t * state);
+void a52_free (a52_state_t * state);
void* a52_resample_init(uint32_t mm_accel,int flags,int chans);
extern int (* a52_resample) (float * _f, int16_t * s16);
diff --git a/liba52/a52_internal.h b/liba52/a52_internal.h
index 91fc54a300..d420803699 100644
--- a/liba52/a52_internal.h
+++ b/liba52/a52_internal.h
@@ -1,6 +1,6 @@
/*
* a52_internal.h
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -25,6 +25,72 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+typedef struct {
+ uint8_t bai; /* fine SNR offset, fast gain */
+ uint8_t deltbae; /* delta bit allocation exists */
+ int8_t deltba[50]; /* per-band delta bit allocation */
+} ba_t;
+
+typedef struct {
+ uint8_t exp[256]; /* decoded channel exponents */
+ int8_t bap[256]; /* derived channel bit allocation */
+} expbap_t;
+
+struct a52_state_s {
+ uint8_t fscod; /* sample rate */
+ uint8_t halfrate; /* halfrate factor */
+ uint8_t acmod; /* coded channels */
+ uint8_t lfeon; /* coded lfe channel */
+ sample_t clev; /* centre channel mix level */
+ sample_t slev; /* surround channels mix level */
+
+ int output; /* type of output */
+ sample_t level; /* output level */
+ sample_t bias; /* output bias */
+
+ int dynrnge; /* apply dynamic range */
+ sample_t dynrng; /* dynamic range */
+ void * dynrngdata; /* dynamic range callback funtion and data */
+ sample_t (* dynrngcall) (sample_t range, void * dynrngdata);
+
+ uint8_t chincpl; /* channel coupled */
+ uint8_t phsflginu; /* phase flags in use (stereo only) */
+ uint8_t cplstrtmant; /* coupling channel start mantissa */
+ uint8_t cplendmant; /* coupling channel end mantissa */
+ uint32_t cplbndstrc; /* coupling band structure */
+ sample_t cplco[5][18]; /* coupling coordinates */
+
+ /* derived information */
+ uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */
+ uint8_t ncplbnd; /* number of coupling bands */
+
+ uint8_t rematflg; /* stereo rematrixing */
+
+ uint8_t endmant[5]; /* channel end mantissa */
+
+ uint16_t bai; /* bit allocation information */
+
+ uint32_t * buffer_start;
+ uint16_t lfsr_state; /* dither state */
+ uint32_t bits_left;
+ uint32_t current_word;
+
+ uint8_t csnroffst; /* coarse SNR offset */
+ ba_t cplba; /* coupling bit allocation parameters */
+ ba_t ba[5]; /* channel bit allocation parameters */
+ ba_t lfeba; /* lfe bit allocation parameters */
+
+ uint8_t cplfleak; /* coupling fast leak init */
+ uint8_t cplsleak; /* coupling slow leak init */
+
+ expbap_t cpl_expbap;
+ expbap_t fbw_expbap[5];
+ expbap_t lfe_expbap;
+
+ sample_t * samples;
+ int downmixed;
+};
+
#define LEVEL_PLUS6DB 2.0
#define LEVEL_PLUS3DB 1.4142135623730951
#define LEVEL_3DB 0.7071067811865476
@@ -55,21 +121,20 @@
# define REG_BP "ebp"
#endif
-void bit_allocate (a52_state_t * state, a52_ba_t * ba, int bndstart,
+void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap);
+ expbap_t * expbap);
-int downmix_init (int input, int flags, sample_t * level,
+int a52_downmix_init (int input, int flags, sample_t * level,
sample_t clev, sample_t slev);
void downmix_accel_init(uint32_t mm_accel);
-int downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
+int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
sample_t clev, sample_t slev);
-extern void (*downmix) (sample_t * samples, int acmod, int output, sample_t bias,
+extern void (*a52_downmix) (sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev);
-extern void (*upmix) (sample_t * samples, int acmod, int output);
+extern void (*a52_upmix) (sample_t * samples, int acmod, int output);
-void imdct_init (uint32_t mm_accel);
-extern void (* imdct_256) (sample_t * data, sample_t * delay, sample_t bias);
-extern void (* imdct_512) (sample_t * data, sample_t * delay, sample_t bias);
-void imdct_do_256_mlib (sample_t * data, sample_t * delay, sample_t bias);
-void imdct_do_512_mlib (sample_t * data, sample_t * delay, sample_t bias);
+void a52_imdct_init (uint32_t mm_accel);
+void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias);
+extern void (*a52_imdct_512) (sample_t * data, sample_t * delay, sample_t bias);
+void imdct_do_512 (sample_t * data, sample_t * delay, sample_t bias);
diff --git a/liba52/bit_allocate.c b/liba52/bit_allocate.c
index d0dd602156..a5f3b77024 100644
--- a/liba52/bit_allocate.c
+++ b/liba52/bit_allocate.c
@@ -1,6 +1,6 @@
/*
* bit_allocate.c
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -121,9 +121,9 @@ do { \
mask -= floor; \
} while (0)
-void bit_allocate (a52_state_t * state, a52_ba_t * ba, int bndstart,
+void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap)
+ expbap_t * expbap)
{
static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100};
@@ -131,6 +131,8 @@ void bit_allocate (a52_state_t * state, a52_ba_t * ba, int bndstart,
0xa10, 0xa90, 0xb10, 0x1400};
int i, j;
+ uint8_t * exp;
+ int8_t * bap;
int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
int psd, mask;
int8_t * deltba;
@@ -138,21 +140,24 @@ void bit_allocate (a52_state_t * state, a52_ba_t * ba, int bndstart,
int halfrate;
halfrate = state->halfrate;
- fdecay = (63 + 20 * state->fdcycod) >> halfrate;
- fgain = 128 + 128 * ba->fgaincod;
- sdecay = (15 + 2 * state->sdcycod) >> halfrate;
- sgain = slowgain[state->sgaincod];
- dbknee = dbpbtab[state->dbpbcod];
+ fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate; /* fdcycod */
+ fgain = 128 + 128 * (ba->bai & 7); /* fgaincod */
+ sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate; /* sdcycod */
+ sgain = slowgain[(state->bai >> 5) & 3]; /* sgaincod */
+ dbknee = dbpbtab[(state->bai >> 3) & 3]; /* dbpbcod */
hth = hthtab[state->fscod];
/*
* if there is no delta bit allocation, make deltba point to an area
* known to contain zeroes. baptab+156 here.
*/
deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
- floor = floortab[state->floorcod];
- snroffset = 960 - 64 * state->csnroffst - 4 * ba->fsnroffst + floor;
+ floor = floortab[state->bai & 7]; /* floorcod */
+ snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor;
floor >>= 5;
+ exp = expbap->exp;
+ bap = expbap->bap;
+
i = bndstart;
j = start;
if (start == 0) { /* not the coupling channel */
diff --git a/liba52/bitstream.c b/liba52/bitstream.c
index 3a25001c57..6c275109d1 100644
--- a/liba52/bitstream.c
+++ b/liba52/bitstream.c
@@ -1,6 +1,6 @@
/*
* bitstream.c
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -37,34 +37,27 @@
#ifdef ALT_BITSTREAM_READER
int indx=0;
-uint32_t * buffer_start;
-#else
-static uint32_t * buffer_start;
#endif
-uint32_t bits_left;
-uint32_t current_word;
-
-void bitstream_set_ptr (uint8_t * buf)
+void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf)
{
int align;
- align = (int)buf & 3;
- buffer_start = (uint32_t *) (buf - align);
- bits_left = 0;
+ align = (long)buf & 3;
+ state->buffer_start = (uint32_t *) (buf - align);
+ state->bits_left = 0;
#ifdef ALT_BITSTREAM_READER
indx=0;
#endif
- bitstream_get (align * 8);
+ bitstream_get (state, align * 8);
}
-static inline void
-bitstream_fill_current(void)
+static inline void bitstream_fill_current (a52_state_t * state)
{
uint32_t tmp;
- tmp = *(buffer_start++);
- current_word = swab32 (tmp);
+ tmp = *(state->buffer_start++);
+ state->current_word = swab32 (tmp);
}
/*
@@ -76,38 +69,38 @@ bitstream_fill_current(void)
* -ah
*/
-uint32_t
-bitstream_get_bh(uint32_t num_bits)
+uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits)
{
uint32_t result;
- num_bits -= bits_left;
- result = (current_word << (32 - bits_left)) >> (32 - bits_left);
+ num_bits -= state->bits_left;
+ result = ((state->current_word << (32 - state->bits_left)) >>
+ (32 - state->bits_left));
- bitstream_fill_current();
+ bitstream_fill_current (state);
if(num_bits != 0)
- result = (result << num_bits) | (current_word >> (32 - num_bits));
+ result = (result << num_bits) | (state->current_word >> (32 - num_bits));
- bits_left = 32 - num_bits;
+ state->bits_left = 32 - num_bits;
return result;
}
-int32_t
-bitstream_get_bh_2(uint32_t num_bits)
+int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits)
{
int32_t result;
- num_bits -= bits_left;
- result = (((int32_t)current_word) << (32 - bits_left)) >> (32 - bits_left);
+ num_bits -= state->bits_left;
+ result = ((((int32_t)state->current_word) << (32 - state->bits_left)) >>
+ (32 - state->bits_left));
- bitstream_fill_current();
+ bitstream_fill_current(state);
if(num_bits != 0)
- result = (result << num_bits) | (current_word >> (32 - num_bits));
+ result = (result << num_bits) | (state->current_word >> (32 - num_bits));
- bits_left = 32 - num_bits;
+ state->bits_left = 32 - num_bits;
return result;
}
diff --git a/liba52/bitstream.h b/liba52/bitstream.h
index 7e4ff676c8..8576f8b282 100644
--- a/liba52/bitstream.h
+++ b/liba52/bitstream.h
@@ -1,6 +1,6 @@
/*
* bitstream.h
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -77,7 +77,7 @@ static inline uint32_t unaligned32(const void *v) {
# if defined (__i386__)
# define swab32(x) __i386_swab32(x)
- static always_inline const uint32_t __i386_swab32(uint32_t x)
+ static inline const uint32_t __i386_swab32(uint32_t x)
{
__asm__("bswap %0" : "=r" (x) : "0" (x));
return x;
@@ -95,23 +95,17 @@ static inline uint32_t unaligned32(const void *v) {
#endif
#ifdef ALT_BITSTREAM_READER
-extern uint32_t *buffer_start;
extern int indx;
-#else
-extern uint32_t bits_left;
-extern uint32_t current_word;
#endif
-void bitstream_set_ptr (uint8_t * buf);
-uint32_t bitstream_get_bh(uint32_t num_bits);
-int32_t bitstream_get_bh_2(uint32_t num_bits);
-
+void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf);
+uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits);
+int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits);
-static inline uint32_t
-bitstream_get(uint32_t num_bits) // note num_bits is practically a constant due to inlineing
+static inline uint32_t bitstream_get (a52_state_t * state, uint32_t num_bits)
{
#ifdef ALT_BITSTREAM_READER
- uint32_t result= swab32( unaligned32(((uint8_t *)buffer_start)+(indx>>3)) );
+ uint32_t result= swab32( unaligned32(((uint8_t *)state->buffer_start)+(indx>>3)) );
result<<= (indx&0x07);
result>>= 32 - num_bits;
@@ -121,30 +115,29 @@ bitstream_get(uint32_t num_bits) // note num_bits is practically a constant due
#else
uint32_t result;
- if(num_bits < bits_left) {
- result = (current_word << (32 - bits_left)) >> (32 - num_bits);
- bits_left -= num_bits;
+ if (num_bits < state->bits_left) {
+ result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits);
+ state->bits_left -= num_bits;
return result;
}
- return bitstream_get_bh(num_bits);
+ return a52_bitstream_get_bh (state, num_bits);
#endif
}
-static inline void bitstream_skip(int num_bits)
+static inline void bitstream_skip(a52_state_t * state, int num_bits)
{
#ifdef ALT_BITSTREAM_READER
indx+= num_bits;
#else
- bitstream_get(num_bits);
+ bitstream_get(state, num_bits);
#endif
}
-static inline int32_t
-bitstream_get_2(uint32_t num_bits)
+static inline int32_t bitstream_get_2 (a52_state_t * state, uint32_t num_bits)
{
#ifdef ALT_BITSTREAM_READER
- int32_t result= swab32( unaligned32(((uint8_t *)buffer_start)+(indx>>3)) );
+ int32_t result= swab32( unaligned32(((uint8_t *)state->buffer_start)+(indx>>3)) );
result<<= (indx&0x07);
result>>= 32 - num_bits;
@@ -154,12 +147,12 @@ bitstream_get_2(uint32_t num_bits)
#else
int32_t result;
- if(num_bits < bits_left) {
- result = (((int32_t)current_word) << (32 - bits_left)) >> (32 - num_bits);
- bits_left -= num_bits;
+ if (num_bits < state->bits_left) {
+ result = (((int32_t)state->current_word) << (32 - state->bits_left)) >> (32 - num_bits);
+ state->bits_left -= num_bits;
return result;
}
- return bitstream_get_bh_2(num_bits);
+ return a52_bitstream_get_bh_2 (state, num_bits);
#endif
}
diff --git a/liba52/downmix.c b/liba52/downmix.c
index 67eee7a89e..5c61cee475 100644
--- a/liba52/downmix.c
+++ b/liba52/downmix.c
@@ -1,6 +1,6 @@
/*
* downmix.c
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -40,9 +40,9 @@
#define CONVERT(acmod,output) (((output) << 3) + (acmod))
-void (*downmix)(sample_t * samples, int acmod, int output, sample_t bias,
+void (*a52_downmix)(sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev)= NULL;
-void (*upmix)(sample_t * samples, int acmod, int output)= NULL;
+void (*a52_upmix)(sample_t * samples, int acmod, int output)= NULL;
static void downmix_SSE (sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev);
@@ -55,16 +55,16 @@ static void upmix_C (sample_t * samples, int acmod, int output);
void downmix_accel_init(uint32_t mm_accel)
{
- upmix= upmix_C;
- downmix= downmix_C;
+ a52_upmix= upmix_C;
+ a52_downmix= downmix_C;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- if(mm_accel & MM_ACCEL_X86_MMX) upmix= upmix_MMX;
- if(mm_accel & MM_ACCEL_X86_SSE) downmix= downmix_SSE;
- if(mm_accel & MM_ACCEL_X86_3DNOW) downmix= downmix_3dnow;
+ if(mm_accel & MM_ACCEL_X86_MMX) a52_upmix= upmix_MMX;
+ if(mm_accel & MM_ACCEL_X86_SSE) a52_downmix= downmix_SSE;
+ if(mm_accel & MM_ACCEL_X86_3DNOW) a52_downmix= downmix_3dnow;
#endif
}
-int downmix_init (int input, int flags, sample_t * level,
+int a52_downmix_init (int input, int flags, sample_t * level,
sample_t clev, sample_t slev)
{
static uint8_t table[11][8] = {
@@ -183,7 +183,7 @@ int downmix_init (int input, int flags, sample_t * level,
return output;
}
-int downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
+int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
sample_t clev, sample_t slev)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
@@ -478,7 +478,7 @@ static void zero (sample_t * samples)
samples[i] = 0;
}
-static void downmix_C (sample_t * samples, int acmod, int output, sample_t bias,
+void downmix_C (sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
@@ -619,7 +619,7 @@ static void downmix_C (sample_t * samples, int acmod, int output, sample_t bias,
}
}
-static void upmix_C (sample_t * samples, int acmod, int output)
+void upmix_C (sample_t * samples, int acmod, int output)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
diff --git a/liba52/imdct.c b/liba52/imdct.c
index a535823584..4909fc5ce9 100644
--- a/liba52/imdct.c
+++ b/liba52/imdct.c
@@ -1,8 +1,11 @@
/*
* imdct.c
- * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
+ * The ifft algorithms in this file have been largely inspired by Dan
+ * Bernstein's work, djbfft, available at http://cr.yp.to/djbfft.html
+ *
* This file is part of a52dec, a free ATSC A-52 stream decoder.
* See http://liba52.sourceforge.net/ for updates.
*
@@ -35,6 +38,9 @@
#include <math.h>
#include <stdio.h>
+#ifdef LIBA52_DJBFFT
+#include <fftc4.h>
+#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795029
#endif
@@ -45,22 +51,17 @@
#include "mm_accel.h"
#include "mangle.h"
+void (*a52_imdct_512) (sample_t * data, sample_t * delay, sample_t bias);
+
#ifdef RUNTIME_CPUDETECT
#undef HAVE_3DNOWEX
#endif
-#define USE_AC3_C
-
-void (* imdct_256) (sample_t data[], sample_t delay[], sample_t bias);
-void (* imdct_512) (sample_t data[], sample_t delay[], sample_t bias);
-
typedef struct complex_s {
sample_t real;
sample_t imag;
} complex_t;
-static void fft_128p(complex_t *a);
-
static const int pm128[128] attribute_used __attribute__((aligned(16))) =
{
0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120,
@@ -73,7 +74,6 @@ static const int pm128[128] attribute_used __attribute__((aligned(16))) =
7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127
};
-/* 128 point bit-reverse LUT */
static uint8_t attribute_used bit_reverse_512[] = {
0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78,
@@ -92,20 +92,36 @@ static uint8_t attribute_used bit_reverse_512[] = {
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 uint8_t fftorder[] = {
+ 0,128, 64,192, 32,160,224, 96, 16,144, 80,208,240,112, 48,176,
+ 8,136, 72,200, 40,168,232,104,248,120, 56,184, 24,152,216, 88,
+ 4,132, 68,196, 36,164,228,100, 20,148, 84,212,244,116, 52,180,
+ 252,124, 60,188, 28,156,220, 92, 12,140, 76,204,236,108, 44,172,
+ 2,130, 66,194, 34,162,226, 98, 18,146, 82,210,242,114, 50,178,
+ 10,138, 74,202, 42,170,234,106,250,122, 58,186, 26,154,218, 90,
+ 254,126, 62,190, 30,158,222, 94, 14,142, 78,206,238,110, 46,174,
+ 6,134, 70,198, 38,166,230,102,246,118, 54,182, 22,150,214, 86
+};
+
+static complex_t __attribute__((aligned(16))) buf[128];
+
+/* Twiddle factor LUT */
+static complex_t __attribute__((aligned(16))) w_1[1];
+static complex_t __attribute__((aligned(16))) w_2[2];
+static complex_t __attribute__((aligned(16))) w_4[4];
+static complex_t __attribute__((aligned(16))) w_8[8];
+static complex_t __attribute__((aligned(16))) w_16[16];
+static complex_t __attribute__((aligned(16))) w_32[32];
+static complex_t __attribute__((aligned(16))) w_64[64];
+static complex_t __attribute__((aligned(16))) * w[7] = {w_1, w_2, w_4, w_8, w_16, w_32, w_64};
+
+/* Twiddle factors for IMDCT */
+static sample_t __attribute__((aligned(16))) xcos1[128];
+static sample_t __attribute__((aligned(16))) xsin1[128];
#if defined(ARCH_X86) || defined(ARCH_X86_64)
// NOTE: SSE needs 16byte alignment or it will segfault
//
-static complex_t __attribute__((aligned(16))) buf[128];
static float __attribute__((aligned(16))) sseSinCos1c[256];
static float __attribute__((aligned(16))) sseSinCos1d[256];
static float attribute_used __attribute__((aligned(16))) ps111_1[4]={1,1,1,-1};
@@ -119,274 +135,234 @@ static float __attribute__((aligned(16))) sseW6[256];
static float __attribute__((aligned(16))) *sseW[7]=
{NULL /*sseW0*/,sseW1,sseW2,sseW3,sseW4,sseW5,sseW6};
static float __attribute__((aligned(16))) sseWindow[512];
-#else
-static complex_t __attribute__((aligned(16))) buf[128];
#endif
-/* Twiddle factor LUT */
-static complex_t __attribute__((aligned(16))) w_1[1];
-static complex_t __attribute__((aligned(16))) w_2[2];
-static complex_t __attribute__((aligned(16))) w_4[4];
-static complex_t __attribute__((aligned(16))) w_8[8];
-static complex_t __attribute__((aligned(16))) w_16[16];
-static complex_t __attribute__((aligned(16))) w_32[32];
-static complex_t __attribute__((aligned(16))) w_64[64];
-static complex_t __attribute__((aligned(16))) * w[7] = {w_1, w_2, w_4, w_8, w_16, w_32, w_64};
+/* Root values for IFFT */
+static sample_t roots16[3];
+static sample_t roots32[7];
+static sample_t roots64[15];
+static sample_t roots128[31];
/* Twiddle factors for IMDCT */
-static sample_t __attribute__((aligned(16))) xcos1[128];
-static sample_t __attribute__((aligned(16))) xsin1[128];
-static sample_t __attribute__((aligned(16))) xcos2[64];
-static sample_t __attribute__((aligned(16))) xsin2[64];
-
-/* Windowing function for Modified DCT - Thank you acroread */
-sample_t 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,
- 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
- 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
- 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
- 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
- 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
- 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
- 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
- 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
- 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
- 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
- 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
- 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
- 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
- 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
- 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
- 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
- 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
- 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
- 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
- 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
- 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
- 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
- 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
- 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
- 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
- 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
- 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
- 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
- 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 };
-
-
-static inline void swap_cmplx(complex_t *a, complex_t *b)
-{
- complex_t tmp;
+static complex_t pre1[128];
+static complex_t post1[64];
+static complex_t pre2[64];
+static complex_t post2[32];
- tmp = *a;
- *a = *b;
- *b = tmp;
-}
+static sample_t a52_imdct_window[256];
+static void (* ifft128) (complex_t * buf);
+static void (* ifft64) (complex_t * buf);
+static inline void ifft2 (complex_t * buf)
+{
+ double r, i;
+
+ r = buf[0].real;
+ i = buf[0].imag;
+ buf[0].real += buf[1].real;
+ buf[0].imag += buf[1].imag;
+ buf[1].real = r - buf[1].real;
+ buf[1].imag = i - buf[1].imag;
+}
-static inline complex_t cmplx_mult(complex_t a, complex_t b)
+static inline void ifft4 (complex_t * buf)
{
- complex_t ret;
+ double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+
+ tmp1 = buf[0].real + buf[1].real;
+ tmp2 = buf[3].real + buf[2].real;
+ tmp3 = buf[0].imag + buf[1].imag;
+ tmp4 = buf[2].imag + buf[3].imag;
+ tmp5 = buf[0].real - buf[1].real;
+ tmp6 = buf[0].imag - buf[1].imag;
+ tmp7 = buf[2].imag - buf[3].imag;
+ tmp8 = buf[3].real - buf[2].real;
+
+ buf[0].real = tmp1 + tmp2;
+ buf[0].imag = tmp3 + tmp4;
+ buf[2].real = tmp1 - tmp2;
+ buf[2].imag = tmp3 - tmp4;
+ buf[1].real = tmp5 + tmp7;
+ buf[1].imag = tmp6 + tmp8;
+ buf[3].real = tmp5 - tmp7;
+ buf[3].imag = tmp6 - tmp8;
+}
- ret.real = a.real * b.real - a.imag * b.imag;
- ret.imag = a.real * b.imag + a.imag * b.real;
+/* the basic split-radix ifft butterfly */
+
+#define BUTTERFLY(a0,a1,a2,a3,wr,wi) do { \
+ tmp5 = a2.real * wr + a2.imag * wi; \
+ tmp6 = a2.imag * wr - a2.real * wi; \
+ tmp7 = a3.real * wr - a3.imag * wi; \
+ tmp8 = a3.imag * wr + a3.real * wi; \
+ tmp1 = tmp5 + tmp7; \
+ tmp2 = tmp6 + tmp8; \
+ tmp3 = tmp6 - tmp8; \
+ tmp4 = tmp7 - tmp5; \
+ a2.real = a0.real - tmp1; \
+ a2.imag = a0.imag - tmp2; \
+ a3.real = a1.real - tmp3; \
+ a3.imag = a1.imag - tmp4; \
+ a0.real += tmp1; \
+ a0.imag += tmp2; \
+ a1.real += tmp3; \
+ a1.imag += tmp4; \
+} while (0)
+
+/* split-radix ifft butterfly, specialized for wr=1 wi=0 */
+
+#define BUTTERFLY_ZERO(a0,a1,a2,a3) do { \
+ tmp1 = a2.real + a3.real; \
+ tmp2 = a2.imag + a3.imag; \
+ tmp3 = a2.imag - a3.imag; \
+ tmp4 = a3.real - a2.real; \
+ a2.real = a0.real - tmp1; \
+ a2.imag = a0.imag - tmp2; \
+ a3.real = a1.real - tmp3; \
+ a3.imag = a1.imag - tmp4; \
+ a0.real += tmp1; \
+ a0.imag += tmp2; \
+ a1.real += tmp3; \
+ a1.imag += tmp4; \
+} while (0)
+
+/* split-radix ifft butterfly, specialized for wr=wi */
+
+#define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \
+ tmp5 = (a2.real + a2.imag) * w; \
+ tmp6 = (a2.imag - a2.real) * w; \
+ tmp7 = (a3.real - a3.imag) * w; \
+ tmp8 = (a3.imag + a3.real) * w; \
+ tmp1 = tmp5 + tmp7; \
+ tmp2 = tmp6 + tmp8; \
+ tmp3 = tmp6 - tmp8; \
+ tmp4 = tmp7 - tmp5; \
+ a2.real = a0.real - tmp1; \
+ a2.imag = a0.imag - tmp2; \
+ a3.real = a1.real - tmp3; \
+ a3.imag = a1.imag - tmp4; \
+ a0.real += tmp1; \
+ a0.imag += tmp2; \
+ a1.real += tmp3; \
+ a1.imag += tmp4; \
+} while (0)
+
+static inline void ifft8 (complex_t * buf)
+{
+ double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
- return ret;
+ ifft4 (buf);
+ ifft2 (buf + 4);
+ ifft2 (buf + 6);
+ BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]);
+ BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], roots