summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libac3/Makefile.am9
-rw-r--r--src/libac3/ac3.h108
-rw-r--r--src/libac3/ac3_internal.h134
-rw-r--r--src/libac3/bit_allocate.c75
-rw-r--r--src/libac3/bit_allocate.h26
-rw-r--r--src/libac3/bitstream.c17
-rw-r--r--src/libac3/coeff.c337
-rw-r--r--src/libac3/coeff.h24
-rw-r--r--src/libac3/debug.c58
-rw-r--r--src/libac3/debug.h37
-rw-r--r--src/libac3/decode.c163
-rw-r--r--src/libac3/decode.h22
-rw-r--r--src/libac3/dither.c114
-rw-r--r--src/libac3/dither.h37
-rw-r--r--src/libac3/downmix.c956
-rw-r--r--src/libac3/downmix.h29
-rw-r--r--src/libac3/imdct.c118
-rw-r--r--src/libac3/imdct.h26
-rw-r--r--src/libac3/parse.c563
-rw-r--r--src/libac3/parse.h26
-rw-r--r--src/libac3/rematrix.c81
-rw-r--r--src/libac3/rematrix.h25
-rw-r--r--src/libac3/sanity_check.c117
-rw-r--r--src/libac3/sanity_check.h27
-rw-r--r--src/libac3/stats.c107
-rw-r--r--src/libac3/stats.h27
-rw-r--r--src/libac3/xine_decoder.c203
27 files changed, 1197 insertions, 2269 deletions
diff --git a/src/libac3/Makefile.am b/src/libac3/Makefile.am
index e783c3fb9..38b5f5b39 100644
--- a/src/libac3/Makefile.am
+++ b/src/libac3/Makefile.am
@@ -7,15 +7,12 @@ libdir = $(XINE_PLUGINDIR)
lib_LTLIBRARIES = xineplug_decode_ac3.la
xineplug_decode_ac3_la_SOURCES = bitstream.c bit_allocate.c \
- coeff.c decode.c debug.c dither.c downmix.c imdct.c \
- imdct_mlib.c parse.c rematrix.c sanity_check.c stats.c \
+ parse.c downmix.c imdct.c imdct_mlib.c \
xine_decoder.c
xineplug_decode_ac3_la_LDFLAGS = -avoid-version -module
-noinst_HEADERS = ac3.h ac3_internal.h bit_allocate.h \
- bitstream.h coeff.h debug.h decode.h dither.h \
- downmix.h imdct.h parse.h rematrix.h \
- sanity_check.h stats.h
+noinst_HEADERS = ac3.h ac3_internal.h \
+ bitstream.h tables.h
##
## Install header files (default=$includedir/xine)
diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h
index 69c11b9ed..305a10e49 100644
--- a/src/libac3/ac3.h
+++ b/src/libac3/ac3.h
@@ -22,30 +22,84 @@
*
*/
-#include <inttypes.h>
-
-#define AC3_DOLBY_SURR_ENABLE 0x1
-
-typedef struct ac3_config_s
-{
- //Bit flags that enable various things
- uint32_t flags;
- //Callback that points the decoder to new stream data
- void (* fill_buffer_callback) (uint8_t **, uint8_t **);
- //Number of discrete channels in final output (for downmixing)
- uint16_t num_output_ch;
- //Which channel of a dual mono stream to select
- uint16_t dual_mono_ch_sel;
-} ac3_config_t;
-
-typedef struct ac3_frame_s
-{
- uint32_t sampling_rate;
- int16_t * audio_data;
- int num_channels;
-} ac3_frame_t;
-
-void ac3_init(void);
-int ac3_frame_length(uint8_t * buf);
-int ac3_sampling_rate(uint8_t * buf);
-ac3_frame_t* ac3_decode_frame(uint8_t * buf, int max_num_channels);
+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 {
+ uint8_t fscod; // sample rate
+ uint8_t halfrate; // halfrate factor
+ uint8_t acmod; // coded channels
+ float clev; // centre channel mix level
+ float slev; // surround channels mix level
+ uint8_t lfeon; // coded lfe channel
+
+ int output; // type of output
+ float level; // output level
+ float 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
+ float 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,
+ float * level, float bias);
+int ac3_block (ac3_state_t * state);
diff --git a/src/libac3/ac3_internal.h b/src/libac3/ac3_internal.h
index d90fc598a..b414578bd 100644
--- a/src/libac3/ac3_internal.h
+++ b/src/libac3/ac3_internal.h
@@ -21,9 +21,10 @@
*
*/
-#ifndef __GNUC__
-#define inline
-#endif
+#define LEVEL_PLUS3DB 1.4142135623730951
+#define LEVEL_3DB 0.7071067811865476
+#define LEVEL_45DB 0.5946035575013605
+#define LEVEL_6DB 0.5
/* Exponent strategy constants */
#define EXP_REUSE (0)
@@ -40,123 +41,14 @@
/* samples work structure */
typedef float stream_samples_t[6][256];
-/* global error flag */
-extern uint32_t error_flag;
-
-/* Everything you wanted to know about band structure */
-/*
- * The entire frequency domain is represented by 256 real
- * floating point fourier coefficients. Only the lower 253
- * coefficients are actually utilized however. We use arrays
- * of 256 to be efficient in some cases.
- *
- * The 5 full bandwidth channels (fbw) can have their higher
- * frequencies coupled together. These coupled channels then
- * share their high frequency components.
- *
- * This coupling band is broken up into 18 sub-bands starting
- * at mantissa number 37. Each sub-band is 12 bins wide.
- *
- * There are 50 bit allocation sub-bands which cover the entire
- * frequency range. The sub-bands are of non-uniform width, and
- * approximate a 1/6 octave scale.
- */
-
-/* The following structures are filled in by their corresponding parse_*
- * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
- * full details on each field. Indented fields are used to denote
- * conditional fields.
- */
-
-typedef struct ac3_state_s {
- int nfchans; // number of channels, derived from acmod
-
- /* from syncinfo */
- uint8_t fscod; // sample rate
-
- /* from bsi */
- uint8_t acmod; // coded channels
- uint8_t cmixlev; // centre channel mix level
- uint8_t surmixlev; // surround channels mix level
- uint8_t lfeon; // coded lfe channel
-} ac3_state_t;
-
-typedef struct ac3_ba_s {
- uint16_t fsnroffst; // fine SNR offset
- uint16_t fgaincod; // fast gain
- uint16_t deltbae; // delta bit allocation exists
- int8_t deltba[50]; // per-band delta bit allocation
-} ac3_ba_t;
-
-/* more pain */
-typedef struct audblk_s {
- uint32_t magic1;
-
- // not reused between blocks
- uint16_t blksw[5]; // imdct block transform switch
- uint16_t dithflag[5]; // channel dither flag
-
- uint16_t cplinu; // coupling in use
- uint16_t chincpl[5]; // channel coupled
- uint16_t phsflginu; // phase flags in use (stereo only)
- uint16_t cplbegf; // coupling begin frequency code
- uint16_t cplendf; // coupling end frequency code
- uint16_t cplbndstrc[18]; // coupling band structure
- // derived information
- uint16_t cplstrtmant; // coupling channel start mantissa
- uint16_t cplendmant; // coupling channel end mantissa
- uint16_t ncplsubnd; // number of coupling sub-bands
- uint16_t ncplbnd; // number of coupling bands
-
- // should we simply have float cplco[5][18] instead of these 4 ?
- uint8_t mstrcplco[5]; // per channel master coupling coordinate
- uint8_t cplcoexp[5][18]; // per band coupling exponent
- uint8_t cplcomant[5][18]; // per band coupling mantissa
- uint8_t phsflg[18]; // per band phase flags for stereo
-
- uint16_t rematflg[4]; // stereo rematrixing
-
- uint16_t chbwcod[5]; // channel bandwidth for independant channels
-
- uint32_t magic2;
-
- uint16_t sdcycod; // slow decay
- uint16_t fdcycod; // fast decay
- uint16_t sgaincod; // slow gain
- uint16_t dbpbcod; // dB per bit - encodes the dbknee value
- uint16_t floorcod; // masking floor
-
- uint16_t csnroffst; // coarse SNR offset
- ac3_ba_t cplba; // coupling bit allocation parameters
- ac3_ba_t ba[5]; // channel bit allocation parameters
- ac3_ba_t lfeba; // lfe bit allocation parameters
-
- uint16_t cplfleak; // coupling fast leak init
- uint16_t cplsleak; // coupling slow leak init
-
-
-
-
- /* coupling mantissas */
- uint16_t cplmant[256];
-
-
- /* -- Information not in the bitstream, but derived thereof -- */
-
- /* End mantissa numbers of fbw channels */
- uint16_t endmant[5];
-
- /* Decoded exponent info */
- uint8_t fbw_exp[5][256];
- uint8_t cpl_exp[256];
- uint8_t lfe_exp[7];
-
- /* Bit allocation pointer results */
- int8_t fbw_bap[5][256];
- int8_t cpl_bap[256];
- int8_t lfe_bap[7];
-
- uint32_t magic3;
-} audblk_t;
+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, float * level, float clev, float slev);
+void downmix (float * samples, int acmod, int output, float level, float bias,
+ float clev, float slev);
+void imdct_init (void);
+extern void (* imdct_256) (float data[], float delay[]);
+extern void (* imdct_512) (float data[], float delay[]);
diff --git a/src/libac3/bit_allocate.c b/src/libac3/bit_allocate.c
index 17f35b159..307c0074c 100644
--- a/src/libac3/bit_allocate.c
+++ b/src/libac3/bit_allocate.c
@@ -21,11 +21,11 @@
*
*/
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include "ac3.h"
#include "ac3_internal.h"
-#include "bit_allocate.h"
static int hthtab[3][50] = {
{0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
@@ -46,17 +46,17 @@ static int hthtab[3][50] = {
};
static int8_t baptab[305] = {
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, // 93 padding entries
-
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14,
- 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10,
- 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6,
- 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0,
+ 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, 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, 14, 14, 14, 14, 14, 14, 14,
+ 14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
+ 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
+ 5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -113,18 +113,16 @@ do { \
do { \
if (psd > dbknee) \
mask -= (psd - dbknee) >> 2; \
- if (mask > hth[i]) \
- mask = hth[i]; \
- if (deltba != NULL) \
- mask -= 128 * deltba[i]; \
- mask -= snroffset; \
+ if (mask > hth [i >> halfrate]) \
+ mask = hth [i >> halfrate]; \
+ mask -= snroffset + 128 * deltba[i]; \
mask = (mask > 0) ? 0 : ((-mask) >> 5); \
mask -= floor; \
} while (0)
-void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
- int bndstart, int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap)
+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)
{
static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100};
@@ -136,16 +134,22 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
int psd, mask;
int8_t * deltba;
int * hth;
+ int halfrate;
- fdecay = 63 + 20 * audblk->fdcycod;
+ halfrate = state->halfrate;
+ fdecay = (63 + 20 * state->fdcycod) >> halfrate;
fgain = 128 + 128 * ba->fgaincod;
- sdecay = 15 + 2 * audblk->sdcycod;
- sgain = slowgain[audblk->sgaincod];
- dbknee = dbpbtab[audblk->dbpbcod];
- hth = hthtab[fscod];
- deltba = (ba->deltbae == DELTA_BIT_NONE) ? NULL : ba->deltba;
- floor = floortab[audblk->floorcod];
- snroffset = 960 - 64 * audblk->csnroffst - 4 * ba->fsnroffst + floor;
+ sdecay = (15 + 2 * state->sdcycod) >> halfrate;
+ sgain = slowgain[state->sgaincod];
+ dbknee = dbpbtab[state->dbpbcod];
+ hth = hthtab[state->fscod];
+ /*
+ * if there is no delta bit allocation, make deltba point to an area
+ * known to contain zeroes. baptab+156 here.
+ */
+ deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
+ floor = floortab[state->floorcod];
+ snroffset = 960 - 64 * state->csnroffst - 4 * ba->fsnroffst + floor;
floor >>= 5;
i = bndstart;
@@ -165,8 +169,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
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;
@@ -183,8 +186,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
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
@@ -200,8 +202,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
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
@@ -211,8 +212,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
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;
}
@@ -249,8 +249,7 @@ void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
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++;
+ bap[j++] = (baptab+156)[mask + 4 * exp[j]];
} while (j < endband);
} while (j < end);
}
diff --git a/src/libac3/bit_allocate.h b/src/libac3/bit_allocate.h
deleted file mode 100644
index 089acc56c..000000000
--- a/src/libac3/bit_allocate.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * bit_allocate.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.
- *
- */
-
-void bit_allocate(int fscod, audblk_t * audblk, ac3_ba_t * ba,
- int bndstart, int start, int end, int fastleak, int slowleak,
- uint8_t * exp, int8_t * bap);
diff --git a/src/libac3/bitstream.c b/src/libac3/bitstream.c
index 2a06ea747..7e9bd1f66 100644
--- a/src/libac3/bitstream.c
+++ b/src/libac3/bitstream.c
@@ -21,8 +21,8 @@
*
*/
+#include <inttypes.h>
#include <stdlib.h>
-#include <stddef.h>
#include <stdio.h>
#include "ac3.h"
@@ -31,30 +31,21 @@
#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;
+static uint8_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);
+ buffer_start = buf;
bits_left = 0;
- if (align > 0) bitstream_get(align * 8);
}
static inline void
bitstream_fill_current()
{
- current_word = *buffer_start++;
+ current_word = *((uint32_t*)buffer_start)++;
current_word = swab32(current_word);
}
diff --git a/src/libac3/coeff.c b/src/libac3/coeff.c
deleted file mode 100644
index 2913c18d4..000000000
--- a/src/libac3/coeff.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * coeff.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ac3.h"
-#include "ac3_internal.h"
-
-
-#include "decode.h"
-#include "bitstream.h"
-#include "dither.h"
-#include "coeff.h"
-
-//
-//Lookup tables of 0.15 two's complement quantization values
-//
-static const uint16_t q_1[3] =
-{
- ( -2 << 15)/3, 0,( 2 << 15)/3
-};
-
-static const uint16_t q_2[5] =
-{
- ( -4 << 15)/5,( -2 << 15)/5, 0,
- ( 2 << 15)/5,( 4 << 15)/5
-};
-
-static const uint16_t q_3[7] =
-{
- ( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, 0,
- ( 2 << 15)/7,( 4 << 15)/7,( 6 << 15)/7
-};
-
-static const uint16_t q_4[11] =
-{
- (-10 << 15)/11,(-8 << 15)/11,(-6 << 15)/11, ( -4 << 15)/11,(-2 << 15)/11, 0,
- ( 2 << 15)/11,( 4 << 15)/11,( 6 << 15)/11, ( 8 << 15)/11,(10 << 15)/11
-};
-
-static const uint16_t q_5[15] =
-{
- (-14 << 15)/15,(-12 << 15)/15,(-10 << 15)/15,
- ( -8 << 15)/15,( -6 << 15)/15,( -4 << 15)/15,
- ( -2 << 15)/15, 0 ,( 2 << 15)/15,
- ( 4 << 15)/15,( 6 << 15)/15,( 8 << 15)/15,
- ( 10 << 15)/15,( 12 << 15)/15,( 14 << 15)/15
-};
-
-//
-// Scale factors for convert_to_float
-//
-
-static const uint32_t u32_scale_factors[25] =
-{
- 0x38000000, //2 ^ -(0 + 15)
- 0x37800000, //2 ^ -(1 + 15)
- 0x37000000, //2 ^ -(2 + 15)
- 0x36800000, //2 ^ -(3 + 15)
- 0x36000000, //2 ^ -(4 + 15)
- 0x35800000, //2 ^ -(5 + 15)
- 0x35000000, //2 ^ -(6 + 15)
- 0x34800000, //2 ^ -(7 + 15)
- 0x34000000, //2 ^ -(8 + 15)
- 0x33800000, //2 ^ -(9 + 15)
- 0x33000000, //2 ^ -(10 + 15)
- 0x32800000, //2 ^ -(11 + 15)
- 0x32000000, //2 ^ -(12 + 15)
- 0x31800000, //2 ^ -(13 + 15)
- 0x31000000, //2 ^ -(14 + 15)
- 0x30800000, //2 ^ -(15 + 15)
- 0x30000000, //2 ^ -(16 + 15)
- 0x2f800000, //2 ^ -(17 + 15)
- 0x2f000000, //2 ^ -(18 + 15)
- 0x2e800000, //2 ^ -(19 + 15)
- 0x2e000000, //2 ^ -(20 + 15)
- 0x2d800000, //2 ^ -(21 + 15)
- 0x2d000000, //2 ^ -(22 + 15)
- 0x2c800000, //2 ^ -(23 + 15)
- 0x2c000000 //2 ^ -(24 + 15)
-};
-
-static float *scale_factor = (float*)u32_scale_factors;
-
-//These store the persistent state of the packed mantissas
-static uint16_t m_1[3];
-static uint16_t m_2[3];
-static uint16_t m_4[2];
-static uint16_t m_1_pointer;
-static uint16_t m_2_pointer;
-static uint16_t m_4_pointer;
-
-//Conversion from bap to number of bits in the mantissas
-//zeros account for cases 0,1,2,4 which are special cased
-static uint16_t qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16};
-
-static void coeff_reset(void);
-static int16_t coeff_get_mantissa(uint16_t bap, uint16_t dithflag);
-static void coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch);
-
-//
-// Convert a 0.15 fixed point number into IEEE single
-// precision floating point and scale by 2^-exp
-//
-static inline float
-convert_to_float(uint16_t exp, int16_t mantissa)
-{
- float x;
-
- //the scale by 2^-15 is built into the scale factor table
- x = mantissa * scale_factor[exp];
-
- return x;
-}
-
-void
-coeff_unpack(ac3_state_t *state, audblk_t *audblk, stream_samples_t samples)
-{
- uint16_t i,j;
- uint32_t done_cpl = 0;
- int16_t mantissa;
-
- coeff_reset();
-
- for(i=0; i< state->nfchans; i++) {
- for(j=0; j < audblk->endmant[i]; j++) {
- mantissa = coeff_get_mantissa(audblk->fbw_bap[i][j],audblk->dithflag[i]);
- samples[i][j] = convert_to_float(audblk->fbw_exp[i][j],mantissa);
- }
-
- if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) {
- // ncplmant is equal to 12 * ncplsubnd
- // Don't dither coupling channel until channel separation so that
- // interchannel noise is uncorrelated
- for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++)
- audblk->cplmant[j] = coeff_get_mantissa(audblk->cpl_bap[j],0);
- done_cpl = 1;
- }
- }
-
- //uncouple the channel if necessary
- if(audblk->cplinu) {
- for(i=0; i< state->nfchans; i++) {
- if(audblk->chincpl[i])
- coeff_uncouple_ch(samples[i],state,audblk,i);
- }
- }
-
- if(state->lfeon) {
- // There are always 7 mantissas for lfe, no dither for lfe
- for(j=0; j < 7 ; j++) {
- mantissa = coeff_get_mantissa(audblk->lfe_bap[j],0);
- samples[5][j] = convert_to_float(audblk->lfe_exp[j],mantissa);
- }
- }
-}
-
-//
-//Fetch a mantissa from the bitstream
-//
-//The mantissa returned is a signed 0.15 fixed point number
-//
-static int16_t
-coeff_get_mantissa(uint16_t bap, uint16_t dithflag)
-{
- uint16_t mantissa;
- uint16_t group_code;
-
- //If the bap is 0-5 then we have special cases to take care of
- switch(bap) {
- case 0:
- if(dithflag)
- mantissa = dither_gen();
- else
- mantissa = 0;
- break;
-
- case 1:
- if(m_1_pointer > 2) {
- group_code = bitstream_get(5);
-
- if(group_code > 26)
- goto error;
-
- m_1[0] = group_code / 9;
- m_1[1] = (group_code % 9) / 3;
- m_1[2] = (group_code % 9) % 3;
- m_1_pointer = 0;
- }
- mantissa = m_1[m_1_pointer++];
- mantissa = q_1[mantissa];
- break;
- case 2:
-
- if(m_2_pointer > 2) {
- group_code = bitstream_get(7);
-
- if(group_code > 124)
- goto error;
-
- m_2[0] = group_code / 25;
- m_2[1] = (group_code % 25) / 5 ;
- m_2[2] = (group_code % 25) % 5 ;
- m_2_pointer = 0;
- }
- mantissa = m_2[m_2_pointer++];
- mantissa = q_2[mantissa];
- break;
-
- case 3:
- mantissa = bitstream_get(3);
-
- if(mantissa > 6)
- goto error;
-
- mantissa = q_3[mantissa];
- break;
-
- case 4:
- if(m_4_pointer > 1) {
- group_code = bitstream_get(7);
-
- if(group_code > 120)
- goto error;
-
- m_4[0] = group_code / 11;
- m_4[1] = group_code % 11;
- m_4_pointer = 0;
- }
- mantissa = m_4[m_4_pointer++];
- mantissa = q_4[mantissa];
- break;
-
- case 5:
- mantissa = bitstream_get(4);
-
- if(mantissa > 14)
- goto error;
-
- mantissa = q_5[mantissa];
- break;
-
- default:
- mantissa = bitstream_get(qnttztab[bap]);
- mantissa <<= 16 - qnttztab[bap];
- }
-
- return mantissa;
-
-
-
-error:
- if(!error_flag)
- fprintf(stderr,"** Invalid mantissa - skipping frame **\n");
- error_flag = 1;
-
- return 0;
-}
-
-//
-// Reset the mantissa state
-//
-static void
-coeff_reset(void)
-{
- m_1[2] = m_1[1] = m_1[0] = 0;
- m_2[2] = m_2[1] = m_2[0] = 0;
- m_4[1] = m_4[0] = 0;
- m_1_pointer = m_2_pointer = m_4_pointer = 3;
-}
-
-//
-// Uncouple the coupling channel into a fbw channel
-//
-static void
-coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch)
-{
- uint32_t bnd = 0;
- uint32_t sub_bnd = 0;
- uint32_t i,j;
- float cpl_coord = 1.0;
- uint32_t cpl_exp_tmp;
- uint32_t cpl_mant_tmp;
- int16_t mantissa;
-
- for(i=audblk->cplstrtmant;i<audblk->cplendmant;) {
- if(!audblk->cplbndstrc[sub_bnd++]) {
- cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch];
- if(audblk->cplcoexp[ch][bnd] == 15)
- cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11;
- else
- cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10;
-
- cpl_coord = convert_to_float(cpl_exp_tmp,cpl_mant_tmp) * 8.0f;
-
- //Invert the phase for the right channel if necessary
- if(state->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd])
- cpl_coord *= -1;
-
- bnd++;
- }
-
- for(j=0;j < 12; j++) {
- //Get new dither values for each channel if necessary, so
- //the channels are uncorrelated
- if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0)
- mantissa = dither_gen();
- else
- mantissa = audblk->cplmant[i];
-
- samples[i] = cpl_coord * convert_to_float(audblk->cpl_exp[i],mantissa);
-
- i++;
- }
- }
-}
diff --git a/src/libac3/coeff.h b/src/libac3/coeff.h
deleted file mode 100644
index fd3e1a6d9..000000000
--- a/src/libac3/coeff.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * coeff.h
- *
- * Copyright (C) Aaron Holtzman - Feb 2000
- *
- * 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.
- *
- */
-
-void coeff_unpack(ac3_state_t * state, audblk_t *audblk,stream_samples_t samples);
diff --git a/src/libac3/debug.c b/src/libac3/debug.c
deleted file mode 100644
index b7d6a3b08..000000000
--- a/src/libac3/debug.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *
- * debug.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include "debug.h"
-
-static int debug_level = -1;
-
-// Determine is debug output is required.
-// We could potentially have multiple levels of debug info
-int debug_is_on(void)
-{
- char *env_var;
-
- if(debug_level < 0)
- {
- env_var = getenv("AC3_DEBUG");
-
- if (env_var)
- {
- debug_level = 1;
- }
- else
- debug_level = 0;
- }
-
- return debug_level;
-}
-
-//If you don't have gcc, then ya don't get debug output
-#ifndef __GNUC__
-void dprintf(char fmt[],...)
-{
- int foo = 0;
-}
-#endif
-
diff --git a/src/libac3/debug.h b/src/libac3/debug.h
deleted file mode 100644
index f45cb5b1a..000000000
--- a/src/libac3/debug.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * debug.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.
- *
- */
-
-int debug_is_on(void);
-
-#ifdef __GNUC__
-#define dprintf(format,args...)\
-{\
- if (debug_is_on())\
- {\
- fprintf(stderr,format,## args);\
- }\
-}
-#else
-void dprintf(char fmt[],...);
-#endif
diff --git a/src/libac3/decode.c b/src/libac3/decode.c
deleted file mode 100644
index c859525e8..000000000
--- a/src/libac3/decode.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * decode.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/time.h>
-#include <inttypes.h>
-#include "ac3.h"
-#include "ac3_internal.h"
-#include "bitstream.h"
-#include "imdct.h"
-#include "coeff.h"
-#include "bit_allocate.h"
-#include "parse.h"
-#include "stats.h"
-#include "rematrix.h"
-#include "sanity_check.h"
-#include "downmix.h"
-#include "debug.h"
-
-//our global config structure
-uint32_t error_flag = 0;
-
-static audblk_t audblk;
-static ac3_state_t state;
-static uint32_t frame_count = 0;
-static uint32_t done_banner;
-static ac3_frame_t frame;
-
-//the floating point samples for one audblk
-static stream_samples_t samples;
-
-//the integer samples for the entire frame (with enough space for 5 ch out)
-//if this size change, be sure to change the size when muting
-static int16_t s16_samples[5 * 6 * 256];
-
-void
-ac3_init(void)
-{
- imdct_init();
- sanity_check_init(&state,&audblk);
-
- frame.audio_data = s16_samples;
-}
-
-int ac3_frame_length(uint8_t * buf)
-{
- int dummy;
-
- return parse_syncinfo (buf, &dummy, &dummy);
-}
-
-int ac3_sampling_rate(uint8_t * buf)
-{
- int dummy, rate;
-
- parse_syncinfo (buf, &rate, &dummy);
- return rate;
-}
-
-ac3_frame_t*
-ac3_decode_frame(uint8_t * buf, int max_num_channels)
-{
- uint32_t i;
- int dummy;
- int num_channels;
-
- if (!parse_syncinfo (buf, &frame.sampling_rate, &dummy))
- goto error;
-
- dprintf("(decode) begin frame %d\n",frame_count++);
-
- if (parse_bsi (&state, buf))
- goto error;
-
- switch (state.acmod) {
- case 7 :
- case 5 :
- /* case 3 : FIXME : implement downmix functions*/
- num_channels = (max_num_channels<5) ? max_num_channels : 5;
- break;
- case 4 :
- case 6 :
- num_channels = (max_num_channels<4) ? max_num_channels : 4;
- break;
- default:
- num_channels = 2;
- }
-
- frame.num_channels = num_channels;
-
- if (!done_banner) {
- stats_print_banner (&state);
- done_banner = 1;
- }
-
- for(i=0; i < 6; i++) {
- //Initialize freq/time sample storage
- memset(samples,0,sizeof(float) * 256 * (state.nfchans + state.lfeon));
-
- // Extract most of the audblk info from the bitstream
- // (minus the mantissas
- if (parse_audblk (&state, &audblk))
- goto error;
-
- // Figure out how many bits per mantissa
- //bit_allocate(&state,&audblk);
-
- // Extract the mantissas from the stream and
- // generate floating point frequency coefficients
- coeff_unpack(&state,&audblk,samples);
- if(error_flag)
- goto error;
-
- if(state.acmod == 0x2)
- rematrix(&audblk,samples);
-
- // Convert the frequency samples into time samples
- imdct(&state,&audblk,samples);
-
- // Downmix into the requested number of channels
- // and convert floating point to int16_t
- downmix(&state,samples,&s16_samples[i * num_channels * 256],
- num_channels);
-
- sanity_check(&state,&audblk);
- if(error_flag)
- goto error;
- }
-
-
- return &frame;
-
-error:
- //mute the frame
- memset(s16_samples,0,sizeof(int16_t) * 256 * 2 * 6);
-
- error_flag = 0;
- return &frame;
-}
diff --git a/src/libac3/decode.h b/src/libac3/decode.h
deleted file mode 100644
index bb84a1105..000000000
--- a/src/libac3/decode.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * decode.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.
- *
- */
diff --git a/src/libac3/dither.c b/src/libac3/dither.c
deleted file mode 100644
index 8b7ef3427..000000000
--- a/src/libac3/dither.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * dither.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ac3.h"
-#include "ac3_internal.h"
-
-
-#include "dither.h"
-
-
-const uint16_t dither_lut[256] =
-{
- 0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055,
- 0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb,
- 0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198,
- 0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176,
- 0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf,
- 0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321,
- 0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202,
- 0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec,
- 0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761,
- 0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f,
- 0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac,
- 0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642,
- 0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb,
- 0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415,
- 0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536,
- 0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8,
- 0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c,
- 0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2,
- 0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1,
- 0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f,
- 0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6,
- 0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58,
- 0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b,
- 0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95,
- 0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918,
- 0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6,
- 0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5,
- 0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b,
- 0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82,
- 0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c,
- 0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f,
- 0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1
-};
-
-uint16_t lfsr_state = 1;
-
-//
-// see dither_gen (inline-able) in dither.h
-//
-
-#if 0
-
-//
-// this is the old dither_gen with is much slower than the new inlined
-// lut version and is still here because it's easier to understand.
-//
-
-/*
- * Generate eight bits of pseudo-entropy using a 16 bit linear
- * feedback shift register (LFSR). The primitive polynomial used
- * is 1 + x^4 + x^14 + x^16.
- *
- * The distribution is uniform, over the range [-0.707,0.707]
- *
- */
-
-uint16_t dither_gen(void)
-{
- int i;
- uint32_t state;
-
- //explicitly bring the state into a local var as gcc > 3.0?
- //doesn't know how to optimize out the stores
- state = lfsr_state;
-
- //Generate eight pseudo random bits
- for(i=0;i<8;i++) {
- state <<= 1;
-
- if(state & 0x10000)
- state ^= 0xa011;
- }
-
- lfsr_state = state;
-
- return (((((int32_t)state<<8)>>8) * (int32_t) (0.707106 * 256.0))>>16);
-}
-
-#endif
diff --git a/src/libac3/dither.h b/src/libac3/dither.h
deleted file mode 100644
index 1a605ee14..000000000
--- a/src/libac3/dither.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * dither.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.
- *
- */
-
-
-extern uint16_t lfsr_state;
-extern const uint16_t dither_lut[256];
-
-static inline uint16_t dither_gen(void)
-{
- int16_t state;
-
- state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
-
- lfsr_state = (uint16_t) state;
-
- return ((state * (int32_t) (0.707106 * 256.0))>>8);
-}
diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c
index fd801308d..9e7fbfb8b 100644
--- a/src/libac3/downmix.c
+++ b/src/libac3/downmix.c
@@ -25,567 +25,509 @@
*
*/
+#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
+#include <string.h>
#include "ac3.h"
#include "ac3_internal.h"
-#include "decode.h"
-#include "downmix.h"
-#include "debug.h"
+#define CONVERT(acmod,output) (((output) << 3) + (acmod))
+int downmix_init (int input, int flags, float * level, float clev, float 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;
-//Pre-scaled downmix coefficients
-static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
-static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 };
+ case CONVERT (AC3_STEREO, AC3_MONO):
+ case CONVERT (AC3_2F2R, AC3_2F1R):
+ case CONVERT (AC3_3F2R, AC3_3F1R):
+ level_3db:
+ *level *= LEVEL_3DB;
+ break;
-static void
-downmix_3f_2r_to_5ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
-{
- uint32_t j;
- float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- left_sur = samples[3];
- right_sur = samples[4];
-
- for (j = 0; j < 256; j++)
- {
- s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f);
- s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f);
- s16_samples[j * 5 + 2] = (int16_t) (*left_sur++ * 32767.0f);
- s16_samples[j * 5 + 3] = (int16_t) (*right_sur++ * 32767.0f);
- s16_samples[j * 5 + 4] = (int16_t) (*centre++ * 32767.0f);
- }
+ 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
-downmix_3f_2r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix1to1 (float * samples, float level, float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- left_sur = samples[3];
- right_sur = samples[4];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.5000f * *left++ + 0.500f * *centre ;
- right_tmp= 0.5000f * *right++ + 0.500f * *centre++ ;
-
- s16_samples[j * 4 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 4 + 1] = (int16_t) (right_tmp * 32767.0f);
- s16_samples[j * 4 + 2] = (int16_t) (*left_sur++ * 32767.0f);
- s16_samples[j * 4 + 3] = (int16_t) (*right_sur++ * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] = samples[i] * level + bias;
}
-static void
-downmix_3f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void move1to1 (float * src, float * dest, float level, float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float clev,slev;
- float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- left_sur = samples[3];
- right_sur = samples[4];
-
- clev = cmixlev_lut[state->cmixlev];
- slev = smixlev_lut[state->surmixlev];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.4142f * *left++ + clev * *centre + slev * *left_sur++;
- right_tmp= 0.4142f * *right++ + clev * *centre++ + slev * *right_sur++;
-
- s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] = src[i] * level + bias;
}
-static void
-downmix_2f_2r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix2to1 (float * samples, float level, float bias)
{
- uint32_t j;
- float slev;
- float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
-
- left = samples[0];
- right = samples[1];
- left_sur = samples[2];
- right_sur = samples[3];
-
- slev = smixlev_lut[state->surmixlev];
-
- for (j = 0; j < 256; j++)
- {
- s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f);
- s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f);
- s16_samples[j * 5 + 2] = (int16_t) (*left_sur++ * 32767.0f);
- s16_samples[j * 5 + 3] = (int16_t) (*right_sur++ * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] = (samples[i] + samples[i + 256]) * level + bias;
}
-static void
-downmix_2f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void move2to1 (float * src, float * dest, float level, float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float slev;
- float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
-
- left = samples[0];
- right = samples[1];
- left_sur = samples[2];
- right_sur = samples[3];
-
- slev = smixlev_lut[state->surmixlev];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.4142f * *left++ + slev * *left_sur++;
- right_tmp= 0.4142f * *right++ + slev * *right_sur++;
-
- s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] = (src[i] + src[i + 256]) * level + bias;
}
-static void
-downmix_3f_1r_to_5ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix3to1 (float * samples, float level, float clev, float bias)
{
- uint32_t j;
- float *centre = 0, *left = 0, *right = 0, *sur = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- //Mono surround
- sur = samples[3];
-
- for (j = 0; j < 256; j++)
- {
- s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f);
- s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f);
- s16_samples[j * 5 + 2] = (int16_t) (*sur * 32767.0f);
- s16_samples[j * 5 + 3] = (int16_t) (*sur++ * 32767.0f);
- s16_samples[j * 5 + 4] = (int16_t) (*centre++ * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] = ((samples[i] + samples[i + 512]) * level +
+ samples[i + 256] * clev + bias);
}
-static void
-downmix_3f_1r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix21to1 (float * samples, float level, float slev, float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float clev,slev;
- float *centre = 0, *left = 0, *right = 0, *sur = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- //Mono surround
- sur = samples[3];
-
- clev = cmixlev_lut[state->cmixlev];
- slev = smixlev_lut[state->surmixlev];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.5000f * *left++ + 0.500f * *centre ;
- right_tmp= 0.5000f * *right++ + 0.500f * *centre++ ;
-
- s16_samples[j * 4 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 4 + 1] = (int16_t) (right_tmp * 32767.0f);
- s16_samples[j * 4 + 2] = (int16_t) (*sur * 32767.0f);
- s16_samples[j * 4 + 3] = (int16_t) (*sur++ * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] = ((samples[i] + samples[i + 256]) * level +
+ samples[i + 512] * slev + bias);
}
-static void
-downmix_3f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix31to1 (float * samples, float level, float clev, float slev,
+ float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float clev,slev;
- float *centre = 0, *left = 0, *right = 0, *sur = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- //Mono surround
- sur = samples[3];
-
- clev = cmixlev_lut[state->cmixlev];
- slev = smixlev_lut[state->surmixlev];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *sur;
- right_tmp= 0.4142f * *right++ + clev * *centre + slev * *sur++;
-
- s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f);
- }
+ 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 (float * samples, float level, float slev, float 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
-downmix_2f_1r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix32to1 (float * samples, float level, float clev, float slev,
+ float bias)
{
- uint32_t j;
- float *left = 0, *right = 0, *sur = 0;
-
- left = samples[0];
- right = samples[1];
- //Mono surround
- sur = samples[2];
-
- for (j = 0; j < 256; j++)
- {
- s16_samples[j * 4 ] = (int16_t) (*left++ * 32767.0f);
- s16_samples[j * 4 + 1] = (int16_t) (*right++ * 32767.0f);
- s16_samples[j * 4 + 2] = (int16_t) (*sur * 32767.0f);
- s16_samples[j * 4 + 3] = (int16_t) (*sur++ * 32767.0f);
- }
+ 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
-downmix_2f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix1to2 (float * src, float * dest, float level, float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float slev;
- float *left = 0, *right = 0, *sur = 0;
-
- left = samples[0];
- right = samples[1];
- //Mono surround
- sur = samples[2];
-
- slev = smixlev_lut[state->surmixlev];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.4142f * *left++ + slev * *sur;
- right_tmp= 0.4142f * *right++ + slev * *sur++;
-
- s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f);
- }
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] = src[i] = src[i] * level + bias;
}
-static void
-downmix_3f_0r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+static void mix3to2 (float * samples, float level, float clev, float bias)
{
- uint32_t j;
- float right_tmp;
- float left_tmp;
- float clev;
- float *centre = 0, *left = 0, *right = 0;
-
- left = samples[0];
- centre = samples[1];
- right = samples[2];
-
- clev = cmixlev_lut[state->cmixlev];
-
- for (j = 0; j < 256; j++)
- {
- left_tmp = 0.4142f * *left++ + clev * *centre;
- right_tmp= 0.4142f * *right++ + clev * *centre++;
-
- s16_samples[j * 2 ] = (int16_t) (left_tmp * 32767.0f);
- s16_samples[j * 2 + 1] = (int16_t) (right_tmp * 32767.0f);
- }
+ int i;
+ float 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
-downmix_2f_0r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+
+static void mix21to2 (float * left, float * right, float level, float slev,
+ float bias)
{
- uint32_t j;
- float *left = 0, *right = 0;
+ int i;
+ float 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;
+ }
+}
- left = samples[0];
- right = samples[1];
+static void mix11to1 (float * front, float * rear, float level, float slev,
+ float bias)
+{
+ int i;
- for (j = 0; j < 256; j++)
- {
- s16_samples[j * 2 ] = (int16_t) (*left++ * 32767.0f);
- s16_samples[j * 2 + 1] = (int16_t) (*right++ * 32767.0f);
- }
+ for (i = 0; i < 256; i++)
+ front[i] = front[i] * level + rear[i] * slev + bias;
}
-static void
-downmix_1f_0r_to_2ch(float *centre,int16_t *s16_samples)
+static void mix31to2 (float * samples, float level, float clev, float slev,
+ float bias)
{
- uint32_t j;
- float tmp;
-
- //Mono program!
+ int i;
+ float 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;
+ }
+}
- for (j = 0; j < 256; j++)
- {
- tmp = 32767.0f * 0.7071f * *centre++;
+static void mix32to2 (float * samples, float level, float clev, float slev,
+ float bias)
+{
+ int i;
+ float 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);
+ }
+}
- s16_samples[j * 2 ] = s16_samples[j * 2 + 1] = (int16_t) tmp;
- }
+static void mix21toS (float * samples, float level, float level3db, float bias)
+{
+ int i;
+ float 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;
+ }
}
-//
-// Downmix into 2 or 4 or 5 channels (4 ch isn't in quite yet)
-//
-// The downmix function names have the following format
-//
-// downmix_Xf_Yr_to_[2|4|5]ch[_dolby]
-//
-// where X = number of front channels
-// Y = number of rear channels
-// [2|4|5] = number of output channels
-// [_dolby] = with or without dolby surround mix
-//
-
-void downmix(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples, int num_channels)
+static void mix22toS (float * samples, float level, float level3db, float bias)
{
- if(state->acmod > 7)
- dprintf("(downmix) invalid acmod number\n");
-
-#if 0
- //
- //There are two main cases, with or without Dolby Surround
- //
- if(ac3_config.flags & AC3_DOLBY_SURR_ENABLE)
- {
- fprintf(stderr,"Dolby Surround Mixes not currently enabled\n");
- exit(1);
- }
-#endif
-
- //Non-Dolby surround downmixes
- switch(state->acmod)
- {
- // 3/2
- case 7:
- switch (num_channels) {
- case 5:
- downmix_3f_2r_to_5ch(state, samples,s16_samples);
- break;
- case 4:
- downmix_3f_2r_to_4ch(state, samples,s16_samples);
- break;
- case 2:
- downmix_3f_2r_to_2ch(state, samples,s16_samples);
- break;
- }
- break;
-
- // 2/2
- case 6:
- if (num_channels == 4)
- downmix_2f_2r_to_4ch(state, samples,s16_samples);
- else
- downmix_2f_2r_to_2ch(state, samples,s16_samples);
- break;
-
- // 3/1
- case 5:
-
- switch (num_channels) {
- case 5:
- downmix_3f_1r_to_5ch(state, samples,s16_samples);
- break;
- case 4:
- downmix_3f_1r_to_4ch(state, samples,s16_samples);
- break;
- case 2:
- downmix_3f_1r_to_2ch(state, samples,s16_samples);
- break;
- }
-
- break;
-
- // 2/1
- case 4:
- if (num_channels == 4)
- downmix_2f_1r_to_4ch(state, samples,s16_samples);
- else
- downmix_2f_1r_to_2ch(state, samples,s16_samples);
- break;
-
- // 3/0
- case 3:
- downmix_3f_0r_to_2ch(state, samples,s16_samples);
- break;
-
- case 2:
- downmix_2f_0r_to_2ch(state, samples,s16_samples);
- break;
-
- // 1/0
- case 1:
- downmix_1f_0r_to_2ch(samples[0],s16_samples);
- break;
-
- // 1+1
- case 0:
-#if 0
- downmix_1f_0r_to_2ch(samples[ac3_config.dual_mono_ch_sel],s16_samples);
-#endif
- break;
- }
+ int i;
+ float 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 (float * samples, float level, float level3db, float bias)
+{
+ int i;
+ float 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 (float * samples, float level, float level3db, float bias)
+{
+ int i;
+ float 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;
+ }
+}
-#if 0
-
- //the dolby mixes lay here for the time being
- switch(state->acmod)
- {
- // 3/2
- case 7:
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- left_sur = samples[3];
- right_sur = samples[4];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
- left_tmp = -1 * right_tmp;
- right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
- left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
-
- samples[1][j] = right_tmp;
- samples[0][j] = left_tmp;
- }
-
- break;
-
- // 2/2
- case 6:
- left = samples[0];
- right = samples[1];
- left_sur = samples[2];
- right_sur = samples[3];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
- left_tmp = -1 * right_tmp;
- right_tmp += 0.3204f * *right++;
- left_tmp += 0.3204f * *left++ ;
-
- samples[1][j] = right_tmp;
- samples[0][j] = left_tmp;
- }
- break;
-
- // 3/1
- case 5:
- left = samples[0];
- centre = samples[1];
- right = samples[2];
- //Mono surround
- right_sur = samples[3];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.2265f * *right_sur++;
- left_tmp = -1 * right_tmp;
- right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
- left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
-
- samples[1][j] = right_tmp;
- samples[0][j] = left_tmp;
- }
- break;
-
- // 2/1
- case 4:
- left = samples[0];
- right = samples[1];
- //Mono surround
- right_sur = samples[2];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.2265f * *right_sur++;
- left_tmp = -1 * right_tmp;
- right_tmp += 0.3204f * *right++;
- left_tmp += 0.3204f * *left++;
-
- samples[1][j] = right_tmp;
- samples[0][j] = left_tmp;
- }
- break;
-
- // 3/0
- case 3:
- left = samples[0];
- centre = samples[1];
- right = samples[2];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.3204f * *right++ + 0.2265f * *centre;
- left_tmp = 0.3204f * *left++ + 0.2265f * *centre++;
-
- samples[1][j] = right_tmp;
- samples[0][j] = left_tmp;
- }
- break;
-
- // 2/0
- case 2:
- //Do nothing!
- break;
-
- // 1/0
- case 1:
- //Mono program!
- right = samples[0];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.7071f * *right++;
-
- samples[1][j] = right_tmp;
- samples[0][j] = right_tmp;
- }
-
- break;
-
- // 1+1
- case 0:
- //Dual mono, output selected by user
- right = samples[ac3_config.dual_mono_ch_sel];
-
- for (j = 0; j < 256; j++)
- {
- right_tmp = 0.7071f * *right++;
-
- samples[1][j] = right_tmp;
- samples[0][j] = right_tmp;
- }
- break;
-#endif
+void downmix (float * samples, int acmod, int output, float level, float bias,
+ float clev, float 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):
+ mix_1to1_b:
+ mix1to1 (samples + 256, 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);
+ goto mix_1to1_b;
+
+ 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;
+
+ }
+}
diff --git a/src/libac3/downmix.h b/src/libac3/downmix.h
deleted file mode 100644
index 28c6aea15..000000000
--- a/src/libac3/downmix.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *
- * downmix.h
- *
- * Copyright (C) Aaron Holtzman - Sept 1999
- *
- * Originally based on code by Yeqing 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.
- *
- *
- */
-
-void downmix(ac3_state_t * state, stream_samples_t stream_samples,int16_t *s16_samples,
- int num_channels);
diff --git a/src/libac3/imdct.c b/src/libac3/imdct.c
index a2e83d423..030026a54 100644
--- a/src/libac3/imdct.c
+++ b/src/libac3/imdct.c
@@ -24,32 +24,23 @@
#include "config.h"
+#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "ac3.h"
#include "ac3_internal.h"
-
-#include "decode.h"
-#include "imdct.h"
-
-void imdct_do_256(float data[],float delay[]);
-void imdct_do_512(float data[],float delay[]);
-
-void imdct_do_256_mlib(float data[],float delay[]);
-void imdct_do_512_mlib(float data[],float delay[]);
+void (* imdct_256) (float data[], float delay[]);
+void (* imdct_512) (float data[], float delay[]);
typedef struct complex_s
{
- float real;
- float imag;
+ float real;
+ float imag;
} complex_t;
-#define N 512
-
-
/* 128 point bit-reverse LUT */
static uint8_t bit_reverse_512[] = {
0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
@@ -82,7 +73,6 @@ static uint8_t bit_reverse_256[] = {
static complex_t buf[128];
/* Twiddle factor LUT */
-static complex_t *w[7];
static complex_t w_1[1];
static complex_t w_2[2];
static complex_t w_4[4];
@@ -90,6 +80,7 @@ static complex_t w_8[8];
static complex_t w_16[16];
static complex_t w_32[32];
static complex_t w_64[64];
+static complex_t * w[7] = {w_1, w_2, w_4, w_8, w_16, w_32, w_64};
/* Twiddle factors for IMDCT */
static float xcos1[128];
@@ -97,9 +88,6 @@ static float xsin1[128];
static float xcos2[64];
static float xsin2[64];
-/* Delay buffer for time domain interleaving */
-static float delay[6][256];
-
/* Windowing function for Modified DCT - Thank you acroread */
float imdct_window[] = {
0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
@@ -157,51 +145,6 @@ static inline complex_t cmplx_mult(complex_t a, complex_t b)
return ret;
}
-void imdct_init(void)
-{
- int i,k;
- complex_t angle_step;
- complex_t current_angle;
-
-#ifdef LIBAC3_MLIB
- return;
-#endif
-
- /* Twiddle factors to turn IFFT into IMDCT */
- for( i=0; i < 128; i++) {
- xcos1[i] = -cos(2.0f * M_PI * (8*i+1)/(8*N)) ;
- xsin1[i] = -sin(2.0f * M_PI * (8*i+1)/(8*N)) ;
- }
-
- /* More twiddle factors to turn IFFT into IMDCT */
- for( i=0; i < 64; i++) {
- xcos2[i] = -cos(2.0f * M_PI * (8*i+1)/(4*N)) ;
- xsin2[i] = -sin(2.0f * M_PI * (8*i+1)/(4*N)) ;
- }
-
- /* Canonical twiddle factors for FFT */
- w[0] = w_1;
- w[1] = w_2;
- w[2] = w_4;
- w[3] = w_8;
- w[4] = w_16;
- w[5] = w_32;
- w[6] = w_64;
-
- for( i = 0; i < 7; i++) {
- angle_step.real = cos(-2.0 * M_PI / (1 << (i+1)));
- angle_step.imag = sin(-2.0 * M_PI / (1 << (i+1)));
-
- current_angle.real = 1.0;
- current_angle.imag = 0.0;
-
- for (k = 0; k < 1 << i; k++) {
- w[i][k] = current_angle;
- current_angle = cmplx_mult(current_angle,angle_step);
- }
- }
-}
-
void
imdct_do_512(float data[],float delay[])
{
@@ -429,30 +372,37 @@ imdct_do_256(float data[],float delay[])
}
}
-void
-imdct(ac3_state_t *state,audblk_t *audblk, stream_samples_t samples) {
- int i;
-
+void imdct_init (void)
+{
#ifdef LIBAC3_MLIB
- for(i=0; i<state->nfchans;i++) {
- if(audblk->blksw[i])
- imdct_do_256_mlib(samples[i],delay[i]);
- else
- imdct_do_512_mlib(samples[i],delay[i]);
+ void imdct_do_256_mlib(float data[],float delay[]);
+ void imdct_do_512_mlib(float data[],float delay[]);
+
+ 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));
}
- return;
-#endif
- for(i=0; i<state->nfchans;i++) {
- if(audblk->blksw[i])
- imdct_do_256(samples[i],delay[i]);
- else
- imdct_do_512(samples[i],delay[i]);
+ /* 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));
}
- //XXX We don't bother with the IMDCT for the LFE as it's currently
- //unused.
- //if (state->lfeon)
- // imdct_do_512(coeffs->lfe,samples->channel[5],delay[5]);
- //
+ 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;
+#endif
}
diff --git a/src/libac3/imdct.h b/src/libac3/imdct.h
deleted file mode 100644
index c6b3325a9..000000000
--- a/src/libac3/imdct.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * imdct.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.
- *
- *
- */
-
-void imdct(ac3_state_t *state,audblk_t *audblk, stream_samples_t samples);
-void imdct_init(void);
diff --git a/src/libac3/parse.c b/src/libac3/parse.c
index 7feee2bbe..98ee09012 100644
--- a/src/libac3/parse.c
+++ b/src/libac3/parse.c
@@ -22,78 +22,106 @@
*
*/
-#include <stdlib.h>
-#include <stdio.h>
+#include <inttypes.h>
#include <string.h>
+
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
-#include "stats.h"
-#include "debug.h"
-#include "parse.h"
-#include "bit_allocate.h"
+#include "tables.h"
+
+extern stream_samples_t samples; // FIXME
+static float delay[6][256];
+
+void ac3_init (void)
+{
+ imdct_init ();
+}
-static const uint8_t nfchans[8] = {2, 1, 2, 3, 3, 4, 4, 5};
+static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
-int parse_syncinfo (uint8_t * buf, int * sample_rate, int * bit_rate)
+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;
- *bit_rate = bitrate = rate [frmsizecod >> 1];
+ bitrate = rate [frmsizecod >> 1];
+ *bit_rate = (bitrate * 1000) >> half;
switch (buf[4] & 0xc0) {
case 0: // 48 KHz
- *sample_rate = 48000;
+ *sample_rate = 48000 >> half;
return 4 * bitrate;
case 0x40:
- *sample_rate = 44100;
+ *sample_rate = 44100 >> half;
return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
case 0x80:
- *sample_rate = 32000;
+ *sample_rate = 32000 >> half;
return 6 * bitrate;
default:
return 0;
}
}
-int parse_bsi (ac3_state_t * state, uint8_t * buf)
+int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, float * level,
+ float bias)
{
+ static float clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB};
+ static float slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB};
int chaninfo;
+ int acmod;
state->fscod = buf[4] >> 6;
-
- if (buf[5] >= 0x48) // bsid >= 9
- return 1;
-
- state->acmod = buf[6] >> 5;
- state->nfchans = nfchans[state->acmod];
+ 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 ((state->acmod & 0x1) && (state->acmod != 0x1))
- state->cmixlev = bitstream_get (2);
+ if ((acmod == 2) && (bitstream_get (2) == 2)) // dsurmod
+ acmod = AC3_DOLBY;
- if (state->acmod & 0x4)
- state->surmixlev = bitstream_get (2);
+ if ((acmod & 1) && (acmod != 1))
+ state->clev = clev[bitstream_get (2)]; // cmixlev
- if (state->acmod == 0x2)
- bitstream_get (2); // dsurmod
+ if (acmod & 4)
+ state->slev = slev[bitstream_get (2)]; // surmixlev
state->lfeon = bitstream_get (1);
- chaninfo = (state->acmod) ? 0 : 1;
+ state->output = downmix_init (acmod, *flags, level,
+ state->clev, state->slev);
+ if (state->output < 0) {
+ return 1;
+ }
+ *flags = state->output;
+ state->level = *level;
+ state->bias = bias;
+
+ chaninfo = !acmod;
do {
bitstream_get (5); // dialnorm
if (bitstream_get (1)) // compre
@@ -120,7 +148,6 @@ int parse_bsi (ac3_state_t * state, uint8_t * buf)
} while (addbsil--);
}
- stats_print_bsi(state);
return 0;
}
@@ -128,18 +155,11 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
uint8_t * dest)
{
int exps;
- int8_t exp_1, exp_2, exp_3;
while (ngrps--) {
exps = bitstream_get (7);
- if (exps >= 125)
- return 1;
- exp_1 = exps / 25;
- exp_2 = (exps - (exp_1 * 25)) / 5;
- exp_3 = exps - (exp_1 * 25) - (exp_2 * 5) ;
-
- exponent += (exp_1 - 2);
+ exponent += exp_1[exps];
if (exponent > 24)
return 1;
@@ -153,7 +173,7 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
*(dest++) = exponent;
}
- exponent += (exp_2 - 2);
+ exponent += exp_2[exps];
if (exponent > 24)
return 1;
@@ -167,7 +187,7 @@ static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
*(dest++) = exponent;
}
- exponent += (exp_3 - 2);
+ exponent += exp_3[exps];
if (exponent > 24)
return 1;
@@ -209,106 +229,252 @@ static int parse_deltba (int8_t * deltba)
return 0;
}
-static inline int zero_snr_offsets (ac3_state_t * state, audblk_t * audblk)
+static inline int zero_snr_offsets (int nfchans, ac3_state_t * state)
{
int i;
- if ((audblk->csnroffst) ||
- (audblk->cplinu && audblk->cplba.fsnroffst) ||
- (state->lfeon && audblk->lfeba.fsnroffst))
+ if ((state->csnroffst) || (state->cplinu && state->cplba.fsnroffst) ||
+ (state->lfeon && state->lfeba.fsnroffst))
return 0;
- for (i = 0; i < state->nfchans; i++)
- if (audblk->ba[i].fsnroffst)
+ for (i = 0; i < nfchans; i++)
+ if (state->ba[i].fsnroffst)
return 0;
return 1;
}
-int parse_audblk (ac3_state_t * state, audblk_t * audblk)
+static float q_1[2];
+static float q_2[2];
+static float 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; \
+ continue;
+
+#define CHANNEL_DITHER(val) \
+ if (dither) { \
+ coeff[i++] = dither_gen () * val; \
+ continue; \
+ } else { \
+ coeff[i++] = 0; \
+ 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 (float * coeff, uint8_t * exp, int8_t * bap,
+ int dither, int end)
{
- int i, chaninfo;
- uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc;
+ 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)
+{
+ 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 < state->nfchans; i++)
- audblk->blksw[i] = bitstream_get (1);
+ for (i = 0; i < nfchans; i++)
+ blksw[i] = bitstream_get (1);
- for (i = 0; i < state->nfchans; i++)
- audblk->dithflag[i] = bitstream_get (1);
+ for (i = 0; i < nfchans; i++)
+ dithflag[i] = bitstream_get (1);
- chaninfo = (state->acmod) ? 0 : 1;
+ chaninfo = !(state->acmod);
do {
if (bitstream_get (1)) // dynrnge
bitstream_get (8); // dynrng
} while (chaninfo--);
if (bitstream_get (1)) { // cplstre
- audblk->cplinu = bitstream_get (1);
- if (audblk->cplinu) {
- for (i = 0; i < state->nfchans; i++)
- audblk->chincpl[i] = bitstream_get (1);
- if (state->acmod == 0x2)
- audblk->phsflginu = bitstream_get (1);
- audblk->cplbegf = bitstream_get (4);
- audblk->cplendf = bitstream_get (4);
-
- audblk->cplstrtmant = audblk->cplbegf * 12 + 37;
- audblk->cplendmant = audblk->cplendf * 12 + 73;
- audblk->ncplsubnd = audblk->cplendf + 3 - audblk->cplbegf;
- audblk->ncplbnd = audblk->ncplsubnd;
-
- for(i = 1; i< audblk->ncplsubnd; i++) {
- audblk->cplbndstrc[i] = bitstream_get (1);
- audblk->ncplbnd -= audblk->cplbndstrc[i];
+ 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 (audblk->cplinu) {
+ if (state->cplinu) {
int j, cplcoe;
cplcoe = 0;
- for (i = 0; i < state->nfchans; i++)
- if (audblk->chincpl[i])
+ for (i = 0; i < nfchans; i++)
+ if (state->chincpl[i])
if (bitstream_get (1)) { // cplcoe
+ int mstrcplco, cplcoexp, cplcomant;
+
cplcoe = 1;
- audblk->mstrcplco[i] = bitstream_get (2);
- for (j = 0; j < audblk->ncplbnd; j++) {
- audblk->cplcoexp[i][j] = bitstream_get (4);
- audblk->cplcomant[i][j] = bitstream_get (4);
+ 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 == 0x2) && audblk->phsflginu && cplcoe)
- for (j = 0; j < audblk->ncplbnd; j++)
- audblk->phsflg[j] = bitstream_get (1);
+ 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 == 0x2) && (bitstream_get (1))) { // rematstr
- if ((audblk->cplbegf > 2) || (audblk->cplinu == 0))
- for (i = 0; i < 4; i++)
- audblk->rematflg[i] = bitstream_get (1);
- else if ((audblk->cplbegf == 0) && audblk->cplinu)
- for (i = 0; i < 2; i++)
- audblk->rematflg[i] = bitstream_get (1);
- else if ((audblk->cplbegf <= 2) && audblk->cplinu)
- for(i = 0; i < 3; i++)
- audblk->rematflg[i] = bitstream_get (1);
+ 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 (audblk->cplinu)
+ if (state->cplinu)
cplexpstr = bitstream_get (2);
- for (i = 0; i < state->nfchans; i++)
+ for (i = 0; i < nfchans; i++)
chexpstr[i] = bitstream_get (2);
if (state->lfeon)
lfeexpstr = bitstream_get (1);
- for (i = 0; i < state->nfchans; i++)
+ for (i = 0; i < nfchans; i++)
if (chexpstr[i] != EXP_REUSE) {
- if (audblk->cplinu && audblk->chincpl[i])
- audblk->endmant[i] = audblk->cplstrtmant;
+ if (state->cplinu && state->chincpl[i])
+ state->endmant[i] = state->cplstrtmant;
else {
- audblk->chbwcod[i] = bitstream_get (6);
- audblk->endmant[i] = audblk->chbwcod[i] * 3 + 73;
+ int chbwcod;
+
+ chbwcod = bitstream_get (6);
+ if (chbwcod > 60)
+ return 1;
+ state->endmant[i] = chbwcod * 3 + 73;
}
}
@@ -318,103 +484,97 @@ int parse_audblk (ac3_state_t * state, audblk_t * audblk)
int cplabsexp, ncplgrps;
do_bit_alloc = 1;
- ncplgrps = ((audblk->cplendmant - audblk->cplstrtmant) /
+ ncplgrps = ((state->cplendmant - state->cplstrtmant) /
(3 << (cplexpstr - 1)));
cplabsexp = bitstream_get (4) << 1;
if (parse_exponents (cplexpstr, ncplgrps, cplabsexp,
- audblk->cpl_exp + audblk->cplstrtmant))
+ state->cpl_exp + state->cplstrtmant))
return 1;
}
- for (i = 0; i < state->nfchans; i++)
+ for (i = 0; i < nfchans; i++)
if (chexpstr[i] != EXP_REUSE) {
int grp_size, nchgrps;
do_bit_alloc = 1;
- grp_size = 3 * (1 << (chexpstr[i] - 1));
- nchgrps = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size;
- audblk->fbw_exp[i][0] = bitstream_get (4);
- if (parse_exponents (chexpstr[i], nchgrps, audblk->fbw_exp[i][0],
- audblk->fbw_exp[i] + 1))
+ 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;
- audblk->lfe_exp[0] = bitstream_get (4);
- if (parse_exponents (lfeexpstr, 2, audblk->lfe_exp[0],
- audblk->lfe_exp + 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;
- audblk->sdcycod = bitstream_get (2);
- audblk->fdcycod = bitstream_get (2);
- audblk->sgaincod = bitstream_get (2);
- audblk->dbpbcod = bitstream_get (2);
- audblk->floorcod = bitstream_get (3);
+ 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;
- audblk->csnroffst = bitstream_get (6);
- if (audblk->cplinu) {
- audblk->cplba.fsnroffst = bitstream_get (4);
- audblk->cplba.fgaincod = bitstream_get (3);
+ state->csnroffst = bitstream_get (6);
+ if (state->cplinu) {
+ state->cplba.fsnroffst = bitstream_get (4);
+ state->cplba.fgaincod = bitstream_get (3);
}
- for (i = 0; i < state->nfchans; i++) {
- audblk->ba[i].fsnroffst = bitstream_get (4);
- audblk->ba[i].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) {
- audblk->lfeba.fsnroffst = bitstream_get (4);
- audblk->lfeba.fgaincod = bitstream_get (3);
+ state->lfeba.fsnroffst = bitstream_get (4);
+ state->lfeba.fgaincod = bitstream_get (3);
}
}
- if ((audblk->cplinu) && (bitstream_get (1))) { // cplleake
+ if ((state->cplinu) && (bitstream_get (1))) { // cplleake
do_bit_alloc = 1;
- audblk->cplfleak = bitstream_get (3);
- audblk->cplsleak = bitstream_get (3);
+ state->cplfleak = 2304 - (bitstream_get (3) << 8);
+ state->cplsleak = 2304 - (bitstream_get (3) << 8);
}
if (bitstream_get (1)) { // deltbaie
do_bit_alloc = 1;
- if (audblk->cplinu)
- audblk->cplba.deltbae = bitstream_get (2);
- for (i = 0; i < state->nfchans; i++)
- audblk->ba[i].deltbae = bitstream_get (2);
- if (audblk->cplinu && (audblk->cplba.deltbae == DELTA_BIT_NEW) &&
- parse_deltba (audblk->cplba.deltba))
+ 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 < state->nfchans; i++)
- if ((audblk->ba[i].deltbae == DELTA_BIT_NEW) &&
- parse_deltba (audblk->ba[i].deltba))
+ 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 (state, audblk)) {
- memset (audblk->cpl_bap, 0, sizeof (audblk->cpl_bap));
- memset (audblk->fbw_bap, 0, sizeof (audblk->fbw_bap));
- memset (audblk->lfe_bap, 0, sizeof (audblk->lfe_bap));
+ 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 {
- static int bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44,
- 45, 45, 46, 46, 47, 47, 48, 48};
-
- if (audblk->cplinu)
- bit_allocate (state->fscod, audblk, &audblk->cplba,
- bndtab[audblk->cplbegf], audblk->cplstrtmant,
- audblk->cplendmant,
- 2304 - (audblk->cplfleak << 8),
- 2304 - (audblk->cplsleak << 8),
- audblk->cpl_exp, audblk->cpl_bap);
- for (i = 0; i < state->nfchans; i++)
- bit_allocate (state->fscod, audblk, audblk->ba + i, 0, 0,
- audblk->endmant[i], 0, 0,
- audblk->fbw_exp[i], audblk->fbw_bap[i]);
+ 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) {
- audblk->lfeba.deltbae = DELTA_BIT_NONE;
- bit_allocate (state->fscod, audblk, &audblk->lfeba, 0, 0, 7,
- 0, 0, audblk->lfe_exp, audblk->lfe_bap);
+ state->lfeba.deltbae = DELTA_BIT_NONE;
+ bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
+ state->lfe_exp, state->lfe_bap);
}
}
}
@@ -425,6 +585,101 @@ int parse_audblk (ac3_state_t * state, audblk_t * audblk)
bitstream_get (8);
}
- stats_print_audblk(state,audblk);
+ 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;
+ float 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 {
+ float 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[5], state->lfe_exp, state->lfe_bap, 0, 7);
+#if 0
+ for (i = 7; i < 256; i++)
+ samples[5][i] = 0;
+#endif
+ }
+
+ for (i = 0; i < nfchans; i++)
+ if (blksw[i])
+ imdct_256 (samples[i], delay[i]);
+ else
+ imdct_512 (samples[i], delay[i]);
+
+#if 0
+ if (state->lfeon)
+ imdct_512 (samples[5], delay[5]);
+#endif
+
+ downmix (*samples, state->acmod, state->output, state->level, state->bias,
+ state->clev, state->slev);
+
return 0;
}
diff --git a/src/libac3/parse.h b/src/libac3/parse.h
deleted file mode 100644
index 39b5d8a2a..000000000
--- a/src/libac3/parse.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * parse.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.
- *
- */
-
-int parse_syncinfo(uint8_t * buf, int * sample_rate, int * bit_rate);
-int parse_audblk(ac3_state_t *state,audblk_t *audblk);
-int parse_bsi(ac3_state_t *state, uint8_t * buf);
diff --git a/src/libac3/rematrix.c b/src/libac3/rematrix.c
deleted file mode 100644
index 7098f0526..000000000
--- a/src/libac3/rematrix.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * rematrix.c
- *
- * Copyright (C) Aaron Holtzman - July 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ac3.h"
-#include "ac3_internal.h"
-
-
-#include "decode.h"
-#include "rematrix.h"
-
-struct rematrix_band_s
-{
- uint32_t start;
- uint32_t end;
-};
-
-struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}};
-
-static inline uint32_t min(uint32_t a,uint32_t b);
-
-static inline uint32_t
-min(uint32_t a,uint32_t b)
-{
- return (a < b ? a : b);
-}
-
-/* This routine simply does stereo rematixing for the 2 channel
- * stereo mode */
-void rematrix(audblk_t *audblk, stream_samples_t samples)
-{
- uint32_t num_bands;
- uint32_t start;
- uint32_t end;
- uint32_t i,j;
- float left,right;
-
- if(!audblk->cplinu || audblk->cplbegf > 2)
- num_bands = 4;
- else if (audblk->cplbegf > 0)
- num_bands = 3;
- else
- num_bands = 2;
-
- for(i=0;i < num_bands; i++) {
- if(!audblk->rematflg[i])
- continue;
-
- start = rematrix_band[i].start;
- end = min(rematrix_band[i].end ,12 * audblk->cplbegf + 36);
-
- for(j=start;j < end; j++) {
- left = samples[0][j] + samples[1][j];
- right = samples[0][j] - samples[1][j];
- samples[0][j] = left;
- samples[1][j] = right;
- }
- }
-}
diff --git a/src/libac3/rematrix.h b/src/libac3/rematrix.h
deleted file mode 100644
index 0be6528f6..000000000
--- a/src/libac3/rematrix.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * rematrix.h
- *
- * Copyright (C) Aaron Holtzman - July 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.
- *
- *
- */
-
-void rematrix(audblk_t *audblk, stream_samples_t samples);
diff --git a/src/libac3/sanity_check.c b/src/libac3/sanity_check.c
deleted file mode 100644
index 199fe6b4c..000000000
--- a/src/libac3/sanity_check.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * sanity_check.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ac3.h"
-#include "ac3_internal.h"
-#include "sanity_check.h"
-
-
-void
-sanity_check_init(ac3_state_t * state, audblk_t *audblk)
-{
- audblk->magic1 = AC3_MAGIC_NUMBER;
- audblk->magic2 = AC3_MAGIC_NUMBER;
- audblk->magic3 = AC3_MAGIC_NUMBER;
-}
-
-void
-sanity_check(ac3_state_t * state, audblk_t *audblk)
-{
- int i;
-
- if(audblk->magic1 != AC3_MAGIC_NUMBER)
- {
- fprintf(stderr,"\n** Sanity check failed -- audblk magic number 1 **");
- error_flag = 1;
- }
-
- if(audblk->magic2 != AC3_MAGIC_NUMBER)
- {
- fprintf(stderr,"\n** Sanity check failed -- audblk magic number 2 **");
- error_flag = 1;
- }
-
- if(audblk->magic3 != AC3_MAGIC_NUMBER)
- {
- fprintf(stderr,"\n** Sanity check failed -- audblk magic number 3 **");
- error_flag = 1;
- }
-
- for(i = 0;i < 5 ; i++)
- {
- if (audblk->fbw_exp[i][255] !=0 || audblk->fbw_exp[i][254] !=0 ||
- audblk->fbw_exp[i][253] !=0)
- {
- fprintf(stderr,"\n** Sanity check failed -- fbw_exp out of bounds **");
- error_flag = 1;
- }
-
- if (audblk->fbw_bap[i][255] !=0 || audblk->fbw_bap[i][254] !=0 ||
- audblk->fbw_bap[i][253] !=0)
- {
- fprintf(stderr,"\n** Sanity check failed -- fbw_bap out of bounds **");
- error_flag = 1;
- }
-
- }
-
- if (audblk->cpl_exp[255] !=0 || audblk->cpl_exp[254] !=0 ||
- audblk->cpl_exp[253] !=0)
- {
- fprintf(stderr,"\n** Sanity check failed -- cpl_exp out of bounds **");
- error_flag = 1;
- }
-
- if (audblk->cpl_bap[255] !=0 || audblk->cpl_bap[254] !=0 ||
- audblk->cpl_bap[253] !=0)
- {
- fprintf(stderr,"\n** Sanity check failed -- cpl_bap out of bounds **");
- error_flag = 1;
- }
-
- if (audblk->cplmant[255] !=0 || audblk->cplmant[254] !=0 ||
- audblk->cplmant[253] !=0)
- {
- fprintf(stderr,"\n** Sanity check failed -- cpl_mant out of bounds **");
- error_flag = 1;
- }
-
- if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2)))
- {
- fprintf(stderr,"\n** Sanity check failed -- cpl params inconsistent **");
- error_flag = 1;
- }
-
- for(i=0; i < state->nfchans; i++)
- {
- if((audblk->chincpl[i] == 0) && (audblk->chbwcod[i] > 60))
- {
- fprintf(stderr,"\n** Sanity check failed -- chbwcod too big **");
- error_flag = 1;
- }
- }
-
- return;
-}
diff --git a/src/libac3/sanity_check.h b/src/libac3/sanity_check.h
deleted file mode 100644
index e098aebce..000000000
--- a/src/libac3/sanity_check.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * sanity_check.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 AC3_MAGIC_NUMBER 0xdeadbeef
-
-void sanity_check_init(ac3_state_t * state, audblk_t *audblk);
-void sanity_check(ac3_state_t * state, audblk_t *audblk);
diff --git a/src/libac3/stats.c b/src/libac3/stats.c
deleted file mode 100644
index 7f73ceb62..000000000
--- a/src/libac3/stats.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * stats.c
- *
- * Copyright (C) Aaron Holtzman - May 1999
- *
- * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
- *
- * ac3dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ac3dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "config.h"
-#include "ac3.h"
-#include "ac3_internal.h"
-
-
-#include "decode.h"
-#include "stats.h"
-#include "debug.h"
-
-
-struct mixlev_s
-{
- float clev;
- char *desc;
-};
-
-static const struct mixlev_s cmixlev_tbl[4] =
-{
- {0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"},
- {0.500, "(-6.0 dB)"}, {1.0, "Invalid"}
-};
-
-static const struct mixlev_s smixlev_tbl[4] =
-{
- {0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"},
- { 0.0, "off "}, { 1.0, "Invalid"}
-};
-
-void stats_print_banner(ac3_state_t * state)
-{
- fprintf(stdout,"%d.%d Mode\n",state->nfchans,state->lfeon);
-}
-
-void stats_print_syncinfo(ac3_state_t * state)
-{
- dprintf("(syncinfo) ");
-
- switch (state->fscod)
- {
- case 2:
- dprintf("32 KHz ");
- break;
- case 1:
- dprintf("44.1 KHz ");
- break;
- case 0:
- dprintf("48 KHz ");
- break;
- default:
- dprintf("Invalid sampling rate ");
- break;
- }
-}
-
-void stats_print_bsi(ac3_state_t * state)
-{
- dprintf("(bsi) ");
- dprintf(" %d.%d Mode ",state->nfchans,state->lfeon);
- if ((state->acmod & 0x1) && (state->acmod != 0x1))
- dprintf(" Centre Mix Level %s ",cmixlev_tbl[state->cmixlev].desc);
- if (state->acmod & 0x4)
- dprintf(" Sur Mix Level %s ",smixlev_tbl[state->cmixlev].desc);
- dprintf("\n");
-
-}
-
-char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "};
-
-void stats_print_audblk(ac3_state_t * state,audblk_t *audblk)
-{
- uint32_t i;
-
- dprintf("(audblk) ");
- dprintf("%s ",audblk->cplinu ? "cpl on " : "cpl off");
- dprintf("%s ",audblk->phsflginu? "phsflg " : " ");
- dprintf("[");
- for(i=0;i<state->nfchans;i++)
- dprintf("%1d",audblk->blksw[i]);
- dprintf("]");
-
- dprintf("\n");
-}
diff --git a/src/libac3/stats.h b/src/libac3/stats.h
deleted file mode 100644
index a87911888..000000000
--- a/src/libac3/stats.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * stats.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.
- *
- */
-
-void stats_print_syncinfo(ac3_state_t * state);
-void stats_print_bsi(ac3_state_t * state);
-void stats_print_audblk(ac3_state_t * state,audblk_t *audblk);
-void stats_print_banner(ac3_state_t * state);
diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c
index 46ac1b8a3..8249618f6 100644
--- a/src/libac3/xine_decoder.c
+++ b/src/libac3/xine_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.10 2001/06/09 17:07:21 guenter Exp $
+ * $Id: xine_decoder.c,v 1.11 2001/07/10 21:50:31 guenter Exp $
*
* stuff needed to turn libac3 into a xine decoder plugin
*/
@@ -36,11 +36,14 @@
#include "audio_out.h"
#include "ac3.h"
+#include "ac3_internal.h"
#include "buffer.h"
#include "xine_internal.h"
#define FRAME_SIZE 4096
+stream_samples_t samples;
+
/* int ac3file; */
typedef struct ac3dec_decoder_s {
@@ -54,10 +57,20 @@ typedef struct ac3dec_decoder_s {
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 ac3_flags_map[8];
+ int ao_flags_map[8];
+
+ int16_t samples [6 * 6 * 256];
+
ao_functions_t *audio_out;
int audio_caps;
int bypass_mode;
- int max_num_channels;
int output_sampling_rate;
int output_open;
int output_mode;
@@ -72,6 +85,7 @@ int ac3dec_can_handle (audio_decoder_t *this_gen, int buf_type) {
void ac3dec_init (audio_decoder_t *this_gen, ao_functions_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);
@@ -91,31 +105,94 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) {
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_5CHANNEL)
- this->max_num_channels = 5;
- else if (this->audio_caps & AO_CAP_MODE_4CHANNEL)
- this->max_num_channels = 4;
- else if (this->audio_caps & AO_CAP_MODE_STEREO)
- this->max_num_channels = 2;
- 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 {
printf ("HELP! a mono-only audio driver?!\n");
- this->max_num_channels = 1;
+
+ 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;
+*/
/* ac3file = open ("test.ac3", O_CREAT); */
}
+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]);
+ }
+}
+
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;
- ac3_frame_t *ac3_frame=NULL;
-/* int sampling_rate; */
int output_mode = AO_CAP_MODE_STEREO;
uint8_t byte;
@@ -123,7 +200,8 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if (buf->decoder_info[0] == 0)
return;
- this->pts = buf->PTS;
+ if (buf->PTS)
+ this->pts = buf->PTS;
while (current != end) {
@@ -144,7 +222,7 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->frame_buffer[0] = 0x0b;
this->frame_buffer[1] = 0x77;
- this->sync_todo = 4;
+ this->sync_todo = 5;
this->frame_ptr = this->frame_buffer+2;
}
} else {
@@ -152,8 +230,12 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->sync_todo--;
if (this->sync_todo==0) {
- this->frame_length = ac3_frame_length (this->frame_buffer);
- this->frame_todo = this->frame_length - 6;
+
+ this->frame_length = ac3_syncinfo (this->frame_buffer,
+ &this->ac3_flags,
+ &this->ac3_sample_rate,
+ &this->ac3_bit_rate);
+ this->frame_todo = this->frame_length - 7;
}
}
@@ -175,33 +257,69 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
*/
if (!this->bypass_mode) {
+
+ int ac3_output_flags, i;
+ float level = this->ac3_level;
/* oki, decode this frame in software*/
/* write (ac3file, this->frame_buffer, this->frame_length); */
- ac3_frame = ac3_decode_frame (this->frame_buffer, this->max_num_channels);
-
/* determine output mode */
- switch (ac3_frame->num_channels) {
- case 1:
- output_mode = AO_CAP_MODE_MONO;
- break;
- case 2:
- output_mode = AO_CAP_MODE_STEREO;
- break;
- case 4:
- output_mode = AO_CAP_MODE_4CHANNEL;
- break;
- case 5:
- output_mode = AO_CAP_MODE_5CHANNEL;
- break;
+
+ 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)) {
+ printf ("libac3: ac3_frame error\n");
+ goto error;
}
+ output_mode = this->ao_flags_map[ac3_output_flags];
+
+ /*
+ * decode ac3 and convert/interleave samples
+ */
+
+ for (i = 0; i < 6; i++) {
+ if (ac3_block (&this->ac3_state)) {
+ printf ("libac3: ac3_block error\n");
+ goto error;
+ }
+
+ switch (output_mode) {
+ case AO_CAP_MODE_MONO:
+ float_to_int (*samples, this->samples+i*256, 1);
+ break;
+ case AO_CAP_MODE_STEREO:
+ float_to_int (samples[0], this->samples+i*256*2, 2);
+ float_to_int (samples[1], this->samples+1+i*256*2, 2);
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ float_to_int (samples[0], this->samples+i*256*4, 4);
+ float_to_int (samples[1], this->samples+1+i*256*4, 4);
+ float_to_int (samples[2], this->samples+2+i*256*4, 4);
+ float_to_int (samples[3], this->samples+3+i*256*4, 4);
+ break;
+ case AO_CAP_MODE_5CHANNEL:
+ float_to_int (samples[0], this->samples+i*256*5, 5);
+ float_to_int (samples[1], this->samples+1+i*256*5, 5);
+ float_to_int (samples[2], this->samples+2+i*256*5, 5);
+ float_to_int (samples[3], this->samples+3+i*256*5, 5);
+ float_to_int (samples[4], this->samples+4+i*256*5, 5);
+ break;
+ default:
+ printf ("libac3: help - unsupported mode %08x\n", output_mode);
+ }
+ }
+
+
/* output decoded samples */
if (!this->output_open
- || (ac3_frame->sampling_rate != this->output_sampling_rate)
+ || (this->ac3_sample_rate != this->output_sampling_rate)
|| (output_mode != this->output_mode)) {
if (this->output_open)
@@ -209,19 +327,23 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->output_open = (this->audio_out->open (this->audio_out, 16,
- ac3_frame->sampling_rate,
+ this->ac3_sample_rate,
output_mode) == 1);
- this->output_sampling_rate = ac3_frame->sampling_rate;
+ this->output_sampling_rate = this->ac3_sample_rate;
this->output_mode = output_mode;
}
if (this->output_open) {
+
this->audio_out->write_audio_data (this->audio_out,
- ac3_frame->audio_data,
+ this->samples,
256*6,
this->pts);
this->pts = 0;
}
+
+ error:
+
} else {
/*
@@ -229,8 +351,13 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
*/
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,
- ac3_sampling_rate(this->frame_buffer),
+ sample_rate,
AO_CAP_MODE_AC3) == 1);
this->output_mode = AO_CAP_MODE_AC3;
}
@@ -261,6 +388,8 @@ void ac3dec_close (audio_decoder_t *this_gen) {
if (this->output_open)
this->audio_out->close (this->audio_out);
+ this->output_open = 0;
+
/* close (ac3file); */
}
@@ -283,6 +412,8 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t *
this->audio_decoder.decode_data = ac3dec_decode_data;
this->audio_decoder.close = ac3dec_close;
this->audio_decoder.get_identifier = ac3dec_get_id;
+
+ this->ac3_level = (float) cfg->lookup_int (cfg, "ac3_level", 100) / 100.0;
return (audio_decoder_t *) this;
}