Commit c6313a9b authored by Michel Lespinasse's avatar Michel Lespinasse

Separation du decodeur ac3 et de la partie specifique a videolan

Les interfaces du deco ac3 ne sont pas encore bien propres et documentees
mais ca viendra dans un second temps. Les fichiers ac3 ne dependent plus
d'includes videolan. C'est deja une bonne premiere etape.

Au niveau du bitstream compresse, l'interface avec le decodeur ac3 ne se fait
plus par le fichier decoder_fifo.h. En effet, le decodeur ac3 a besoin de
connaitre la structure exact d'un bitstream_t, donc cette interface n'etait
pas la plus propre. La nouvelle interface se compose d'une fonction
ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream) que le decodeur
ac3 appelle lorsqu'il a besoin d'un nouveau buffer de donnees compressees.

ac3_byte_stream_t est une structure comprenant les champs
u8 * p_byte (pointeur sur le debut du buffer),
u8 * p_end (pointeur sur la fin du buffer),
void * info (utilisation libre pour implementer ac3_byte_stream_next)

L'implementation actuelle de ac3_byte_stream_next () dans ac3_decoder_thread.c
fait un peu double emploi avec misc/decoder_fifo.c mais je reglerai tout ca
plus tard.
parent 7373cdfb
......@@ -324,25 +324,37 @@ typedef struct stream_samples_s
*****************************************************************************/
typedef s16 ac3dec_frame_t[ AC3DEC_FRAME_SIZE ];
typedef struct ac3_byte_stream_s
{
u8 * p_byte;
u8 * p_end;
void * info;
} ac3_byte_stream_t;
typedef struct ac3_bit_stream_s
{
u32 buffer;
int i_available;
ac3_byte_stream_t byte_stream;
unsigned int total_bits_read; /* temporary */
} ac3_bit_stream_t;
/*****************************************************************************
* ac3dec_t : ac3 decoder descriptor
*****************************************************************************/
typedef struct ac3dec_s
{
boolean_t b_invalid; /* `invalid' flag */
/*
* Input properties
*/
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
ac3_bit_stream_t bit_stream;
/*
* Decoder properties
*/
unsigned int total_bits_read;
syncinfo_t syncinfo;
bsi_t bsi;
audblk_t audblk;
......@@ -353,3 +365,5 @@ typedef struct ac3dec_s
} ac3dec_t;
int ac3_audio_block (ac3dec_t * p_ac3dec, s16 * buffer);
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream);
......@@ -19,6 +19,8 @@ typedef struct ac3dec_thread_s
* Input properties
*/
decoder_fifo_t fifo; /* stores the PES stream data */
input_thread_t * p_input;
ts_packet_t * p_ts;
/*
* Decoder properties
......
......@@ -12,15 +12,7 @@
* Basic types definitions
*****************************************************************************/
/* Basic types definitions */
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
#include "int_types.h"
typedef u8 byte_t;
......
/* Basic types definitions */
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
typedef unsigned long long u64;
typedef signed long long s64;
#include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
#include <sys/soundcard.h> /* "audio_output.h" */
#include <sys/types.h>
#include <sys/uio.h> /* "input.h" */
#include "common.h"
#include "config.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "debug.h" /* "input_netlist.h" */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "input.h" /* pes_packet_t */
#include "input_netlist.h" /* input_NetlistFreePES() */
#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
#include "audio_output.h"
#include "int_types.h"
#include "ac3_decoder.h"
#include "ac3_bit_allocate.h"
......@@ -29,6 +8,7 @@ static s16 calc_lowcomp(s16 a,s16 b0,s16 b1,s16 bin);
static inline u16 min(s16 a,s16 b);
static inline u16 max(s16 a,s16 b);
*/
static void ba_compute_psd(s16 start, s16 end, s16 exps[],
s16 psd[], s16 bndpsd[]);
......@@ -53,16 +33,16 @@ static s16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400
static s16 bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 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 };
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 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 };
static s16 bndsz[] = { 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, 3, 3,
3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
6, 12, 12, 12, 12, 24, 24, 24, 24, 24 };
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
6, 12, 12, 12, 12, 24, 24, 24, 24, 24 };
static s16 masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29,
......
static __inline__ u8 GetByte (ac3_byte_stream_t * p_byte_stream)
{
/* Are there some bytes left in the current buffer ? */
if (p_byte_stream->p_byte >= p_byte_stream->p_end) {
/* no, switch to next buffer */
ac3_byte_stream_next (p_byte_stream);
}
return *(p_byte_stream->p_byte++);
}
/*****************************************************************************
* NeedBits : reads i_bits new bits in the bit stream and stores them in the
* bit buffer
*****************************************************************************
* - i_bits must be less or equal 32 !
* - There is something important to notice with that function : if the number
* of bits available in the bit buffer when calling NeedBits() is greater than
* 24 (i_available > 24) but less than the number of needed bits
* (i_available < i_bits), the byte returned by GetByte() will be shifted with
* a negative value and the number of bits available in the bit buffer will be
* set to more than 32 !
*****************************************************************************/
static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{
while (p_bit_stream->i_available < i_bits) {
p_bit_stream->buffer |=
((u32)GetByte (&p_bit_stream->byte_stream)) << (24 - p_bit_stream->i_available);
p_bit_stream->i_available += 8;
}
}
/*****************************************************************************
* DumpBits : removes i_bits bits from the bit buffer
*****************************************************************************
* - i_bits <= i_available
* - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
*****************************************************************************/
static __inline__ void DumpBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{
p_bit_stream->buffer <<= i_bits;
p_bit_stream->i_available -= i_bits;
p_bit_stream->total_bits_read += i_bits;
}
#include <math.h>
#include <sys/uio.h> /* "input.h" */
#include "common.h"
#include "config.h"
#include "vlc_thread.h"
#include "mtime.h"
#include "input.h"
#include "decoder_fifo.h"
#include "audio_output.h"
#include "int_types.h"
#include "ac3_decoder.h"
#include "ac3_parse.h"
#include "ac3_exponent.h"
......@@ -21,13 +11,10 @@
int ac3_audio_block (ac3dec_t * p_ac3dec, s16 * buffer)
{
parse_audblk( p_ac3dec );
exponent_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
if (exponent_unpack( p_ac3dec ))
return 1;
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
return 1;
if ( p_ac3dec->bsi.acmod == 0x2 )
rematrix( p_ac3dec );
imdct( p_ac3dec );
......
......@@ -85,10 +85,9 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
p_ac3dec->fifo.i_start = 0;
p_ac3dec->fifo.i_end = 0;
/* Initialize the bit stream structure */
p_ac3dec->ac3_decoder.bit_stream.p_input = p_input;
p_ac3dec->ac3_decoder.bit_stream.p_decoder_fifo = &p_ac3dec->fifo;
p_ac3dec->ac3_decoder.bit_stream.fifo.buffer = 0;
p_ac3dec->ac3_decoder.bit_stream.fifo.i_available = 0;
p_ac3dec->p_input = p_input;
p_ac3dec->ac3_decoder.bit_stream.buffer = 0;
p_ac3dec->ac3_decoder.bit_stream.i_available = 0;
/*
* Initialize the output properties
......@@ -139,14 +138,8 @@ static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
{
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{
NeedBits( &(p_ac3dec->ac3_decoder.bit_stream), 16 );
if ( (p_ac3dec->ac3_decoder.bit_stream.fifo.buffer >> (32 - 16)) == 0x0b77 )
{
DumpBits( &(p_ac3dec->ac3_decoder.bit_stream), 16 );
p_ac3dec->ac3_decoder.total_bits_read = 16;
return( 0 );
}
DumpBits( &(p_ac3dec->ac3_decoder.bit_stream), 1 ); /* XXX?? */
if (! (ac3_test_sync (&p_ac3dec->ac3_decoder)))
return 0;
}
return( -1 );
}
......@@ -172,9 +165,12 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
}
vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
}
p_ac3dec->ac3_decoder.bit_stream.p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts;
p_ac3dec->ac3_decoder.bit_stream.p_byte = p_ac3dec->ac3_decoder.bit_stream.p_ts->buffer + p_ac3dec->ac3_decoder.bit_stream.p_ts->i_payload_start;
p_ac3dec->ac3_decoder.bit_stream.p_end = p_ac3dec->ac3_decoder.bit_stream.p_ts->buffer + p_ac3dec->ac3_decoder.bit_stream.p_ts->i_payload_end;
p_ac3dec->p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.p_byte =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.p_end =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.info = p_ac3dec;
vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
......@@ -214,8 +210,6 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
{
int i;
p_ac3dec->ac3_decoder.b_invalid = 0;
decode_find_sync( p_ac3dec );
if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts )
......@@ -245,12 +239,7 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
default: /* XXX?? */
fprintf( stderr, "ac3dec debug: invalid fscod\n" );
p_ac3dec->ac3_decoder.b_invalid = 1;
break;
}
if ( p_ac3dec->ac3_decoder.b_invalid ) /* XXX?? */
{
continue;
continue;
}
parse_bsi( &p_ac3dec->ac3_decoder );
......@@ -301,7 +290,7 @@ static void ErrorThread( ac3dec_thread_t * p_ac3dec )
/* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(p_ac3dec->fifo) )
{
input_NetlistFreePES( p_ac3dec->ac3_decoder.bit_stream.p_input, DECODER_FIFO_START(p_ac3dec->fifo) );
input_NetlistFreePES( p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo) );
DECODER_FIFO_INCSTART( p_ac3dec->fifo );
}
......@@ -336,3 +325,61 @@ static void EndThread( ac3dec_thread_t * p_ac3dec )
intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p destroyed\n", p_ac3dec );
}
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
{
ac3dec_thread_t * p_ac3dec = p_byte_stream->info;
/* We are looking for the next TS packet that contains real data,
* and not just a PES header */
do {
/* We were reading the last TS packet of this PES packet... It's
* time to jump to the next PES packet */
if (p_ac3dec->p_ts->p_next_ts == NULL) {
/* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before */
vlc_mutex_lock (&p_ac3dec->fifo.data_lock);
/* Is the input thread dying ? */
if (p_ac3dec->p_input->b_die) {
vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
return;
}
/* We should increase the start index of the decoder fifo, but
* if we do this now, the input thread could overwrite the
* pointer to the current PES packet, and we weren't able to
* give it back to the netlist. That's why we free the PES
* packet first. */
input_NetlistFreePES (p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo) );
DECODER_FIFO_INCSTART (p_ac3dec->fifo);
while (DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) {
vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
if (p_ac3dec->p_input->b_die) {
vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
return;
}
}
/* The next byte could be found in the next PES packet */
p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
/* We can release the fifo's data lock */
vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
}
/* Perhaps the next TS packet of the current PES packet contains
* real data (ie its payload's size is greater than 0) */
else {
p_ac3dec->p_ts = p_ac3dec->p_ts->p_next_ts;
}
} while (p_ac3dec->p_ts->i_payload_start == p_ac3dec->p_ts->i_payload_end);
p_byte_stream->p_byte =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
p_byte_stream->p_end =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
}
#include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
#include <sys/soundcard.h> /* "audio_output.h" */
#include <sys/types.h>
#include <sys/uio.h> /* "input.h" */
#include "common.h"
#include "config.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "debug.h" /* "input_netlist.h" */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "input.h" /* pes_packet_t */
#include "input_netlist.h" /* input_NetlistFreePES() */
#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
#include "audio_output.h"
#include "int_types.h"
#include "ac3_decoder.h"
#include "ac3_downmix.h"
......@@ -29,7 +8,6 @@ typedef struct prefs_s
{
u16 use_dolby_surround;
u16 dual_mono_channel_select;
} prefs_t;
prefs_t global_prefs = {0,0};
......
#include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
#include <sys/soundcard.h> /* "audio_output.h" */
#include <sys/types.h>
#include <sys/uio.h> /* "input.h" */
#include "common.h"
#include "config.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "debug.h" /* "input_netlist.h" */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "input.h" /* pes_packet_t */
#include "input_netlist.h" /* input_NetlistFreePES() */
#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
#include "audio_output.h"
#include "int_types.h"
#include "ac3_decoder.h"
#include "ac3_bit_stream.h"
#include "ac3_exponent.h"
static const s16 exps_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, 3, 3, 3 };
static const s16 exps_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, -2, -2, -2 };
static const s16 exps_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, -2, -1, 0 };
static __inline__ void exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, u16 ngrps, u16 initial_exp, u16 exps[], u16 * dest )
static const s16 exps_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,
0, 0, 0 };
static const s16 exps_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,
0, 0, 0 };
static const s16 exps_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,
0, 0, 0 };
#define UNPACK_FBW 1
#define UNPACK_CPL 2
#define UNPACK_LFE 4
static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, u16 ngrps, u16 initial_exp, u16 exps[], u16 * dest )
{
u16 i,j;
s16 exp_acc;
if ( expstr == EXP_REUSE )
{
return;
return 0;
}
/* Handle the initial absolute exponent */
......@@ -53,87 +57,105 @@ static __inline__ void exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
/* Loop through the groups and fill the dest array appropriately */
switch ( expstr )
{
case EXP_D45:
for ( i = 0; i < ngrps; i++ )
{
if ( exps[i] > 124 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
p_ac3dec->b_invalid = 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
case EXP_D25:
for ( i = 0; i < ngrps; i++ )
{
if ( exps[i] > 124 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
p_ac3dec->b_invalid = 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
case EXP_D15:
for ( i = 0; i < ngrps; i++ )
{
if ( exps[i] > 124 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
p_ac3dec->b_invalid = 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
}
break;
case EXP_D15: /* 1 */
for ( i = 0; i < ngrps; i++ )
{
if ( exps[i] > 124 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
}
break;
case EXP_D25: /* 2 */
for ( i = 0; i < ngrps; i++ )
{
if ( exps[i] > 124 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;