summaryrefslogtreecommitdiff
path: root/src/libac3/decode.c
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-05-26 15:07:18 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-05-26 15:07:18 +0000
commit2bb1b8f3a4984075743b17fbe1d00b1af9917254 (patch)
tree06aa3a03497e938d80a7146013fef96324ef073c /src/libac3/decode.c
parent65480cd3d11b465f0ede5f6c3d1b9f12e06dc98b (diff)
downloadxine-lib-2bb1b8f3a4984075743b17fbe1d00b1af9917254.tar.gz
xine-lib-2bb1b8f3a4984075743b17fbe1d00b1af9917254.tar.bz2
switch to walken's libac3 and minor bugfixes
CVS patchset: 83 CVS date: 2001/05/26 15:07:18
Diffstat (limited to 'src/libac3/decode.c')
-rw-r--r--src/libac3/decode.c299
1 files changed, 59 insertions, 240 deletions
diff --git a/src/libac3/decode.c b/src/libac3/decode.c
index 96ee6c1a3..db0068b8d 100644
--- a/src/libac3/decode.c
+++ b/src/libac3/decode.c
@@ -22,296 +22,115 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
-#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
-
+#include <inttypes.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
-#include "downmix.h"
-#include "srfft.h"
#include "imdct.h"
-#include "exponent.h"
#include "coeff.h"
#include "bit_allocate.h"
#include "parse.h"
-#include "crc.h"
+#include "stats.h"
#include "rematrix.h"
#include "sanity_check.h"
-
-#include "audio_out.h"
-#include "metronom.h"
-#include "attributes.h"
-
+#include "downmix.h"
+#include "debug.h"
//our global config structure
-ac3_config_t ac3_config;
-#ifdef FAST_ERROR
-jmp_buf error_jmp_mark;
-#else
uint32_t error_flag = 0;
-#endif
static audblk_t audblk;
-static bsi_t bsi;
-static syncinfo_t syncinfo;
+static ac3_state_t state;
static uint32_t frame_count = 0;
-static uint32_t is_output_initialized = 0;
+static uint32_t done_banner;
+static ac3_frame_t frame;
//the floating point samples for one audblk
static stream_samples_t samples;
//the integer samples for the entire frame (with enough space for 2 ch out)
//if this size change, be sure to change the size when muting
-static int16_t s16_samples[2 * 6 * 256] __attribute__ ((aligned(16)));
-
-/* output buffer for spdiv output */
-static int16_t s16_samples_out[4 * 6 * 256] __attribute__ ((aligned(16)));
-
-static ao_functions_t *ac3_output;
+static int16_t s16_samples[2 * 6 * 256];
-// downmix stuff
-static float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
-static float smixlev_lut[4] = { 0.707, 0.500, 0.0 , 0.500 };
-static dm_par_t dm_par;
-
-//Storage for the syncframe
-#define BUFFER_MAX_SIZE 4096
-static uint8_t buffer[BUFFER_MAX_SIZE];
-static uint32_t buffer_size = 0;;
-
-static uint32_t decode_buffer_syncframe (syncinfo_t *syncinfo, uint8_t **start, uint8_t *end)
+void
+ac3_init(void)
{
- uint8_t *cur = *start;
- uint16_t syncword = syncinfo->syncword;
- uint32_t ret = 0;
-
- //
- // Find an ac3 sync frame.
- //
- while (syncword != 0x0b77) {
- if (cur >= end)
- goto done;
- syncword = (syncword << 8) + *cur++;
- }
+ imdct_init();
+ sanity_check_init(&state,&audblk);
- //need the next 3 bytes to decide how big the frame is
- while (buffer_size < 3) {
- if(cur >= end)
- goto done;
- buffer[buffer_size++] = *cur++;
- }
-
- parse_syncinfo (syncinfo,buffer);
-
- while (buffer_size < syncinfo->frame_size * 2 - 2) {
- if(cur >= end)
- goto done;
-
- buffer[buffer_size++] = *cur++;
- }
-
-#if 0
- // Check the crc over the entire frame
- crc_init();
- crc_process_frame (buffer, syncinfo->frame_size * 2 - 2);
-
- if (!crc_validate()) {
-#ifndef FAST_ERROR
- error_flag = 1;
-#endif
- fprintf(stderr,"** CRC failed - skipping frame **\n");
- goto done;
- }
-#endif
-
- //
- //if we got to this point, we found a valid ac3 frame to decode
- //
-
- if ((ac3_config.flags & AO_CAP_MODE_AC3) == 0) {
- bitstream_init (buffer);
- //get rid of the syncinfo struct as we already parsed it
- bitstream_get (24);
- }
-
- //reset the syncword for next time
- syncword = 0xffff;
- buffer_size = 0;
- ret = 1;
-
-done:
- syncinfo->syncword = syncword;
- *start = cur;
- return ret;
+ frame.audio_data = s16_samples;
}
-
-void inline decode_mute (void)
+int ac3_frame_length(uint8_t * buf)
{
- //mute the frame
- memset (s16_samples, 0, sizeof(int16_t) * 256 * 2 * 6);
-#ifndef FAST_ERROR
- error_flag = 0;
-#endif
-}
-
-
-void ac3_init(ac3_config_t *config ,ao_functions_t *foo)
-{
- memcpy(&ac3_config,config,sizeof(ac3_config_t));
- ac3_output = foo;
-
- imdct_init ();
- /* downmix_init (); */
- sanity_check_init (&syncinfo,&bsi,&audblk);
- memset(s16_samples_out,0,4 * 6 * 256);
-
-}
-
-void ac3_reset ()
-{
- printf ("ac3_reset\n");
-#ifndef FAST_ERROR
- error_flag = 0;
-#endif
-
- frame_count = 0;
- is_output_initialized = 0;
-
- buffer_size = 0;
- syncinfo.syncword = 0;
- imdct_init();
- sanity_check_init(&syncinfo,&bsi,&audblk);
+ int dummy;
+ return parse_syncinfo (buf, &dummy, &dummy);
}
-size_t ac3_decode_data (uint8_t *data_start, uint8_t *data_end, uint32_t pts_)
+ac3_frame_t*
+ac3_decode_frame(uint8_t * buf)
{
- uint32_t i;
+ uint32_t i;
+ int dummy;
-#ifdef FAST_ERROR
- if (setjmp (error_jmp_mark) < 0) {
- imdct_init ();
- sanity_check_init(&syncinfo,&bsi,&audblk);
- return 0;
- }
-#endif
-
- while (decode_buffer_syncframe (&syncinfo, &data_start, data_end)) {
+ if (!parse_syncinfo (buf, &frame.sampling_rate, &dummy))
+ goto error;
-#ifndef FAST_ERROR
- if (error_flag)
- goto error;
-#endif
+ dprintf("(decode) begin frame %d\n",frame_count++);
- if ((ac3_config.flags & AO_CAP_MODE_AC3) == 0) {
- parse_bsi (&bsi);
+ if (parse_bsi (&state, buf))
+ goto error;
- // compute downmix parameters
- // downmix to two channels for now
- dm_par.clev = 0.0; dm_par.slev = 0.0; dm_par.unit = 1.0;
- if (bsi.acmod & 0x1) // have center
- dm_par.clev = cmixlev_lut[bsi.cmixlev];
+ if (!done_banner) {
+ stats_print_banner (&state);
+ done_banner = 1;
+ }
- if (bsi.acmod & 0x4) // have surround channels
- dm_par.slev = smixlev_lut[bsi.surmixlev];
+ for(i=0; i < 6; i++) {
+ //Initialize freq/time sample storage
+ memset(samples,0,sizeof(float) * 256 * (state.nfchans + state.lfeon));
- dm_par.unit /= 1.0 + dm_par.clev + dm_par.slev;
- dm_par.clev *= dm_par.unit;
- dm_par.slev *= dm_par.unit;
+ // Extract most of the audblk info from the bitstream
+ // (minus the mantissas
+ if (parse_audblk (&state, &audblk))
+ goto error;
- for(i=0; i < 6; i++) {
- //Initialize freq/time sample storage
- memset (samples, 0, sizeof(float) * 256 * (bsi.nfchans + bsi.lfeon));
+ // Figure out how many bits per mantissa
+ //bit_allocate(&state,&audblk);
- // Extract most of the audblk info from the bitstream
- // (minus the mantissas
- parse_audblk (&bsi,&audblk);
+ // Extract the mantissas from the stream and
+ // generate floating point frequency coefficients
+ coeff_unpack(&state,&audblk,samples);
+ if(error_flag)
+ goto error;
- // Take the differential exponent data and turn it into
- // absolute exponents
- exponent_unpack (&bsi,&audblk);
-#ifndef FAST_ERROR
- if (error_flag)
- goto error;
-#endif
+ if(state.acmod == 0x2)
+ rematrix(&audblk,samples);
- // Figure out how many bits per mantissa
- bit_allocate (syncinfo.fscod,&bsi,&audblk);
+ // Convert the frequency samples into time samples
+ imdct(&state,&audblk,samples);
- // Extract the mantissas from the stream and
- // generate floating point frequency coefficients
- coeff_unpack (&bsi,&audblk,samples);
-#ifndef FAST_ERROR
- if (error_flag)
- goto error;
-#endif
+ // Downmix into the requested number of channels
+ // and convert floating point to int16_t
+ downmix(&state,samples,&s16_samples[i * 2 * 256]);
- if (bsi.acmod == 0x2)
- rematrix (&audblk,samples);
+ sanity_check(&state,&audblk);
+ if(error_flag)
+ goto error;
+ }
- // Convert the frequency samples into time samples
- imdct (&bsi,&audblk,samples, &s16_samples[i * 2 * 256], &dm_par);
+ return &frame;
- // Downmix into the requested number of channels
- // and convert floating point to int16_t
- // downmix(&bsi,samples,&s16_samples[i * 2 * 256]);
-
- if (sanity_check(&syncinfo,&bsi,&audblk) < 0)
- sanity_check_init (&syncinfo,&bsi,&audblk);
-
- continue;
- }
- }
- else {
- s16_samples_out[0] = 0xf872; //spdif syncword
- s16_samples_out[1] = 0x4e1f; // .............
- s16_samples_out[2] = 0x0001; // AC3 data
- s16_samples_out[3] = syncinfo.frame_size * 16;
- s16_samples_out[4] = 0x0b77; // AC3 syncwork
-
- // ac3 seems to be swabbed data
- swab(buffer,&s16_samples_out[5], syncinfo.frame_size * 2 );
-
- }
-
- if (!is_output_initialized) {
- ac3_output->open (ac3_output, 16, syncinfo.sampling_rate,
- (ac3_config.flags & AO_CAP_MODE_AC3) ? AO_CAP_MODE_AC3 : AO_CAP_MODE_STEREO);
- is_output_initialized = 1;
- }
-
- if ((ac3_config.flags & AO_CAP_MODE_AC3) == 0) {
- ac3_output->write_audio_data(ac3_output,
- s16_samples, 256*6, pts_);
- }
- else {
- ac3_output->write_audio_data(ac3_output,
- s16_samples_out, 6 * 256, pts_);
- }
-
- pts_ = 0;
-
-#ifndef FAST_ERROR
error:
-
- //find a new frame
- decode_mute (); //RMB CHECK
-#endif
- }
-#ifdef FAST_ERROR
- decode_mute ();
-#endif
+ //mute the frame
+ memset(s16_samples,0,sizeof(int16_t) * 256 * 2 * 6);
- return 0;
+ error_flag = 0;
+ return &frame;
}
-