Commit c947dec9 authored by Zdenek Kabelac's avatar Zdenek Kabelac
Browse files

* sync with main liba52 sources

Originally committed as revision 1590 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent ca390e72
/*
* a52.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
......@@ -30,10 +30,15 @@
#undef free
#undef realloc
#ifndef LIBA52_DOUBLE
typedef float sample_t;
#else
#if defined(LIBA52_FIXED)
typedef int32_t sample_t;
typedef int32_t level_t;
#elif defined(LIBA52_DOUBLE)
typedef double sample_t;
typedef double level_t;
#else
typedef float sample_t;
typedef float level_t;
#endif
typedef struct a52_state_s a52_state_t;
......@@ -59,9 +64,9 @@ sample_t * a52_samples (a52_state_t * state);
int a52_syncinfo (uint8_t * buf, int * flags,
int * sample_rate, int * bit_rate);
int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
sample_t * level, sample_t bias);
level_t * level, sample_t bias);
void a52_dynrng (a52_state_t * state,
sample_t (* call) (sample_t, void *), void * data);
level_t (* call) (level_t, void *), void * data);
int a52_block (a52_state_t * state);
void a52_free (a52_state_t * state);
......
/*
* a52_internal.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
......@@ -37,24 +37,24 @@ struct a52_state_s {
uint8_t halfrate; /* halfrate factor */
uint8_t acmod; /* coded channels */
uint8_t lfeon; /* coded lfe channel */
sample_t clev; /* centre channel mix level */
sample_t slev; /* surround channels mix level */
level_t clev; /* centre channel mix level */
level_t slev; /* surround channels mix level */
int output; /* type of output */
sample_t level; /* output level */
level_t level; /* output level */
sample_t bias; /* output bias */
int dynrnge; /* apply dynamic range */
sample_t dynrng; /* dynamic range */
level_t dynrng; /* dynamic range */
void * dynrngdata; /* dynamic range callback funtion and data */
sample_t (* dynrngcall) (sample_t range, void * dynrngdata);
level_t (* dynrngcall) (level_t range, void * dynrngdata);
uint8_t chincpl; /* channel coupled */
uint8_t phsflginu; /* phase flags in use (stereo only) */
uint8_t cplstrtmant; /* coupling channel start mantissa */
uint8_t cplendmant; /* coupling channel end mantissa */
uint32_t cplbndstrc; /* coupling band structure */
sample_t cplco[5][18]; /* coupling coordinates */
level_t cplco[5][18]; /* coupling coordinates */
/* derived information */
uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */
......@@ -66,6 +66,11 @@ struct a52_state_s {
uint16_t bai; /* bit allocation information */
uint32_t * buffer_start;
uint16_t lfsr_state; /* dither state */
uint32_t bits_left;
uint32_t current_word;
uint8_t csnroffst; /* coarse SNR offset */
ba_t cplba; /* coupling bit allocation parameters */
ba_t ba[5]; /* channel bit allocation parameters */
......@@ -102,14 +107,54 @@ void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
int start, int end, int fastleak, int slowleak,
expbap_t * expbap);
int a52_downmix_init (int input, int flags, sample_t * level,
sample_t clev, sample_t slev);
int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
sample_t clev, sample_t slev);
int a52_downmix_init (int input, int flags, level_t * level,
level_t clev, level_t slev);
int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
level_t clev, level_t slev);
void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev);
level_t clev, level_t slev);
void a52_upmix (sample_t * samples, int acmod, int output);
void a52_imdct_init (uint32_t mm_accel);
void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias);
void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias);
#define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5)))
#ifndef LIBA52_FIXED
typedef sample_t quantizer_t;
#define SAMPLE(x) (x)
#define LEVEL(x) (x)
#define MUL(a,b) ((a) * (b))
#define MUL_L(a,b) ((a) * (b))
#define MUL_C(a,b) ((a) * (b))
#define DIV(a,b) ((a) / (b))
#define BIAS(x) ((x) + bias)
#else /* LIBA52_FIXED */
typedef int16_t quantizer_t;
#define SAMPLE(x) (sample_t)((x) * (1 << 30))
#define LEVEL(x) (level_t)((x) * (1 << 26))
#if 0
#define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30))
#define MUL_L(a,b) ((int)(((int64_t)(a) * (b) + (1 << 25)) >> 26))
#elif 1
#define MUL(a,b) \
({ int32_t _ta=(a), _tb=(b), _tc; \
_tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)(((_tc >> 14))+ (((_ta >> 16)*(_tb >> 16)) << 2 )); })
#define MUL_L(a,b) \
({ int32_t _ta=(a), _tb=(b), _tc; \
_tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)((_tc >> 10) + (((_ta >> 16)*(_tb >> 16)) << 6)); })
#else
#define MUL(a,b) (((a) >> 15) * ((b) >> 15))
#define MUL_L(a,b) (((a) >> 13) * ((b) >> 13))
#endif
#define MUL_C(a,b) MUL_L (a, LEVEL (b))
#define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b))
#define BIAS(x) (x)
#endif
/*
* audio_out.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
* See http://liba52.sourceforge.net/ for updates.
*
* a52dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* a52dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
typedef struct ao_instance_s ao_instance_t;
struct ao_instance_s {
int (* setup) (ao_instance_t * instance, int sample_rate, int * flags,
sample_t * level, sample_t * bias);
int (* play) (ao_instance_t * instance, int flags, sample_t * samples);
void (* close) (ao_instance_t * instance);
};
typedef ao_instance_t * ao_open_t (void);
typedef struct ao_driver_s {
char * name;
ao_open_t * open;
} ao_driver_t;
/* return NULL terminated array of all drivers */
ao_driver_t * ao_drivers (void);
static inline ao_instance_t * ao_open (ao_open_t * open)
{
return open ();
}
static inline int ao_setup (ao_instance_t * instance, int sample_rate,
int * flags, sample_t * level, sample_t * bias)
{
return instance->setup (instance, sample_rate, flags, level, bias);
}
static inline int ao_play (ao_instance_t * instance, int flags,
sample_t * samples)
{
return instance->play (instance, flags, samples);
}
static inline void ao_close (ao_instance_t * instance)
{
if (instance->close)
instance->close (instance);
}
/*
* bit_allocate.c
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
......@@ -20,6 +20,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <inttypes.h>
#include "a52.h"
#include "a52_internal.h"
......@@ -226,7 +231,7 @@ void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
int startband, endband;
startband = j;
endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end;
endband = (bndtab[i-20] < end) ? bndtab[i-20] : end;
psd = 128 * exp[j++];
while (j < endband) {
int next, delta;
......
/*
* bitstream.c
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
......@@ -21,34 +21,33 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <inttypes.h>
#include "a52.h"
#include "a52_internal.h"
#include "bitstream.h"
#define BUFFER_SIZE 4096
static uint32_t * buffer_start;
uint32_t a52_bits_left;
uint32_t a52_current_word;
void a52_bitstream_set_ptr (uint8_t * buf)
void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf)
{
int align;
align = (long)buf & 3;
buffer_start = (uint32_t *) (buf - align);
a52_bits_left = 0;
bitstream_get (align * 8);
state->buffer_start = (uint32_t *) (buf - align);
state->bits_left = 0;
state->current_word = 0;
bitstream_get (state, align * 8);
}
static inline void
bitstream_fill_current()
static inline void bitstream_fill_current (a52_state_t * state)
{
uint32_t tmp;
tmp = *(buffer_start++);
a52_current_word = swab32 (tmp);
tmp = *(state->buffer_start++);
state->current_word = swab32 (tmp);
}
/*
......@@ -60,40 +59,38 @@ bitstream_fill_current()
* -ah
*/
uint32_t
a52_bitstream_get_bh(uint32_t num_bits)
uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits)
{
uint32_t result;
num_bits -= a52_bits_left;
result = ((a52_current_word << (32 - a52_bits_left)) >>
(32 - a52_bits_left));
num_bits -= state->bits_left;
result = ((state->current_word << (32 - state->bits_left)) >>
(32 - state->bits_left));
bitstream_fill_current();
bitstream_fill_current (state);
if(num_bits != 0)
result = (result << num_bits) | (a52_current_word >> (32 - num_bits));
if (num_bits != 0)
result = (result << num_bits) | (state->current_word >> (32 - num_bits));
a52_bits_left = 32 - num_bits;
state->bits_left = 32 - num_bits;
return result;
}
int32_t
a52_bitstream_get_bh_2(uint32_t num_bits)
int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits)
{
int32_t result;
num_bits -= a52_bits_left;
result = ((((int32_t)a52_current_word) << (32 - a52_bits_left)) >>
(32 - a52_bits_left));
num_bits -= state->bits_left;
result = ((((int32_t)state->current_word) << (32 - state->bits_left)) >>
(32 - state->bits_left));
bitstream_fill_current();
bitstream_fill_current(state);
if(num_bits != 0)
result = (result << num_bits) | (a52_current_word >> (32 - num_bits));
if (num_bits != 0)
result = (result << num_bits) | (state->current_word >> (32 - num_bits));
a52_bits_left = 32 - num_bits;
state->bits_left = 32 - num_bits;
return result;
}
/*
* bitstream.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
......@@ -46,37 +46,32 @@
# endif
#endif
extern uint32_t a52_bits_left;
extern uint32_t a52_current_word;
void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf);
uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits);
int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits);
void a52_bitstream_set_ptr (uint8_t * buf);
uint32_t a52_bitstream_get_bh(uint32_t num_bits);
int32_t a52_bitstream_get_bh_2(uint32_t num_bits);
static inline uint32_t
bitstream_get(uint32_t num_bits)
static inline uint32_t bitstream_get (a52_state_t * state, uint32_t num_bits)
{
uint32_t result;
if(num_bits < a52_bits_left) {
result = (a52_current_word << (32 - a52_bits_left)) >> (32 - num_bits);
a52_bits_left -= num_bits;
if (num_bits < state->bits_left) {
result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits);
state->bits_left -= num_bits;
return result;
}
return a52_bitstream_get_bh(num_bits);
return a52_bitstream_get_bh (state, num_bits);
}
static inline int32_t
bitstream_get_2(uint32_t num_bits)
static inline int32_t bitstream_get_2 (a52_state_t * state, uint32_t num_bits)
{
int32_t result;
if(num_bits < a52_bits_left) {
result = (((int32_t)a52_current_word) << (32 - a52_bits_left)) >> (32 - num_bits);
a52_bits_left -= num_bits;
if (num_bits < state->bits_left) {
result = (((int32_t)state->current_word) << (32 - state->bits_left)) >> (32 - num_bits);
state->bits_left -= num_bits;
return result;
}
return a52_bitstream_get_bh_2(num_bits);
return a52_bitstream_get_bh_2 (state, num_bits);
}
/*
* downmix.c
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of a52dec, a free ATSC A-52 stream decoder.
......@@ -21,13 +21,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <string.h>
#include <inttypes.h>
#include "a52.h"
#include "a52_internal.h"
#define CONVERT(acmod,output) (((output) << 3) + (acmod))
int a52_downmix_init (int input, int flags, sample_t * level,
sample_t clev, sample_t slev)
int a52_downmix_init (int input, int flags, level_t * level,
level_t clev, level_t slev)
{
static uint8_t table[11][8] = {
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
......@@ -61,94 +66,106 @@ int a52_downmix_init (int input, int flags, sample_t * level,
output = table[output][input & 7];
if ((output == A52_STEREO) &&
((input == A52_DOLBY) || ((input == A52_3F) && (clev == LEVEL_3DB))))
if (output == A52_STEREO &&
(input == A52_DOLBY || (input == A52_3F && clev == LEVEL (LEVEL_3DB))))
output = A52_DOLBY;
if (flags & A52_ADJUST_LEVEL)
if (flags & A52_ADJUST_LEVEL) {
level_t adjust;
switch (CONVERT (input & 7, output)) {
case CONVERT (A52_3F, A52_MONO):
*level *= LEVEL_3DB / (1 + clev);
adjust = DIV (LEVEL_3DB, LEVEL (1) + clev);
break;
case CONVERT (A52_STEREO, A52_MONO):
case CONVERT (A52_2F2R, A52_2F1R):
case CONVERT (A52_3F2R, A52_3F1R):
level_3db:
*level *= LEVEL_3DB;
adjust = LEVEL (LEVEL_3DB);
break;
case CONVERT (A52_3F2R, A52_2F1R):
if (clev < LEVEL_PLUS3DB - 1)
if (clev < LEVEL (LEVEL_PLUS3DB - 1))
goto level_3db;
/* break thru */
case CONVERT (A52_3F, A52_STEREO):
case CONVERT (A52_3F1R, A52_2F1R):
case CONVERT (A52_3F1R, A52_2F2R):
case CONVERT (A52_3F2R, A52_2F2R):
*level /= 1 + clev;
adjust = DIV (1, LEVEL (1) + clev);
break;
case CONVERT (A52_2F1R, A52_MONO):
*level *= LEVEL_PLUS3DB / (2 + slev);
adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev);
break;
case CONVERT (A52_2F1R, A52_STEREO):
case CONVERT (A52_3F1R, A52_3F):
*level /= 1 + slev * LEVEL_3DB;
adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB));
break;
case CONVERT (A52_3F1R, A52_MONO):
*level *= LEVEL_3DB / (1 + clev + 0.5 * slev);
adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5));
break;
case CONVERT (A52_3F1R, A52_STEREO):
*level /= 1 + clev + slev * LEVEL_3DB;
adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB));
break;
case CONVERT (A52_2F2R, A52_MONO):
*level *= LEVEL_3DB / (1 + slev);
adjust = DIV (LEVEL_3DB, LEVEL (1) + slev);
break;
case CONVERT (A52_2F2R, A52_STEREO):
case CONVERT (A52_3F2R, A52_3F):
*level /= 1 + slev;
adjust = DIV (1, LEVEL (1) + slev);
break;
case CONVERT (A52_3F2R, A52_MONO):
*level *= LEVEL_3DB / (1 + clev + slev);
adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev);
break;
case CONVERT (A52_3F2R, A52_STEREO):
*level /= 1 + clev + slev;
adjust = DIV (1, LEVEL (1) + clev + slev);
break;
case CONVERT (A52_MONO, A52_DOLBY):
*level *= LEVEL_PLUS3DB;
adjust = LEVEL (LEVEL_PLUS3DB);
break;
case CONVERT (A52_3F, A52_DOLBY):
case CONVERT (A52_2F1R, A52_DOLBY):
*level *= 1 / (1 + LEVEL_3DB);
adjust = LEVEL (1 / (1 + LEVEL_3DB));
break;
case CONVERT (A52_3F1R, A52_DOLBY):
case CONVERT (A52_2F2R, A52_DOLBY):
*level *= 1 / (1 + 2 * LEVEL_3DB);
adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB));
break;
case CONVERT (A52_3F2R, A52_DOLBY):
*level *= 1 / (1 + 3 * LEVEL_3DB);
adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB));
break;
default:
return output;
}
*level = MUL_L (*level, adjust);
}
return output;
}
int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
sample_t clev, sample_t slev)
int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
level_t clev, level_t slev)
{
level_t level_3db;
level_3db = MUL_C (level, LEVEL_3DB);
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
case CONVERT (A52_CHANNEL, A52_CHANNEL):
......@@ -164,120 +181,138 @@ int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
return 0;
case CONVERT (A52_CHANNEL, A52_MONO):
coeff[0] = coeff[1] = level * LEVEL_6DB;
coeff[0] = coeff[1] = MUL_C (level, LEVEL_6DB);
return 3;
case CONVERT (A52_STEREO, A52_MONO):
coeff[0] = coeff[1] = level * LEVEL_3DB;
coeff[0] = coeff[1] = level_3db;
return 3;
case CONVERT (A52_3F, A52_MONO):
coeff[0] = coeff[2] = level * LEVEL_3DB;
coeff[1] = level * clev * LEVEL_PLUS3DB;
coeff[0] = coeff[2] = level_3db;
coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
return 7;
case CONVERT (A52_2F1R, A52_MONO):
coeff[0] = coeff[1] = level * LEVEL_3DB;
coeff[2] = level * slev * LEVEL_3DB;
coeff[0] = coeff[1] = level_3db;
coeff[2] = MUL_L (level_3db, slev);
return 7;
case CONVERT (A52_2F2R, A52_MONO):
coeff[0] = coeff[1] = level * LEVEL_3DB;
coeff[2] = coeff[3] = level * slev * LEVEL_3DB;
coeff[0] = coeff[1] = level_3db;
coeff[2] = coeff[3] = MUL_L (level_3db, slev);
return 15;
case CONVERT (A52_3F1R, A52_MONO):
coeff[0] = coeff[2] = level * LEVEL_3DB;
coeff[1] = level * clev * LEVEL_PLUS3DB;
coeff[3] = level * slev * LEVEL_3DB;
coeff[0] = coeff[2] = level_3db;