Commit afa90da5 authored by Zdenek Kabelac's avatar Zdenek Kabelac

* replaced with liba52

Originally committed as revision 447 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 7aaf3b98
/*
* ac3.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
typedef 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;
/* samples work structure */
typedef float stream_samples_t[6][256];
#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);
/*
* ac3_internal.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#define LEVEL_PLUS3DB 1.4142135623730951
#define LEVEL_3DB 0.7071067811865476
#define LEVEL_45DB 0.5946035575013605
#define LEVEL_6DB 0.5
/* Exponent strategy constants */
#define EXP_REUSE (0)
#define EXP_D15 (1)
#define EXP_D25 (2)
#define EXP_D45 (3)
/* Delta bit allocation constants */
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1)
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)
void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
int start, int end, int fastleak, int slowleak,
uint8_t * exp, int8_t * bap);
int downmix_init (int input, int flags, 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[]);
/*
* bit_allocate.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 "../common.h"
#include "ac3.h"
#include "ac3_internal.h"
static int hthtab[3][50] = {
{0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890,
0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900,
0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0,
0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0},
{0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860,
0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880,
0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0,
0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820,
0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0},
{0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850,
0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860,
0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0,
0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0,
0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720}
};
static int8_t baptab[305] = {
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 // 148 padding entries
};
static int bndtab[30] = {21, 22, 23, 24, 25, 26, 27, 28, 31, 34,
37, 40, 43, 46, 49, 55, 61, 67, 73, 79,
85, 97, 109, 121, 133, 157, 181, 205, 229, 253};
static int8_t latab[256] = {
-64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53,
-52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44,
-43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35,
-35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28,
-28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22,
-22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18,
-17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14,
-13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11,
-10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -8, -8,
-8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6,
-6, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5,
-5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
-4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
-3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
};
#define UPDATE_LEAK() \
do { \
fastleak += fdecay; \
if (fastleak > psd + fgain) \
fastleak = psd + fgain; \
slowleak += sdecay; \
if (slowleak > psd + sgain) \
slowleak = psd + sgain; \
} while (0)
#define COMPUTE_MASK() \
do { \
if (psd > dbknee) \
mask -= (psd - dbknee) >> 2; \
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 (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};
static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0,
0xa10, 0xa90, 0xb10, 0x1400};
int i, j;
int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
int psd, mask;
int8_t * deltba;
int * hth;
int halfrate;
halfrate = state->halfrate;
fdecay = (63 + 20 * state->fdcycod) >> halfrate;
fgain = 128 + 128 * ba->fgaincod;
sdecay = (15 + 2 * state->sdcycod) >> halfrate;
sgain = slowgain[state->sgaincod];
dbknee = dbpbtab[state->dbpbcod];
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;
j = start;
if (start == 0) { // not the coupling channel
int lowcomp;
lowcomp = 0;
j = end - 1;
do {
if (i < j) {
if (exp[i+1] == exp[i] - 2)
lowcomp = 384;
else if (lowcomp && (exp[i+1] > exp[i]))
lowcomp -= 64;
}
psd = 128 * exp[i];
mask = psd + fgain + lowcomp;
COMPUTE_MASK ();
bap[i++] = (baptab+156)[mask + 4 * exp[i]];
} while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
fastleak = psd + fgain;
slowleak = psd + sgain;
while (i < 7) {
if (i < j) {
if (exp[i+1] == exp[i] - 2)
lowcomp = 384;
else if (lowcomp && (exp[i+1] > exp[i]))
lowcomp -= 64;
}
psd = 128 * exp[i];
UPDATE_LEAK ();
mask = ((fastleak + lowcomp < slowleak) ?
fastleak + lowcomp : slowleak);
COMPUTE_MASK ();
bap[i++] = (baptab+156)[mask + 4 * exp[i]];
}
if (end == 7) // lfe channel
return;
do {
if (exp[i+1] == exp[i] - 2)
lowcomp = 320;
else if (lowcomp && (exp[i+1] > exp[i]))
lowcomp -= 64;
psd = 128 * exp[i];
UPDATE_LEAK ();
mask = ((fastleak + lowcomp < slowleak) ?
fastleak + lowcomp : slowleak);
COMPUTE_MASK ();
bap[i++] = (baptab+156)[mask + 4 * exp[i]];
} while (i < 20);
while (lowcomp > 128) { // two iterations maximum
lowcomp -= 128;
psd = 128 * exp[i];
UPDATE_LEAK ();
mask = ((fastleak + lowcomp < slowleak) ?
fastleak + lowcomp : slowleak);
COMPUTE_MASK ();
bap[i++] = (baptab+156)[mask + 4 * exp[i]];
}
j = i;
}
do {
int startband, endband;
startband = j;
endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end;
psd = 128 * exp[j++];
while (j < endband) {
int next, delta;
next = 128 * exp[j++];
delta = next - psd;
switch (delta >> 9) {
case -6: case -5: case -4: case -3: case -2:
psd = next;
break;
case -1:
psd = next + latab[(-delta) >> 1];
break;
case 0:
psd += latab[delta >> 1];
break;
}
}
// minpsd = -289
UPDATE_LEAK ();
mask = (fastleak < slowleak) ? fastleak : slowleak;
COMPUTE_MASK ();
i++;
j = startband;
do {
// max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp
// min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5
bap[j++] = (baptab+156)[mask + 4 * exp[j]];
} while (j < endband);
} while (j < end);
}
/*
* bitstream.c
*
* Copyright (C) Aaron Holtzman - Dec 1999
*
* This file is part of ac3dec, a free AC-3 audio decoder
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "../common.h"
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#define BUFFER_SIZE 4096
static uint8_t *buffer_start;
uint32_t bits_left;
uint32_t current_word;
void bitstream_set_ptr (uint8_t * buf)
{
buffer_start = buf;
bits_left = 0;
}
static inline void
bitstream_fill_current()
{
current_word = *((uint32_t*)buffer_start)++;
current_word = swab32(current_word);
}
//
// The fast paths for _get is in the
// bitstream.h header file so it can be inlined.
//
// The "bottom half" of this routine is suffixed _bh
//
// -ah
//
uint32_t
bitstream_get_bh(uint32_t num_bits)
{
uint32_t result;
num_bits -= bits_left;
result = (current_word << (32 - bits_left)) >> (32 - bits_left);
bitstream_fill_current();
if(num_bits != 0)
result = (result << num_bits) | (current_word >> (32 - num_bits));
bits_left = 32 - num_bits;
return result;
}
/*
* bitstream.h
*
* Copyright (C) Aaron Holtzman - Dec 1999
*
* This file is part of ac3dec, a free AC-3 audio decoder
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
//My new and improved vego-matic endian swapping routine
//(stolen from the kernel)
#ifdef WORDS_BIGENDIAN
# define swab32(x) (x)
#else
# if defined (__i386__)
# define swab32(x) __i386_swab32(x)
static inline const uint32_t __i386_swab32(uint32_t x)
{
__asm__("bswap %0" : "=r" (x) : "0" (x));
return x;
}
# else
# define swab32(x)\
((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \
(((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3]))
# endif
#endif
extern uint32_t bits_left;
extern uint32_t current_word;
void bitstream_set_ptr (uint8_t * buf);
uint32_t bitstream_get_bh(uint32_t num_bits);
static inline uint32_t
bitstream_get(uint32_t num_bits)
{
uint32_t result;
if(num_bits < bits_left) {
result = (current_word << (32 - bits_left)) >> (32 - num_bits);
bits_left -= num_bits;
return result;
}
return bitstream_get_bh(num_bits);
}
/*
*
* downmix.c
*
* Copyright (C) Aaron Holtzman - Sept 1999
*
* Originally based on code by Yuqing Deng.
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include "../common.h"
#include <math.h>
#include "ac3.h"
#include "ac3_internal.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;
case CONVERT (AC3_STEREO, AC3_MONO):
case CONVERT (AC3_2F2R, AC3_2F1R):
case CONVERT (AC3_3F2R, AC3_3F1R):
level_3db:
*level *= LEVEL_3DB;
break;
case CONVERT (AC3_3F2R, AC3_2F1R):
if (clev < LEVEL_PLUS3DB - 1)
goto level_3db;
// break thru
case CONVERT (AC3_3F, AC3_STEREO):
case CONVERT (AC3_3F1R, AC3_2F1R):
case CONVERT (AC3_3F1R, AC3_2F2R):
case CONVERT (AC3_3F2R, AC3_2F2R):
*level /= 1 + clev;
break;
case CONVERT (AC3_2F1R, AC3_MONO):
*level *= LEVEL_PLUS3DB / (2 + slev);
break;
case CONVERT (AC3_2F1R, AC3_STEREO):
case CONVERT (AC3_3F1R, AC3_3F):
*level /= 1 + slev * LEVEL_3DB;
break;
case CONVERT (AC3_3F1R, AC3_MONO):
*level *= LEVEL_3DB / (1 + clev + 0.5 * slev);
break;
case CONVERT (AC3_3F1R, AC3_STEREO):
*level /= 1 + clev + slev * LEVEL_3DB;
break;
case CONVERT (AC3_2F2R, AC3_MONO):
*level *= LEVEL_3DB / (1 + slev);
break;
case CONVERT (AC3_2F2R, AC3_STEREO):
case CONVERT (AC3_3F2R, AC3_3F):
*level /= (1 + slev);
break;
case CONVERT (AC3_3F2R, AC3_MONO):
*level *= LEVEL_3DB / (1 + clev + slev);
break;
case CONVERT (AC3_3F2R, AC3_STEREO):
*level /= 1 + clev + slev;
break;
case CONVERT (AC3_MONO, AC3_DOLBY):
*level *= LEVEL_PLUS3DB;
break;
case CONVERT (AC3_3F, AC3_DOLBY):
case CONVERT (AC3_2F1R, AC3_DOLBY):
*level *= 1 / (1 + LEVEL_3DB);
break;
case CONVERT (AC3_3F1R, AC3_DOLBY):
case CONVERT (AC3_2F2R, AC3_DOLBY):
*level *= 1 / (1 + 2 * LEVEL_3DB);
break;
case CONVERT (AC3_3F2R, AC3_DOLBY):
*level *= 1 / (1 + 3 * LEVEL_3DB);
break;
}
return output;
}
static void mix1to1 (float * samples, float level, float bias)
{
int i;
for (i = 0; i < 256; i++)
samples[i] = samples[i] * level + bias;
}
static void move1to1 (float * src, float * dest, float level, float bias)
{
int i;
for (i = 0; i < 256; i++)
dest[i] = src[i] * level + bias;
}
static void mix2to1 (float * samples, float level, float bias)
{
int i;
for (i = 0; i < 256; i++)
samples[i] = (samples[i] + samples[i + 256]) * level + bias;
}
static void move2to1 (float * src, float * dest, float level, float bias)
{
int i;
for (i = 0; i < 256; i++)
dest[i] = (src[i] + src[i + 256]) * level + bias;
}
static void mix3to1 (float * samples, float level, float clev, float bias)
{
int i;
for (i = 0; i < 256; i++)
samples[i] = ((samples[i] + samples[i + 512]) * level +
samples[i + 256] * clev + bias);
}
static void mix21to1 (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] * slev + bias);
}
static void mix31to1 (float * samples, float level, float clev, float slev,
float bias)
{
int i;
for (i = 0; i < 256; i++)
samples[i] = ((samples[i] + samples[i + 512]) * level +
samples[i + 256] * clev + samples[i + 768] * slev +
bias);
}
static void mix22to1 (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 mix32to1 (float * samples, float level, float clev, float slev,
float bias)
{
int i;
for (i = 0; i < 256; i++)
samples[i] = ((samples[i] + samples[i + 512]) * level +
samples[i + 256] * clev +
(samples[i + 768] + samples[i + 1024]) * slev + bias);
}
static void mix1to2 (float * src, float * dest, float level, float bias)
{
int i;
for (i = 0; i < 256; i++)
dest[i] = src[i] = src[i] * level + bias;
}
static void mix3to2 (float * samples, float level, float clev, 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 + 256] = samples[i + 512] * level + common;
}
}
static void mix21to2 (float * left, float * right, float level, float slev,
float bias)
{
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;
}
}
static void mix11to1 (float * front, float * rear, float level, float slev,
float bias)
{
int i;
for (i = 0; i < 256; i++)
front[i] = front[i] * level + rear[i] * slev + bias;
}
static void mix31to2 (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 + samples[i + 768] * slev + bias;
samples[i] = samples[i] * level + common;
samples[i + 256] = samples[i + 512] * level + common;
}
}
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);
}
}
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;
}
}
static void mix22toS (float * samples, float level, float level3db, float bias)
{
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;
}
}
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;
}
}
/*
* imdct.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 "../common.h"
#include <math.h>
#include "ac3.h"
#include "ac3_internal.h"
void (* imdct_256) (float data[], float delay[]);
void (* imdct_512) (float data[], float delay[]);
typedef struct complex_s
{
float real;
float imag;
} complex_t;
/* 128 point bit-reverse LUT */
static uint8_t bit_reverse_512[] = {
0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78,
0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74,
0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c,
0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72,
0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a,
0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76,
0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e,
0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71,
0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79,
0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75,
0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d,
0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73,
0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b,
0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77,
0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f};
static uint8_t bit_reverse_256[] = {
0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f};
static complex_t buf[128];
/* Twiddle factor LUT */
static complex_t w_1[1];
static complex_t w_2[2];
static complex_t w_4[4];
static complex_t w_8[8];
static complex_t w_16[16];
static complex_t w_32[32];
static complex_t w_64[64];
static complex_t * w[7] = {w_1, w_2, w_4, w_8, w_16, w_32, w_64};
/* Twiddle factors for IMDCT */
static float xcos1[128];
static float xsin1[128];
static float xcos2[64];
static float xsin2[64];
/* 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,
0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 };
static inline void swap_cmplx(complex_t *a, complex_t *b)
{
complex_t tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
static inline complex_t cmplx_mult(complex_t a, complex_t b)
{
complex_t ret;
ret.real = a.real * b.real - a.imag * b.imag;
ret.imag = a.real * b.imag + a.imag * b.real;
return ret;
}
void
imdct_do_512(float data[],float delay[])
{
int i,k;
int p,q;
int m;
int two_m;
int two_m_plus_one;
float tmp_a_i;
float tmp_a_r;
float tmp_b_i;
float tmp_b_r;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
//
// 512 IMDCT with source and dest data in 'data'
//
// Pre IFFT complex multiply plus IFFT cmplx conjugate
for( i=0; i < 128; i++) {
/* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */
buf[i].real = (data[256-2*i-1] * xcos1[i]) - (data[2*i] * xsin1[i]);
buf[i].imag = -1.0 * ((data[2*i] * xcos1[i]) + (data[256-2*i-1] * xsin1[i]));
}
//Bit reversed shuffling
for(i=0; i<128; i++) {
k = bit_reverse_512[i];
if (k < i)
swap_cmplx(&buf[i],&buf[k]);
}
/* FFT Merge */
for (m=0; m < 7; m++) {
if(m)
two_m = (1 << m);
else
two_m = 1;
two_m_plus_one = (1 << (m+1));
for(k = 0; k < two_m; k++) {
for(i = 0; i < 128; i += two_m_plus_one) {
p = k + i;
q = p + two_m;
tmp_a_r = buf[p].real;
tmp_a_i = buf[p].imag;
tmp_b_r = buf[q].real * w[m][k].real - buf[q].imag * w[m][k].imag;
tmp_b_i = buf[q].imag * w[m][k].real + buf[q].real * w[m][k].imag;
buf[p].real = tmp_a_r + tmp_b_r;
buf[p].imag = tmp_a_i + tmp_b_i;
buf[q].real = tmp_a_r - tmp_b_r;
buf[q].imag = tmp_a_i - tmp_b_i;
}
}
}
/* Post IFFT complex multiply plus IFFT complex conjugate*/
for( i=0; i < 128; i++) {
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
tmp_a_r = buf[i].real;
tmp_a_i = -1.0 * buf[i].imag;
buf[i].real =(tmp_a_r * xcos1[i]) - (tmp_a_i * xsin1[i]);
buf[i].imag =(tmp_a_r * xsin1[i]) + (tmp_a_i * xcos1[i]);
}
data_ptr = data;
delay_ptr = delay;
window_ptr = imdct_window;
/* Window and convert to real valued signal */
for(i=0; i< 64; i++) {
*data_ptr++ = 2.0f * (-buf[64+i].imag * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf[64-i-1].real * *window_ptr++ + *delay_ptr++);
}
for(i=0; i< 64; i++) {
*data_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf[128-i-1].imag * *window_ptr++ + *delay_ptr++);
}
/* The trailing edge of the window goes into the delay line */
delay_ptr = delay;
for(i=0; i< 64; i++) {
*delay_ptr++ = -buf[64+i].real * *--window_ptr;
*delay_ptr++ = buf[64-i-1].imag * *--window_ptr;
}
for(i=0; i<64; i++) {
*delay_ptr++ = buf[i].imag * *--window_ptr;
*delay_ptr++ = -buf[128-i-1].real * *--window_ptr;
}
}
void
imdct_do_256(float data[],float delay[])
{
int i,k;
int p,q;
int m;
int two_m;
int two_m_plus_one;
float tmp_a_i;
float tmp_a_r;
float tmp_b_i;
float tmp_b_r;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
complex_t *buf_1, *buf_2;
buf_1 = &buf[0];
buf_2 = &buf[64];
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for(k=0; k<64; k++) {
/* X1[k] = X[2*k] */
/* X2[k] = X[2*k+1] */
p = 2 * (128-2*k-1);
q = 2 * (2 * k);
/* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf_1[k].real = data[p] * xcos2[k] - data[q] * xsin2[k];
buf_1[k].imag = -1.0f * (data[q] * xcos2[k] + data[p] * xsin2[k]);
/* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf_2[k].real = data[p + 1] * xcos2[k] - data[q + 1] * xsin2[k];
buf_2[k].imag = -1.0f * ( data[q + 1] * xcos2[k] + data[p + 1] * xsin2[k]);
}
//IFFT Bit reversed shuffling
for(i=0; i<64; i++) {
k = bit_reverse_256[i];
if (k < i) {
swap_cmplx(&buf_1[i],&buf_1[k]);
swap_cmplx(&buf_2[i],&buf_2[k]);
}
}
/* FFT Merge */
for (m=0; m < 6; m++) {
two_m = (1 << m);
two_m_plus_one = (1 << (m+1));
//FIXME
if(m)
two_m = (1 << m);
else
two_m = 1;
for(k = 0; k < two_m; k++) {
for(i = 0; i < 64; i += two_m_plus_one) {
p = k + i;
q = p + two_m;
//Do block 1
tmp_a_r = buf_1[p].real;
tmp_a_i = buf_1[p].imag;
tmp_b_r = buf_1[q].real * w[m][k].real - buf_1[q].imag * w[m][k].imag;
tmp_b_i = buf_1[q].imag * w[m][k].real + buf_1[q].real * w[m][k].imag;
buf_1[p].real = tmp_a_r + tmp_b_r;
buf_1[p].imag = tmp_a_i + tmp_b_i;
buf_1[q].real = tmp_a_r - tmp_b_r;
buf_1[q].imag = tmp_a_i - tmp_b_i;
//Do block 2
tmp_a_r = buf_2[p].real;
tmp_a_i = buf_2[p].imag;
tmp_b_r = buf_2[q].real * w[m][k].real - buf_2[q].imag * w[m][k].imag;
tmp_b_i = buf_2[q].imag * w[m][k].real + buf_2[q].real * w[m][k].imag;
buf_2[p].real = tmp_a_r + tmp_b_r;
buf_2[p].imag = tmp_a_i + tmp_b_i;
buf_2[q].real = tmp_a_r - tmp_b_r;
buf_2[q].imag = tmp_a_i - tmp_b_i;
}
}
}
/* Post IFFT complex multiply */
for( i=0; i < 64; i++) {
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
tmp_a_r = buf_1[i].real;
tmp_a_i = -buf_1[i].imag;
buf_1[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf_1[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
/* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
tmp_a_r = buf_2[i].real;
tmp_a_i = -buf_2[i].imag;
buf_2[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf_2[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
}
data_ptr = data;
delay_ptr = delay;
window_ptr = imdct_window;
/* Window and convert to real valued signal */
for(i=0; i< 64; i++) {
*data_ptr++ = 2.0f * (-buf_1[i].imag * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf_1[64-i-1].real * *window_ptr++ + *delay_ptr++);
}
for(i=0; i< 64; i++) {
*data_ptr++ = 2.0f * (-buf_1[i].real * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf_1[64-i-1].imag * *window_ptr++ + *delay_ptr++);
}
delay_ptr = delay;
for(i=0; i< 64; i++) {
*delay_ptr++ = -buf_2[i].real * *--window_ptr;
*delay_ptr++ = buf_2[64-i-1].imag * *--window_ptr;
}
for(i=0; i< 64; i++) {
*delay_ptr++ = buf_2[i].imag * *--window_ptr;
*delay_ptr++ = -buf_2[64-i-1].real * *--window_ptr;
}
}
void imdct_init (void)
{
#ifdef LIBAC3_MLIB
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));
}
/* More twiddle factors to turn IFFT into IMDCT */
for (i = 0; i < 64; i++) {
xcos2[i] = -cos ((M_PI / 1024) * (8 * i + 1));
xsin2[i] = -sin ((M_PI / 1024) * (8 * i + 1));
}
for (i = 0; i < 7; i++) {
j = 1 << i;
for (k = 0; k < j; k++) {
w[i][k].real = cos (-M_PI * k / j);
w[i][k].imag = sin (-M_PI * k / j);
}
}
imdct_512 = imdct_do_512;
imdct_256 = imdct_do_256;
#endif
}
/*
* parse.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include "../common.h"
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#include "tables.h"
extern stream_samples_t samples; // FIXME
static float delay[6][256];
void ac3_init (void)
{
imdct_init ();
}
static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
int ac3_syncinfo (uint8_t * buf, int * flags,
int * sample_rate, int * bit_rate)
{
static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
128, 160, 192, 224, 256, 320, 384, 448,
512, 576, 640};
static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01};
int frmsizecod;
int bitrate;
int half;
int acmod;
if ((buf[0] != 0x0b) || (buf[1] != 0x77)) // syncword
return 0;
if (buf[5] >= 0x60) // bsid >= 12
return 0;
half = halfrate[buf[5] >> 3];
// acmod, dsurmod and lfeon
acmod = buf[6] >> 5;
*flags = (((buf[6] & 0xf8) == 0x50) ? AC3_DOLBY : acmod) |
((buf[6] & lfeon[acmod]) ? AC3_LFE : 0);
frmsizecod = buf[4] & 63;
if (frmsizecod >= 38)
return 0;
bitrate = rate [frmsizecod >> 1];
*bit_rate = (bitrate * 1000) >> half;
switch (buf[4] & 0xc0) {
case 0: // 48 KHz
*sample_rate = 48000 >> half;
return 4 * bitrate;
case 0x40:
*sample_rate = 44100 >> half;
return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
case 0x80:
*sample_rate = 32000 >> half;
return 6 * bitrate;
default:
return 0;
}
}
int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, 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;
state->halfrate = halfrate[buf[5] >> 3];
state->acmod = acmod = buf[6] >> 5;
bitstream_set_ptr (buf + 6);
bitstream_get (3); // skip acmod we already parsed
if ((acmod == 2) && (bitstream_get (2) == 2)) // dsurmod
acmod = AC3_DOLBY;
if ((acmod & 1) && (acmod != 1))
state->clev = clev[bitstream_get (2)]; // cmixlev
if (acmod & 4)
state->slev = slev[bitstream_get (2)]; // surmixlev
state->lfeon = bitstream_get (1);
state->output = downmix_init (acmod, *flags, level,
state->clev, state->slev);
if (state->output < 0)
return 1;
*flags = state->output;
state->level = *level;
state->bias = bias;
chaninfo = !acmod;
do {
bitstream_get (5); // dialnorm
if (bitstream_get (1)) // compre
bitstream_get (8); // compr
if (bitstream_get (1)) // langcode
bitstream_get (8); // langcod
if (bitstream_get (1)) // audprodie
bitstream_get (7); // mixlevel + roomtyp
} while (chaninfo--);
bitstream_get (2); // copyrightb + origbs
if (bitstream_get (1)) // timecod1e
bitstream_get (14); // timecod1
if (bitstream_get (1)) // timecod2e
bitstream_get (14); // timecod2
if (bitstream_get (1)) { // addbsie
int addbsil;
addbsil = bitstream_get (6);
do {
bitstream_get (8); // addbsi
} while (addbsil--);
}
return 0;
}
static int parse_exponents (int expstr, int ngrps, uint8_t exponent,
uint8_t * dest)
{
int exps;
while (ngrps--) {
exps = bitstream_get (7);
exponent += exp_1[exps];
if (exponent > 24)
return 1;
switch (expstr) {
case EXP_D45:
*(dest++) = exponent;
*(dest++) = exponent;
case EXP_D25:
*(dest++) = exponent;
case EXP_D15:
*(dest++) = exponent;
}
exponent += exp_2[exps];
if (exponent > 24)
return 1;
switch (expstr) {
case EXP_D45:
*(dest++) = exponent;
*(dest++) = exponent;
case EXP_D25:
*(dest++) = exponent;
case EXP_D15:
*(dest++) = exponent;
}
exponent += exp_3[exps];
if (exponent > 24)
return 1;
switch (expstr) {
case EXP_D45:
*(dest++) = exponent;
*(dest++) = exponent;
case EXP_D25:
*(dest++) = exponent;
case EXP_D15:
*(dest++) = exponent;
}
}
return 0;
}
static int parse_deltba (int8_t * deltba)
{
int deltnseg, deltlen, delta, j;
memset (deltba, 0, 50);
deltnseg = bitstream_get (3);
j = 0;
do {
j += bitstream_get (5);
deltlen = bitstream_get (4);
delta = bitstream_get (3);
delta -= (delta >= 4) ? 3 : 4;
if (!deltlen)
continue;
if (j + deltlen >= 50)
return 1;
while (deltlen--)
deltba[j++] = delta;
} while (deltnseg--);
return 0;
}
static inline int zero_snr_offsets (int nfchans, ac3_state_t * state)
{
int i;
if ((state->csnroffst) || (state->cplinu && state->cplba.fsnroffst) ||
(state->lfeon && state->lfeba.fsnroffst))
return 0;
for (i = 0; i < nfchans; i++)
if (state->ba[i].fsnroffst)
return 0;
return 1;
}
static 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;
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 < nfchans; i++)
blksw[i] = bitstream_get (1);
for (i = 0; i < nfchans; i++)
dithflag[i] = bitstream_get (1);
chaninfo = !(state->acmod);
do {
if (bitstream_get (1)) // dynrnge
bitstream_get (8); // dynrng
} while (chaninfo--);
if (bitstream_get (1)) { // cplstre
state->cplinu = bitstream_get (1);
if (state->cplinu) {
static int bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44,
45, 45, 46, 46, 47, 47, 48, 48};
int cplbegf;
int cplendf;
int ncplsubnd;
for (i = 0; i < nfchans; i++)
state->chincpl[i] = bitstream_get (1);
switch (state->acmod) {
case 0: case 1:
return 1;
case 2:
state->phsflginu = bitstream_get (1);
}
cplbegf = bitstream_get (4);
cplendf = bitstream_get (4);
if (cplendf + 3 - cplbegf < 0)
return 1;
state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
state->cplstrtbnd = bndtab[cplbegf];
state->cplstrtmant = cplbegf * 12 + 37;
state->cplendmant = cplendf * 12 + 73;
for (i = 0; i < ncplsubnd - 1; i++) {
state->cplbndstrc[i] = bitstream_get (1);
state->ncplbnd -= state->cplbndstrc[i];
}
state->cplbndstrc[i] = 0; // last value is a sentinel
}
}
if (state->cplinu) {
int j, cplcoe;
cplcoe = 0;
for (i = 0; i < nfchans; i++)
if (state->chincpl[i])
if (bitstream_get (1)) { // cplcoe
int mstrcplco, cplcoexp, cplcomant;
cplcoe = 1;
mstrcplco = 3 * bitstream_get (2);
for (j = 0; j < state->ncplbnd; j++) {
cplcoexp = bitstream_get (4);
cplcomant = bitstream_get (4);
if (cplcoexp == 15)
cplcomant <<= 14;
else
cplcomant = (cplcomant | 0x10) << 13;
state->cplco[i][j] =
cplcomant * scale_factor[cplcoexp + mstrcplco];
}
}
if ((state->acmod == 2) && state->phsflginu && cplcoe)
for (j = 0; j < state->ncplbnd; j++)
if (bitstream_get (1)) // phsflg
state->cplco[1][j] = -state->cplco[1][j];
}
if ((state->acmod == 2) && (bitstream_get (1))) { // rematstr
int end;
end = (state->cplinu) ? state->cplstrtmant : 253;
i = 0;
do
state->rematflg[i] = bitstream_get (1);
while (rematrix_band[i++] < end);
}
cplexpstr = EXP_REUSE;
lfeexpstr = EXP_REUSE;
if (state->cplinu)
cplexpstr = bitstream_get (2);
for (i = 0; i < nfchans; i++)
chexpstr[i] = bitstream_get (2);
if (state->lfeon)
lfeexpstr = bitstream_get (1);
for (i = 0; i < nfchans; i++)
if (chexpstr[i] != EXP_REUSE) {
if (state->cplinu && state->chincpl[i])
state->endmant[i] = state->cplstrtmant;
else {
int chbwcod;
chbwcod = bitstream_get (6);
if (chbwcod > 60)
return 1;
state->endmant[i] = chbwcod * 3 + 73;
}
}
do_bit_alloc = 0;
if (cplexpstr != EXP_REUSE) {
int cplabsexp, ncplgrps;
do_bit_alloc = 1;
ncplgrps = ((state->cplendmant - state->cplstrtmant) /
(3 << (cplexpstr - 1)));
cplabsexp = bitstream_get (4) << 1;
if (parse_exponents (cplexpstr, ncplgrps, cplabsexp,
state->cpl_exp + state->cplstrtmant))
return 1;
}
for (i = 0; i < nfchans; i++)
if (chexpstr[i] != EXP_REUSE) {
int grp_size, nchgrps;
do_bit_alloc = 1;
grp_size = 3 << (chexpstr[i] - 1);
nchgrps = (state->endmant[i] + grp_size - 4) / grp_size;
state->fbw_exp[i][0] = bitstream_get (4);
if (parse_exponents (chexpstr[i], nchgrps, state->fbw_exp[i][0],
state->fbw_exp[i] + 1))
return 1;
bitstream_get (2); // gainrng
}
if (lfeexpstr != EXP_REUSE) {
do_bit_alloc = 1;
state->lfe_exp[0] = bitstream_get (4);
if (parse_exponents (lfeexpstr, 2, state->lfe_exp[0],
state->lfe_exp + 1))
return 1;
}
if (bitstream_get (1)) { // baie
do_bit_alloc = 1;
state->sdcycod = bitstream_get (2);
state->fdcycod = bitstream_get (2);
state->sgaincod = bitstream_get (2);
state->dbpbcod = bitstream_get (2);
state->floorcod = bitstream_get (3);
}
if (bitstream_get (1)) { //snroffste
do_bit_alloc = 1;
state->csnroffst = bitstream_get (6);
if (state->cplinu) {
state->cplba.fsnroffst = bitstream_get (4);
state->cplba.fgaincod = bitstream_get (3);
}
for (i = 0; i < nfchans; i++) {
state->ba[i].fsnroffst = bitstream_get (4);
state->ba[i].fgaincod = bitstream_get (3);
}
if (state->lfeon) {
state->lfeba.fsnroffst = bitstream_get (4);
state->lfeba.fgaincod = bitstream_get (3);
}
}
if ((state->cplinu) && (bitstream_get (1))) { // cplleake
do_bit_alloc = 1;
state->cplfleak = 2304 - (bitstream_get (3) << 8);
state->cplsleak = 2304 - (bitstream_get (3) << 8);
}
if (bitstream_get (1)) { // deltbaie
do_bit_alloc = 1;
if (state->cplinu)
state->cplba.deltbae = bitstream_get (2);
for (i = 0; i < nfchans; i++)
state->ba[i].deltbae = bitstream_get (2);
if (state->cplinu && (state->cplba.deltbae == DELTA_BIT_NEW) &&
parse_deltba (state->cplba.deltba))
return 1;
for (i = 0; i < nfchans; i++)
if ((state->ba[i].deltbae == DELTA_BIT_NEW) &&
parse_deltba (state->ba[i].deltba))
return 1;
}
if (do_bit_alloc) {
if (zero_snr_offsets (nfchans, state)) {
memset (state->cpl_bap, 0, sizeof (state->cpl_bap));
memset (state->fbw_bap, 0, sizeof (state->fbw_bap));
memset (state->lfe_bap, 0, sizeof (state->lfe_bap));
} else {
if (state->cplinu)
bit_allocate (state, &state->cplba, state->cplstrtbnd,
state->cplstrtmant, state->cplendmant,
state->cplfleak, state->cplsleak,
state->cpl_exp, state->cpl_bap);
for (i = 0; i < nfchans; i++)
bit_allocate (state, state->ba + i, 0, 0, state->endmant[i],
0, 0, state->fbw_exp[i], state->fbw_bap[i]);
if (state->lfeon) {
state->lfeba.deltbae = DELTA_BIT_NONE;
bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
state->lfe_exp, state->lfe_bap);
}
}
}
if (bitstream_get (1)) { // skiple
i = bitstream_get (9); // skipl
while (i--)
bitstream_get (8);
}
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;
}
/*
* parse.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
static int8_t exp_1[128] = {
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
25,25,25
};
static int8_t exp_2[128] = {
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
25,25,25
};
static int8_t exp_3[128] = {
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
25,25,25
};
#define Q0 ((-2 << 15) / 3.0)
#define Q1 (0)
#define Q2 ((2 << 15) / 3.0)
static const float q_1_0[ 32 ] = {
Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
0,0,0,0,0
};
static const float q_1_1[ 32 ] = {
Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
0,0,0,0,0
};
static const float q_1_2[ 32 ] = {
Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
0,0,0,0,0
};
#undef Q0
#undef Q1
#undef Q2
#define Q0 ((-4 << 15) / 5.0)
#define Q1 ((-2 << 15) / 5.0)
#define Q2 (0)
#define Q3 ((2 << 15) / 5.0)
#define Q4 ((4 << 15) / 5.0)
static const float q_2_0[ 128 ] = {
Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
0,0,0
};
static const float q_2_1[ 128 ] = {
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
0,0,0
};
static const float q_2_2[ 128 ] = {
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
0,0,0
};
#undef Q0
#undef Q1
#undef Q2
#undef Q3
#undef Q4
static const float q_3[8] = {
(-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0, 0,
( 2 << 15)/7.0, ( 4 << 15)/7.0, ( 6 << 15)/7.0, 0
};
#define Q0 ((-10 << 15) / 11.0)
#define Q1 ((-8 << 15) / 11.0)
#define Q2 ((-6 << 15) / 11.0)
#define Q3 ((-4 << 15) / 11.0)
#define Q4 ((-2 << 15) / 11.0)
#define Q5 (0)
#define Q6 ((2 << 15) / 11.0)
#define Q7 ((4 << 15) / 11.0)
#define Q8 ((6 << 15) / 11.0)
#define Q9 ((8 << 15) / 11.0)
#define QA ((10 << 15) / 11.0)
static const float q_4_0[ 128 ] = {
Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3,
Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4,
Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5,
Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6,
Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7,
Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8,
Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9,
QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA,
0, 0, 0, 0, 0, 0, 0
};
static const float q_4_1[ 128 ] = {
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
0, 0, 0, 0, 0, 0, 0
};
#undef Q0
#undef Q1
#undef Q2
#undef Q3
#undef Q4
#undef Q5
#undef Q6
#undef Q7
#undef Q8
#undef Q9
#undef QA
static const float q_5[16] = {
(-14 << 15)/15.0,(-12 << 15)/15.0,(-10 << 15)/15.0,
( -8 << 15)/15.0,( -6 << 15)/15.0,( -4 << 15)/15.0,
( -2 << 15)/15.0, 0 ,( 2 << 15)/15.0,
( 4 << 15)/15.0,( 6 << 15)/15.0,( 8 << 15)/15.0,
( 10 << 15)/15.0,( 12 << 15)/15.0,( 14 << 15)/15.0,
0
};
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;
static 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
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment