summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2002-08-28 20:27:56 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2002-08-28 20:27:56 +0000
commit6ee05b430232df905b3413bcf20fe2c60da024fd (patch)
treed2ac4921038a5871d2859b17071fd24774b42ee3
parentb5ccc95d14f0937c3096c536165af0e2dbfc10ee (diff)
downloadxine-lib-6ee05b430232df905b3413bcf20fe2c60da024fd.tar.gz
xine-lib-6ee05b430232df905b3413bcf20fe2c60da024fd.tar.bz2
sync to latest liba52 release (0.7.4)
CVS patchset: 2543 CVS date: 2002/08/28 20:27:56
-rw-r--r--ChangeLog1
-rw-r--r--src/liba52/Makefile.am2
-rw-r--r--src/liba52/a52.h79
-rw-r--r--src/liba52/a52_internal.h99
-rw-r--r--src/liba52/bit_allocate.c29
-rw-r--r--src/liba52/bitstream.c60
-rw-r--r--src/liba52/bitstream.h37
-rw-r--r--src/liba52/diff_against_release.patch56
-rw-r--r--src/liba52/downmix.c20
-rw-r--r--src/liba52/imdct.c665
-rw-r--r--src/liba52/imdct_mlib.c136
-rw-r--r--src/liba52/parse.c513
-rw-r--r--src/liba52/tables.h12
-rw-r--r--src/liba52/xine_decoder.c61
14 files changed, 885 insertions, 885 deletions
diff --git a/ChangeLog b/ChangeLog
index f2301685b..004168eb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,7 @@ xine-lib (next version) [someone fill in stability and urgency]
* icecast/shoutcast support
* dvd raw device support
* decode id3v1 tags in mp3 files
+ * updated internal liba52 to version 0.7.4
xine-lib (0.9.13) unstable; urgency=low
diff --git a/src/liba52/Makefile.am b/src/liba52/Makefile.am
index ccd8bd557..2a5375560 100644
--- a/src/liba52/Makefile.am
+++ b/src/liba52/Makefile.am
@@ -9,7 +9,7 @@ libdir = $(XINE_PLUGINDIR)
lib_LTLIBRARIES = xineplug_decode_a52.la
xineplug_decode_a52_la_SOURCES = bitstream.c bit_allocate.c \
- parse.c downmix.c imdct.c imdct_mlib.c \
+ parse.c downmix.c imdct.c \
xine_decoder.c
xineplug_decode_a52_la_LDFLAGS = -avoid-version -module
diff --git a/src/liba52/a52.h b/src/liba52/a52.h
index 6b3cecddd..9db52ccf8 100644
--- a/src/liba52/a52.h
+++ b/src/liba52/a52.h
@@ -1,8 +1,10 @@
/*
* a52.h
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,75 +21,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifndef A52_H
+#define A52_H
+
#ifndef LIBA52_DOUBLE
typedef float sample_t;
#else
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
@@ -105,11 +48,15 @@ typedef struct a52_state_s {
#define A52_LFE 16
#define A52_ADJUST_LEVEL 32
-sample_t * a52_init (uint32_t mm_accel, sample_t **samples_base);
+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);
+
+#endif /* A52_H */
diff --git a/src/liba52/a52_internal.h b/src/liba52/a52_internal.h
index a1b88c229..541d94803 100644
--- a/src/liba52/a52_internal.h
+++ b/src/liba52/a52_internal.h
@@ -1,8 +1,10 @@
/*
* a52_internal.h
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +21,73 @@
* 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;
+ void * samples_base;
+ int downmixed;
+};
+
#define LEVEL_PLUS6DB 2.0
#define LEVEL_PLUS3DB 1.4142135623730951
#define LEVEL_3DB 0.7071067811865476
@@ -35,20 +104,18 @@
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)
-void bit_allocate (a52_state_t * state, a52_ba_t * ba, int bndstart,
- int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap);
+void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
+ int start, int end, int fastleak, int slowleak,
+ 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);
+int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
+ sample_t clev, sample_t slev);
+void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev);
-int downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
- sample_t clev, sample_t slev);
-void downmix (sample_t * samples, int acmod, int output, sample_t bias,
- sample_t clev, sample_t slev);
-void 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_upmix (sample_t * samples, int acmod, int output);
+
+void a52_imdct_init (uint32_t mm_accel);
+void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias);
+void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias);
diff --git a/src/liba52/bit_allocate.c b/src/liba52/bit_allocate.c
index 000e6c0dd..0567b2285 100644
--- a/src/liba52/bit_allocate.c
+++ b/src/liba52/bit_allocate.c
@@ -1,8 +1,10 @@
/*
* bit_allocate.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -119,9 +121,9 @@ do { \
mask -= floor; \
} while (0)
-void bit_allocate (a52_state_t * state, a52_ba_t * ba, int bndstart,
- int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap)
+void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
+ int start, int end, int fastleak, int slowleak,
+ expbap_t * expbap)
{
static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100};
@@ -129,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;
@@ -136,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/src/liba52/bitstream.c b/src/liba52/bitstream.c
index 30caa5ea3..04e8ca6d0 100644
--- a/src/liba52/bitstream.c
+++ b/src/liba52/bitstream.c
@@ -1,8 +1,10 @@
/*
* bitstream.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,28 +31,22 @@
#define BUFFER_SIZE 4096
-static uint32_t * buffer_start;
-
-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;
- bitstream_get (align * 8);
+ align = (long)buf & 3;
+ state->buffer_start = (uint32_t *) (buf - align);
+ state->bits_left = 0;
+ bitstream_get (state, align * 8);
}
-static inline void
-bitstream_fill_current()
+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);
}
/*
@@ -62,38 +58,38 @@ bitstream_fill_current()
* -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));
-
- bits_left = 32 - num_bits;
+ if (num_bits != 0)
+ result = (result << num_bits) | (state->current_word >> (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));
+ if (num_bits != 0)
+ 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/src/liba52/bitstream.h b/src/liba52/bitstream.h
index be15907e9..7d7ea7679 100644
--- a/src/liba52/bitstream.h
+++ b/src/liba52/bitstream.h
@@ -1,8 +1,10 @@
/*
* bitstream.h
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +28,7 @@
#else
-# if defined (__i386__) && defined(__GNUC__)
+# if 0 && defined (__i386__)
# define swab32(x) __i386_swab32(x)
static inline const uint32_t __i386_swab32(uint32_t x)
@@ -44,37 +46,32 @@
# endif
#endif
-extern uint32_t bits_left;
-extern uint32_t current_word;
+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);
-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);
-
-static inline uint32_t
-bitstream_get(uint32_t num_bits)
+static inline uint32_t bitstream_get (a52_state_t * state, 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;
+ 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);
}
-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)
{
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);
}
diff --git a/src/liba52/diff_against_release.patch b/src/liba52/diff_against_release.patch
new file mode 100644
index 000000000..2e1ac44ce
--- /dev/null
+++ b/src/liba52/diff_against_release.patch
@@ -0,0 +1,56 @@
+--- src/liba52/a52_internal.h Sun Jul 28 03:52:06 2002
++++ src/liba52/a52_internal.h Wed Aug 28 19:01:05 2002
+@@ -84,6 +84,7 @@
+ expbap_t lfe_expbap;
+
+ sample_t * samples;
++ void * samples_base;
+ int downmixed;
+ };
+
+--- src/liba52/imdct.c Sun Jul 28 03:52:07 2002
++++ src/liba52/imdct.c Wed Aug 28 18:55:38 2002
+@@ -38,7 +38,7 @@
+
+ #include "a52.h"
+ #include "a52_internal.h"
+-#include "mm_accel.h"
++#include "xineutils.h"
+
+ typedef struct complex_s {
+ sample_t real;
+--- src/liba52/parse.c Sun Jul 28 03:52:07 2002
++++ src/liba52/parse.c Wed Aug 28 19:02:21 2002
+@@ -31,14 +31,7 @@
+ #include "a52_internal.h"
+ #include "bitstream.h"
+ #include "tables.h"
+-
+-#ifdef HAVE_MEMALIGN
+-/* some systems have memalign() but no declaration for it */
+-void * memalign (size_t align, size_t size);
+-#else
+-/* assume malloc alignment is sufficient */
+-#define memalign(align,size) malloc (size)
+-#endif
++#include "xineutils.h"
+
+ typedef struct {
+ sample_t q1[2];
+@@ -60,7 +53,7 @@
+ if (state == NULL)
+ return NULL;
+
+- state->samples = memalign (16, 256 * 12 * sizeof (sample_t));
++ state->samples = xine_xmalloc_aligned (16, 256 * 12 * sizeof (sample_t), &state->samples_base);
+ if (state->samples == NULL) {
+ free (state);
+ return NULL;
+@@ -896,6 +889,6 @@
+
+ void a52_free (a52_state_t * state)
+ {
+- free (state->samples);
++ free (state->samples_base);
+ free (state);
+ }
diff --git a/src/liba52/downmix.c b/src/liba52/downmix.c
index 6feeab433..b9ac1fdea 100644
--- a/src/liba52/downmix.c
+++ b/src/liba52/downmix.c
@@ -1,8 +1,10 @@
/*
* downmix.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,16 +23,16 @@
#include "config.h"
-#include <inttypes.h>
#include <string.h>
+#include <inttypes.h>
#include "a52.h"
#include "a52_internal.h"
#define CONVERT(acmod,output) (((output) << 3) + (acmod))
-int downmix_init (int input, int flags, sample_t * level,
- sample_t clev, sample_t slev)
+int a52_downmix_init (int input, int flags, sample_t * level,
+ sample_t clev, sample_t slev)
{
static uint8_t table[11][8] = {
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
@@ -149,8 +151,8 @@ 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,
- sample_t clev, sample_t slev)
+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)) {
@@ -445,8 +447,8 @@ static void zero (sample_t * samples)
samples[i] = 0;
}
-void downmix (sample_t * samples, int acmod, int output, sample_t bias,
- sample_t clev, sample_t slev)
+void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
+ sample_t clev, sample_t slev)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
@@ -586,7 +588,7 @@ void downmix (sample_t * samples, int acmod, int output, sample_t bias,
}
}
-void upmix (sample_t * samples, int acmod, int output)
+void a52_upmix (sample_t * samples, int acmod, int output)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
diff --git a/src/liba52/imdct.c b/src/liba52/imdct.c
index cf4236555..648c95ede 100644
--- a/src/liba52/imdct.c
+++ b/src/liba52/imdct.c
@@ -1,8 +1,13 @@
/*
* imdct.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,383 +26,407 @@
#include "config.h"
-#include <inttypes.h>
#include <math.h>
-
-#include "xineutils.h"
+#include <stdio.h>
+#ifdef LIBA52_DJBFFT
+#include <fftc4.h>
+#endif
+#ifndef M_PI
+#define M_PI 3.1415926535897932384626433832795029
+#endif
+#include <inttypes.h>
#include "a52.h"
#include "a52_internal.h"
-
-void (* imdct_256) (sample_t data[], sample_t delay[], sample_t bias);
-void (* imdct_512) (sample_t data[], sample_t delay[], sample_t bias);
+#include "xineutils.h"
typedef struct complex_s {
sample_t real;
sample_t imag;
} complex_t;
-
-/* 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_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];
-static complex_t * w[7] = {w_1, w_2, w_4, w_8, w_16, w_32, w_64};
+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
+};
+
+/* 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 xcos1[128];
-static sample_t xsin1[128];
-static sample_t xcos2[64];
-static sample_t 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)
+static complex_t pre1[128];
+static complex_t post1[64];
+static complex_t pre2[64];
+static complex_t post2[32];
+
+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)
{
- complex_t tmp;
+ 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;
+}
- tmp = *a;
- *a = *b;
- *b = tmp;
+static inline void ifft4 (complex_t * buf)
+{
+ 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;
}
+/* 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;
+ 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], roots16[1]);
+}
-static inline complex_t cmplx_mult(complex_t a, complex_t b)
+static void ifft_pass (complex_t * buf, sample_t * weight, int n)
{
- complex_t ret;
+ complex_t * buf1;
+ complex_t * buf2;
+ complex_t * buf3;
+ double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+ int i;
+
+ buf++;
+ buf1 = buf + n;
+ buf2 = buf + 2 * n;
+ buf3 = buf + 3 * n;
+
+ BUTTERFLY_ZERO (buf[-1], buf1[-1], buf2[-1], buf3[-1]);
+
+ i = n - 1;
+
+ do {
+ BUTTERFLY (buf[0], buf1[0], buf2[0], buf3[0], weight[n], weight[2*i]);
+ buf++;
+ buf1++;
+ buf2++;
+ buf3++;
+ weight++;
+ } while (--i);
+}
- ret.real = a.real * b.real - a.imag * b.imag;
- ret.imag = a.real * b.imag + a.imag * b.real;
+static void ifft16 (complex_t * buf)
+{
+ ifft8 (buf);
+ ifft4 (buf + 8);
+ ifft4 (buf + 12);
+ ifft_pass (buf, roots16 - 4, 4);
+}
- return ret;
+static void ifft32 (complex_t * buf)
+{
+ ifft16 (buf);
+ ifft8 (buf + 16);
+ ifft8 (buf + 24);
+ ifft_pass (buf, roots32 - 8, 8);
}
-void
-imdct_do_512(sample_t data[],sample_t delay[], sample_t bias)
+static void ifft64_c (complex_t * buf)
{
- int i,k;
- int p,q;
- int m;
- int two_m;
- int two_m_plus_one;
-
- sample_t tmp_a_i;
- sample_t tmp_a_r;
- sample_t tmp_b_i;
- sample_t tmp_b_r;
-
- sample_t *data_ptr;
- sample_t *delay_ptr;
- sample_t *window_ptr;
-
- /* 512 IMDCT with source and dest data in 'data' */
+ ifft32 (buf);
+ ifft16 (buf + 32);
+ ifft16 (buf + 48);
+ ifft_pass (buf, roots64 - 16, 16);
+}
+
+static void ifft128_c (complex_t * buf)
+{
+ ifft32 (buf);
+ ifft16 (buf + 32);
+ ifft16 (buf + 48);
+ ifft_pass (buf, roots64 - 16, 16);
+
+ ifft32 (buf + 64);
+ ifft32 (buf + 96);
+ ifft_pass (buf, roots128 - 32, 32);
+}
+
+void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias)
+{
+ int i, k;
+ sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2;
+ const sample_t * window = a52_imdct_window;
+ complex_t buf[128];
- /* 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]));
- }
+ for (i = 0; i < 128; i++) {
+ k = fftorder[i];
+ t_r = pre1[i].real;
+ t_i = pre1[i].imag;
- /* Bit reversed shuffling */
- for(i=0; i<128; i++) {
- k = bit_reverse_512[i];
- if (k < i)
- swap_cmplx(&buf[i],&buf[k]);
+ buf[i].real = t_i * data[255-k] + t_r * data[k];
+ buf[i].imag = t_r * data[255-k] - t_i * data[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;
- }
- }
- }
+ ifft128 (buf);
- /* Post IFFT complex multiply plus IFFT complex conjugate*/
- for( i=0; i < 128; i++) {
+ /* Post IFFT complex multiply plus IFFT complex conjugate*/
+ /* Window and convert to real valued signal */
+ for (i = 0; i < 64; 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]);
+ t_r = post1[i].real;
+ t_i = post1[i].imag;
+
+ a_r = t_r * buf[i].real + t_i * buf[i].imag;
+ a_i = t_i * buf[i].real - t_r * buf[i].imag;
+ b_r = t_i * buf[127-i].real + t_r * buf[127-i].imag;
+ b_i = t_r * buf[127-i].real - t_i * buf[127-i].imag;
+
+ w_1 = window[2*i];
+ w_2 = window[255-2*i];
+ data[2*i] = delay[2*i] * w_2 - a_r * w_1 + bias;
+ data[255-2*i] = delay[2*i] * w_1 + a_r * w_2 + bias;
+ delay[2*i] = a_i;
+
+ w_1 = window[2*i+1];
+ w_2 = window[254-2*i];
+ data[2*i+1] = delay[2*i+1] * w_2 + b_r * w_1 + bias;
+ data[254-2*i] = delay[2*i+1] * w_1 - b_r * w_2 + bias;
+ delay[2*i+1] = b_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++ = -buf[64+i].imag * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf[64-i-1].real * *window_ptr++ + *delay_ptr++ + bias;
- }
+void a52_imdct_256(sample_t * data, sample_t * delay, sample_t bias)
+{
+ int i, k;
+ sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2;
+ const sample_t * window = a52_imdct_window;
+ complex_t buf1[64], buf2[64];
- for(i=0; i< 64; i++) {
- *data_ptr++ = -buf[i].real * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf[128-i-1].imag * *window_ptr++ + *delay_ptr++ + bias;
- }
+ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+ for (i = 0; i < 64; i++) {
+ k = fftorder[i];
+ t_r = pre2[i].real;
+ t_i = pre2[i].imag;
- /* The trailing edge of the window goes into the delay line */
- delay_ptr = delay;
+ buf1[i].real = t_i * data[254-k] + t_r * data[k];
+ buf1[i].imag = t_r * data[254-k] - t_i * data[k];
- for(i=0; i< 64; i++) {
- *delay_ptr++ = -buf[64+i].real * *--window_ptr;
- *delay_ptr++ = buf[64-i-1].imag * *--window_ptr;
+ buf2[i].real = t_i * data[255-k] + t_r * data[k+1];
+ buf2[i].imag = t_r * data[255-k] - t_i * data[k+1];
}
- for(i=0; i<64; i++) {
- *delay_ptr++ = buf[i].imag * *--window_ptr;
- *delay_ptr++ = -buf[128-i-1].real * *--window_ptr;
+ ifft64 (buf1);
+ ifft64 (buf2);
+
+ /* Post IFFT complex multiply */
+ /* Window and convert to real valued signal */
+ for (i = 0; i < 32; i++) {
+ /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
+ t_r = post2[i].real;
+ t_i = post2[i].imag;
+
+ a_r = t_r * buf1[i].real + t_i * buf1[i].imag;
+ a_i = t_i * buf1[i].real - t_r * buf1[i].imag;
+ b_r = t_i * buf1[63-i].real + t_r * buf1[63-i].imag;
+ b_i = t_r * buf1[63-i].real - t_i * buf1[63-i].imag;
+
+ c_r = t_r * buf2[i].real + t_i * buf2[i].imag;
+ c_i = t_i * buf2[i].real - t_r * buf2[i].imag;
+ d_r = t_i * buf2[63-i].real + t_r * buf2[63-i].imag;
+ d_i = t_r * buf2[63-i].real - t_i * buf2[63-i].imag;
+
+ w_1 = window[2*i];
+ w_2 = window[255-2*i];
+ data[2*i] = delay[2*i] * w_2 - a_r * w_1 + bias;
+ data[255-2*i] = delay[2*i] * w_1 + a_r * w_2 + bias;
+ delay[2*i] = c_i;
+
+ w_1 = window[128+2*i];
+ w_2 = window[127-2*i];
+ data[128+2*i] = delay[127-2*i] * w_2 + a_i * w_1 + bias;
+ data[127-2*i] = delay[127-2*i] * w_1 - a_i * w_2 + bias;
+ delay[127-2*i] = c_r;
+
+ w_1 = window[2*i+1];
+ w_2 = window[254-2*i];
+ data[2*i+1] = delay[2*i+1] * w_2 - b_i * w_1 + bias;
+ data[254-2*i] = delay[2*i+1] * w_1 + b_i * w_2 + bias;
+ delay[2*i+1] = d_r;
+
+ w_1 = window[129+2*i];
+ w_2 = window[126-2*i];
+ data[129+2*i] = delay[126-2*i] * w_2 + b_r * w_1 + bias;
+ data[126-2*i] = delay[126-2*i] * w_1 - b_r * w_2 + bias;
+ delay[126-2*i] = d_i;
}
}
-void
-imdct_do_256(sample_t data[],sample_t delay[],sample_t bias)
+static double besselI0 (double x)
{
- int i,k;
- int p,q;
- int m;
- int two_m;
- int two_m_plus_one;
-
- sample_t tmp_a_i;
- sample_t tmp_a_r;
- sample_t tmp_b_i;
- sample_t tmp_b_r;
+ double bessel = 1;
+ int i = 100;
- sample_t *data_ptr;
- sample_t *delay_ptr;
- sample_t *window_ptr;
+ do
+ bessel = bessel * x / (i * i) + 1;
+ while (--i);
+ return bessel;
+}
- complex_t *buf_1, *buf_2;
+void a52_imdct_init (uint32_t mm_accel)
+{
+ int i, k;
+ double sum;
+
+ /* compute imdct window - kaiser-bessel derived window, alpha = 5.0 */
+ sum = 0;
+ for (i = 0; i < 256; i++) {
+ sum += besselI0 (i * (256 - i) * (5 * M_PI / 256) * (5 * M_PI / 256));
+ a52_imdct_window[i] = sum;
+ }
+ sum++;
+ for (i = 0; i < 256; i++)
+ a52_imdct_window[i] = sqrt (a52_imdct_window[i] / sum);
- buf_1 = &buf[0];
- buf_2 = &buf[64];
+ for (i = 0; i < 3; i++)
+ roots16[i] = cos ((M_PI / 8) * (i + 1));
- /* 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]);
- }
+ for (i = 0; i < 7; i++)
+ roots32[i] = cos ((M_PI / 16) * (i + 1));
- /* 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]);
- }
- }
+ for (i = 0; i < 15; i++)
+ roots64[i] = cos ((M_PI / 32) * (i + 1));
- /* FFT Merge */
- for (m=0; m < 6; m++) {
- two_m = (1 << m);
- two_m_plus_one = (1 << (m+1));
-
- /* 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;
- }
- }
- }
+ for (i = 0; i < 31; i++)
+ roots128[i] = cos ((M_PI / 64) * (i + 1));
- /* 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]);
+ for (i = 0; i < 64; i++) {
+ k = fftorder[i] / 2 + 64;
+ pre1[i].real = cos ((M_PI / 256) * (k - 0.25));
+ pre1[i].imag = sin ((M_PI / 256) * (k - 0.25));
}
-
- 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++ = -buf_1[i].imag * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf_1[64-i-1].real * *window_ptr++ + *delay_ptr++ + bias;
+ for (i = 64; i < 128; i++) {
+ k = fftorder[i] / 2 + 64;
+ pre1[i].real = -cos ((M_PI / 256) * (k - 0.25));
+ pre1[i].imag = -sin ((M_PI / 256) * (k - 0.25));
}
- for(i=0; i< 64; i++) {
- *data_ptr++ = -buf_1[i].real * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf_1[64-i-1].imag * *window_ptr++ + *delay_ptr++ + bias;
+ for (i = 0; i < 64; i++) {
+ post1[i].real = cos ((M_PI / 256) * (i + 0.5));
+ post1[i].imag = sin ((M_PI / 256) * (i + 0.5));
}
-
- delay_ptr = delay;
- 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++) {
+ k = fftorder[i] / 4;
+ pre2[i].real = cos ((M_PI / 128) * (k - 0.25));
+ pre2[i].imag = sin ((M_PI / 128) * (k - 0.25));
}
- for(i=0; i< 64; i++) {
- *delay_ptr++ = buf_2[i].imag * *--window_ptr;
- *delay_ptr++ = -buf_2[64-i-1].real * *--window_ptr;
+ for (i = 0; i < 32; i++) {
+ post2[i].real = cos ((M_PI / 128) * (i + 0.5));
+ post2[i].imag = sin ((M_PI / 128) * (i + 0.5));
}
-}
-void imdct_init (uint32_t mm_accel)
-{
-#ifdef LIBA52_MLIB
- if (mm_accel & MM_ACCEL_MLIB) {
- imdct_512 = imdct_do_512_mlib;
- imdct_256 = imdct_do_256_mlib;
+#ifdef LIBA52_DJBFFT
+ if (mm_accel & MM_ACCEL_DJBFFT) {
+ fprintf (stderr, "Using djbfft for IMDCT transform\n");
+ ifft128 = (void (*) (complex_t *)) fftc4_un128;
+ ifft64 = (void (*) (complex_t *)) fftc4_un64;
} else
#endif
{
- int i, j, k;
-
- /* Twiddle factors to turn IFFT into IMDCT */
- for (i = 0; i < 128; i++) {
- xcos1[i] = -cos ((M_PI / 2048) * (8 * i + 1));
- xsin1[i] = -sin ((M_PI / 2048) * (8 * i + 1));
- }
-
- /* More twiddle factors to turn IFFT into IMDCT */
- for (i = 0; i < 64; i++) {
- xcos2[i] = -cos ((M_PI / 1024) * (8 * i + 1));
- xsin2[i] = -sin ((M_PI / 1024) * (8 * i + 1));
- }
-
- for (i = 0; i < 7; i++) {
- j = 1 << i;
- for (k = 0; k < j; k++) {
- w[i][k].real = cos (-M_PI * k / j);
- w[i][k].imag = sin (-M_PI * k / j);
- }
- }
- imdct_512 = imdct_do_512;
- imdct_256 = imdct_do_256;
+ fprintf (stderr, "No accelerated IMDCT transform found\n");
+ ifft128 = ifft128_c;
+ ifft64 = ifft64_c;
}
}
diff --git a/src/liba52/imdct_mlib.c b/src/liba52/imdct_mlib.c
deleted file mode 100644
index 2ec6639b8..000000000
--- a/src/liba52/imdct_mlib.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * imdct_mlib.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- *
- * This file is part of a52dec, a free ATSC A-52 stream decoder.
- *
- * a52dec 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 of the License, or
- * (at your option) any later version.
- *
- * a52dec 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#ifdef LIBA52_MLIB
-
-#include <inttypes.h>
-#include <string.h>
-#include <mlib_types.h>
-#include <mlib_status.h>
-#include <mlib_signal.h>
-
-#include "a52.h"
-#include "a52_internal.h"
-
-extern sample_t imdct_window[];
-
-void
-imdct_do_512_mlib(sample_t data[], sample_t delay[], sample_t bias)
-{
- sample_t *buf_real;
- sample_t *buf_imag;
- sample_t *data_ptr;
- sample_t *delay_ptr;
- sample_t *window_ptr;
- sample_t tmp[256] __attribute__ ((__aligned__ (16)));
- int i;
-
- memcpy(tmp, data, 256 * sizeof(sample_t));
- mlib_SignalIMDCT_F32(tmp);
-
- 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++ = -buf_imag[64+i] * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf_real[64-i-1] * *window_ptr++ + *delay_ptr++ + bias;
- }
-
- for(i=0; i< 64; i++)
- {
- *data_ptr++ = -buf_real[i] * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf_imag[128-i-1] * *window_ptr++ + *delay_ptr++ + bias;
- }
-
- /* 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(sample_t data[], sample_t delay[], sample_t bias)
-{
- sample_t *buf1_real, *buf1_imag;
- sample_t *buf2_real, *buf2_imag;
- sample_t *data_ptr;
- sample_t *delay_ptr;
- sample_t *window_ptr;
- sample_t tmp[256] __attribute__ ((__aligned__ (16)));
- int i;
-
- memcpy(tmp, data, 256 * sizeof(sample_t));
- mlib_SignalIMDCT_F32(tmp);
-
- 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++ = -buf1_imag[i] * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf1_real[64-i-1] * *window_ptr++ + *delay_ptr++ + bias;
- }
-
- for(i=0; i< 64; i++)
- {
- *data_ptr++ = -buf1_real[i] * *window_ptr++ + *delay_ptr++ + bias;
- *data_ptr++ = buf1_imag[64-i-1] * *window_ptr++ + *delay_ptr++ + bias;
- }
-
- 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/liba52/parse.c b/src/liba52/parse.c
index e2be25d12..61dccb7f3 100644
--- a/src/liba52/parse.c
+++ b/src/liba52/parse.c
@@ -1,8 +1,10 @@
/*
* parse.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,10 +23,9 @@
#include "config.h"
-#include <inttypes.h>
-#include <stdio.h> /* For printf */
#include <stdlib.h>
#include <string.h>
+#include <inttypes.h>
#include "a52.h"
#include "a52_internal.h"
@@ -32,35 +33,47 @@
#include "tables.h"
#include "xineutils.h"
-static sample_t q_1[2];
-static sample_t q_2[2];
-static sample_t q_4;
-static int q_1_pointer;
-static int q_2_pointer;
-static int q_4_pointer;
+typedef struct {
+ sample_t q1[2];
+ sample_t q2[2];
+ sample_t q4;
+ int q1_ptr;
+ int q2_ptr;
+ int q4_ptr;
+} quantizer_t;
static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
-sample_t * a52_init (uint32_t mm_accel, sample_t **samples_base)
+a52_state_t * a52_init (uint32_t mm_accel)
{
- sample_t * samples;
+ a52_state_t * state;
int i;
- imdct_init (mm_accel);
-
- samples = xine_xmalloc_aligned (16, 256 * 12 * sizeof (sample_t),
- (void**) samples_base);
- if (samples == NULL) {
-
- printf ("liba52: samples malloc failed!\n");
+ state = malloc (sizeof (a52_state_t));
+ if (state == NULL)
+ return NULL;
+ state->samples = xine_xmalloc_aligned (16, 256 * 12 * sizeof (sample_t), &state->samples_base);
+ if (state->samples == NULL) {
+ free (state);
return NULL;
}
for (i = 0; i < 256 * 12; i++)
- samples[i] = 0;
+ state->samples[i] = 0;
+
+ state->downmixed = 1;
+
+ state->lfsr_state = 1;
+
+ a52_imdct_init (mm_accel);
- return samples;
+ return state;
+}
+
+sample_t * a52_samples (a52_state_t * state)
+{
+ return state->samples;
}
int a52_syncinfo (uint8_t * buf, int * flags,
@@ -94,7 +107,7 @@ int a52_syncinfo (uint8_t * buf, int * flags,
*bit_rate = (bitrate * 1000) >> half;
switch (buf[4] & 0xc0) {
- case 0: /* 48 KHz */
+ case 0:
*sample_rate = 48000 >> half;
return 4 * bitrate;
case 0x40:
@@ -120,57 +133,60 @@ int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
state->halfrate = halfrate[buf[5] >> 3];
state->acmod = acmod = buf[6] >> 5;
- bitstream_set_ptr (buf + 6);
- bitstream_get (3); /* skip acmod we already parsed */
+ a52_bitstream_set_ptr (state, buf + 6);
+ bitstream_get (state, 3); /* skip acmod we already parsed */
- if ((acmod == 2) && (bitstream_get (2) == 2)) /* dsurmod */
+ if ((acmod == 2) && (bitstream_get (state, 2) == 2)) /* dsurmod */
acmod = A52_DOLBY;
if ((acmod & 1) && (acmod != 1))
- state->clev = clev[bitstream_get (2)]; /* cmixlev */
+ state->clev = clev[bitstream_get (state, 2)]; /* cmixlev */
if (acmod & 4)
- state->slev = slev[bitstream_get (2)]; /* surmixlev */
+ state->slev = slev[bitstream_get (state, 2)]; /* surmixlev */
- state->lfeon = bitstream_get (1);
+ state->lfeon = bitstream_get (state, 1);
- state->output = downmix_init (acmod, *flags, level,
- state->clev, state->slev);
+ state->output = a52_downmix_init (acmod, *flags, level,
+ state->clev, state->slev);
if (state->output < 0)
return 1;
if (state->lfeon && (*flags & A52_LFE))
state->output |= A52_LFE;
*flags = state->output;
- // the 2* compensates for differences in imdct
+ /* the 2* compensates for differences in imdct */
state->dynrng = state->level = 2 * *level;
state->bias = bias;
state->dynrnge = 1;
state->dynrngcall = NULL;
+ state->cplba.deltbae = DELTA_BIT_NONE;
+ state->ba[0].deltbae = state->ba[1].deltbae = state->ba[2].deltbae =
+ state->ba[3].deltbae = state->ba[4].deltbae = DELTA_BIT_NONE;
chaninfo = !acmod;
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 */
+ bitstream_get (state, 5); /* dialnorm */
+ if (bitstream_get (state, 1)) /* compre */
+ bitstream_get (state, 8); /* compr */
+ if (bitstream_get (state, 1)) /* langcode */
+ bitstream_get (state, 8); /* langcod */
+ if (bitstream_get (state, 1)) /* audprodie */
+ bitstream_get (state, 7); /* mixlevel + roomtyp */
} while (chaninfo--);
- bitstream_get (2); /* copyrightb + origbs */
+ bitstream_get (state, 2); /* copyrightb + origbs */
- if (bitstream_get (1)) /* timecod1e */
- bitstream_get (14); /* timecod1 */
- if (bitstream_get (1)) /* timecod2e */
- bitstream_get (14); /* timecod2 */
+ if (bitstream_get (state, 1)) /* timecod1e */
+ bitstream_get (state, 14); /* timecod1 */
+ if (bitstream_get (state, 1)) /* timecod2e */
+ bitstream_get (state, 14); /* timecod2 */
- if (bitstream_get (1)) { /* addbsie */
+ if (bitstream_get (state, 1)) { /* addbsie */
int addbsil;
- addbsil = bitstream_get (6);
+ addbsil = bitstream_get (state, 6);
do {
- bitstream_get (8); /* addbsi */
+ bitstream_get (state, 8); /* addbsi */
} while (addbsil--);
}
@@ -188,13 +204,13 @@ void a52_dynrng (a52_state_t * state,
}
}
-static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
- uint8_t * dest)
+static int parse_exponents (a52_state_t * state, int expstr, int ngrps,
+ uint8_t exponent, uint8_t * dest)
{
int exps;
while (ngrps--) {
- exps = bitstream_get (7);
+ exps = bitstream_get (state, 7);
exponent += exp_1[exps];
if (exponent > 24)
@@ -242,18 +258,18 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
return 0;
}
-static int parse_deltba (int8_t * deltba)
+static int parse_deltba (a52_state_t * state, int8_t * deltba)
{
int deltnseg, deltlen, delta, j;
memset (deltba, 0, 50);
- deltnseg = bitstream_get (3);
+ deltnseg = bitstream_get (state, 3);
j = 0;
do {
- j += bitstream_get (5);
- deltlen = bitstream_get (4);
- delta = bitstream_get (3);
+ j += bitstream_get (state, 5);
+ deltlen = bitstream_get (state, 4);
+ delta = bitstream_get (state, 3);
delta -= (delta >= 4) ? 3 : 4;
if (!deltlen)
continue;
@@ -270,36 +286,42 @@ static inline int zero_snr_offsets (int nfchans, a52_state_t * state)
{
int i;
- if ((state->csnroffst) || (state->cplinu && state->cplba.fsnroffst) ||
- (state->lfeon && state->lfeba.fsnroffst))
+ if ((state->csnroffst) ||
+ (state->chincpl && state->cplba.bai >> 3) || /* cplinu, fsnroffst */
+ (state->lfeon && state->lfeba.bai >> 3)) /* fsnroffst */
return 0;
for (i = 0; i < nfchans; i++)
- if (state->ba[i].fsnroffst)
+ if (state->ba[i].bai >> 3) /* fsnroffst */
return 0;
return 1;
}
-static inline int16_t dither_gen (void)
+static inline int16_t dither_gen (a52_state_t * state)
{
- static uint16_t lfsr_state = 1;
- int16_t state;
+ int16_t nstate;
- state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
+ nstate = dither_lut[state->lfsr_state >> 8] ^ (state->lfsr_state << 8);
- lfsr_state = (uint16_t) state;
+ state->lfsr_state = (uint16_t) nstate;
- return state;
+ return nstate;
}
-static void coeff_get (sample_t * coeff, uint8_t * exp, int8_t * bap,
+static void coeff_get (a52_state_t * state, sample_t * coeff,
+ expbap_t * expbap, quantizer_t * quantizer,
sample_t level, int dither, int end)
{
int i;
+ uint8_t * exp;
+ int8_t * bap;
sample_t factor[25];
for (i = 0; i <= 24; i++)
factor[i] = scale_factor[i] * level;
+ exp = expbap->exp;
+ bap = expbap->bap;
+
for (i = 0; i < end; i++) {
int bapi;
@@ -307,7 +329,7 @@ static void coeff_get (sample_t * coeff, uint8_t * exp, int8_t * bap,
switch (bapi) {
case 0:
if (dither) {
- coeff[i] = dither_gen() * LEVEL_3DB * factor[exp[i]];
+ coeff[i] = dither_gen (state) * LEVEL_3DB * factor[exp[i]];
continue;
} else {
coeff[i] = 0;
@@ -315,85 +337,89 @@ static void coeff_get (sample_t * coeff, uint8_t * exp, int8_t * bap,
}
case -1:
- if (q_1_pointer >= 0) {
- coeff[i] = q_1[q_1_pointer--] * factor[exp[i]];
+ if (quantizer->q1_ptr >= 0) {
+ coeff[i] = quantizer->q1[quantizer->q1_ptr--] * factor[exp[i]];
continue;
} else {
int code;
- code = bitstream_get (5);
+ code = bitstream_get (state, 5);
- q_1_pointer = 1;
- q_1[0] = q_1_2[code];
- q_1[1] = q_1_1[code];
+ quantizer->q1_ptr = 1;
+ quantizer->q1[0] = q_1_2[code];
+ quantizer->q1[1] = q_1_1[code];
coeff[i] = q_1_0[code] * factor[exp[i]];
continue;
}
case -2:
- if (q_2_pointer >= 0) {
- coeff[i] = q_2[q_2_pointer--] * factor[exp[i]];
+ if (quantizer->q2_ptr >= 0) {
+ coeff[i] = quantizer->q2[quantizer->q2_ptr--] * factor[exp[i]];
continue;
} else {
int code;
- code = bitstream_get (7);
+ code = bitstream_get (state, 7);
- q_2_pointer = 1;
- q_2[0] = q_2_2[code];
- q_2[1] = q_2_1[code];
+ quantizer->q2_ptr = 1;
+ quantizer->q2[0] = q_2_2[code];
+ quantizer->q2[1] = q_2_1[code];
coeff[i] = q_2_0[code] * factor[exp[i]];
continue;
}
case 3:
- coeff[i] = q_3[bitstream_get (3)] * factor[exp[i]];
+ coeff[i] = q_3[bitstream_get (state, 3)] * factor[exp[i]];
continue;
case -3:
- if (q_4_pointer == 0) {
- q_4_pointer = -1;
- coeff[i] = q_4 * factor[exp[i]];
+ if (quantizer->q4_ptr == 0) {
+ quantizer->q4_ptr = -1;
+ coeff[i] = quantizer->q4 * factor[exp[i]];
continue;
} else {
int code;
- code = bitstream_get (7);
+ code = bitstream_get (state, 7);
- q_4_pointer = 0;
- q_4 = q_4_1[code];
+ quantizer->q4_ptr = 0;
+ quantizer->q4 = q_4_1[code];
coeff[i] = q_4_0[code] * factor[exp[i]];
continue;
}
case 4:
- coeff[i] = q_5[bitstream_get (4)] * factor[exp[i]];
+ coeff[i] = q_5[bitstream_get (state, 4)] * factor[exp[i]];
continue;
default:
- coeff[i] = ((bitstream_get_2 (bapi) << (16 - bapi)) *
+ coeff[i] = ((bitstream_get_2 (state, bapi) << (16 - bapi)) *
factor[exp[i]]);
}
}
}
static void coeff_get_coupling (a52_state_t * state, int nfchans,
- sample_t * coeff,
- sample_t (* samples)[256], uint8_t dithflag[5])
+ sample_t * coeff, sample_t (* samples)[256],
+ quantizer_t * quantizer, uint8_t dithflag[5])
{
- int sub_bnd, bnd, i, i_end, ch;
- int8_t * bap;
+ int cplbndstrc, bnd, i, i_end, ch;
uint8_t * exp;
+ int8_t * bap;
sample_t cplco[5];
- bap = state->cpl_bap;
- exp = state->cpl_exp;
- sub_bnd = bnd = 0;
+ exp = state->cpl_expbap.exp;
+ bap = state->cpl_expbap.bap;
+ bnd = 0;
+ cplbndstrc = state->cplbndstrc;
i = state->cplstrtmant;
while (i < state->cplendmant) {
i_end = i + 12;
- while (state->cplbndstrc[sub_bnd++])
+ while (cplbndstrc & 1) {
+ cplbndstrc >>= 1;
i_end += 12;
+ }
+ cplbndstrc >>= 1;
for (ch = 0; ch < nfchans; ch++)
cplco[ch] = state->cplco[ch][bnd] * coeff[ch];
bnd++;
@@ -407,10 +433,10 @@ static void coeff_get_coupling (a52_state_t * state, int nfchans,
case 0:
cplcoeff = LEVEL_3DB * scale_factor[exp[i]];
for (ch = 0; ch < nfchans; ch++)
- if (state->chincpl[ch]) {
+ if ((state->chincpl >> ch) & 1) {
if (dithflag[ch])
samples[ch][i] = (cplcoeff * cplco[ch] *
- dither_gen ());
+ dither_gen (state));
else
samples[ch][i] = 0;
}
@@ -418,75 +444,75 @@ static void coeff_get_coupling (a52_state_t * state, int nfchans,
continue;
case -1:
- if (q_1_pointer >= 0) {
- cplcoeff = q_1[q_1_pointer--];
+ if (quantizer->q1_ptr >= 0) {
+ cplcoeff = quantizer->q1[quantizer->q1_ptr--];
break;
} else {
int code;
- code = bitstream_get (5);
+ code = bitstream_get (state, 5);
- q_1_pointer = 1;
- q_1[0] = q_1_2[code];
- q_1[1] = q_1_1[code];
+ quantizer->q1_ptr = 1;
+ quantizer->q1[0] = q_1_2[code];
+ quantizer->q1[1] = q_1_1[code];
cplcoeff = q_1_0[code];
break;
}
case -2:
- if (q_2_pointer >= 0) {
- cplcoeff = q_2[q_2_pointer--];
+ if (quantizer->q2_ptr >= 0) {
+ cplcoeff = quantizer->q2[quantizer->q2_ptr--];
break;
} else {
int code;
- code = bitstream_get (7);
+ code = bitstream_get (state, 7);
- q_2_pointer = 1;
- q_2[0] = q_2_2[code];
- q_2[1] = q_2_1[code];
+ quantizer->q2_ptr = 1;
+ quantizer->q2[0] = q_2_2[code];
+ quantizer->q2[1] = q_2_1[code];
cplcoeff = q_2_0[code];
break;
}
case 3:
- cplcoeff = q_3[bitstream_get (3)];
+ cplcoeff = q_3[bitstream_get (state, 3)];
break;
case -3:
- if (q_4_pointer == 0) {
- q_4_pointer = -1;
- cplcoeff = q_4;
+ if (quantizer->q4_ptr == 0) {
+ quantizer->q4_ptr = -1;
+ cplcoeff = quantizer->q4;
break;
} else {
int code;
- code = bitstream_get (7);
+ code = bitstream_get (state, 7);
- q_4_pointer = 0;
- q_4 = q_4_1[code];
+ quantizer->q4_ptr = 0;
+ quantizer->q4 = q_4_1[code];
cplcoeff = q_4_0[code];
break;
}
case 4:
- cplcoeff = q_5[bitstream_get (4)];
+ cplcoeff = q_5[bitstream_get (state, 4)];
break;
default:
- cplcoeff = bitstream_get_2 (bapi) << (16 - bapi);
+ cplcoeff = bitstream_get_2 (state, bapi) << (16 - bapi);
}
cplcoeff *= scale_factor[exp[i]];
for (ch = 0; ch < nfchans; ch++)
- if (state->chincpl[ch])
+ if ((state->chincpl >> ch) & 1)
samples[ch][i] = cplcoeff * cplco[ch];
i++;
}
}
}
-int a52_block (a52_state_t * state, sample_t * samples)
+int a52_block (a52_state_t * state)
{
static const uint8_t nfchans_tbl[] = {2, 1, 2, 3, 3, 4, 4, 5, 1, 1, 2};
static int rematrix_band[4] = {25, 37, 61, 253};
@@ -495,21 +521,23 @@ int a52_block (a52_state_t * state, sample_t * samples)
uint8_t blksw[5], dithflag[5];
sample_t coeff[5];
int chanbias;
+ quantizer_t quantizer;
+ sample_t * samples;
nfchans = nfchans_tbl[state->acmod];
for (i = 0; i < nfchans; i++)
- blksw[i] = bitstream_get (1);
+ blksw[i] = bitstream_get (state, 1);
for (i = 0; i < nfchans; i++)
- dithflag[i] = bitstream_get (1);
+ dithflag[i] = bitstream_get (state, 1);
- chaninfo = !(state->acmod);
+ chaninfo = !state->acmod;
do {
- if (bitstream_get (1)) { /* dynrnge */
+ if (bitstream_get (state, 1)) { /* dynrnge */
int dynrng;
- dynrng = bitstream_get_2 (8);
+ dynrng = bitstream_get_2 (state, 8);
if (state->dynrnge) {
sample_t range;
@@ -522,25 +550,25 @@ int a52_block (a52_state_t * state, sample_t * samples)
}
} while (chaninfo--);
- if (bitstream_get (1)) { /* cplstre */
- state->cplinu = bitstream_get (1);
- if (state->cplinu) {
- static int bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44,
- 45, 45, 46, 46, 47, 47, 48, 48};
+ if (bitstream_get (state, 1)) { /* cplstre */
+ state->chincpl = 0;
+ if (bitstream_get (state, 1)) { /* cplinu */
+ static uint8_t bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44,
+ 45, 45, 46, 46, 47, 47, 48, 48};
int cplbegf;
int cplendf;
int ncplsubnd;
for (i = 0; i < nfchans; i++)
- state->chincpl[i] = bitstream_get (1);
+ state->chincpl |= bitstream_get (state, 1) << i;
switch (state->acmod) {
case 0: case 1:
return 1;
case 2:
- state->phsflginu = bitstream_get (1);
+ state->phsflginu = bitstream_get (state, 1);
}
- cplbegf = bitstream_get (4);
- cplendf = bitstream_get (4);
+ cplbegf = bitstream_get (state, 4);
+ cplendf = bitstream_get (state, 4);
if (cplendf + 3 - cplbegf < 0)
return 1;
@@ -549,28 +577,29 @@ int a52_block (a52_state_t * state, sample_t * samples)
state->cplstrtmant = cplbegf * 12 + 37;
state->cplendmant = cplendf * 12 + 73;
- for (i = 0; i < ncplsubnd - 1; i++) {
- state->cplbndstrc[i] = bitstream_get (1);
- state->ncplbnd -= state->cplbndstrc[i];
- }
- state->cplbndstrc[i] = 0; /* last value is a sentinel */
+ state->cplbndstrc = 0;
+ for (i = 0; i < ncplsubnd - 1; i++)
+ if (bitstream_get (state, 1)) {
+ state->cplbndstrc |= 1 << i;
+ state->ncplbnd--;
+ }
}
}
- if (state->cplinu) {
+ if (state->chincpl) { /* cplinu */
int j, cplcoe;
cplcoe = 0;
for (i = 0; i < nfchans; i++)
- if (state->chincpl[i])
- if (bitstream_get (1)) { /* cplcoe */
+ if ((state->chincpl) >> i & 1)
+ if (bitstream_get (state, 1)) { /* cplcoe */
int mstrcplco, cplcoexp, cplcomant;
cplcoe = 1;
- mstrcplco = 3 * bitstream_get (2);
+ mstrcplco = 3 * bitstream_get (state, 2);
for (j = 0; j < state->ncplbnd; j++) {
- cplcoexp = bitstream_get (4);
- cplcomant = bitstream_get (4);
+ cplcoexp = bitstream_get (state, 4);
+ cplcomant = bitstream_get (state, 4);
if (cplcoexp == 15)
cplcomant <<= 14;
else
@@ -581,37 +610,38 @@ int a52_block (a52_state_t * state, sample_t * samples)
}
if ((state->acmod == 2) && state->phsflginu && cplcoe)
for (j = 0; j < state->ncplbnd; j++)
- if (bitstream_get (1)) /* phsflg */
+ if (bitstream_get (state, 1)) /* phsflg */
state->cplco[1][j] = -state->cplco[1][j];
}
- if ((state->acmod == 2) && (bitstream_get (1))) { /* rematstr */
+ if ((state->acmod == 2) && (bitstream_get (state, 1))) { /* rematstr */
int end;
- end = (state->cplinu) ? state->cplstrtmant : 253;
+ state->rematflg = 0;
+ end = (state->chincpl) ? state->cplstrtmant : 253; /* cplinu */
i = 0;
do
- state->rematflg[i] = bitstream_get (1);
+ state->rematflg |= bitstream_get (state, 1) << i;
while (rematrix_band[i++] < end);
}
cplexpstr = EXP_REUSE;
lfeexpstr = EXP_REUSE;
- if (state->cplinu)
- cplexpstr = bitstream_get (2);
+ if (state->chincpl) /* cplinu */
+ cplexpstr = bitstream_get (state, 2);
for (i = 0; i < nfchans; i++)
- chexpstr[i] = bitstream_get (2);
+ chexpstr[i] = bitstream_get (state, 2);
if (state->lfeon)
- lfeexpstr = bitstream_get (1);
+ lfeexpstr = bitstream_get (state, 1);
for (i = 0; i < nfchans; i++)
if (chexpstr[i] != EXP_REUSE) {
- if (state->cplinu && state->chincpl[i])
+ if ((state->chincpl >> i) & 1)
state->endmant[i] = state->cplstrtmant;
else {
int chbwcod;
- chbwcod = bitstream_get (6);
+ chbwcod = bitstream_get (state, 6);
if (chbwcod > 60)
return 1;
state->endmant[i] = chbwcod * 3 + 73;
@@ -626,9 +656,9 @@ int a52_block (a52_state_t * state, sample_t * samples)
do_bit_alloc = 64;
ncplgrps = ((state->cplendmant - state->cplstrtmant) /
(3 << (cplexpstr - 1)));
- cplabsexp = bitstream_get (4) << 1;
- if (parse_exponents (cplexpstr, ncplgrps, cplabsexp,
- state->cpl_exp + state->cplstrtmant))
+ cplabsexp = bitstream_get (state, 4) << 1;
+ if (parse_exponents (state, cplexpstr, ncplgrps, cplabsexp,
+ state->cpl_expbap.exp + state->cplstrtmant))
return 1;
}
for (i = 0; i < nfchans; i++)
@@ -638,115 +668,111 @@ int a52_block (a52_state_t * state, sample_t * samples)
do_bit_alloc |= 1 << i;
grp_size = 3 << (chexpstr[i] - 1);
nchgrps = (state->endmant[i] + grp_size - 4) / grp_size;
- state->fbw_exp[i][0] = bitstream_get (4);
- if (parse_exponents (chexpstr[i], nchgrps, state->fbw_exp[i][0],
- state->fbw_exp[i] + 1))
+ state->fbw_expbap[i].exp[0] = bitstream_get (state, 4);
+ if (parse_exponents (state, chexpstr[i], nchgrps,
+ state->fbw_expbap[i].exp[0],
+ state->fbw_expbap[i].exp + 1))
return 1;
- bitstream_get (2); /* gainrng */
+ bitstream_get (state, 2); /* gainrng */
}
if (lfeexpstr != EXP_REUSE) {
do_bit_alloc |= 32;
- state->lfe_exp[0] = bitstream_get (4);
- if (parse_exponents (lfeexpstr, 2, state->lfe_exp[0],
- state->lfe_exp + 1))
+ state->lfe_expbap.exp[0] = bitstream_get (state, 4);
+ if (parse_exponents (state, lfeexpstr, 2, state->lfe_expbap.exp[0],
+ state->lfe_expbap.exp + 1))
return 1;
}
- if (bitstream_get (1)) { /* baie */
+ if (bitstream_get (state, 1)) { /* baie */
do_bit_alloc = -1;
- state->sdcycod = bitstream_get (2);
- state->fdcycod = bitstream_get (2);
- state->sgaincod = bitstream_get (2);
- state->dbpbcod = bitstream_get (2);
- state->floorcod = bitstream_get (3);
+ state->bai = bitstream_get (state, 11);
}
- if (bitstream_get (1)) { /* snroffste */
+ if (bitstream_get (state, 1)) { /* snroffste */
do_bit_alloc = -1;
- state->csnroffst = bitstream_get (6);
- if (state->cplinu) {
- state->cplba.fsnroffst = bitstream_get (4);
- state->cplba.fgaincod = bitstream_get (3);
- }
- for (i = 0; i < nfchans; i++) {
- state->ba[i].fsnroffst = bitstream_get (4);
- state->ba[i].fgaincod = bitstream_get (3);
- }
- if (state->lfeon) {
- state->lfeba.fsnroffst = bitstream_get (4);
- state->lfeba.fgaincod = bitstream_get (3);
- }
+ state->csnroffst = bitstream_get (state, 6);
+ if (state->chincpl) /* cplinu */
+ state->cplba.bai = bitstream_get (state, 7);
+ for (i = 0; i < nfchans; i++)
+ state->ba[i].bai = bitstream_get (state, 7);
+ if (state->lfeon)
+ state->lfeba.bai = bitstream_get (state, 7);
}
- if ((state->cplinu) && (bitstream_get (1))) { /* cplleake */
+ if ((state->chincpl) && (bitstream_get (state, 1))) { /* cplleake */
do_bit_alloc |= 64;
- state->cplfleak = 2304 - (bitstream_get (3) << 8);
- state->cplsleak = 2304 - (bitstream_get (3) << 8);
+ state->cplfleak = 9 - bitstream_get (state, 3);
+ state->cplsleak = 9 - bitstream_get (state, 3);
}
- if (bitstream_get (1)) { /* deltbaie */
+ if (bitstream_get (state, 1)) { /* deltbaie */
do_bit_alloc = -1;
- if (state->cplinu)
- state->cplba.deltbae = bitstream_get (2);
+ if (state->chincpl) /* cplinu */
+ state->cplba.deltbae = bitstream_get (state, 2);
for (i = 0; i < nfchans; i++)
- state->ba[i].deltbae = bitstream_get (2);
- if (state->cplinu && (state->cplba.deltbae == DELTA_BIT_NEW) &&
- parse_deltba (state->cplba.deltba))
+ state->ba[i].deltbae = bitstream_get (state, 2);
+ if (state->chincpl && /* cplinu */
+ (state->cplba.deltbae == DELTA_BIT_NEW) &&
+ parse_deltba (state, state->cplba.deltba))
return 1;
for (i = 0; i < nfchans; i++)
if ((state->ba[i].deltbae == DELTA_BIT_NEW) &&
- parse_deltba (state->ba[i].deltba))
+ parse_deltba (state, state->ba[i].deltba))
return 1;
}
if (do_bit_alloc) {
if (zero_snr_offsets (nfchans, state)) {
- memset (state->cpl_bap, 0, sizeof (state->cpl_bap));
- memset (state->fbw_bap, 0, sizeof (state->fbw_bap));
- memset (state->lfe_bap, 0, sizeof (state->lfe_bap));
+ memset (state->cpl_expbap.bap, 0, sizeof (state->cpl_expbap.bap));
+ for (i = 0; i < nfchans; i++)
+ memset (state->fbw_expbap[i].bap, 0,
+ sizeof (state->fbw_expbap[i].bap));
+ memset (state->lfe_expbap.bap, 0, sizeof (state->lfe_expbap.bap));
} else {
- if (state->cplinu && (do_bit_alloc & 64))
- bit_allocate (state, &state->cplba, state->cplstrtbnd,
- state->cplstrtmant, state->cplendmant,
- state->cplfleak, state->cplsleak,
- state->cpl_exp, state->cpl_bap);
+ if (state->chincpl && (do_bit_alloc & 64)) /* cplinu */
+ a52_bit_allocate (state, &state->cplba, state->cplstrtbnd,
+ state->cplstrtmant, state->cplendmant,
+ state->cplfleak << 8, state->cplsleak << 8,
+ &state->cpl_expbap);
for (i = 0; i < nfchans; i++)
if (do_bit_alloc & (1 << i))
- bit_allocate (state, state->ba + i, 0, 0,
- state->endmant[i], 0, 0, state->fbw_exp[i],
- state->fbw_bap[i]);
+ a52_bit_allocate (state, state->ba + i, 0, 0,
+ state->endmant[i], 0, 0,
+ state->fbw_expbap +i);
if (state->lfeon && (do_bit_alloc & 32)) {
state->lfeba.deltbae = DELTA_BIT_NONE;
- bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
- state->lfe_exp, state->lfe_bap);
+ a52_bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
+ &state->lfe_expbap);
}
}
}
- if (bitstream_get (1)) { /* skiple */
- i = bitstream_get (9); /* skipl */
+ if (bitstream_get (state, 1)) { /* skiple */
+ i = bitstream_get (state, 9); /* skipl */
while (i--)
- bitstream_get (8);
+ bitstream_get (state, 8);
}
+ samples = state->samples;
if (state->output & A52_LFE)
samples += 256; /* shift for LFE channel */
- chanbias = downmix_coeff (coeff, state->acmod, state->output,
- state->dynrng, state->clev, state->slev);
+ chanbias = a52_downmix_coeff (coeff, state->acmod, state->output,
+ state->dynrng, state->clev, state->slev);
- q_1_pointer = q_2_pointer = q_4_pointer = -1;
+ quantizer.q1_ptr = quantizer.q2_ptr = quantizer.q4_ptr = -1;
done_cpl = 0;
for (i = 0; i < nfchans; i++) {
int j;
- coeff_get (samples + 256 * i, state->fbw_exp[i], state->fbw_bap[i],
+ coeff_get (state, samples + 256 * i, state->fbw_expbap +i, &quantizer,
coeff[i], dithflag[i], state->endmant[i]);
- if (state->cplinu && state->chincpl[i]) {
+ if ((state->chincpl >> i) & 1) {
if (!done_cpl) {
done_cpl = 1;
coeff_get_coupling (state, nfchans, coeff,
- (sample_t (*)[256])samples, dithflag);
+ (sample_t (*)[256])samples, &quantizer,
+ dithflag);
}
j = state->cplendmant;
} else
@@ -757,18 +783,21 @@ int a52_block (a52_state_t * state, sample_t * samples)
}
if (state->acmod == 2) {
- int j, end, band;
+ int j, end, band, rematflg;
end = ((state->endmant[0] < state->endmant[1]) ?
state->endmant[0] : state->endmant[1]);
i = 0;
j = 13;
+ rematflg = state->rematflg;
do {
- if (!state->rematflg[i]) {
+ if (! (rematflg & 1)) {
+ rematflg >>= 1;
j = rematrix_band[i++];
continue;
}
+ rematflg >>= 1;
band = rematrix_band[i++];
if (band > end)
band = end;
@@ -785,14 +814,14 @@ int a52_block (a52_state_t * state, sample_t * samples)
if (state->lfeon) {
if (state->output & A52_LFE) {
- coeff_get (samples - 256, state->lfe_exp, state->lfe_bap,
+ coeff_get (state, samples - 256, &state->lfe_expbap, &quantizer,
state->dynrng, 0, 7);
for (i = 7; i < 256; i++)
(samples-256)[i] = 0;
- imdct_512 (samples - 256, samples + 1536 - 256, state->bias);
+ a52_imdct_512 (samples - 256, samples + 1536 - 256, state->bias);
} else {
/* just skip the LFE coefficients */
- coeff_get (samples + 1280, state->lfe_exp, state->lfe_bap,
+ coeff_get (state, samples + 1280, &state->lfe_expbap, &quantizer,
0, 0, 7);
}
}
@@ -804,9 +833,9 @@ int a52_block (a52_state_t * state, sample_t * samples)
break;
if (i < nfchans) {
- if (samples[2 * 1536 - 1] == (sample_t)0x776b6e21) {
- samples[2 * 1536 - 1] = 0;
- upmix (samples + 1536, state->acmod, state->output);
+ if (state->downmixed) {
+ state->downmixed = 0;
+ a52_upmix (samples + 1536, state->acmod, state->output);
}
for (i = 0; i < nfchans; i++) {
@@ -818,11 +847,11 @@ int a52_block (a52_state_t * state, sample_t * samples)
if (coeff[i]) {
if (blksw[i])
- imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
- bias);
+ a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
+ bias);
else
- imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
- bias);
+ a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
+ bias);
} else {
int j;
@@ -831,29 +860,35 @@ int a52_block (a52_state_t * state, sample_t * samples)
}
}
- downmix (samples, state->acmod, state->output, state->bias,
- state->clev, state->slev);
+ a52_downmix (samples, state->acmod, state->output, state->bias,
+ state->clev, state->slev);
} else {
nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK];
- downmix (samples, state->acmod, state->output, 0,
- state->clev, state->slev);
-
- if (samples[2 * 1536 - 1] != (sample_t)0x776b6e21) {
- downmix (samples + 1536, state->acmod, state->output, 0,
+ a52_downmix (samples, state->acmod, state->output, 0,
state->clev, state->slev);
- samples[2 * 1536 - 1] = (sample_t)0x776b6e21;
+
+ if (!state->downmixed) {
+ state->downmixed = 1;
+ a52_downmix (samples + 1536, state->acmod, state->output, 0,
+ state->clev, state->slev);
}
if (blksw[0])
for (i = 0; i < nfchans; i++)
- imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
- state->bias);
+ a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
+ state->bias);
else
for (i = 0; i < nfchans; i++)
- imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
- state->bias);
+ a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
+ state->bias);
}
return 0;
}
+
+void a52_free (a52_state_t * state)
+{
+ free (state->samples_base);
+ free (state);
+}
diff --git a/src/liba52/tables.h b/src/liba52/tables.h
index ddac9e5cb..a35543db7 100644
--- a/src/liba52/tables.h
+++ b/src/liba52/tables.h
@@ -1,8 +1,10 @@
/*
* tables.h
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * 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.
+ * See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-static int8_t exp_1[128] = {
+static const int8_t exp_1[128] = {
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -27,7 +29,7 @@ static int8_t exp_1[128] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
25,25,25
};
-static int8_t exp_2[128] = {
+static const int8_t exp_2[128] = {
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
@@ -35,7 +37,7 @@ static int8_t exp_2[128] = {
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
25,25,25
};
-static int8_t exp_3[128] = {
+static const int8_t exp_3[128] = {
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
@@ -180,7 +182,7 @@ static const sample_t q_5[16] = {
0
};
-static sample_t scale_factor[25] = {
+static const sample_t scale_factor[25] = {
0.000030517578125,
0.0000152587890625,
0.00000762939453125,
diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c
index e26e1653d..ee64afe07 100644
--- a/src/liba52/xine_decoder.c
+++ b/src/liba52/xine_decoder.c
@@ -17,7 +17,7 @@
* 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.28 2002/07/05 17:32:02 mroi Exp $
+ * $Id: xine_decoder.c,v 1.29 2002/08/28 20:27:56 mroi Exp $
*
* stuff needed to turn liba52 into a xine decoder plugin
*/
@@ -58,7 +58,7 @@ typedef struct a52dec_decoder_s {
int frame_length, frame_todo;
uint16_t syncword;
- a52_state_t a52_state;
+ a52_state_t *a52_state;
int a52_flags;
int a52_bit_rate;
int a52_sample_rate;
@@ -68,8 +68,6 @@ typedef struct a52dec_decoder_s {
int a52_flags_map[11];
int ao_flags_map[11];
- sample_t *samples, *samples_base;
-
ao_instance_t *audio_out;
int audio_caps;
int bypass_mode;
@@ -154,8 +152,8 @@ void a52dec_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) {
this->output_open = 0;
this->pts = 0;
- if( !this->samples )
- this->samples = a52_init (xine_mm_accel(), &this->samples_base);
+ if( !this->a52_state )
+ this->a52_state = a52_init (xine_mm_accel());
/*
* find out if this driver supports a52 output
@@ -275,6 +273,7 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts) {
sample_t level = this->a52_level;
audio_buffer_t *buf;
int16_t *int_samples;
+ sample_t *samples = a52_samples(this->a52_state);
/*
* oki, decode this frame in software
@@ -284,7 +283,7 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts) {
a52_output_flags = this->a52_flags_map[this->a52_flags & A52_CHANNEL_MASK];
- if (a52_frame (&this->a52_state,
+ if (a52_frame (this->a52_state,
this->frame_buffer,
&a52_output_flags,
&level, 384)) {
@@ -293,7 +292,7 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts) {
}
if (this->disable_dynrng)
- a52_dynrng (&this->a52_state, NULL, NULL);
+ a52_dynrng (this->a52_state, NULL, NULL);
this->have_lfe = a52_output_flags & A52_LFE;
if (this->have_lfe)
@@ -334,7 +333,7 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts) {
buf->num_frames = 256*6;
for (i = 0; i < 6; i++) {
- if (a52_block (&this->a52_state, this->samples)) {
+ if (a52_block (this->a52_state)) {
printf ("liba52: a52_block error\n");
buf->num_frames = 0;
break;
@@ -342,32 +341,32 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts) {
switch (output_mode) {
case AO_CAP_MODE_MONO:
- float_to_int (&this->samples[0], int_samples+(i*256), 1);
+ float_to_int (&samples[0], int_samples+(i*256), 1);
break;
case AO_CAP_MODE_STEREO:
- float_to_int (&this->samples[0*256], int_samples+(i*256*2), 2);
- float_to_int (&this->samples[1*256], int_samples+(i*256*2)+1, 2);
+ float_to_int (&samples[0*256], int_samples+(i*256*2), 2);
+ float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2);
break;
case AO_CAP_MODE_4CHANNEL:
- float_to_int (&this->samples[0*256], int_samples+(i*256*4), 4); /* L */
- float_to_int (&this->samples[1*256], int_samples+(i*256*4)+1, 4); /* R */
- float_to_int (&this->samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */
- float_to_int (&this->samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */
+ float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */
+ float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */
+ float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */
+ float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */
break;
case AO_CAP_MODE_5CHANNEL:
- float_to_int (&this->samples[0*256], int_samples+(i*256*5)+0, 5); /* L */
- float_to_int (&this->samples[1*256], int_samples+(i*256*5)+4, 5); /* C */
- float_to_int (&this->samples[2*256], int_samples+(i*256*5)+1, 5); /* R */
- float_to_int (&this->samples[3*256], int_samples+(i*256*5)+2, 5); /* RL */
- float_to_int (&this->samples[4*256], int_samples+(i*256*5)+3, 5); /* RR */
+ float_to_int (&samples[0*256], int_samples+(i*256*5)+0, 5); /* L */
+ float_to_int (&samples[1*256], int_samples+(i*256*5)+4, 5); /* C */
+ float_to_int (&samples[2*256], int_samples+(i*256*5)+1, 5); /* R */
+ float_to_int (&samples[3*256], int_samples+(i*256*5)+2, 5); /* RL */
+ float_to_int (&samples[4*256], int_samples+(i*256*5)+3, 5); /* RR */
break;
case AO_CAP_MODE_5_1CHANNEL:
- float_to_int (&this->samples[0*256], int_samples+(i*256*6)+5, 6); /* lfe */
- float_to_int (&this->samples[1*256], int_samples+(i*256*6)+0, 6); /* L */
- float_to_int (&this->samples[2*256], int_samples+(i*256*6)+4, 6); /* C */
- float_to_int (&this->samples[3*256], int_samples+(i*256*6)+1, 6); /* R */
- float_to_int (&this->samples[4*256], int_samples+(i*256*6)+2, 6); /* RL */
- float_to_int (&this->samples[5*256], int_samples+(i*256*6)+3, 6); /* RR */
+ float_to_int (&samples[0*256], int_samples+(i*256*6)+5, 6); /* lfe */
+ float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */
+ float_to_int (&samples[2*256], int_samples+(i*256*6)+4, 6); /* C */
+ float_to_int (&samples[3*256], int_samples+(i*256*6)+1, 6); /* R */
+ float_to_int (&samples[4*256], int_samples+(i*256*6)+2, 6); /* RL */
+ float_to_int (&samples[5*256], int_samples+(i*256*6)+3, 6); /* RR */
break;
default:
printf ("liba52: help - unsupported mode %08x\n", output_mode);
@@ -521,12 +520,10 @@ void a52dec_close (audio_decoder_t *this_gen) {
if (this->output_open)
this->audio_out->close (this->audio_out);
- if( this->samples ) {
- free (this->samples_base);
- this->samples = NULL;
- }
-
this->output_open = 0;
+
+ a52_free(this->a52_state);
+ this->a52_state = NULL;
#ifdef DEBUG_A52
close (a52file);