summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/audio_out/audio_alsa05_out.c14
-rw-r--r--src/audio_out/audio_oss_out.c14
-rw-r--r--src/liba52/Makefile.am (renamed from src/libac3/Makefile.am)8
-rw-r--r--src/liba52/a52.h115
-rw-r--r--src/liba52/a52_internal.h54
-rw-r--r--src/liba52/bit_allocate.c (renamed from src/libac3/bit_allocate.c)71
-rw-r--r--src/liba52/bitstream.c99
-rw-r--r--src/liba52/bitstream.h80
-rw-r--r--src/liba52/downmix.c653
-rw-r--r--src/liba52/imdct.c (renamed from src/libac3/imdct.c)130
-rw-r--r--src/liba52/imdct_mlib.c135
-rw-r--r--src/liba52/parse.c861
-rw-r--r--src/liba52/tables.h (renamed from src/libac3/tables.h)33
-rw-r--r--src/liba52/xine_decoder.c477
-rw-r--r--src/libac3/ac3.h109
-rw-r--r--src/libac3/ac3_internal.h52
-rw-r--r--src/libac3/bitstream.c87
-rw-r--r--src/libac3/bitstream.h68
-rw-r--r--src/libac3/downmix.c546
-rw-r--r--src/libac3/imdct_mlib.c142
-rw-r--r--src/libac3/parse.c689
-rw-r--r--src/libac3/xine_decoder.c474
-rw-r--r--src/xine-engine/audio_out.c14
-rw-r--r--src/xine-engine/audio_out.h4
25 files changed, 2613 insertions, 2318 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d96543a0a..350099b66 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = audio_out video_out dxr3 input libmpeg2 libspudec demuxers \
- libac3 libffmpeg liblpcm libw32dll libmad xine-engine
+ liba52 libffmpeg liblpcm libw32dll libmad xine-engine
debug:
@list='$(SUBDIRS)'; for subdir in $$list; do \
diff --git a/src/audio_out/audio_alsa05_out.c b/src/audio_out/audio_alsa05_out.c
index 79c547414..d66bc192a 100644
--- a/src/audio_out/audio_alsa05_out.c
+++ b/src/audio_out/audio_alsa05_out.c
@@ -21,10 +21,10 @@
* Plugin for ALSA Version 0.5.x
*
* Credits go
- * for the SPDIF AC3 sync part
+ * for the SPDIF A52 sync part
* (c) 2000 Andy Lo A Foe <andy@alsaplayer.org>
*
- * $Id: audio_alsa05_out.c,v 1.8 2001/08/25 08:19:58 guenter Exp $
+ * $Id: audio_alsa05_out.c,v 1.9 2001/08/29 00:51:57 guenter Exp $
*/
/* required for swab() */
@@ -174,7 +174,7 @@ static int ao_alsa_open(ao_driver_t *this_gen,uint32_t bits, uint32_t rate, int
switch (ao_mode) {
case AO_CAP_MODE_STEREO:
- case AO_CAP_MODE_AC3:
+ case AO_CAP_MODE_A52:
channels = 2;
break;
@@ -206,7 +206,7 @@ static int ao_alsa_open(ao_driver_t *this_gen,uint32_t bits, uint32_t rate, int
this->bytes_in_buffer = 0;
this->direction = SND_PCM_CHANNEL_PLAYBACK;
- if (ao_mode == AO_CAP_MODE_AC3) {
+ if (ao_mode == AO_CAP_MODE_A52) {
this->pcm_default_device = 2;
mode = SND_PCM_MODE_BLOCK;
}
@@ -295,7 +295,7 @@ static int ao_alsa_open(ao_driver_t *this_gen,uint32_t bits, uint32_t rate, int
this->stop_mode = pcm_chan_params.stop_mode;
this->ao_mode = ao_mode;
- if (ao_mode == AO_CAP_MODE_AC3) {
+ if (ao_mode == AO_CAP_MODE_A52) {
pcm_chan_params.digital.dig_valid = 1;
pcm_chan_params.digital.dig_status[0] = SND_PCM_DIG0_NONAUDIO;
pcm_chan_params.digital.dig_status[0] |= SND_PCM_DIG0_PROFESSIONAL;
@@ -528,8 +528,8 @@ ao_driver_t *init_audio_out_plugin(config_values_t *config) {
this->pcm_default_device);
this->capabilities = AO_CAP_MODE_STEREO;
- if (config->lookup_int (config, "ac3_pass_through", 0))
- this->capabilities |= AO_CAP_MODE_AC3;
+ if (config->lookup_int (config, "a52_pass_through", 0))
+ this->capabilities |= AO_CAP_MODE_A52;
this->ao_driver.get_capabilities = ao_alsa_get_capabilities;
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index c0534673b..a205be43f 100644
--- a/src/audio_out/audio_oss_out.c
+++ b/src/audio_out/audio_oss_out.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: audio_oss_out.c,v 1.34 2001/08/25 08:11:41 guenter Exp $
+ * $Id: audio_oss_out.c,v 1.35 2001/08/29 00:51:57 guenter Exp $
*
* 20-8-2001 First implementation of Audio sync and Audio driver separation.
* Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk
@@ -79,7 +79,7 @@
#endif
#ifndef AFMT_AC3
-# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */
+# define AFMT_AC3 0x00000400
#endif
#define AO_OUT_OSS_IFACE_VERSION 2
@@ -167,9 +167,9 @@ static int ao_oss_open(ao_driver_t *this_gen,
/*
* configure audio device
- * In AC3 mode, skip all other SNDCTL commands
+ * In A52 mode, skip all other SNDCTL commands
*/
- if(!(mode & AO_CAP_MODE_AC3)) {
+ if(!(mode & AO_CAP_MODE_A52)) {
tmp = (mode & AO_CAP_MODE_STEREO) ? 1 : 0;
ioctl(this->audio_fd,SNDCTL_DSP_STEREO,&tmp);
@@ -225,7 +225,7 @@ static int ao_oss_open(ao_driver_t *this_gen,
ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
this->num_channels = tmp;
break;
- case AO_CAP_MODE_AC3:
+ case AO_CAP_MODE_A52:
tmp = AFMT_AC3;
if (ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != AFMT_AC3) {
printf("audio_oss_out: AC3 SNDCTL_DSP_SETFMT failed. %d\n",tmp);
@@ -233,7 +233,7 @@ static int ao_oss_open(ao_driver_t *this_gen,
}
this->num_channels = 2; /* FIXME: is this correct ? */
this->output_sample_rate = this->input_sample_rate;
- printf ("audio_oss_out : AO_CAP_MODE_AC3\n");
+ printf ("audio_oss_out : AO_CAP_MODE_A52\n");
break;
}
@@ -548,7 +548,7 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
ioctl(audio_fd,SNDCTL_DSP_GETFMTS,&caps);
if (caps & AFMT_AC3) {
if (config->lookup_int (config, "ac3_pass_through", 0)) {
- this->capabilities |= AO_CAP_MODE_AC3;
+ this->capabilities |= AO_CAP_MODE_A52;
printf ("ac3-pass-through ");
} else
printf ("(ac3-pass-through not enabled in .xinerc)");
diff --git a/src/libac3/Makefile.am b/src/liba52/Makefile.am
index 38b5f5b39..78ea2055f 100644
--- a/src/libac3/Makefile.am
+++ b/src/liba52/Makefile.am
@@ -4,14 +4,14 @@ LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
libdir = $(XINE_PLUGINDIR)
-lib_LTLIBRARIES = xineplug_decode_ac3.la
+lib_LTLIBRARIES = xineplug_decode_a52.la
-xineplug_decode_ac3_la_SOURCES = bitstream.c bit_allocate.c \
+xineplug_decode_a52_la_SOURCES = bitstream.c bit_allocate.c \
parse.c downmix.c imdct.c imdct_mlib.c \
xine_decoder.c
-xineplug_decode_ac3_la_LDFLAGS = -avoid-version -module
+xineplug_decode_a52_la_LDFLAGS = -avoid-version -module
-noinst_HEADERS = ac3.h ac3_internal.h \
+noinst_HEADERS = a52.h a52_internal.h \
bitstream.h tables.h
##
diff --git a/src/liba52/a52.h b/src/liba52/a52.h
new file mode 100644
index 000000000..6825ec2bf
--- /dev/null
+++ b/src/liba52/a52.h
@@ -0,0 +1,115 @@
+/*
+ * a52.h
+ * 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
+ */
+
+#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;
+
+#define A52_CHANNEL 0
+#define A52_MONO 1
+#define A52_STEREO 2
+#define A52_3F 3
+#define A52_2F1R 4
+#define A52_3F1R 5
+#define A52_2F2R 6
+#define A52_3F2R 7
+#define A52_CHANNEL1 8
+#define A52_CHANNEL2 9
+#define A52_DOLBY 10
+#define A52_CHANNEL_MASK 15
+
+#define A52_LFE 16
+#define A52_ADJUST_LEVEL 32
+
+sample_t * a52_init (uint32_t mm_accel);
+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);
diff --git a/src/liba52/a52_internal.h b/src/liba52/a52_internal.h
new file mode 100644
index 000000000..a1b88c229
--- /dev/null
+++ b/src/liba52/a52_internal.h
@@ -0,0 +1,54 @@
+/*
+ * a52_internal.h
+ * 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
+ */
+
+#define LEVEL_PLUS6DB 2.0
+#define LEVEL_PLUS3DB 1.4142135623730951
+#define LEVEL_3DB 0.7071067811865476
+#define LEVEL_45DB 0.5946035575013605
+#define LEVEL_6DB 0.5
+
+#define EXP_REUSE (0)
+#define EXP_D15 (1)
+#define EXP_D25 (2)
+#define EXP_D45 (3)
+
+#define DELTA_BIT_REUSE (0)
+#define DELTA_BIT_NEW (1)
+#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);
+
+int downmix_init (int input, int flags, sample_t * level,
+ 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);
diff --git a/src/libac3/bit_allocate.c b/src/liba52/bit_allocate.c
index 45bc16cef..a44142ae3 100644
--- a/src/libac3/bit_allocate.c
+++ b/src/liba52/bit_allocate.c
@@ -1,32 +1,30 @@
-/*
- * bit_allocate.c
+/*
+ * bit_allocate.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
- * Copyright (C) Aaron Holtzman - May 1999
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
*
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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"
#include <inttypes.h>
-#include "ac3.h"
-#include "ac3_internal.h"
+#include "a52.h"
+#include "a52_internal.h"
static int hthtab[3][50] = {
{0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
@@ -52,7 +50,7 @@ static int8_t baptab[305] = {
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, // 93 padding entries
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, /* 93 padding elems */
16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14,
14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
@@ -68,7 +66,7 @@ static int8_t baptab[305] = {
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, 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, 0, 0 // 148 padding entries
+ 0, 0, 0, 0 /* 148 padding elems */
};
static int bndtab[30] = {21, 22, 23, 24, 25, 26, 27, 28, 31, 34,
@@ -121,7 +119,7 @@ do { \
mask -= floor; \
} while (0)
-void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
+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)
{
@@ -155,7 +153,7 @@ void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
i = bndstart;
j = start;
- if (start == 0) { // not the coupling channel
+ if (start == 0) { /* not the coupling channel */
int lowcomp;
lowcomp = 0;
@@ -170,8 +168,7 @@ void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
psd = 128 * exp[i];
mask = psd + fgain + lowcomp;
COMPUTE_MASK ();
- bap[i] = (baptab+156)[mask + 4 * exp[i]];
- i++;
+ bap[i++] = (baptab+156)[mask + 4 * exp[i]];
} while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
fastleak = psd + fgain;
slowleak = psd + sgain;
@@ -188,11 +185,10 @@ void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
mask = ((fastleak + lowcomp < slowleak) ?
fastleak + lowcomp : slowleak);
COMPUTE_MASK ();
- bap[i] = (baptab+156)[mask + 4 * exp[i]];
- i++;
+ bap[i++] = (baptab+156)[mask + 4 * exp[i]];
}
- if (end == 7) // lfe channel
+ if (end == 7) /* lfe channel */
return;
do {
@@ -205,19 +201,17 @@ void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
mask = ((fastleak + lowcomp < slowleak) ?
fastleak + lowcomp : slowleak);
COMPUTE_MASK ();
- bap[i] = (baptab+156)[mask + 4 * exp[i]];
- i++;
+ bap[i++] = (baptab+156)[mask + 4 * exp[i]];
} while (i < 20);
- while (lowcomp > 128) { // two iterations maximum
+ while (lowcomp > 128) { /* two iterations maximum */
lowcomp -= 128;
psd = 128 * exp[i];
UPDATE_LEAK ();
mask = ((fastleak + lowcomp < slowleak) ?
fastleak + lowcomp : slowleak);
COMPUTE_MASK ();
- bap[i] = (baptab+156)[mask + 4 * exp[i]];
- i++;
+ bap[i++] = (baptab+156)[mask + 4 * exp[i]];
}
j = i;
}
@@ -245,17 +239,16 @@ void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
break;
}
}
- // minpsd = -289
+ /* minpsd = -289 */
UPDATE_LEAK ();
mask = (fastleak < slowleak) ? fastleak : slowleak;
COMPUTE_MASK ();
i++;
j = startband;
do {
- // max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp
- // min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5
- bap[j] = (baptab+156)[mask + 4 * exp[j]];
- j++;
+ /* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */
+ /* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */
+ bap[j++] = (baptab+156)[mask + 4 * exp[j]];
} while (j < endband);
} while (j < end);
}
diff --git a/src/liba52/bitstream.c b/src/liba52/bitstream.c
new file mode 100644
index 000000000..30caa5ea3
--- /dev/null
+++ b/src/liba52/bitstream.c
@@ -0,0 +1,99 @@
+/*
+ * bitstream.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"
+
+#include <inttypes.h>
+
+#include "a52.h"
+#include "a52_internal.h"
+#include "bitstream.h"
+
+#define BUFFER_SIZE 4096
+
+static uint32_t * buffer_start;
+
+uint32_t bits_left;
+uint32_t current_word;
+
+void bitstream_set_ptr (uint8_t * buf)
+{
+ int align;
+
+ align = (int)buf & 3;
+ buffer_start = (uint32_t *) (buf - align);
+ bits_left = 0;
+ bitstream_get (align * 8);
+}
+
+static inline void
+bitstream_fill_current()
+{
+ uint32_t tmp;
+
+ tmp = *(buffer_start++);
+ current_word = swab32 (tmp);
+}
+
+/*
+ * The fast paths for _get is in the
+ * bitstream.h header file so it can be inlined.
+ *
+ * The "bottom half" of this routine is suffixed _bh
+ *
+ * -ah
+ */
+
+uint32_t
+bitstream_get_bh(uint32_t num_bits)
+{
+ uint32_t result;
+
+ num_bits -= bits_left;
+ result = (current_word << (32 - bits_left)) >> (32 - bits_left);
+
+ bitstream_fill_current();
+
+ if(num_bits != 0)
+ result = (result << num_bits) | (current_word >> (32 - num_bits));
+
+ bits_left = 32 - num_bits;
+
+ return result;
+}
+
+int32_t
+bitstream_get_bh_2(uint32_t num_bits)
+{
+ int32_t result;
+
+ num_bits -= bits_left;
+ result = (((int32_t)current_word) << (32 - bits_left)) >> (32 - bits_left);
+
+ bitstream_fill_current();
+
+ if(num_bits != 0)
+ result = (result << num_bits) | (current_word >> (32 - num_bits));
+
+ bits_left = 32 - num_bits;
+
+ return result;
+}
diff --git a/src/liba52/bitstream.h b/src/liba52/bitstream.h
new file mode 100644
index 000000000..1f3c447c0
--- /dev/null
+++ b/src/liba52/bitstream.h
@@ -0,0 +1,80 @@
+/*
+ * bitstream.h
+ * 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
+ */
+
+/* (stolen from the kernel) */
+#ifdef WORDS_BIGENDIAN
+
+# define swab32(x) (x)
+
+#else
+
+# if defined (__i386__)
+
+# define swab32(x) __i386_swab32(x)
+ static inline const uint32_t __i386_swab32(uint32_t x)
+ {
+ __asm__("bswap %0" : "=r" (x) : "0" (x));
+ return x;
+ }
+
+# else
+
+# define swab32(x)\
+((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \
+ (((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3]))
+
+# endif
+#endif
+
+extern uint32_t bits_left;
+extern uint32_t current_word;
+
+void bitstream_set_ptr (uint8_t * buf);
+uint32_t bitstream_get_bh(uint32_t num_bits);
+int32_t bitstream_get_bh_2(uint32_t num_bits);
+
+static inline uint32_t
+bitstream_get(uint32_t num_bits)
+{
+ uint32_t result;
+
+ if(num_bits < bits_left) {
+ result = (current_word << (32 - bits_left)) >> (32 - num_bits);
+ bits_left -= num_bits;
+ return result;
+ }
+
+ return bitstream_get_bh(num_bits);
+}
+
+static inline int32_t
+bitstream_get_2(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;
+ return result;
+ }
+
+ return bitstream_get_bh_2(num_bits);
+}
diff --git a/src/liba52/downmix.c b/src/liba52/downmix.c
new file mode 100644
index 000000000..6feeab433
--- /dev/null
+++ b/src/liba52/downmix.c
@@ -0,0 +1,653 @@
+/*
+ * downmix.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"
+
+#include <inttypes.h>
+#include <string.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)
+{
+ static uint8_t table[11][8] = {
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO},
+ {A52_MONO, A52_MONO, A52_MONO, A52_MONO,
+ A52_MONO, A52_MONO, A52_MONO, A52_MONO},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
+ A52_STEREO, A52_3F, A52_STEREO, A52_3F},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_2F1R, A52_2F1R, A52_2F1R, A52_2F1R},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_2F1R, A52_3F1R, A52_2F1R, A52_3F1R},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
+ A52_2F2R, A52_2F2R, A52_2F2R, A52_2F2R},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
+ A52_2F2R, A52_3F2R, A52_2F2R, A52_3F2R},
+ {A52_CHANNEL1, A52_MONO, A52_MONO, A52_MONO,
+ A52_MONO, A52_MONO, A52_MONO, A52_MONO},
+ {A52_CHANNEL2, A52_MONO, A52_MONO, A52_MONO,
+ A52_MONO, A52_MONO, A52_MONO, A52_MONO},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_DOLBY,
+ A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY}
+ };
+ int output;
+
+ output = flags & A52_CHANNEL_MASK;
+ if (output > A52_DOLBY)
+ return -1;
+
+ output = table[output][input & 7];
+
+ if ((output == A52_STEREO) &&
+ ((input == A52_DOLBY) || ((input == A52_3F) && (clev == LEVEL_3DB))))
+ output = A52_DOLBY;
+
+ if (flags & A52_ADJUST_LEVEL)
+ switch (CONVERT (input & 7, output)) {
+
+ case CONVERT (A52_3F, A52_MONO):
+ *level *= LEVEL_3DB / (1 + clev);
+ break;
+
+ case CONVERT (A52_STEREO, A52_MONO):
+ case CONVERT (A52_2F2R, A52_2F1R):
+ case CONVERT (A52_3F2R, A52_3F1R):
+ level_3db:
+ *level *= LEVEL_3DB;
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ if (clev < LEVEL_PLUS3DB - 1)
+ goto level_3db;
+ /* break thru */
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_2F1R):
+ case CONVERT (A52_3F1R, A52_2F2R):
+ case CONVERT (A52_3F2R, A52_2F2R):
+ *level /= 1 + clev;
+ break;
+
+ case CONVERT (A52_2F1R, A52_MONO):
+ *level *= LEVEL_PLUS3DB / (2 + slev);
+ break;
+
+ case CONVERT (A52_2F1R, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_3F):
+ *level /= 1 + slev * LEVEL_3DB;
+ break;
+
+ case CONVERT (A52_3F1R, A52_MONO):
+ *level *= LEVEL_3DB / (1 + clev + 0.5 * slev);
+ break;
+
+ case CONVERT (A52_3F1R, A52_STEREO):
+ *level /= 1 + clev + slev * LEVEL_3DB;
+ break;
+
+ case CONVERT (A52_2F2R, A52_MONO):
+ *level *= LEVEL_3DB / (1 + slev);
+ break;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ case CONVERT (A52_3F2R, A52_3F):
+ *level /= 1 + slev;
+ break;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ *level *= LEVEL_3DB / (1 + clev + slev);
+ break;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ *level /= 1 + clev + slev;
+ break;
+
+ case CONVERT (A52_MONO, A52_DOLBY):
+ *level *= LEVEL_PLUS3DB;
+ break;
+
+ case CONVERT (A52_3F, A52_DOLBY):
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ *level *= 1 / (1 + LEVEL_3DB);
+ break;
+
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ *level *= 1 / (1 + 2 * LEVEL_3DB);
+ break;
+
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ *level *= 1 / (1 + 3 * LEVEL_3DB);
+ break;
+ }
+
+ return output;
+}
+
+int 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)) {
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL):
+ case CONVERT (A52_MONO, A52_MONO):
+ case CONVERT (A52_STEREO, A52_STEREO):
+ case CONVERT (A52_3F, A52_3F):
+ case CONVERT (A52_2F1R, A52_2F1R):
+ case CONVERT (A52_3F1R, A52_3F1R):
+ case CONVERT (A52_2F2R, A52_2F2R):
+ case CONVERT (A52_3F2R, A52_3F2R):
+ case CONVERT (A52_STEREO, A52_DOLBY):
+ coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level;
+ return 0;
+
+ case CONVERT (A52_CHANNEL, A52_MONO):
+ coeff[0] = coeff[1] = level * LEVEL_6DB;
+ return 3;
+
+ case CONVERT (A52_STEREO, A52_MONO):
+ coeff[0] = coeff[1] = level * LEVEL_3DB;
+ return 3;
+
+ case CONVERT (A52_3F, A52_MONO):
+ coeff[0] = coeff[2] = level * LEVEL_3DB;
+ coeff[1] = level * clev * LEVEL_PLUS3DB;
+ return 7;
+
+ case CONVERT (A52_2F1R, A52_MONO):
+ coeff[0] = coeff[1] = level * LEVEL_3DB;
+ coeff[2] = level * slev * LEVEL_3DB;
+ return 7;
+
+ case CONVERT (A52_2F2R, A52_MONO):
+ coeff[0] = coeff[1] = level * LEVEL_3DB;
+ coeff[2] = coeff[3] = level * slev * LEVEL_3DB;
+ return 15;
+
+ case CONVERT (A52_3F1R, A52_MONO):
+ coeff[0] = coeff[2] = level * LEVEL_3DB;
+ coeff[1] = level * clev * LEVEL_PLUS3DB;
+ coeff[3] = level * slev * LEVEL_3DB;
+ return 15;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ coeff[0] = coeff[2] = level * LEVEL_3DB;
+ coeff[1] = level * clev * LEVEL_PLUS3DB;
+ coeff[3] = coeff[4] = level * slev * LEVEL_3DB;
+ return 31;
+
+ case CONVERT (A52_MONO, A52_DOLBY):
+ coeff[0] = level * LEVEL_3DB;
+ return 0;
+
+ case CONVERT (A52_3F, A52_DOLBY):
+ clev = LEVEL_3DB;
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_2F1R):
+ case CONVERT (A52_3F2R, A52_2F2R):
+ coeff[0] = coeff[2] = coeff[3] = coeff[4] = level;
+ coeff[1] = level * clev;
+ return 7;
+
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ slev = 1;
+ case CONVERT (A52_2F1R, A52_STEREO):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = level * slev * LEVEL_3DB;
+ return 7;
+
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ clev = LEVEL_3DB;
+ slev = 1;
+ case CONVERT (A52_3F1R, A52_STEREO):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = level * clev;
+ coeff[3] = level * slev * LEVEL_3DB;
+ return 15;
+
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ slev = LEVEL_3DB;
+ case CONVERT (A52_2F2R, A52_STEREO):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = coeff[3] = level * slev;
+ return 15;
+
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ clev = LEVEL_3DB;
+ case CONVERT (A52_3F2R, A52_2F1R):
+ slev = LEVEL_3DB;
+ case CONVERT (A52_3F2R, A52_STEREO):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = level * clev;
+ coeff[3] = coeff[4] = level * slev;
+ return 31;
+
+ case CONVERT (A52_3F1R, A52_3F):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = level * slev * LEVEL_3DB;
+ return 13;
+
+ case CONVERT (A52_3F2R, A52_3F):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = coeff[4] = level * slev;
+ return 29;
+
+ case CONVERT (A52_2F2R, A52_2F1R):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = coeff[3] = level * LEVEL_3DB;
+ return 12;
+
+ case CONVERT (A52_3F2R, A52_3F1R):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = coeff[4] = level * LEVEL_3DB;
+ return 24;
+
+ case CONVERT (A52_2F1R, A52_2F2R):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = level * LEVEL_3DB;
+ return 0;
+
+ case CONVERT (A52_3F1R, A52_2F2R):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = level * clev;
+ coeff[3] = level * LEVEL_3DB;
+ return 7;
+
+ case CONVERT (A52_3F1R, A52_3F2R):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = level * LEVEL_3DB;
+ return 0;
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL1):
+ coeff[0] = level;
+ coeff[1] = 0;
+ return 0;
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL2):
+ coeff[0] = 0;
+ coeff[1] = level;
+ return 0;
+ }
+
+ return -1; /* NOTREACHED */
+}
+
+static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] += src[i] + bias;
+}
+
+static void mix3to1 (sample_t * samples, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] += samples[i + 256] + samples[i + 512] + bias;
+}
+
+static void mix4to1 (sample_t * samples, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] += (samples[i + 256] + samples[i + 512] +
+ samples[i + 768] + bias);
+}
+
+static void mix5to1 (sample_t * samples, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] += (samples[i + 256] + samples[i + 512] +
+ samples[i + 768] + samples[i + 1024] + bias);
+}
+
+static void mix3to2 (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = samples[i + 256] + bias;
+ samples[i] += common;
+ samples[i + 256] = samples[i + 512] + common;
+ }
+}
+
+static void mix21to2 (sample_t * left, sample_t * right, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = right[i + 256] + bias;
+ left[i] += common;
+ right[i] += common;
+ }
+}
+
+static void mix21toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t surround;
+
+ for (i = 0; i < 256; i++) {
+ surround = samples[i + 512];
+ samples[i] += bias - surround;
+ samples[i + 256] += bias + surround;
+ }
+}
+
+static void mix31to2 (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = samples[i + 256] + samples[i + 768] + bias;
+ samples[i] += common;
+ samples[i + 256] = samples[i + 512] + common;
+ }
+}
+
+static void mix31toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common, surround;
+
+ for (i = 0; i < 256; i++) {
+ common = samples[i + 256] + bias;
+ surround = samples[i + 768];
+ samples[i] += common - surround;
+ samples[i + 256] = samples[i + 512] + common + surround;
+ }
+}
+
+static void mix22toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t surround;
+
+ for (i = 0; i < 256; i++) {
+ surround = samples[i + 512] + samples[i + 768];
+ samples[i] += bias - surround;
+ samples[i + 256] += bias + surround;
+ }
+}
+
+static void mix32to2 (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = samples[i + 256] + bias;
+ samples[i] += common + samples[i + 768];
+ samples[i + 256] = common + samples[i + 512] + samples[i + 1024];
+ }
+}
+
+static void mix32toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common, surround;
+
+ for (i = 0; i < 256; i++) {
+ common = samples[i + 256] + bias;
+ surround = samples[i + 768] + samples[i + 1024];
+ samples[i] += common - surround;
+ samples[i + 256] = samples[i + 512] + common + surround;
+ }
+}
+
+static void move2to1 (sample_t * src, sample_t * dest, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] = src[i] + src[i + 256] + bias;
+}
+
+static void zero (sample_t * samples)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] = 0;
+}
+
+void downmix (sample_t * samples, int acmod, int output, sample_t bias,
+ sample_t clev, sample_t slev)
+{
+ switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL2):
+ memcpy (samples, samples + 256, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_CHANNEL, A52_MONO):
+ case CONVERT (A52_STEREO, A52_MONO):
+ mix_2to1:
+ mix2to1 (samples, samples + 256, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_MONO):
+ if (slev == 0)
+ goto mix_2to1;
+ case CONVERT (A52_3F, A52_MONO):
+ mix_3to1:
+ mix3to1 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_MONO):
+ if (slev == 0)
+ goto mix_3to1;
+ case CONVERT (A52_2F2R, A52_MONO):
+ if (slev == 0)
+ goto mix_2to1;
+ mix4to1 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ if (slev == 0)
+ goto mix_3to1;
+ mix5to1 (samples, bias);
+ break;
+
+ case CONVERT (A52_MONO, A52_DOLBY):
+ memcpy (samples + 256, samples, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F, A52_DOLBY):
+ mix_3to2:
+ mix3to2 (samples, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_STEREO):
+ if (slev == 0)
+ break;
+ mix21to2 (samples, samples + 256, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ mix21toS (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_STEREO):
+ if (slev == 0)
+ goto mix_3to2;
+ mix31to2 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ mix31toS (samples, bias);
+ break;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ if (slev == 0)
+ break;
+ mix2to1 (samples, samples + 512, bias);
+ mix2to1 (samples + 256, samples + 768, bias);
+ break;
+
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ mix22toS (samples, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ if (slev == 0)
+ goto mix_3to2;
+ mix32to2 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ mix32toS (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_3F):
+ if (slev == 0)
+ break;
+ mix21to2 (samples, samples + 512, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F):
+ if (slev == 0)
+ break;
+ mix2to1 (samples, samples + 768, bias);
+ mix2to1 (samples + 512, samples + 1024, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_2F1R):
+ mix3to2 (samples, bias);
+ memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_2F2R, A52_2F1R):
+ mix2to1 (samples + 512, samples + 768, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ mix3to2 (samples, bias);
+ move2to1 (samples + 768, samples + 512, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F1R):
+ mix2to1 (samples + 768, samples + 1024, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_2F2R):
+ memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F1R, A52_2F2R):
+ mix3to2 (samples, bias);
+ memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F2R):
+ mix3to2 (samples, bias);
+ memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+ memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F1R, A52_3F2R):
+ memcpy (samples + 1027, samples + 768, 256 * sizeof (sample_t));
+ break;
+ }
+}
+
+void upmix (sample_t * samples, int acmod, int output)
+{
+ switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL2):
+ memcpy (samples + 256, samples, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_MONO):
+ case CONVERT (A52_2F2R, A52_MONO):
+ zero (samples + 768);
+ case CONVERT (A52_3F, A52_MONO):
+ case CONVERT (A52_2F1R, A52_MONO):
+ zero (samples + 512);
+ case CONVERT (A52_CHANNEL, A52_MONO):
+ case CONVERT (A52_STEREO, A52_MONO):
+ zero (samples + 256);
+ break;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ zero (samples + 768);
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F, A52_DOLBY):
+ mix_3to2:
+ memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t));
+ zero (samples + 256);
+ break;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ zero (samples + 768);
+ case CONVERT (A52_2F1R, A52_STEREO):
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ zero (samples + 512);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_3F):
+ case CONVERT (A52_2F2R, A52_2F1R):
+ zero (samples + 768);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F1R):
+ zero (samples + 1024);
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_2F1R):
+ mix_31to21:
+ memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
+ goto mix_3to2;
+
+ case CONVERT (A52_3F2R, A52_2F2R):
+ memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
+ goto mix_31to21;
+ }
+}
diff --git a/src/libac3/imdct.c b/src/liba52/imdct.c
index 7cc221c89..726cda973 100644
--- a/src/libac3/imdct.c
+++ b/src/liba52/imdct.c
@@ -1,25 +1,22 @@
-/*
- * imdct.c
+/*
+ * imdct.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
- * Copyright (C) Aaron Holtzman - May 1999
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
*
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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"
@@ -27,11 +24,11 @@
#include <inttypes.h>
#include <math.h>
-#include "ac3.h"
-#include "ac3_internal.h"
+#include "a52.h"
+#include "a52_internal.h"
-void (* imdct_256) (sample_t data[], sample_t delay[]);
-void (* imdct_512) (sample_t data[], sample_t delay[]);
+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;
@@ -144,7 +141,7 @@ static inline complex_t cmplx_mult(complex_t a, complex_t b)
}
void
-imdct_do_512(sample_t data[],sample_t delay[])
+imdct_do_512(sample_t data[],sample_t delay[], sample_t bias)
{
int i,k;
int p,q;
@@ -161,18 +158,16 @@ imdct_do_512(sample_t data[],sample_t delay[])
sample_t *delay_ptr;
sample_t *window_ptr;
- //
- // 512 IMDCT with source and dest data in 'data'
- //
+ /* 512 IMDCT with source and dest data in 'data' */
- // Pre IFFT complex multiply plus IFFT cmplx conjugate
+ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for( i=0; i < 128; i++) {
/* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */
buf[i].real = (data[256-2*i-1] * xcos1[i]) - (data[2*i] * xsin1[i]);
buf[i].imag = -1.0 * ((data[2*i] * xcos1[i]) + (data[256-2*i-1] * xsin1[i]));
}
- //Bit reversed shuffling
+ /* Bit reversed shuffling */
for(i=0; i<128; i++) {
k = bit_reverse_512[i];
if (k < i)
@@ -219,13 +214,13 @@ imdct_do_512(sample_t data[],sample_t delay[])
/* Window and convert to real valued signal */
for(i=0; i< 64; i++) {
- *data_ptr++ = 2.0f * (-buf[64+i].imag * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf[64-i-1].real * *window_ptr++ + *delay_ptr++);
+ *data_ptr++ = -buf[64+i].imag * *window_ptr++ + *delay_ptr++ + bias;
+ *data_ptr++ = buf[64-i-1].real * *window_ptr++ + *delay_ptr++ + bias;
}
for(i=0; i< 64; i++) {
- *data_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf[128-i-1].imag * *window_ptr++ + *delay_ptr++);
+ *data_ptr++ = -buf[i].real * *window_ptr++ + *delay_ptr++ + bias;
+ *data_ptr++ = buf[128-i-1].imag * *window_ptr++ + *delay_ptr++ + bias;
}
/* The trailing edge of the window goes into the delay line */
@@ -243,7 +238,7 @@ imdct_do_512(sample_t data[],sample_t delay[])
}
void
-imdct_do_256(sample_t data[],sample_t delay[])
+imdct_do_256(sample_t data[],sample_t delay[],sample_t bias)
{
int i,k;
int p,q;
@@ -281,7 +276,7 @@ imdct_do_256(sample_t data[],sample_t delay[])
buf_2[k].imag = -1.0f * ( data[q + 1] * xcos2[k] + data[p + 1] * xsin2[k]);
}
- //IFFT Bit reversed shuffling
+ /* IFFT Bit reversed shuffling */
for(i=0; i<64; i++) {
k = bit_reverse_256[i];
if (k < i) {
@@ -295,7 +290,7 @@ imdct_do_256(sample_t data[],sample_t delay[])
two_m = (1 << m);
two_m_plus_one = (1 << (m+1));
- //FIXME
+ /* FIXME */
if(m)
two_m = (1 << m);
else
@@ -305,7 +300,7 @@ imdct_do_256(sample_t data[],sample_t delay[])
for(i = 0; i < 64; i += two_m_plus_one) {
p = k + i;
q = p + two_m;
- //Do block 1
+ /* 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;
@@ -315,7 +310,7 @@ imdct_do_256(sample_t data[],sample_t delay[])
buf_1[q].real = tmp_a_r - tmp_b_r;
buf_1[q].imag = tmp_a_i - tmp_b_i;
- //Do block 2
+ /* 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;
@@ -348,13 +343,13 @@ imdct_do_256(sample_t data[],sample_t delay[])
/* Window and convert to real valued signal */
for(i=0; i< 64; i++) {
- *data_ptr++ = 2.0f * (-buf_1[i].imag * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf_1[64-i-1].real * *window_ptr++ + *delay_ptr++);
+ *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=0; i< 64; i++) {
- *data_ptr++ = 2.0f * (-buf_1[i].real * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf_1[64-i-1].imag * *window_ptr++ + *delay_ptr++);
+ *data_ptr++ = -buf_1[i].real * *window_ptr++ + *delay_ptr++ + bias;
+ *data_ptr++ = buf_1[64-i-1].imag * *window_ptr++ + *delay_ptr++ + bias;
}
delay_ptr = delay;
@@ -370,34 +365,37 @@ imdct_do_256(sample_t data[],sample_t delay[])
}
}
-void imdct_init (void)
+void imdct_init (uint32_t mm_accel)
{
-#ifdef LIBAC3_MLIB
- imdct_512 = imdct_do_512_mlib;
- imdct_256 = imdct_do_256_mlib;
-#else
- 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));
- }
+#ifdef LIBA52_MLIB
+ if (mm_accel & MM_ACCEL_MLIB) {
+ imdct_512 = imdct_do_512_mlib;
+ imdct_256 = imdct_do_256_mlib;
+ } else
+#endif
+ {
+ int i, j, k;
- /* 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));
- }
+ /* 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));
+ }
- 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);
+ /* 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;
}
- imdct_512 = imdct_do_512;
- imdct_256 = imdct_do_256;
-#endif
}
diff --git a/src/liba52/imdct_mlib.c b/src/liba52/imdct_mlib.c
new file mode 100644
index 000000000..dba4b0af3
--- /dev/null
+++ b/src/liba52/imdct_mlib.c
@@ -0,0 +1,135 @@
+/*
+ * 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 <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
new file mode 100644
index 000000000..b6f47247e
--- /dev/null
+++ b/src/liba52/parse.c
@@ -0,0 +1,861 @@
+/*
+ * parse.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"
+
+#include <inttypes.h>
+#include <string.h>
+
+#include "a52.h"
+#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
+
+sample_t * a52_init (uint32_t mm_accel)
+{
+ sample_t * samples;
+ int i;
+
+ imdct_init (mm_accel);
+
+ samples = memalign (16, 256 * 12 * sizeof (sample_t));
+ if (samples == NULL)
+ return NULL;
+
+ for (i = 0; i < 256 * 12; i++)
+ samples[i] = 0;
+
+ return samples;
+}
+
+static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
+
+int a52_syncinfo (uint8_t * buf, int * flags,
+ int * sample_rate, int * bit_rate)
+{
+ static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, 448,
+ 512, 576, 640};
+ static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01};
+ int frmsizecod;
+ int bitrate;
+ int half;
+ int acmod;
+
+ if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */
+ return 0;
+
+ if (buf[5] >= 0x60) /* bsid >= 12 */
+ return 0;
+ half = halfrate[buf[5] >> 3];
+
+ /* acmod, dsurmod and lfeon */
+ acmod = buf[6] >> 5;
+ *flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) |
+ ((buf[6] & lfeon[acmod]) ? A52_LFE : 0));
+
+ frmsizecod = buf[4] & 63;
+ if (frmsizecod >= 38)
+ return 0;
+ bitrate = rate [frmsizecod >> 1];
+ *bit_rate = (bitrate * 1000) >> half;
+
+ switch (buf[4] & 0xc0) {
+ case 0: /* 48 KHz */
+ *sample_rate = 48000 >> half;
+ return 4 * bitrate;
+ case 0x40:
+ *sample_rate = 44100 >> half;
+ return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
+ case 0x80:
+ *sample_rate = 32000 >> half;
+ return 6 * bitrate;
+ default:
+ return 0;
+ }
+}
+
+int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
+ sample_t * level, sample_t bias)
+{
+ static sample_t clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB};
+ static sample_t slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB};
+ int chaninfo;
+ int acmod;
+
+ state->fscod = buf[4] >> 6;
+ 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 */
+
+ if ((acmod == 2) && (bitstream_get (2) == 2)) /* dsurmod */
+ acmod = A52_DOLBY;
+
+ if ((acmod & 1) && (acmod != 1))
+ state->clev = clev[bitstream_get (2)]; /* cmixlev */
+
+ if (acmod & 4)
+ state->slev = slev[bitstream_get (2)]; /* surmixlev */
+
+ state->lfeon = bitstream_get (1);
+
+ state->output = 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
+ state->dynrng = state->level = 2 * *level;
+ state->bias = bias;
+ state->dynrnge = 1;
+ state->dynrngcall = NULL;
+
+ 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 */
+ } while (chaninfo--);
+
+ bitstream_get (2); /* copyrightb + origbs */
+
+ if (bitstream_get (1)) /* timecod1e */
+ bitstream_get (14); /* timecod1 */
+ if (bitstream_get (1)) /* timecod2e */
+ bitstream_get (14); /* timecod2 */
+
+ if (bitstream_get (1)) { /* addbsie */
+ int addbsil;
+
+ addbsil = bitstream_get (6);
+ do {
+ bitstream_get (8); /* addbsi */
+ } while (addbsil--);
+ }
+
+ return 0;
+}
+
+void a52_dynrng (a52_state_t * state,
+ sample_t (* call) (sample_t, void *), void * data)
+{
+ state->dynrnge = 0;
+ if (call) {
+ state->dynrnge = 1;
+ state->dynrngcall = call;
+ state->dynrngdata = data;
+ }
+}
+
+static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
+ uint8_t * dest)
+{
+ int exps;
+
+ while (ngrps--) {
+ exps = bitstream_get (7);
+
+ exponent += exp_1[exps];
+ if (exponent > 24)
+ return 1;
+
+ switch (expstr) {
+ case EXP_D45:
+ *(dest++) = exponent;
+ *(dest++) = exponent;
+ case EXP_D25:
+ *(dest++) = exponent;
+ case EXP_D15:
+ *(dest++) = exponent;
+ }
+
+ exponent += exp_2[exps];
+ if (exponent > 24)
+ return 1;
+
+ switch (expstr) {
+ case EXP_D45:
+ *(dest++) = exponent;
+ *(dest++) = exponent;
+ case EXP_D25:
+ *(dest++) = exponent;
+ case EXP_D15:
+ *(dest++) = exponent;
+ }
+
+ exponent += exp_3[exps];
+ if (exponent > 24)
+ return 1;
+
+ switch (expstr) {
+ case EXP_D45:
+ *(dest++) = exponent;
+ *(dest++) = exponent;
+ case EXP_D25:
+ *(dest++) = exponent;
+ case EXP_D15:
+ *(dest++) = exponent;
+ }
+ }
+
+ return 0;
+}
+
+static int parse_deltba (int8_t * deltba)
+{
+ int deltnseg, deltlen, delta, j;
+
+ memset (deltba, 0, 50);
+
+ deltnseg = bitstream_get (3);
+ j = 0;
+ do {
+ j += bitstream_get (5);
+ deltlen = bitstream_get (4);
+ delta = bitstream_get (3);
+ delta -= (delta >= 4) ? 3 : 4;
+ if (!deltlen)
+ continue;
+ if (j + deltlen >= 50)
+ return 1;
+ while (deltlen--)
+ deltba[j++] = delta;
+ } while (deltnseg--);
+
+ return 0;
+}
+
+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))
+ return 0;
+ for (i = 0; i < nfchans; i++)
+ if (state->ba[i].fsnroffst)
+ return 0;
+ return 1;
+}
+
+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;
+
+static uint16_t lfsr_state = 1;
+
+static inline int16_t dither_gen (void)
+{
+ int16_t state;
+
+ state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
+
+ lfsr_state = (uint16_t) state;
+
+ return state;
+}
+
+static void coeff_get (sample_t * coeff, uint8_t * exp, int8_t * bap,
+ sample_t level, int dither, int end)
+{
+ int i;
+ sample_t factor[25];
+
+ for (i = 0; i <= 24; i++)
+ factor[i] = scale_factor[i] * level;
+
+ i = 0;
+ while (i < end) {
+ int bapi;
+
+ bapi = bap[i];
+ switch (bapi) {
+ case 0:
+ if (dither) {
+ coeff[i++] = dither_gen() * LEVEL_3DB * factor[exp[i]];
+ continue;
+ } else {
+ coeff[i++] = 0;
+ continue;
+ }
+
+ case -1:
+ if (q_1_pointer >= 0) {
+ coeff[i++] = q_1[q_1_pointer--] * factor[exp[i]];
+ continue;
+ } else {
+ int code;
+
+ code = bitstream_get (5);
+
+ q_1_pointer = 1;
+ q_1[0] = q_1_2[code];
+ q_1[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]];
+ continue;
+ } else {
+ int code;
+
+ code = bitstream_get (7);
+
+ q_2_pointer = 1;
+ q_2[0] = q_2_2[code];
+ q_2[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]];
+ continue;
+
+ case -3:
+ if (q_4_pointer == 0) {
+ q_4_pointer = -1;
+ coeff[i++] = q_4 * factor[exp[i]];
+ continue;
+ } else {
+ int code;
+
+ code = bitstream_get (7);
+
+ q_4_pointer = 0;
+ q_4 = 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]];
+ continue;
+
+ default:
+ coeff[i++] = ((bitstream_get_2 (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])
+{
+ int sub_bnd, bnd, i, i_end, ch;
+ int8_t * bap;
+ uint8_t * exp;
+ sample_t cplco[5];
+
+ bap = state->cpl_bap;
+ exp = state->cpl_exp;
+ sub_bnd = bnd = 0;
+ i = state->cplstrtmant;
+ while (i < state->cplendmant) {
+ i_end = i + 12;
+ while (state->cplbndstrc[sub_bnd++])
+ i_end += 12;
+ for (ch = 0; ch < nfchans; ch++)
+ cplco[ch] = state->cplco[ch][bnd] * coeff[ch];
+ bnd++;
+
+ while (i < i_end) {
+ sample_t cplcoeff;
+ int bapi;
+
+ bapi = bap[i];
+ switch (bapi) {
+ case 0:
+ cplcoeff = LEVEL_3DB * scale_factor[exp[i]];
+ for (ch = 0; ch < nfchans; ch++)
+ if (state->chincpl[ch]) {
+ if (dithflag[ch])
+ samples[ch][i] = (cplcoeff * cplco[ch] *
+ dither_gen ());
+ else
+ samples[ch][i] = 0;
+ }
+ i++;
+ continue;
+
+ case -1:
+ if (q_1_pointer >= 0) {
+ cplcoeff = q_1[q_1_pointer--];
+ break;
+ } else {
+ int code;
+
+ code = bitstream_get (5);
+
+ q_1_pointer = 1;
+ q_1[0] = q_1_2[code];
+ q_1[1] = q_1_1[code];
+ cplcoeff = q_1_0[code];
+ break;
+ }
+
+ case -2:
+ if (q_2_pointer >= 0) {
+ cplcoeff = q_2[q_2_pointer--];
+ break;
+ } else {
+ int code;
+
+ code = bitstream_get (7);
+
+ q_2_pointer = 1;
+ q_2[0] = q_2_2[code];
+ q_2[1] = q_2_1[code];
+ cplcoeff = q_2_0[code];
+ break;
+ }
+
+ case 3:
+ cplcoeff = q_3[bitstream_get (3)];
+ break;
+
+ case -3:
+ if (q_4_pointer == 0) {
+ q_4_pointer = -1;
+ cplcoeff = q_4;
+ break;
+ } else {
+ int code;
+
+ code = bitstream_get (7);
+
+ q_4_pointer = 0;
+ q_4 = q_4_1[code];
+ cplcoeff = q_4_0[code];
+ break;
+ }
+
+ case 4:
+ cplcoeff = q_5[bitstream_get (4)];
+ break;
+
+ default:
+ cplcoeff = bitstream_get_2 (bapi) << (16 - bapi);
+ }
+
+ cplcoeff *= scale_factor[exp[i]];
+ for (ch = 0; ch < nfchans; ch++)
+ if (state->chincpl[ch])
+ samples[ch][i] = cplcoeff * cplco[ch];
+ i++;
+ }
+ }
+}
+
+int a52_block (a52_state_t * state, sample_t * samples)
+{
+ 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};
+ int i, nfchans, chaninfo;
+ uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl;
+ uint8_t blksw[5], dithflag[5];
+ sample_t coeff[5];
+ int chanbias;
+
+ nfchans = nfchans_tbl[state->acmod];
+
+ for (i = 0; i < nfchans; i++)
+ blksw[i] = bitstream_get (1);
+
+ for (i = 0; i < nfchans; i++)
+ dithflag[i] = bitstream_get (1);
+
+ chaninfo = !(state->acmod);
+ do {
+ if (bitstream_get (1)) { /* dynrnge */
+ int dynrng;
+
+ dynrng = bitstream_get_2 (8);
+ if (state->dynrnge) {
+ sample_t range;
+
+ range = ((((dynrng & 0x1f) | 0x20) << 13) *
+ scale_factor[3 - (dynrng >> 5)]);
+ if (state->dynrngcall)
+ range = state->dynrngcall (range, state->dynrngdata);
+ state->dynrng = state->level * range;
+ }
+ }
+ } 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};
+ int cplbegf;
+ int cplendf;
+ int ncplsubnd;
+
+ for (i = 0; i < nfchans; i++)
+ state->chincpl[i] = bitstream_get (1);
+ switch (state->acmod) {
+ case 0: case 1:
+ return 1;
+ case 2:
+ state->phsflginu = bitstream_get (1);
+ }
+ cplbegf = bitstream_get (4);
+ cplendf = bitstream_get (4);
+
+ if (cplendf + 3 - cplbegf < 0)
+ return 1;
+ state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
+ state->cplstrtbnd = bndtab[cplbegf];
+ 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 */
+ }
+ }
+
+ if (state->cplinu) {
+ int j, cplcoe;
+
+ cplcoe = 0;
+ for (i = 0; i < nfchans; i++)
+ if (state->chincpl[i])
+ if (bitstream_get (1)) { /* cplcoe */
+ int mstrcplco, cplcoexp, cplcomant;
+
+ cplcoe = 1;
+ mstrcplco = 3 * bitstream_get (2);
+ for (j = 0; j < state->ncplbnd; j++) {
+ cplcoexp = bitstream_get (4);
+ cplcomant = bitstream_get (4);
+ if (cplcoexp == 15)
+ cplcomant <<= 14;
+ else
+ cplcomant = (cplcomant | 0x10) << 13;
+ state->cplco[i][j] =
+ cplcomant * scale_factor[cplcoexp + mstrcplco];
+ }
+ }
+ if ((state->acmod == 2) && state->phsflginu && cplcoe)
+ for (j = 0; j < state->ncplbnd; j++)
+ if (bitstream_get (1)) /* phsflg */
+ state->cplco[1][j] = -state->cplco[1][j];
+ }
+
+ if ((state->acmod == 2) && (bitstream_get (1))) { /* rematstr */
+ int end;
+
+ end = (state->cplinu) ? state->cplstrtmant : 253;
+ i = 0;
+ do
+ state->rematflg[i] = bitstream_get (1);
+ while (rematrix_band[i++] < end);
+ }
+
+ cplexpstr = EXP_REUSE;
+ lfeexpstr = EXP_REUSE;
+ if (state->cplinu)
+ cplexpstr = bitstream_get (2);
+ for (i = 0; i < nfchans; i++)
+ chexpstr[i] = bitstream_get (2);
+ if (state->lfeon)
+ lfeexpstr = bitstream_get (1);
+
+ for (i = 0; i < nfchans; i++)
+ if (chexpstr[i] != EXP_REUSE) {
+ if (state->cplinu && state->chincpl[i])
+ state->endmant[i] = state->cplstrtmant;
+ else {
+ int chbwcod;
+
+ chbwcod = bitstream_get (6);
+ if (chbwcod > 60)
+ return 1;
+ state->endmant[i] = chbwcod * 3 + 73;
+ }
+ }
+
+ do_bit_alloc = 0;
+
+ if (cplexpstr != EXP_REUSE) {
+ int cplabsexp, ncplgrps;
+
+ 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))
+ return 1;
+ }
+ for (i = 0; i < nfchans; i++)
+ if (chexpstr[i] != EXP_REUSE) {
+ int grp_size, nchgrps;
+
+ 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))
+ return 1;
+ bitstream_get (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))
+ return 1;
+ }
+
+ if (bitstream_get (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);
+ }
+ if (bitstream_get (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);
+ }
+ }
+ if ((state->cplinu) && (bitstream_get (1))) { /* cplleake */
+ do_bit_alloc |= 64;
+ state->cplfleak = 2304 - (bitstream_get (3) << 8);
+ state->cplsleak = 2304 - (bitstream_get (3) << 8);
+ }
+
+ if (bitstream_get (1)) { /* deltbaie */
+ do_bit_alloc = -1;
+ if (state->cplinu)
+ state->cplba.deltbae = bitstream_get (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))
+ return 1;
+ for (i = 0; i < nfchans; i++)
+ if ((state->ba[i].deltbae == DELTA_BIT_NEW) &&
+ parse_deltba (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));
+ } 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);
+ 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]);
+ 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);
+ }
+ }
+ }
+
+ if (bitstream_get (1)) { /* skiple */
+ i = bitstream_get (9); /* skipl */
+ while (i--)
+ bitstream_get (8);
+ }
+
+ 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);
+
+ q_1_pointer = q_2_pointer = q_4_pointer = -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[i], dithflag[i], state->endmant[i]);
+
+ if (state->cplinu && state->chincpl[i]) {
+ if (!done_cpl) {
+ done_cpl = 1;
+ coeff_get_coupling (state, nfchans, coeff,
+ (sample_t (*)[256])samples, dithflag);
+ }
+ j = state->cplendmant;
+ } else
+ j = state->endmant[i];
+ do
+ (samples + 256 * i)[j] = 0;
+ while (++j < 256);
+ }
+
+ if (state->acmod == 2) {
+ int j, end, band;
+
+ end = ((state->endmant[0] < state->endmant[1]) ?
+ state->endmant[0] : state->endmant[1]);
+
+ i = 0;
+ j = 13;
+ do {
+ if (!state->rematflg[i]) {
+ j = rematrix_band[i++];
+ continue;
+ }
+ band = rematrix_band[i++];
+ if (band > end)
+ band = end;
+ do {
+ sample_t tmp0, tmp1;
+
+ tmp0 = samples[j];
+ tmp1 = (samples+256)[j];
+ samples[j] = tmp0 + tmp1;
+ (samples+256)[j] = tmp0 - tmp1;
+ } while (++j < band);
+ } while (j < end);
+ }
+
+ if (state->lfeon) {
+ if (state->output & A52_LFE) {
+ coeff_get (samples - 256, state->lfe_exp, state->lfe_bap,
+ state->dynrng, 0, 7);
+ for (i = 7; i < 256; i++)
+ (samples-256)[i] = 0;
+ 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,
+ 0, 0, 7);
+ }
+ }
+
+ i = 0;
+ if (nfchans_tbl[state->output & A52_CHANNEL_MASK] < nfchans)
+ for (i = 1; i < nfchans; i++)
+ if (blksw[i] != blksw[0])
+ break;
+
+ if (i < nfchans) {
+ if (samples[2 * 1536 - 1] == (sample_t)0x776b6e21) {
+ samples[2 * 1536 - 1] = 0;
+ upmix (samples + 1536, state->acmod, state->output);
+ }
+
+ for (i = 0; i < nfchans; i++) {
+ sample_t bias;
+
+ bias = 0;
+ if (!(chanbias & (1 << i)))
+ bias = state->bias;
+
+ if (coeff[i]) {
+ if (blksw[i])
+ imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
+ bias);
+ else
+ imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
+ bias);
+ } else {
+ int j;
+
+ for (j = 0; j < 256; j++)
+ (samples + 256 * i)[j] = bias;
+ }
+ }
+
+ 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,
+ state->clev, state->slev);
+ samples[2 * 1536 - 1] = (sample_t)0x776b6e21;
+ }
+
+ if (blksw[0])
+ for (i = 0; i < nfchans; i++)
+ 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);
+ }
+
+ return 0;
+}
diff --git a/src/libac3/tables.h b/src/liba52/tables.h
index 28f030895..ddac9e5cb 100644
--- a/src/libac3/tables.h
+++ b/src/liba52/tables.h
@@ -1,25 +1,22 @@
-/*
- * parse.c
+/*
+ * tables.h
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
- * Copyright (C) Aaron Holtzman - May 1999
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
*
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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
*/
static int8_t exp_1[128] = {
diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c
new file mode 100644
index 000000000..6d4b89078
--- /dev/null
+++ b/src/liba52/xine_decoder.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine 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.
+ *
+ * xine 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
+ *
+ * $Id: xine_decoder.c,v 1.1 2001/08/29 00:51:57 guenter Exp $
+ *
+ * stuff needed to turn liba52 into a xine decoder plugin
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "audio_out.h"
+#include "a52.h"
+#include "a52_internal.h"
+#include "buffer.h"
+#include "xine_internal.h"
+#include "cpu_accel.h"
+
+#undef DEBUG_A52
+#ifdef DEBUG_A52
+int a52file;
+#endif
+
+typedef struct a52dec_decoder_s {
+ audio_decoder_t audio_decoder;
+
+ uint32_t pts;
+ uint32_t last_pts;
+
+ uint8_t frame_buffer[3840];
+ uint8_t *frame_ptr;
+ int sync_todo;
+ int frame_length, frame_todo;
+ uint16_t syncword;
+
+ a52_state_t a52_state;
+ int a52_flags;
+ int a52_bit_rate;
+ int a52_sample_rate;
+ float a52_level;
+ int have_lfe;
+
+ int a52_flags_map[8];
+ int ao_flags_map[8];
+
+ int16_t int_samples [6 * 256 * 6];
+ sample_t *samples;
+
+ ao_instance_t *audio_out;
+ int audio_caps;
+ int bypass_mode;
+ int output_sampling_rate;
+ int output_open;
+ int output_mode;
+
+ int disable_dynrng ;
+} a52dec_decoder_t;
+
+int a52dec_can_handle (audio_decoder_t *this_gen, int buf_type) {
+ return ((buf_type & 0xFFFF0000) == BUF_AUDIO_A52) ;
+}
+
+
+void a52dec_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) {
+
+ a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen;
+ /* int i; */
+
+ this->audio_out = audio_out;
+ this->audio_caps = audio_out->get_capabilities(audio_out);
+ this->syncword = 0;
+ this->sync_todo = 7;
+ this->output_open = 0;
+ this->pts = 0;
+ this->last_pts = 0;
+
+ this->samples = a52_init (mm_accel());
+
+ /*
+ * find out if this driver supports a52 output
+ * or, if not, how many channels we've got
+ */
+
+ if (this->audio_caps & AO_CAP_MODE_A52)
+ this->bypass_mode = 1;
+ else {
+ this->bypass_mode = 0;
+
+ this->a52_flags_map[A52_MONO] = A52_MONO;
+ this->a52_flags_map[A52_STEREO] = A52_STEREO;
+ this->a52_flags_map[A52_3F] = A52_STEREO;
+ this->a52_flags_map[A52_2F1R] = A52_STEREO;
+ this->a52_flags_map[A52_3F1R] = A52_STEREO;
+ this->a52_flags_map[A52_2F2R] = A52_STEREO;
+ this->a52_flags_map[A52_3F2R] = A52_STEREO;
+
+ this->ao_flags_map[A52_MONO] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_STEREO] = AO_CAP_MODE_STEREO;
+ this->ao_flags_map[A52_3F] = AO_CAP_MODE_STEREO;
+ this->ao_flags_map[A52_2F1R] = AO_CAP_MODE_STEREO;
+ this->ao_flags_map[A52_3F1R] = AO_CAP_MODE_STEREO;
+ this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_STEREO;
+ this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_STEREO;
+
+ /* find best mode */
+ if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) {
+
+ this->a52_flags_map[A52_2F2R] = A52_2F2R;
+ this->a52_flags_map[A52_3F2R] = A52_3F2R | A52_LFE;
+ this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL;
+ this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_5CHANNEL;
+
+ } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) {
+
+ this->a52_flags_map[A52_2F2R] = A52_2F2R;
+ this->a52_flags_map[A52_3F2R] = A52_3F2R;
+ this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL;
+ this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_5CHANNEL;
+
+ } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) {
+
+ this->a52_flags_map[A52_2F2R] = A52_2F2R;
+ this->a52_flags_map[A52_3F2R] = A52_2F2R;
+
+ this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_4CHANNEL;
+ this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_4CHANNEL;
+
+ /* else if (this->audio_caps & AO_CAP_MODE_STEREO)
+ defaults are ok */
+ } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) {
+ printf ("HELP! a mono-only audio driver?!\n");
+
+ this->a52_flags_map[A52_MONO] = A52_MONO;
+ this->a52_flags_map[A52_STEREO] = A52_MONO;
+ this->a52_flags_map[A52_3F] = A52_MONO;
+ this->a52_flags_map[A52_2F1R] = A52_MONO;
+ this->a52_flags_map[A52_3F1R] = A52_MONO;
+ this->a52_flags_map[A52_2F2R] = A52_MONO;
+ this->a52_flags_map[A52_3F2R] = A52_MONO;
+
+ this->ao_flags_map[A52_MONO] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_STEREO] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_3F] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_2F1R] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_3F1R] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_2F2R] = AO_CAP_MODE_MONO;
+ this->ao_flags_map[A52_3F2R] = AO_CAP_MODE_MONO;
+ }
+ }
+
+ /*
+ for (i = 0; i<8; i++)
+ this->a52_flags_map[i] |= A52_ADJUST_LEVEL;
+*/
+#ifdef DEBUG_A52
+ a52file = open ("test.a52", O_CREAT | O_WRONLY | O_TRUNC, 0644);
+#endif
+}
+
+static inline int16_t blah (int32_t i)
+{
+ if (i > 0x43c07fff)
+ return 32767;
+ else if (i < 0x43bf8000)
+ return -32768;
+ else
+ return i - 0x43c00000;
+}
+
+static inline void float_to_int (float * _f, int16_t * s16, int num_channels) {
+ int i;
+ int32_t * f = (int32_t *) _f; /* XXX assumes IEEE float format */
+
+ for (i = 0; i < 256; i++) {
+ s16[num_channels*i] = blah (f[i]);
+ }
+}
+
+static void a52dec_decode_frame (a52dec_decoder_t *this, uint32_t pts) {
+
+ int output_mode = AO_CAP_MODE_STEREO;
+
+ /*
+ * do we want to decode this frame in software?
+ */
+
+ if (!this->bypass_mode) {
+
+ int a52_output_flags, i;
+ sample_t level = this->a52_level;
+
+ /*
+ * oki, decode this frame in software
+ */
+
+ /* determine output mode */
+
+ a52_output_flags = this->a52_flags_map[this->a52_flags & A52_CHANNEL_MASK];
+
+ if (a52_frame (&this->a52_state,
+ this->frame_buffer,
+ &a52_output_flags,
+ &level, 384)) {
+ printf ("liba52: a52_frame error\n");
+ return;
+ }
+
+ if (this->disable_dynrng)
+ a52_dynrng (&this->a52_state, NULL, NULL);
+
+ this->have_lfe = a52_output_flags & A52_LFE;
+ if (this->have_lfe)
+ output_mode = AO_CAP_MODE_5_1CHANNEL;
+ else
+ output_mode = this->ao_flags_map[a52_output_flags];
+
+ /*
+ * (re-)open output device
+ */
+
+ if (!this->output_open
+ || (this->a52_sample_rate != this->output_sampling_rate)
+ || (output_mode != this->output_mode)) {
+
+ if (this->output_open)
+ this->audio_out->close (this->audio_out);
+
+
+ this->output_open = (this->audio_out->open (this->audio_out, 16,
+ this->a52_sample_rate,
+ output_mode) == 1);
+ this->output_sampling_rate = this->a52_sample_rate;
+ this->output_mode = output_mode;
+ }
+
+
+ if (!this->output_open)
+ return;
+
+
+ /*
+ * decode a52 and convert/interleave samples
+ */
+
+ for (i = 0; i < 6; i++) {
+ if (a52_block (&this->a52_state, this->samples)) {
+ printf ("liba52: a52_block error\n");
+ return;
+ }
+
+ switch (output_mode) {
+ case AO_CAP_MODE_MONO:
+ float_to_int (&this->samples[0], this->int_samples+(i*256), 1);
+ break;
+ case AO_CAP_MODE_STEREO:
+ float_to_int (&this->samples[0*256], this->int_samples+(i*256*2), 2);
+ float_to_int (&this->samples[1*256], this->int_samples+(i*256*2)+1, 2);
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ float_to_int (&this->samples[0*256], this->int_samples+(i*256*4), 4); /* L */
+ float_to_int (&this->samples[1*256], this->int_samples+(i*256*4)+1, 4); /* R */
+ float_to_int (&this->samples[2*256], this->int_samples+(i*256*4)+2, 4); /* RL */
+ float_to_int (&this->samples[3*256], this->int_samples+(i*256*4)+3, 4); /* RR */
+ break;
+ case AO_CAP_MODE_5CHANNEL:
+ float_to_int (&this->samples[0*256], this->int_samples+(i*256*5)+0, 5); /* L */
+ float_to_int (&this->samples[1*256], this->int_samples+(i*256*5)+4, 5); /* C */
+ float_to_int (&this->samples[2*256], this->int_samples+(i*256*5)+1, 5); /* R */
+ float_to_int (&this->samples[3*256], this->int_samples+(i*256*5)+2, 5); /* RL */
+ float_to_int (&this->samples[4*256], this->int_samples+(i*256*5)+3, 5); /* RR */
+ break;
+ case AO_CAP_MODE_5_1CHANNEL:
+ float_to_int (&this->samples[0*256], this->int_samples+(i*256*6)+5, 6); /* lfe */
+ float_to_int (&this->samples[1*256], this->int_samples+(i*256*6)+0, 6); /* L */
+ float_to_int (&this->samples[2*256], this->int_samples+(i*256*6)+4, 6); /* C */
+ float_to_int (&this->samples[3*256], this->int_samples+(i*256*6)+1, 6); /* R */
+ float_to_int (&this->samples[4*256], this->int_samples+(i*256*6)+2, 6); /* RL */
+ float_to_int (&this->samples[5*256], this->int_samples+(i*256*6)+3, 6); /* RR */
+ break;
+ default:
+ printf ("liba52: help - unsupported mode %08x\n", output_mode);
+ }
+ }
+
+ /* output decoded samples */
+
+ this->audio_out->write (this->audio_out,
+ this->int_samples,
+ 256*6,
+ pts);
+ pts = 0;
+
+ } else {
+
+ /*
+ * loop through a52 data
+ */
+
+ if (!this->output_open) {
+
+ int sample_rate, bit_rate, flags;
+
+ a52_syncinfo (this->frame_buffer, &flags, &sample_rate, &bit_rate);
+
+ this->output_open = (this->audio_out->open (this->audio_out, 16,
+ sample_rate,
+ AO_CAP_MODE_A52) == 1);
+ this->output_mode = AO_CAP_MODE_A52;
+ }
+
+ if (this->output_open) {
+ this->audio_out->write (this->audio_out,
+ (int16_t*)this->frame_buffer,
+ this->frame_length,
+ pts);
+ }
+ }
+}
+
+void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
+
+ a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen;
+ uint8_t *current = buf->content;
+ uint8_t *end = buf->content + buf->size;
+ uint8_t byte;
+
+ if (buf->decoder_info[0] == 0)
+ return;
+
+ /*
+ printf ("liba52: got buffer, pts =%d, pts - last_pts=%d\n",
+ buf->PTS, buf->PTS - this->last_pts);
+
+ this->last_pts = buf->PTS;
+ */
+
+ if (buf->PTS)
+ this->pts = buf->PTS;
+
+
+ while (current != end) {
+
+ if ( (this->sync_todo == 0) && (this->frame_todo == 0) ) {
+ a52dec_decode_frame (this, this->pts);
+#ifdef DEBUG_A52
+ write (a52file, this->frame_buffer, this->frame_length);
+#endif
+ this->pts = 0;
+ this->sync_todo = 7;
+ this->syncword = 0;
+ }
+
+ while (1) {
+ byte = *current++;
+
+ if (this->sync_todo>0) {
+
+ /* search and collect syncinfo */
+
+ if (this->syncword != 0x0b77) {
+ this->syncword = (this->syncword << 8) | byte;
+
+ if (this->syncword == 0x0b77) {
+
+ this->frame_buffer[0] = 0x0b;
+ this->frame_buffer[1] = 0x77;
+
+ this->sync_todo = 5;
+ this->frame_ptr = this->frame_buffer+2;
+ }
+ } else {
+ *this->frame_ptr++ = byte;
+ this->sync_todo--;
+
+ if (this->sync_todo==0) {
+
+ this->frame_length = a52_syncinfo (this->frame_buffer,
+ &this->a52_flags,
+ &this->a52_sample_rate,
+ &this->a52_bit_rate);
+ if (this->frame_length) {
+ this->frame_todo = this->frame_length - 7;
+ } else {
+ this->sync_todo = 7;
+ this->syncword = 0;
+ printf ("liba52: skip frame of zero length\n");
+ }
+
+ }
+
+ }
+ } else {
+
+ *this->frame_ptr++ = byte;
+ this->frame_todo--;
+
+ if (this->frame_todo == 0) {
+ if (current == end)
+ return ;
+ break;
+ }
+ }
+
+ if (current == end)
+ return ;
+ }
+ }
+}
+
+void a52dec_close (audio_decoder_t *this_gen) {
+
+ a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen;
+
+ if (this->output_open)
+ this->audio_out->close (this->audio_out);
+
+ this->output_open = 0;
+
+#ifdef DEBUG_A52
+ close (a52file);
+#endif
+}
+
+static char *a52dec_get_id(void) {
+ return "a/52dec";
+}
+
+audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t *cfg) {
+
+ a52dec_decoder_t *this ;
+
+ if (iface_version != 2) {
+ printf( "liba52: plugin doesn't support plugin API version %d.\n"
+ "liba52: this means there's a version mismatch between xine and this "
+ "liba52: decoder plugin.\nInstalling current plugins should help.\n",
+ iface_version);
+ return NULL;
+ }
+
+ this = (a52dec_decoder_t *) malloc (sizeof (a52dec_decoder_t));
+
+ this->audio_decoder.interface_version = 2;
+ this->audio_decoder.can_handle = a52dec_can_handle;
+ this->audio_decoder.init = a52dec_init;
+ this->audio_decoder.decode_data = a52dec_decode_data;
+ this->audio_decoder.close = a52dec_close;
+ this->audio_decoder.get_identifier = a52dec_get_id;
+ this->audio_decoder.priority = 1;
+
+
+ this->a52_level = (float) cfg->lookup_int (cfg, "a52_level", 100) / 100.0;
+ this->disable_dynrng = !cfg->lookup_int (cfg, "a52_dynrng", 0);
+
+ return (audio_decoder_t *) this;
+}
+
diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h
deleted file mode 100644
index 03b849357..000000000
--- a/src/libac3/ac3.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * ac3.h
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-typedef float sample_t;
-
-typedef struct ac3_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
-} ac3_ba_t;
-
-typedef struct ac3_state_s {
- sample_t * delay; // delay samples for imdct
-
- 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
-
- 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
- ac3_ba_t cplba; // coupling bit allocation parameters
- ac3_ba_t ba[5]; // channel bit allocation parameters
- ac3_ba_t lfeba; // lfe bit allocation parameters
-
- uint16_t cplfleak; // coupling fast leak init
- uint16_t cplsleak; // coupling slow leak init
-
- // derived bit allocation information
- int8_t fbw_bap[5][256];
- int8_t cpl_bap[256];
- int8_t lfe_bap[7];
-} ac3_state_t;
-
-#define AC3_CHANNEL 0
-#define AC3_MONO 1
-#define AC3_STEREO 2
-#define AC3_3F 3
-#define AC3_2F1R 4
-#define AC3_3F1R 5
-#define AC3_2F2R 6
-#define AC3_3F2R 7
-#define AC3_CHANNEL1 8
-#define AC3_CHANNEL2 9
-#define AC3_DOLBY 10
-#define AC3_CHANNEL_MASK 15
-
-#define AC3_LFE 16
-#define AC3_ADJUST_LEVEL 32
-
-void ac3_init (void);
-int ac3_syncinfo (uint8_t * buf, int * flags,
- int * sample_rate, int * bit_rate);
-int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags,
- sample_t * level, sample_t bias, sample_t * delay);
-int ac3_block (ac3_state_t * state, sample_t samples[][256]);
diff --git a/src/libac3/ac3_internal.h b/src/libac3/ac3_internal.h
deleted file mode 100644
index 065ccbb36..000000000
--- a/src/libac3/ac3_internal.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ac3_internal.h
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define LEVEL_PLUS3DB 1.4142135623730951
-#define LEVEL_3DB 0.7071067811865476
-#define LEVEL_45DB 0.5946035575013605
-#define LEVEL_6DB 0.5
-
-#define EXP_REUSE (0)
-#define EXP_D15 (1)
-#define EXP_D25 (2)
-#define EXP_D45 (3)
-
-#define DELTA_BIT_REUSE (0)
-#define DELTA_BIT_NEW (1)
-#define DELTA_BIT_NONE (2)
-#define DELTA_BIT_RESERVED (3)
-
-void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
- int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap);
-
-int downmix_init (int input, int flags, sample_t * level,
- sample_t clev, sample_t slev);
-void downmix (sample_t * samples, int acmod, int output,
- sample_t level, sample_t bias, sample_t clev, sample_t slev);
-
-void imdct_init (void);
-extern void (* imdct_256) (sample_t * data, sample_t * delay);
-extern void (* imdct_512) (sample_t * data, sample_t * delay);
-void imdct_do_256_mlib (sample_t * data, sample_t * delay);
-void imdct_do_512_mlib (sample_t * data, sample_t * delay);
diff --git a/src/libac3/bitstream.c b/src/libac3/bitstream.c
deleted file mode 100644
index 6e2e36497..000000000
--- a/src/libac3/bitstream.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * bitstream.c
- *
- * Copyright (C) Aaron Holtzman - Dec 1999
- *
- * This file is part of ac3dec, a free AC-3 audio decoder
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "ac3.h"
-#include "ac3_internal.h"
-#include "bitstream.h"
-
-#define BUFFER_SIZE 4096
-
-struct uint32_alignment {
- char a;
- uint32_t b;
-};
-#define UINT32_ALIGNMENT offsetof(struct uint32_alignment, b)
-
-
-static uint32_t *buffer_start;
-
-uint32_t bits_left;
-uint32_t current_word;
-
-void bitstream_set_ptr (uint8_t * buf)
-{
- int align = (long)buf & (UINT32_ALIGNMENT-1);
- buffer_start = (uint32_t *) (buf - align);
- bits_left = 0;
- if (align > 0) bitstream_get(align * 8);
-}
-
-static inline void
-bitstream_fill_current()
-{
- uint32_t tmp_word = *buffer_start++;
- current_word = swab32(tmp_word);
-}
-
-//
-// The fast paths for _get is in the
-// bitstream.h header file so it can be inlined.
-//
-// The "bottom half" of this routine is suffixed _bh
-//
-// -ah
-//
-
-uint32_t
-bitstream_get_bh(uint32_t num_bits)
-{
- uint32_t result;
-
- num_bits -= bits_left;
- result = (current_word << (32 - bits_left)) >> (32 - bits_left);
-
- bitstream_fill_current();
-
- if(num_bits != 0)
- result = (result << num_bits) | (current_word >> (32 - num_bits));
-
- bits_left = 32 - num_bits;
-
- return result;
-}
diff --git a/src/libac3/bitstream.h b/src/libac3/bitstream.h
deleted file mode 100644
index 84f3287c8..000000000
--- a/src/libac3/bitstream.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * bitstream.h
- *
- * Copyright (C) Aaron Holtzman - Dec 1999
- *
- * This file is part of ac3dec, a free AC-3 audio decoder
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-//My new and improved vego-matic endian swapping routine
-//(stolen from the kernel)
-#ifdef WORDS_BIGENDIAN
-
-# define swab32(x) (x)
-
-#else
-
-# if defined (__i386__)
-
-# define swab32(x) __i386_swab32(x)
- static inline const uint32_t __i386_swab32(uint32_t x)
- {
- __asm__("bswap %0" : "=r" (x) : "0" (x));
- return x;
- }
-
-# else
-
-# define swab32(x)\
-((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \
- (((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3]))
-
-# endif
-#endif
-
-extern uint32_t bits_left;
-extern uint32_t current_word;
-
-void bitstream_set_ptr (uint8_t * buf);
-uint32_t bitstream_get_bh(uint32_t num_bits);
-
-static inline uint32_t
-bitstream_get(uint32_t num_bits)
-{
- uint32_t result;
-
- if(num_bits < bits_left) {
- result = (current_word << (32 - bits_left)) >> (32 - num_bits);
- bits_left -= num_bits;
- return result;
- }
-
- return bitstream_get_bh(num_bits);
-}
diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c
deleted file mode 100644
index 498471798..000000000
--- a/src/libac3/downmix.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- *
- * downmix.c
- *
- * Copyright (C) Aaron Holtzman - Sept 1999
- *
- * Originally based on code by Yuqing Deng.
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-#include "config.h"
-
-#include <inttypes.h>
-
-#include "ac3.h"
-#include "ac3_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)
-{
- static uint8_t table[11][8] = {
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO,
- AC3_STEREO, AC3_STEREO, AC3_STEREO, AC3_STEREO},
- {AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO,
- AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO,
- AC3_STEREO, AC3_STEREO, AC3_STEREO, AC3_STEREO},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_3F,
- AC3_STEREO, AC3_3F, AC3_STEREO, AC3_3F},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO,
- AC3_2F1R, AC3_2F1R, AC3_2F1R, AC3_2F1R},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO,
- AC3_2F1R, AC3_3F1R, AC3_2F1R, AC3_3F1R},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_3F,
- AC3_2F2R, AC3_2F2R, AC3_2F2R, AC3_2F2R},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_3F,
- AC3_2F2R, AC3_3F2R, AC3_2F2R, AC3_3F2R},
- {AC3_CHANNEL1, AC3_MONO, AC3_MONO, AC3_MONO,
- AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO},
- {AC3_CHANNEL2, AC3_MONO, AC3_MONO, AC3_MONO,
- AC3_MONO, AC3_MONO, AC3_MONO, AC3_MONO},
- {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_DOLBY,
- AC3_DOLBY, AC3_DOLBY, AC3_DOLBY, AC3_DOLBY}
- };
- int output;
-
- output = flags & AC3_CHANNEL_MASK;
- if (output > AC3_DOLBY)
- return -1;
-
- output = table[output][input & 7];
-
- if ((output == AC3_STEREO) &&
- ((input == AC3_DOLBY) || ((input == AC3_3F) && (clev == LEVEL_3DB))))
- output = AC3_DOLBY;
-
- if (flags & AC3_ADJUST_LEVEL)
- switch (CONVERT (input & 7, output)) {
-
- case CONVERT (AC3_3F, AC3_MONO):
- *level *= LEVEL_3DB / (1 + clev);
- break;
-
- case CONVERT (AC3_STEREO, AC3_MONO):
- case CONVERT (AC3_2F2R, AC3_2F1R):
- case CONVERT (AC3_3F2R, AC3_3F1R):
- level_3db:
- *level *= LEVEL_3DB;
- break;
-
- case CONVERT (AC3_3F2R, AC3_2F1R):
- if (clev < LEVEL_PLUS3DB - 1)
- goto level_3db;
- // break thru
- case CONVERT (AC3_3F, AC3_STEREO):
- case CONVERT (AC3_3F1R, AC3_2F1R):
- case CONVERT (AC3_3F1R, AC3_2F2R):
- case CONVERT (AC3_3F2R, AC3_2F2R):
- *level /= 1 + clev;
- break;
-
- case CONVERT (AC3_2F1R, AC3_MONO):
- *level *= LEVEL_PLUS3DB / (2 + slev);
- break;
-
- case CONVERT (AC3_2F1R, AC3_STEREO):
- case CONVERT (AC3_3F1R, AC3_3F):
- *level /= 1 + slev * LEVEL_3DB;
- break;
-
- case CONVERT (AC3_3F1R, AC3_MONO):
- *level *= LEVEL_3DB / (1 + clev + 0.5 * slev);
- break;
-
- case CONVERT (AC3_3F1R, AC3_STEREO):
- *level /= 1 + clev + slev * LEVEL_3DB;
- break;
-
- case CONVERT (AC3_2F2R, AC3_MONO):
- *level *= LEVEL_3DB / (1 + slev);
- break;
-
- case CONVERT (AC3_2F2R, AC3_STEREO):
- case CONVERT (AC3_3F2R, AC3_3F):
- *level /= (1 + slev);
- break;
-
- case CONVERT (AC3_3F2R, AC3_MONO):
- *level *= LEVEL_3DB / (1 + clev + slev);
- break;
-
- case CONVERT (AC3_3F2R, AC3_STEREO):
- *level /= 1 + clev + slev;
- break;
-
- case CONVERT (AC3_MONO, AC3_DOLBY):
- *level *= LEVEL_PLUS3DB;
- break;
-
- case CONVERT (AC3_3F, AC3_DOLBY):
- case CONVERT (AC3_2F1R, AC3_DOLBY):
- *level *= 1 / (1 + LEVEL_3DB);
- break;
-
- case CONVERT (AC3_3F1R, AC3_DOLBY):
- case CONVERT (AC3_2F2R, AC3_DOLBY):
- *level *= 1 / (1 + 2 * LEVEL_3DB);
- break;
-
- case CONVERT (AC3_3F2R, AC3_DOLBY):
- *level *= 1 / (1 + 3 * LEVEL_3DB);
- break;
- }
-
- return output;
-}
-
-static void mix1to1 (sample_t * samples, sample_t level, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = samples[i] * level + bias;
-}
-
-static void move1to1 (sample_t * src, sample_t * dest,
- sample_t level, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- dest[i] = src[i] * level + bias;
-}
-
-static void mix2to1 (sample_t * samples, sample_t level, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = (samples[i] + samples[i + 256]) * level + bias;
-}
-
-static void move2to1 (sample_t * src, sample_t * dest,
- sample_t level, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- dest[i] = (src[i] + src[i + 256]) * level + bias;
-}
-
-static void mix3to1 (sample_t * samples, sample_t level, sample_t clev,
- sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = ((samples[i] + samples[i + 512]) * level +
- samples[i + 256] * clev + bias);
-}
-
-static void mix21to1 (sample_t * samples, sample_t level, sample_t slev,
- sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = ((samples[i] + samples[i + 256]) * level +
- samples[i + 512] * slev + bias);
-}
-
-static void mix31to1 (sample_t * samples, sample_t level,
- sample_t clev, sample_t slev, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = ((samples[i] + samples[i + 512]) * level +
- samples[i + 256] * clev + samples[i + 768] * slev +
- bias);
-}
-
-static void mix22to1 (sample_t * samples, sample_t level, sample_t slev,
- sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = ((samples[i] + samples[i + 256]) * level +
- (samples[i + 512] + samples[i + 768]) * slev + bias);
-}
-
-static void mix32to1 (sample_t * samples, sample_t level,
- sample_t clev, sample_t slev, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- samples[i] = ((samples[i] + samples[i + 512]) * level +
- samples[i + 256] * clev +
- (samples[i + 768] + samples[i + 1024]) * slev + bias);
-}
-
-static void mix1to2 (sample_t * src, sample_t * dest,
- sample_t level, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- dest[i] = src[i] = src[i] * level + bias;
-}
-
-static void mix3to2 (sample_t * samples, sample_t level, sample_t clev,
- sample_t bias)
-{
- int i;
- sample_t common;
-
- for (i = 0; i < 256; i++) {
- common = samples[i + 256] * clev + bias;
- samples[i] = samples[i] * level + common;
- samples[i + 256] = samples[i + 512] * level + common;
- }
-}
-
-static void mix21to2 (sample_t * left, sample_t * right,
- sample_t level, sample_t slev, sample_t bias)
-{
- int i;
- sample_t common;
-
- for (i = 0; i < 256; i++) {
- common = right[i + 256] * slev + bias;
- left[i] = left[i] * level + common;
- right[i] = right[i] * level + common;
- }
-}
-
-static void mix11to1 (sample_t * front, sample_t * rear,
- sample_t level, sample_t slev, sample_t bias)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- front[i] = front[i] * level + rear[i] * slev + bias;
-}
-
-static void mix31to2 (sample_t * samples, sample_t level,
- sample_t clev, sample_t slev, sample_t bias)
-{
- int i;
- sample_t common;
-
- for (i = 0; i < 256; i++) {
- common = samples[i + 256] * clev + samples[i + 768] * slev + bias;
- samples[i] = samples[i] * level + common;
- samples[i + 256] = samples[i + 512] * level + common;
- }
-}
-
-static void mix32to2 (sample_t * samples, sample_t level,
- sample_t clev, sample_t slev, sample_t bias)
-{
- int i;
- sample_t common;
-
- for (i = 0; i < 256; i++) {
- common = samples[i + 256] * clev + bias;
- samples[i] = samples[i] * level + common + samples[i + 768] * slev;
- samples[i + 256] = (samples[i + 512] * level + common +
- samples[i + 1024] * slev);
- }
-}
-
-static void mix21toS (sample_t * samples,
- sample_t level, sample_t level3db, sample_t bias)
-{
- int i;
- sample_t surround;
-
- for (i = 0; i < 256; i++) {
- surround = samples[i + 512] * level3db;
- samples[i] = samples[i] * level - surround + bias;
- samples[i + 256] = samples[i + 256] * level + surround + bias;
- }
-}
-
-static void mix22toS (sample_t * samples,
- sample_t level, sample_t level3db, sample_t bias)
-{
- int i;
- sample_t surround;
-
- for (i = 0; i < 256; i++) {
- surround = (samples[i + 512] + samples[i + 768]) * level3db;
- samples[i] = samples[i] * level - surround + bias;
- samples[i + 256] = samples[i + 256] * level + surround + bias;
- }
-}
-
-static void mix31toS (sample_t * samples,
- sample_t level, sample_t level3db, sample_t bias)
-{
- int i;
- sample_t common, surround;
-
- for (i = 0; i < 256; i++) {
- common = samples[i + 256] * level3db + bias;
- surround = samples[i + 768] * level3db;
- samples[i] = samples[i] * level + common - surround;
- samples[i + 256] = samples[i + 512] * level + common + surround;
- }
-}
-
-static void mix32toS (sample_t * samples,
- sample_t level, sample_t level3db, sample_t bias)
-{
- int i;
- sample_t common, surround;
-
- for (i = 0; i < 256; i++) {
- common = samples[i + 256] * level3db + bias;
- surround = (samples[i + 768] + samples[i + 1024]) * level3db;
- samples[i] = samples[i] * level + common - surround;
- samples[i + 256] = samples[i + 512] * level + common + surround;
- }
-}
-
-void downmix (sample_t * samples, int acmod, int output,
- sample_t level, sample_t bias, sample_t clev, sample_t slev)
-{
- switch (CONVERT (acmod, output & AC3_CHANNEL_MASK)) {
-
- case CONVERT (AC3_3F2R, AC3_3F2R):
- mix1to1 (samples + 1024, level, bias);
- case CONVERT (AC3_3F1R, AC3_3F1R):
- case CONVERT (AC3_2F2R, AC3_2F2R):
- mix1to1 (samples + 768, level, bias);
- case CONVERT (AC3_3F, AC3_3F):
- case CONVERT (AC3_2F1R, AC3_2F1R):
- mix_3to3:
- mix1to1 (samples + 512, level, bias);
- case CONVERT (AC3_CHANNEL, AC3_CHANNEL):
- case CONVERT (AC3_STEREO, AC3_STEREO):
- case CONVERT (AC3_STEREO, AC3_DOLBY):
- mix_2to2:
- mix1to1 (samples + 256, level, bias);
- case CONVERT (AC3_CHANNEL, AC3_CHANNEL1):
- case CONVERT (AC3_MONO, AC3_MONO):
- mix1to1 (samples, level, bias);
- break;
-
- case CONVERT (AC3_CHANNEL, AC3_CHANNEL2):
- move1to1 (samples + 256, samples, level, bias);
- break;
-
- case CONVERT (AC3_STEREO, AC3_MONO):
- mix_2to1:
- mix2to1 (samples, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_2F1R, AC3_MONO):
- if (slev == 0)
- goto mix_2to1;
- mix21to1 (samples, level * LEVEL_3DB, level * slev * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_2F2R, AC3_MONO):
- if (slev == 0)
- goto mix_2to1;
- mix22to1 (samples, level * LEVEL_3DB, level * slev * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F, AC3_MONO):
- mix_3to1:
- mix3to1 (samples, level * LEVEL_3DB, level * clev * LEVEL_PLUS3DB,
- bias);
- break;
-
- case CONVERT (AC3_3F1R, AC3_MONO):
- if (slev == 0)
- goto mix_3to1;
- mix31to1 (samples, level * LEVEL_3DB, level * clev * LEVEL_PLUS3DB,
- level * slev * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F2R, AC3_MONO):
- if (slev == 0)
- goto mix_3to1;
- mix32to1 (samples, level * LEVEL_3DB, level * clev * LEVEL_PLUS3DB,
- level * slev * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_CHANNEL, AC3_MONO):
- mix2to1 (samples, level * LEVEL_6DB, bias);
- break;
-
- case CONVERT (AC3_MONO, AC3_DOLBY):
- mix1to2 (samples, samples + 256, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F, AC3_DOLBY):
- clev = LEVEL_3DB;
- case CONVERT (AC3_3F, AC3_STEREO):
- mix_3to2:
- mix3to2 (samples, level, level * clev, bias);
- break;
-
- case CONVERT (AC3_2F1R, AC3_DOLBY):
- mix21toS (samples, level, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F1R, AC3_DOLBY):
- mix31toS (samples, level, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_2F2R, AC3_DOLBY):
- mix22toS (samples, level, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F2R, AC3_DOLBY):
- mix32toS (samples, level, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_2F1R, AC3_STEREO):
- if (slev == 0)
- goto mix_2to2;
- mix21to2 (samples, samples + 256, level, level * slev * LEVEL_3DB,
- bias);
- break;
-
- case CONVERT (AC3_3F1R, AC3_STEREO):
- if (slev == 0)
- goto mix_3to2;
- mix31to2 (samples, level, level * clev, level * slev * LEVEL_3DB,
- bias);
- break;
-
- case CONVERT (AC3_2F2R, AC3_STEREO):
- if (slev == 0)
- goto mix_2to2;
- mix11to1 (samples, samples + 512, level, level * slev, bias);
- mix11to1 (samples + 256, samples + 768, level, level * slev, bias);
- break;
-
- case CONVERT (AC3_3F2R, AC3_STEREO):
- if (slev == 0)
- goto mix_3to2;
- mix32to2 (samples, level, level * clev, level * slev, bias);
- break;
-
- case CONVERT (AC3_3F1R, AC3_3F):
- if (slev == 0)
- goto mix_3to3;
- mix21to2 (samples, samples + 512, level, level * slev * LEVEL_3DB,
- bias);
-
- case CONVERT (AC3_3F2R, AC3_3F):
- if (slev == 0)
- goto mix_3to3;
- mix11to1 (samples, samples + 768, level, level * slev, bias);
- mix11to1 (samples + 512, samples + 1024, level, level * slev, bias);
- mix1to1 (samples + 256, level, bias);
- break;
-
- case CONVERT (AC3_2F1R, AC3_2F2R):
- mix1to2 (samples + 512, samples + 768, level * LEVEL_3DB, bias);
- goto mix_2to2;
-
- case CONVERT (AC3_3F1R, AC3_3F2R):
- mix1to2 (samples + 768, samples + 1024, level * LEVEL_3DB, bias);
- goto mix_3to3;
-
- case CONVERT (AC3_2F2R, AC3_2F1R):
- mix2to1 (samples + 512, level * LEVEL_3DB, bias);
- goto mix_2to2;
-
- case CONVERT (AC3_3F2R, AC3_3F1R):
- mix2to1 (samples + 768, level * LEVEL_3DB, bias);
- goto mix_3to3;
-
- case CONVERT (AC3_3F1R, AC3_2F2R):
- mix3to2 (samples, level, level * clev, bias);
- mix1to2 (samples + 768, samples + 512, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F1R, AC3_2F1R):
- mix3to2 (samples, level, level * clev, bias);
- move1to1 (samples + 768, samples + 512, level, bias);
- break;
-
- case CONVERT (AC3_3F2R, AC3_2F1R):
- mix3to2 (samples, level, level * clev, bias);
- move2to1 (samples + 768, samples + 512, level * LEVEL_3DB, bias);
- break;
-
- case CONVERT (AC3_3F2R, AC3_2F2R):
- mix3to2 (samples, level, level * clev, bias);
- move1to1 (samples + 768, samples + 512, level, bias);
- move1to1 (samples + 1024, samples + 768, level, bias);
- break;
- }
-
- if (output & AC3_LFE)
- mix1to1 (samples - 256, level, bias);
-}
diff --git a/src/libac3/imdct_mlib.c b/src/libac3/imdct_mlib.c
deleted file mode 100644
index 1ba783359..000000000
--- a/src/libac3/imdct_mlib.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * imdct_mlib.c
- * Copyright (C) 2001 Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "config.h"
-
-#ifdef LIBAC3_MLIB
-
-#include <inttypes.h>
-#include <mlib_types.h>
-#include <mlib_status.h>
-#include <mlib_signal.h>
-
-#include "ac3.h"
-#include "ac3_internal.h"
-
-extern sample_t imdct_window[];
-
-void
-imdct_do_512_mlib(sample_t data[], sample_t delay[])
-{
- 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));
- if(mlib_SignalIMDCT_F32(tmp) != MLIB_SUCCESS) {
- fprintf(stderr, "mediaLib failure\n");
- exit(-1);
- }
-
- buf_real = tmp;
- buf_imag = tmp + 128;
- data_ptr = data;
- delay_ptr = delay;
- window_ptr = imdct_window;
-
- /* Window and convert to real valued signal */
- for(i=0; i< 64; i++)
- {
- *data_ptr++ = 2.0f * (-buf_imag[64+i] * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf_real[64-i-1] * *window_ptr++ + *delay_ptr++);
- }
-
- for(i=0; i< 64; i++)
- {
- *data_ptr++ = 2.0f * (-buf_real[i] * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf_imag[128-i-1] * *window_ptr++ + *delay_ptr++);
- }
-
- /* The trailing edge of the window goes into the delay line */
- delay_ptr = delay;
-
- for(i=0; i< 64; i++)
- {
- *delay_ptr++ = -buf_real[64+i] * *--window_ptr;
- *delay_ptr++ = buf_imag[64-i-1] * *--window_ptr;
- }
-
- for(i=0; i<64; i++)
- {
- *delay_ptr++ = buf_imag[i] * *--window_ptr;
- *delay_ptr++ = -buf_real[128-i-1] * *--window_ptr;
- }
-}
-
-void
-imdct_do_256_mlib(sample_t data[], sample_t delay[])
-{
- 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));
- if(mlib_SignalIMDCT_F32(tmp) != MLIB_SUCCESS) {
- fprintf(stderr, "mediaLib failure\n");
- exit(-1);
- }
-
- buf1_real = tmp;
- buf1_imag = tmp + 64;
- buf2_real = tmp + 128;
- buf2_imag = tmp + 128 + 64;
- data_ptr = data;
- delay_ptr = delay;
- window_ptr = imdct_window;
-
- /* Window and convert to real valued signal */
- for(i=0; i< 64; i++)
- {
- *data_ptr++ = 2.0f * (-buf1_imag[i] * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf1_real[64-i-1] * *window_ptr++ + *delay_ptr++);
- }
-
- for(i=0; i< 64; i++)
- {
- *data_ptr++ = 2.0f * (-buf1_real[i] * *window_ptr++ + *delay_ptr++);
- *data_ptr++ = 2.0f * ( buf1_imag[64-i-1] * *window_ptr++ + *delay_ptr++);
- }
-
- delay_ptr = delay;
-
- for(i=0; i< 64; i++)
- {
- *delay_ptr++ = -buf2_real[i] * *--window_ptr;
- *delay_ptr++ = buf2_imag[64-i-1] * *--window_ptr;
- }
-
- for(i=0; i< 64; i++)
- {
- *delay_ptr++ = buf2_imag[i] * *--window_ptr;
- *delay_ptr++ = -buf2_real[64-i-1] * *--window_ptr;
- }
-}
-
-#endif
diff --git a/src/libac3/parse.c b/src/libac3/parse.c
deleted file mode 100644
index 7d7d7b3d0..000000000
--- a/src/libac3/parse.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * parse.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-#include "config.h"
-
-#include <inttypes.h>
-#include <string.h>
-
-#include "ac3.h"
-#include "ac3_internal.h"
-#include "bitstream.h"
-#include "tables.h"
-
-void ac3_init (void)
-{
- imdct_init ();
-}
-
-static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
-
-int ac3_syncinfo (uint8_t * buf, int * flags,
- int * sample_rate, int * bit_rate)
-{
- static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
- 128, 160, 192, 224, 256, 320, 384, 448,
- 512, 576, 640};
- static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01};
- int frmsizecod;
- int bitrate;
- int half;
- int acmod;
-
- if ((buf[0] != 0x0b) || (buf[1] != 0x77)) // syncword
- return 0;
-
- if (buf[5] >= 0x60) // bsid >= 12
- return 0;
- half = halfrate[buf[5] >> 3];
-
- // acmod, dsurmod and lfeon
- acmod = buf[6] >> 5;
- *flags = ((((buf[6] & 0xf8) == 0x50) ? AC3_DOLBY : acmod) |
- ((buf[6] & lfeon[acmod]) ? AC3_LFE : 0));
-
- frmsizecod = buf[4] & 63;
- if (frmsizecod >= 38)
- return 0;
- bitrate = rate [frmsizecod >> 1];
- *bit_rate = (bitrate * 1000) >> half;
-
- switch (buf[4] & 0xc0) {
- case 0: // 48 KHz
- *sample_rate = 48000 >> half;
- return 4 * bitrate;
- case 0x40:
- *sample_rate = 44100 >> half;
- return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
- case 0x80:
- *sample_rate = 32000 >> half;
- return 6 * bitrate;
- default:
- return 0;
- }
-}
-
-int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags,
- sample_t * level, sample_t bias, sample_t * delay)
-{
- static sample_t clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB};
- static sample_t slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB};
- int chaninfo;
- int acmod;
-
- state->fscod = buf[4] >> 6;
- 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
-
- if ((acmod == 2) && (bitstream_get (2) == 2)) // dsurmod
- acmod = AC3_DOLBY;
-
- if ((acmod & 1) && (acmod != 1))
- state->clev = clev[bitstream_get (2)]; // cmixlev
-
- if (acmod & 4)
- state->slev = slev[bitstream_get (2)]; // surmixlev
-
- state->lfeon = bitstream_get (1);
-
- state->output = downmix_init (acmod, *flags, level,
- state->clev, state->slev);
- if (state->output < 0)
- return 1;
- if (state->lfeon && (*flags & AC3_LFE)) {
- state->output |= AC3_LFE;
- delay += 256;
- }
- *flags = state->output;
- state->level = *level;
- state->bias = bias;
- state->delay = delay;
-
- 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
- } while (chaninfo--);
-
- bitstream_get (2); // copyrightb + origbs
-
- if (bitstream_get (1)) // timecod1e
- bitstream_get (14); // timecod1
- if (bitstream_get (1)) // timecod2e
- bitstream_get (14); // timecod2
-
- if (bitstream_get (1)) { // addbsie
- int addbsil;
-
- addbsil = bitstream_get (6);
- do {
- bitstream_get (8); // addbsi
- } while (addbsil--);
- }
-
- return 0;
-}
-
-static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
- uint8_t * dest)
-{
- int exps;
-
- while (ngrps--) {
- exps = bitstream_get (7);
-
- exponent += exp_1[exps];
- if (exponent > 24)
- return 1;
-
- switch (expstr) {
- case EXP_D45:
- *(dest++) = exponent;
- *(dest++) = exponent;
- case EXP_D25:
- *(dest++) = exponent;
- case EXP_D15:
- *(dest++) = exponent;
- }
-
- exponent += exp_2[exps];
- if (exponent > 24)
- return 1;
-
- switch (expstr) {
- case EXP_D45:
- *(dest++) = exponent;
- *(dest++) = exponent;
- case EXP_D25:
- *(dest++) = exponent;
- case EXP_D15:
- *(dest++) = exponent;
- }
-
- exponent += exp_3[exps];
- if (exponent > 24)
- return 1;
-
- switch (expstr) {
- case EXP_D45:
- *(dest++) = exponent;
- *(dest++) = exponent;
- case EXP_D25:
- *(dest++) = exponent;
- case EXP_D15:
- *(dest++) = exponent;
- }
- }
-
- return 0;
-}
-
-static int parse_deltba (int8_t * deltba)
-{
- int deltnseg, deltlen, delta, j;
-
- memset (deltba, 0, 50);
-
- deltnseg = bitstream_get (3);
- j = 0;
- do {
- j += bitstream_get (5);
- deltlen = bitstream_get (4);
- delta = bitstream_get (3);
- delta -= (delta >= 4) ? 3 : 4;
- if (!deltlen)
- continue;
- if (j + deltlen >= 50)
- return 1;
- while (deltlen--)
- deltba[j++] = delta;
- } while (deltnseg--);
-
- return 0;
-}
-
-static inline int zero_snr_offsets (int nfchans, ac3_state_t * state)
-{
- int i;
-
- if ((state->csnroffst) || (state->cplinu && state->cplba.fsnroffst) ||
- (state->lfeon && state->lfeba.fsnroffst))
- return 0;
- for (i = 0; i < nfchans; i++)
- if (state->ba[i].fsnroffst)
- return 0;
- return 1;
-}
-
-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;
-
-#define GET_COEFF(COEFF,DITHER) \
- switch (bap[i]) { \
- case 0: \
- DITHER (scale_factor[exp[i]]); \
- \
- case -1: \
- if (q_1_pointer >= 0) { \
- COEFF (q_1[q_1_pointer--] * scale_factor[exp[i]]); \
- } else { \
- int code; \
- \
- code = bitstream_get (5); \
- \
- q_1_pointer = 1; \
- q_1[0] = q_1_2[code]; \
- q_1[1] = q_1_1[code]; \
- COEFF (q_1_0[code] * scale_factor[exp[i]]); \
- } \
- \
- case -2: \
- if (q_2_pointer >= 0) { \
- COEFF (q_2[q_2_pointer--] * scale_factor[exp[i]]); \
- } else { \
- int code; \
- \
- code = bitstream_get (7); \
- \
- q_2_pointer = 1; \
- q_2[0] = q_2_2[code]; \
- q_2[1] = q_2_1[code]; \
- COEFF (q_2_0[code] * scale_factor[exp[i]]); \
- } \
- \
- case 3: \
- COEFF (q_3[bitstream_get (3)] * scale_factor[exp[i]]); \
- \
- case -3: \
- if (q_4_pointer == 0) { \
- q_4_pointer = -1; \
- COEFF (q_4 * scale_factor[exp[i]]); \
- } else { \
- int code; \
- \
- code = bitstream_get (7); \
- \
- q_4_pointer = 0; \
- q_4 = q_4_1[code]; \
- COEFF (q_4_0[code] * scale_factor[exp[i]]); \
- } \
- \
- case 4: \
- COEFF (q_5[bitstream_get (4)] * scale_factor[exp[i]]); \
- \
- default: \
- COEFF (((int16_t)(bitstream_get(bap[i]) << (16 - bap[i]))) * \
- scale_factor[exp[i]]); \
- }
-
-#define CHANNEL_COEFF(val) \
- coeff[i] = val; \
- i++; \
- continue;
-
-#define CHANNEL_DITHER(val) \
- if (dither) { \
- coeff[i] = dither_gen () * val; \
- i++; \
- continue; \
- } else { \
- coeff[i] = 0; \
- i++; \
- continue; \
- }
-
-static uint16_t lfsr_state = 1;
-
-static inline int16_t dither_gen(void)
-{
- int16_t state;
-
- state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
-
- lfsr_state = (uint16_t) state;
-
- return ((state * (int) (LEVEL_3DB * 256)) >> 8);
-}
-
-static void coeff_get (sample_t * coeff, uint8_t * exp, int8_t * bap,
- int dither, int end)
-{
- int i;
-
- i = 0;
- while (i < end)
- GET_COEFF (CHANNEL_COEFF, CHANNEL_DITHER);
-}
-
-#define COUPLING_COEFF(val) \
- cplcoeff = val; \
- break;
-
-#define COUPLING_DITHER(val) \
- cplcoeff = val; \
- for (ch = 0; ch < nfchans; ch++) \
- if (state->chincpl[ch]) { \
- if (dithflag[ch]) \
- samples[ch][i] = \
- state->cplco[ch][bnd] * dither_gen () * cplcoeff; \
- else \
- samples[ch][i] = 0; \
- } \
- i++; \
- continue;
-
-int ac3_block (ac3_state_t * state, sample_t samples[][256])
-{
- static const uint8_t nfchans_tbl[8] = {2, 1, 2, 3, 3, 4, 4, 5};
- static int rematrix_band[4] = {25, 37, 61, 253};
- int i, nfchans, chaninfo;
- uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl;
- uint8_t blksw[5], dithflag[5];
-
- nfchans = nfchans_tbl[state->acmod];
-
- for (i = 0; i < nfchans; i++)
- blksw[i] = bitstream_get (1);
-
- for (i = 0; i < nfchans; i++)
- dithflag[i] = bitstream_get (1);
-
- chaninfo = !(state->acmod);
- do {
- if (bitstream_get (1)) // dynrnge
- bitstream_get (8); // dynrng
- } 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};
- int cplbegf;
- int cplendf;
- int ncplsubnd;
-
- for (i = 0; i < nfchans; i++)
- state->chincpl[i] = bitstream_get (1);
- switch (state->acmod) {
- case 0: case 1:
- return 1;
- case 2:
- state->phsflginu = bitstream_get (1);
- }
- cplbegf = bitstream_get (4);
- cplendf = bitstream_get (4);
-
- if (cplendf + 3 - cplbegf < 0)
- return 1;
- state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
- state->cplstrtbnd = bndtab[cplbegf];
- 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
- }
- }
-
- if (state->cplinu) {
- int j, cplcoe;
-
- cplcoe = 0;
- for (i = 0; i < nfchans; i++)
- if (state->chincpl[i])
- if (bitstream_get (1)) { // cplcoe
- int mstrcplco, cplcoexp, cplcomant;
-
- cplcoe = 1;
- mstrcplco = 3 * bitstream_get (2);
- for (j = 0; j < state->ncplbnd; j++) {
- cplcoexp = bitstream_get (4);
- cplcomant = bitstream_get (4);
- if (cplcoexp == 15)
- cplcomant <<= 14;
- else
- cplcomant = (cplcomant | 0x10) << 13;
- state->cplco[i][j] =
- cplcomant * scale_factor[cplcoexp + mstrcplco];
- }
- }
- if ((state->acmod == 2) && state->phsflginu && cplcoe)
- for (j = 0; j < state->ncplbnd; j++)
- if (bitstream_get (1)) // phsflg
- state->cplco[1][j] = -state->cplco[1][j];
- }
-
- if ((state->acmod == 2) && (bitstream_get (1))) { // rematstr
- int end;
-
- end = (state->cplinu) ? state->cplstrtmant : 253;
- i = 0;
- do
- state->rematflg[i] = bitstream_get (1);
- while (rematrix_band[i++] < end);
- }
-
- cplexpstr = EXP_REUSE;
- lfeexpstr = EXP_REUSE;
- if (state->cplinu)
- cplexpstr = bitstream_get (2);
- for (i = 0; i < nfchans; i++)
- chexpstr[i] = bitstream_get (2);
- if (state->lfeon)
- lfeexpstr = bitstream_get (1);
-
- for (i = 0; i < nfchans; i++)
- if (chexpstr[i] != EXP_REUSE) {
- if (state->cplinu && state->chincpl[i])
- state->endmant[i] = state->cplstrtmant;
- else {
- int chbwcod;
-
- chbwcod = bitstream_get (6);
- if (chbwcod > 60)
- return 1;
- state->endmant[i] = chbwcod * 3 + 73;
- }
- }
-
- do_bit_alloc = 0;
-
- if (cplexpstr != EXP_REUSE) {
- int cplabsexp, ncplgrps;
-
- do_bit_alloc = 1;
- ncplgrps = ((state->cplendmant - state->cplstrtmant) /
- (3 << (cplexpstr - 1)));
- cplabsexp = bitstream_get (4) << 1;
- if (parse_exponents (cplexpstr, ncplgrps, cplabsexp,
- state->cpl_exp + state->cplstrtmant))
- return 1;
- }
- for (i = 0; i < nfchans; i++)
- if (chexpstr[i] != EXP_REUSE) {
- int grp_size, nchgrps;
-
- do_bit_alloc = 1;
- 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))
- return 1;
- bitstream_get (2); // gainrng
- }
- if (lfeexpstr != EXP_REUSE) {
- do_bit_alloc = 1;
- state->lfe_exp[0] = bitstream_get (4);
- if (parse_exponents (lfeexpstr, 2, state->lfe_exp[0],
- state->lfe_exp + 1))
- return 1;
- }
-
- if (bitstream_get (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);
- }
- if (bitstream_get (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);
- }
- }
- if ((state->cplinu) && (bitstream_get (1))) { // cplleake
- do_bit_alloc = 1;
- state->cplfleak = 2304 - (bitstream_get (3) << 8);
- state->cplsleak = 2304 - (bitstream_get (3) << 8);
- }
-
- if (bitstream_get (1)) { // deltbaie
- do_bit_alloc = 1;
- if (state->cplinu)
- state->cplba.deltbae = bitstream_get (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))
- return 1;
- for (i = 0; i < nfchans; i++)
- if ((state->ba[i].deltbae == DELTA_BIT_NEW) &&
- parse_deltba (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));
- } else {
- if (state->cplinu)
- bit_allocate (state, &state->cplba, state->cplstrtbnd,
- state->cplstrtmant, state->cplendmant,
- state->cplfleak, state->cplsleak,
- state->cpl_exp, state->cpl_bap);
- for (i = 0; i < nfchans; i++)
- bit_allocate (state, state->ba + i, 0, 0, state->endmant[i],
- 0, 0, state->fbw_exp[i], state->fbw_bap[i]);
- if (state->lfeon) {
- state->lfeba.deltbae = DELTA_BIT_NONE;
- bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
- state->lfe_exp, state->lfe_bap);
- }
- }
- }
-
- if (bitstream_get (1)) { // skiple
- i = bitstream_get (9); // skipl
- while (i--)
- bitstream_get (8);
- }
-
- if (state->output & AC3_LFE)
- samples++; // shift for LFE channel
-
- q_1_pointer = q_2_pointer = q_4_pointer = -1;
- done_cpl = 0;
-
- for (i = 0; i < nfchans; i++) {
- int j;
-
- coeff_get (samples[i], state->fbw_exp[i], state->fbw_bap[i],
- dithflag[i], state->endmant[i]);
-
- if (state->cplinu && state->chincpl[i]) {
- if (!done_cpl) {
- int i, i_end, bnd, sub_bnd, ch;
- sample_t cplcoeff;
-
- done_cpl = 1;
-
-#define bap state->cpl_bap
-#define exp state->cpl_exp
-
- sub_bnd = bnd = 0;
- i = state->cplstrtmant;
- while (i < state->cplendmant) {
- i_end = i + 12;
- while (state->cplbndstrc[sub_bnd++])
- i_end += 12;
-
- while (i < i_end) {
- GET_COEFF (COUPLING_COEFF, COUPLING_DITHER);
- for (ch = 0; ch < nfchans; ch++)
- if (state->chincpl[ch])
- samples[ch][i] =
- state->cplco[ch][bnd] * cplcoeff;
- i++;
- }
- bnd++;
- }
-
-#undef bap
-#undef exp
- }
- j = state->cplendmant;
- } else
- j = state->endmant[i];
- for (; j < 256; j++)
- samples[i][j] = 0;
- }
-
- if (state->acmod == 2) {
- int j, end, band;
-
- end = ((state->endmant[0] < state->endmant[1]) ?
- state->endmant[0] : state->endmant[1]);
-
- i = 0;
- j = 13;
- do {
- if (!state->rematflg[i]) {
- j = rematrix_band[i++];
- continue;
- }
- band = rematrix_band[i++];
- if (band > end)
- band = end;
- do {
- sample_t tmp0, tmp1;
-
- tmp0 = samples[0][j];
- tmp1 = samples[1][j];
- samples[0][j] = tmp0 + tmp1;
- samples[1][j] = tmp0 - tmp1;
- } while (++j < band);
- } while (j < end);
- }
-
- if (state->lfeon) {
- coeff_get (samples[-1], state->lfe_exp, state->lfe_bap, 0, 7);
- if (state->output & AC3_LFE) {
- for (i = 7; i < 256; i++)
- samples[-1][i] = 0;
- imdct_512 (samples[-1], state->delay - 256);
- }
- }
-
- for (i = 0; i < nfchans; i++)
- if (blksw[i])
- imdct_256 (samples[i], state->delay + i * 256);
- else
- imdct_512 (samples[i], state->delay + i * 256);
-
- downmix (*samples, state->acmod, state->output, state->level, state->bias,
- state->clev, state->slev);
-
- return 0;
-}
diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c
deleted file mode 100644
index 7b7ee8794..000000000
--- a/src/libac3/xine_decoder.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2000-2001 the xine project
- *
- * This file is part of xine, a unix video player.
- *
- * xine 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.
- *
- * xine 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
- *
- * $Id: xine_decoder.c,v 1.24 2001/08/28 19:16:19 guenter Exp $
- *
- * stuff needed to turn libac3 into a xine decoder plugin
- */
-
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "audio_out.h"
-#include "ac3.h"
-#include "ac3_internal.h"
-#include "buffer.h"
-#include "xine_internal.h"
-
-#define FRAME_SIZE 4096+512
-
-#undef DEBUG_AC3
-#ifdef DEBUG_AC3
-int ac3file;
-#endif
-
-typedef struct ac3dec_decoder_s {
- audio_decoder_t audio_decoder;
-
- uint32_t pts;
- uint32_t last_pts;
-
- uint8_t frame_buffer[FRAME_SIZE];
- uint8_t *frame_ptr;
- int sync_todo;
- int frame_length, frame_todo;
- uint16_t syncword;
-
- ac3_state_t ac3_state;
- int ac3_flags;
- int ac3_bit_rate;
- int ac3_sample_rate;
- float ac3_level;
- int have_lfe;
-
- int ac3_flags_map[8];
- int ao_flags_map[8];
-
- int16_t int_samples [6 * 256 * 6];
- sample_t delay[6*256];
- sample_t samples[6][256];
-
- ao_instance_t *audio_out;
- int audio_caps;
- int bypass_mode;
- int output_sampling_rate;
- int output_open;
- int output_mode;
-
-} ac3dec_decoder_t;
-
-int ac3dec_can_handle (audio_decoder_t *this_gen, int buf_type) {
- return ((buf_type & 0xFFFF0000) == BUF_AUDIO_A52) ;
-}
-
-
-void ac3dec_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) {
-
- ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;
- /* int i; */
-
- this->audio_out = audio_out;
- this->audio_caps = audio_out->get_capabilities(audio_out);
- this->syncword = 0;
- this->sync_todo = 7;
- this->output_open = 0;
- this->pts = 0;
- this->last_pts = 0;
-
- ac3_init ();
-
- /*
- * find out if this driver supports ac3 output
- * or, if not, how many channels we've got
- */
-
- if (this->audio_caps & AO_CAP_MODE_AC3)
- this->bypass_mode = 1;
- else {
- this->bypass_mode = 0;
-
- this->ac3_flags_map[AC3_MONO] = AC3_MONO;
- this->ac3_flags_map[AC3_STEREO] = AC3_STEREO;
- this->ac3_flags_map[AC3_3F] = AC3_STEREO;
- this->ac3_flags_map[AC3_2F1R] = AC3_STEREO;
- this->ac3_flags_map[AC3_3F1R] = AC3_STEREO;
- this->ac3_flags_map[AC3_2F2R] = AC3_STEREO;
- this->ac3_flags_map[AC3_3F2R] = AC3_STEREO;
-
- this->ao_flags_map[AC3_MONO] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_STEREO] = AO_CAP_MODE_STEREO;
- this->ao_flags_map[AC3_3F] = AO_CAP_MODE_STEREO;
- this->ao_flags_map[AC3_2F1R] = AO_CAP_MODE_STEREO;
- this->ao_flags_map[AC3_3F1R] = AO_CAP_MODE_STEREO;
- this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_STEREO;
- this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_STEREO;
-
- /* find best mode */
- if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) {
-
- this->ac3_flags_map[AC3_2F2R] = AC3_2F2R;
- this->ac3_flags_map[AC3_3F2R] = AC3_3F2R | AC3_LFE;
- this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL;
- this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_5CHANNEL;
-
- } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) {
-
- this->ac3_flags_map[AC3_2F2R] = AC3_2F2R;
- this->ac3_flags_map[AC3_3F2R] = AC3_3F2R;
- this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL;
- this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_5CHANNEL;
-
- } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) {
-
- this->ac3_flags_map[AC3_2F2R] = AC3_2F2R;
- this->ac3_flags_map[AC3_3F2R] = AC3_2F2R;
-
- this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL;
- this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_4CHANNEL;
-
- /* else if (this->audio_caps & AO_CAP_MODE_STEREO)
- defaults are ok */
- } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) {
- printf ("HELP! a mono-only audio driver?!\n");
-
- this->ac3_flags_map[AC3_MONO] = AC3_MONO;
- this->ac3_flags_map[AC3_STEREO] = AC3_MONO;
- this->ac3_flags_map[AC3_3F] = AC3_MONO;
- this->ac3_flags_map[AC3_2F1R] = AC3_MONO;
- this->ac3_flags_map[AC3_3F1R] = AC3_MONO;
- this->ac3_flags_map[AC3_2F2R] = AC3_MONO;
- this->ac3_flags_map[AC3_3F2R] = AC3_MONO;
-
- this->ao_flags_map[AC3_MONO] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_STEREO] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_3F] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_2F1R] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_3F1R] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_MONO;
- this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_MONO;
- }
- }
-
- /*
- for (i = 0; i<8; i++)
- this->ac3_flags_map[i] |= AC3_ADJUST_LEVEL;
-*/
-#ifdef DEBUG_AC3
- ac3file = open ("test.ac3", O_CREAT | O_WRONLY | O_TRUNC, 0644);
-#endif
-}
-
-static inline int16_t blah (int32_t i)
-{
- if (i > 0x43c07fff)
- return 32767;
- else if (i < 0x43bf8000)
- return -32768;
- else
- return i - 0x43c00000;
-}
-
-static inline void float_to_int (float * _f, int16_t * s16, int num_channels) {
- int i;
- int32_t * f = (int32_t *) _f; /* XXX assumes IEEE float format */
-
- for (i = 0; i < 256; i++) {
- s16[num_channels*i] = blah (f[i]);
- }
-}
-
-static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) {
-
- int output_mode = AO_CAP_MODE_STEREO;
-
- /*
- * do we want to decode this frame in software?
- */
-
- if (!this->bypass_mode) {
-
- int ac3_output_flags, i;
- float level = this->ac3_level;
-
- /*
- * oki, decode this frame in software
- */
-
- /* determine output mode */
-
- ac3_output_flags = this->ac3_flags_map[this->ac3_flags & AC3_CHANNEL_MASK];
-
- if (ac3_frame (&this->ac3_state,
- this->frame_buffer,
- &ac3_output_flags,
- &level, 384, this->delay)) {
- printf ("libac3: ac3_frame error\n");
- return;
- }
-
- this->have_lfe = ac3_output_flags & AC3_LFE;
- if (this->have_lfe)
- output_mode = AO_CAP_MODE_5_1CHANNEL;
- else
- output_mode = this->ao_flags_map[ac3_output_flags];
-
- /*
- * (re-)open output device
- */
-
- if (!this->output_open
- || (this->ac3_sample_rate != this->output_sampling_rate)
- || (output_mode != this->output_mode)) {
-
- if (this->output_open)
- this->audio_out->close (this->audio_out);
-
-
- this->output_open = (this->audio_out->open (this->audio_out, 16,
- this->ac3_sample_rate,
- output_mode) == 1);
- this->output_sampling_rate = this->ac3_sample_rate;
- this->output_mode = output_mode;
- }
-
-
- if (!this->output_open)
- return;
-
-
- /*
- * decode ac3 and convert/interleave samples
- */
-
- for (i = 0; i < 6; i++) {
- if (ac3_block (&this->ac3_state, this->samples)) {
- printf ("libac3: ac3_block error\n");
- return;
- }
-
- switch (output_mode) {
- case AO_CAP_MODE_MONO:
- float_to_int (this->samples[0], this->int_samples+(i*256), 1);
- break;
- case AO_CAP_MODE_STEREO:
- float_to_int (this->samples[0], this->int_samples+(i*256*2), 2);
- float_to_int (this->samples[1], this->int_samples+(i*256*2)+1, 2);
- break;
- case AO_CAP_MODE_4CHANNEL:
- float_to_int (this->samples[0], this->int_samples+(i*256*4), 4); /* L */
- float_to_int (this->samples[1], this->int_samples+(i*256*4)+1, 4); /* R */
- float_to_int (this->samples[2], this->int_samples+(i*256*4)+2, 4); /* RL */
- float_to_int (this->samples[3], this->int_samples+(i*256*4)+3, 4); /* RR */
- break;
- case AO_CAP_MODE_5CHANNEL:
- float_to_int (this->samples[0], this->int_samples+(i*256*5)+0, 5); /* L */
- float_to_int (this->samples[1], this->int_samples+(i*256*5)+4, 5); /* C */
- float_to_int (this->samples[2], this->int_samples+(i*256*5)+1, 5); /* R */
- float_to_int (this->samples[3], this->int_samples+(i*256*5)+2, 5); /* RL */
- float_to_int (this->samples[4], this->int_samples+(i*256*5)+3, 5); /* RR */
- break;
- case AO_CAP_MODE_5_1CHANNEL:
- float_to_int (this->samples[0], this->int_samples+(i*256*6)+5, 6); /* lfe */
- float_to_int (this->samples[1], this->int_samples+(i*256*6)+0, 6); /* L */
- float_to_int (this->samples[2], this->int_samples+(i*256*6)+4, 6); /* C */
- float_to_int (this->samples[3], this->int_samples+(i*256*6)+1, 6); /* R */
- float_to_int (this->samples[4], this->int_samples+(i*256*6)+2, 6); /* RL */
- float_to_int (this->samples[5], this->int_samples+(i*256*6)+3, 6); /* RR */
- break;
- default:
- printf ("libac3: help - unsupported mode %08x\n", output_mode);
- }
- }
-
- /* output decoded samples */
-
- this->audio_out->write (this->audio_out,
- this->int_samples,
- 256*6,
- pts);
- pts = 0;
-
- } else {
-
- /*
- * loop through ac3 data
- */
-
- if (!this->output_open) {
-
- int sample_rate, bit_rate, flags;
-
- ac3_syncinfo (this->frame_buffer, &flags, &sample_rate, &bit_rate);
-
- this->output_open = (this->audio_out->open (this->audio_out, 16,
- sample_rate,
- AO_CAP_MODE_AC3) == 1);
- this->output_mode = AO_CAP_MODE_AC3;
- }
-
- if (this->output_open) {
- this->audio_out->write (this->audio_out,
- (int16_t*)this->frame_buffer,
- this->frame_length,
- pts);
- }
- }
-}
-
-void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
-
- ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;
- uint8_t *current = buf->content;
- uint8_t *end = buf->content + buf->size;
- uint8_t byte;
-
- if (buf->decoder_info[0] == 0)
- return;
-
- /*
- printf ("libac3: got buffer, pts =%d, pts - last_pts=%d\n",
- buf->PTS, buf->PTS - this->last_pts);
-
- this->last_pts = buf->PTS;
- */
-
- if (buf->PTS)
- this->pts = buf->PTS;
-
-
- while (current != end) {
-
- if ( (this->sync_todo == 0) && (this->frame_todo == 0) ) {
- ac3dec_decode_frame (this, this->pts);
-#ifdef DEBUG_AC3
- write (ac3file, this->frame_buffer, this->frame_length);
-#endif
- this->pts = 0;
- this->sync_todo = 7;
- this->syncword = 0;
- }
-
- while (1) {
- byte = *current++;
-
- if (this->sync_todo>0) {
-
- /* search and collect syncinfo */
-
- if (this->syncword != 0x0b77) {
- this->syncword = (this->syncword << 8) | byte;
-
- if (this->syncword == 0x0b77) {
-
- this->frame_buffer[0] = 0x0b;
- this->frame_buffer[1] = 0x77;
-
- this->sync_todo = 5;
- this->frame_ptr = this->frame_buffer+2;
- }
- } else {
- *this->frame_ptr++ = byte;
- this->sync_todo--;
-
- if (this->sync_todo==0) {
-
- this->frame_length = ac3_syncinfo (this->frame_buffer,
- &this->ac3_flags,
- &this->ac3_sample_rate,
- &this->ac3_bit_rate);
- if (this->frame_length) {
- this->frame_todo = this->frame_length - 7;
- } else {
- this->sync_todo = 7;
- this->syncword = 0;
- printf ("libac3: skip frame of zero length\n");
- }
-
- }
-
- }
- } else {
-
- *this->frame_ptr++ = byte;
- this->frame_todo--;
-
- if (this->frame_todo == 0) {
- if (current == end)
- return ;
- break;
- }
- }
-
- if (current == end)
- return ;
- }
- }
-}
-
-void ac3dec_close (audio_decoder_t *this_gen) {
-
- ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;
-
- if (this->output_open)
- this->audio_out->close (this->audio_out);
-
- this->output_open = 0;
-
-#ifdef DEBUG_AC3
- close (ac3file);
-#endif
-}
-
-static char *ac3dec_get_id(void) {
- return "ac3dec";
-}
-
-audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t *cfg) {
-
- ac3dec_decoder_t *this ;
-
- if (iface_version != 2) {
- printf( "libac3: plugin doesn't support plugin API version %d.\n"
- "libac3: this means there's a version mismatch between xine and this "
- "libac3: decoder plugin.\nInstalling current plugins should help.\n",
- iface_version);
- return NULL;
- }
-
- this = (ac3dec_decoder_t *) malloc (sizeof (ac3dec_decoder_t));
-
- this->audio_decoder.interface_version = 2;
- this->audio_decoder.can_handle = ac3dec_can_handle;
- this->audio_decoder.init = ac3dec_init;
- this->audio_decoder.decode_data = ac3dec_decode_data;
- this->audio_decoder.close = ac3dec_close;
- this->audio_decoder.get_identifier = ac3dec_get_id;
- this->audio_decoder.priority = 1;
-
-
- this->ac3_level = (float) cfg->lookup_int (cfg, "ac3_level", 100) / 100.0;
-
- return (audio_decoder_t *) this;
-}
-
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index c080866cc..ab6695aa7 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.8 2001/08/24 01:05:31 guenter Exp $
+ * $Id: audio_out.c,v 1.9 2001/08/29 00:51:58 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -176,7 +176,7 @@ static void ao_fill_gap (ao_instance_t *this, uint32_t pts_len) {
num_frames = pts_len * this->frames_per_kpts / 1024;
- if (this->mode == AO_CAP_MODE_AC3) return; /* FIXME */
+ if (this->mode == AO_CAP_MODE_A52) return; /* FIXME */
printf ("audio_out: inserting %d 0-frames to fill a gap of %d pts\n",num_frames, pts_len);
@@ -264,8 +264,8 @@ static int ao_write(ao_instance_t *this,
else
delay = 0;
- /* External AC3 decoder delay correction */
- if (this->mode==AO_CAP_MODE_AC3)
+ /* External A52 decoder delay correction */
+ if (this->mode==AO_CAP_MODE_A52)
delay+=10;
buffer_vpts += delay * 1024 / this->frames_per_kpts;
@@ -298,13 +298,13 @@ static int ao_write(ao_instance_t *this,
/*
* resample and output frames
*/
- if (this->mode == AO_CAP_MODE_AC3)
+ if (this->mode == AO_CAP_MODE_A52)
bDropPackage=0;
if (!bDropPackage) {
int num_output_frames = (double) num_frames * this->frame_rate_factor;
- if ((!this->do_resample) && (this->mode != AO_CAP_MODE_AC3)) {
+ if ((!this->do_resample) && (this->mode != AO_CAP_MODE_A52)) {
xprintf (VERBOSE|AUDIO, "audio_out: writing without resampling\n");
this->driver->write (this->driver, output_frames,
num_output_frames );
@@ -334,7 +334,7 @@ static int ao_write(ao_instance_t *this,
this->frame_buffer, num_output_frames);
this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
- case AO_CAP_MODE_AC3:
+ case AO_CAP_MODE_A52:
num_output_frames = (num_frames+8)/4;
this->frame_buffer[0] = 0xf872; /* spdif syncword */
this->frame_buffer[1] = 0x4e1f; /* ............. */
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index 047529492..eee66ccff 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -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: audio_out.h,v 1.11 2001/08/24 01:05:31 guenter Exp $
+ * $Id: audio_out.h,v 1.12 2001/08/29 00:51:58 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -196,7 +196,7 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom, confi
*/
#define AO_CAP_NOCAP 0x00000000 /* driver has no capabilities */
-#define AO_CAP_MODE_AC3 0x00000001 /* driver supports AC3 output */
+#define AO_CAP_MODE_A52 0x00000001 /* driver supports A/52 output */
#define AO_CAP_MODE_AC5 0x00000002 /* driver supports AC5 output */
/* 1 sample == 2 bytes (C) */
#define AO_CAP_MODE_MONO 0x00000004 /* driver supports mono output */