summaryrefslogtreecommitdiff
path: root/ac3dec/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'ac3dec/decode.c')
-rw-r--r--ac3dec/decode.c251
1 files changed, 143 insertions, 108 deletions
diff --git a/ac3dec/decode.c b/ac3dec/decode.c
index 5e7f034..fb85205 100644
--- a/ac3dec/decode.c
+++ b/ac3dec/decode.c
@@ -3,9 +3,6 @@
*
* Copyright (C) Aaron Holtzman - May 1999
*
- * Added support for DVB-s PCI card by:
- * Matjaz Thaler <matjaz.thaler@rd.iskraemeco.si> - November 2000
- *
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
@@ -22,6 +19,17 @@
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
+ *------------------------------------------------------------
+ *
+ * Thomas Mirlacher <dent@cosy.sbg.ac.at>
+ * added OMS support
+ * 11 Jan 2001
+ * Thomas Mirlacher <dent@cosy.sbg.ac.at>
+ * faster error response using jmp functions
+ *
+ * 9 Aug 2001
+ * Matjaz Thaler <matjaz.thaler@rd.iskraemeco.si>
+ * Added support for DVB-s PCI card
*
*/
@@ -34,14 +42,17 @@
#include <errno.h>
#include <string.h>
#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+
+#ifdef __OMS__
+#include <oms/oms.h>
+#include <oms/plugin/output_audio.h>
+#endif
#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"
@@ -51,96 +62,91 @@
#include "stats.h"
#include "rematrix.h"
#include "sanity_check.h"
-#include "downmix.h"
#include "debug.h"
-
-#define AC3_BUFFER_SIZE (6*1024*16)
-
+#ifndef __OMS__
+//#include "audio_out.h"
+#endif
//our global config structure
ac3_config_t ac3_config;
-uint_32 error_flag = 0;
static audblk_t audblk;
static bsi_t bsi;
static syncinfo_t syncinfo;
-static uint_32 frame_count = 0;
-//static uint_32 is_output_initialized = 0;
+#ifndef __OMS__
+static uint32_t done_banner;
+#endif
+static uint32_t is_output_initialized = 0;
//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 sint_16 s16_samples[2 * 6 * 256];
-
+static int16_t s16_samples[2 * 6 * 256] __attribute__ ((aligned(16)));
+// 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 SYNC_BUFFER_MAX_SIZE 4096
-static uint_8 sync_buffer[SYNC_BUFFER_MAX_SIZE];
-static uint_32 sync_buffer_size = 0;;
+#define BUFFER_MAX_SIZE 4096
+static uint8_t buffer[BUFFER_MAX_SIZE];
+static uint32_t buffer_size = 0;;
+// for error handling
+jmp_buf error_jmp_mark;
-uint_32
-decode_sync_buffer_syncframe(syncinfo_t *syncinfo, uint_8 **start,uint_8 *end)
+static uint32_t decode_buffer_syncframe (syncinfo_t *syncinfo, uint8_t **start, uint8_t *end)
{
- uint_8 *cur = *start;
- uint_16 syncword = syncinfo->syncword;
- uint_32 ret = 0;
+ uint8_t *cur = *start;
+ uint16_t syncword = syncinfo->syncword;
+ uint32_t ret = 0;
- //
// Find an ac3 sync frame.
- //
-resync:
-
- while(syncword != 0x0b77)
- {
- if(cur >= end)
+ while (syncword != 0x0b77) {
+ if (cur >= end)
goto done;
syncword = (syncword << 8) + *cur++;
}
//need the next 3 bytes to decide how big the frame is
- while(sync_buffer_size < 3)
- {
+ while (buffer_size < 3) {
if(cur >= end)
goto done;
- sync_buffer[sync_buffer_size++] = *cur++;
+ buffer[buffer_size++] = *cur++;
}
- parse_syncinfo(syncinfo,sync_buffer);
- stats_print_syncinfo(syncinfo);
+ parse_syncinfo (syncinfo,buffer);
+ stats_print_syncinfo (syncinfo);
- while(sync_buffer_size < syncinfo->frame_size * 2 - 2)
- {
+ while (buffer_size < syncinfo->frame_size * 2 - 2) {
if(cur >= end)
goto done;
- sync_buffer[sync_buffer_size++] = *cur++;
+ buffer[buffer_size++] = *cur++;
}
-
+
+#if 0
// Check the crc over the entire frame
crc_init();
- crc_process_frame(sync_buffer,syncinfo->frame_size * 2 - 2);
+ crc_process_frame (buffer, syncinfo->frame_size * 2 - 2);
- if(!crc_validate())
- {
+ if (!crc_validate()) {
fprintf(stderr,"** CRC failed - skipping frame **\n");
- syncword = 0xffff;
- sync_buffer_size = 0;
- goto resync;
+ goto done;
}
-
- //
+#endif
+
//if we got to this point, we found a valid ac3 frame to decode
- //
- bitstream_init(sync_buffer);
+ bitstream_init (buffer);
//get rid of the syncinfo struct as we already parsed it
- bitstream_get(24);
+ bitstream_get (24);
//reset the syncword for next time
syncword = 0xffff;
- sync_buffer_size = 0;
+ buffer_size = 0;
ret = 1;
done:
@@ -149,100 +155,131 @@ done:
return ret;
}
-void
-decode_mute(void)
+
+void inline decode_mute (void)
{
- fprintf(stderr,"muting frame\n");
//mute the frame
- memset(s16_samples,0,sizeof(sint_16) * 256 * 2 * 6);
- error_flag = 0;
+ memset (s16_samples, 0, sizeof(int16_t) * 256 * 2 * 6);
}
-void
-ac3_init(ac3_config_t *config)
+void ac3dec_init (void)
{
- memcpy(&ac3_config,config,sizeof(ac3_config_t));
-
- imdct_init();
- sanity_check_init(&syncinfo,&bsi,&audblk);
-
- // ac3_output = *foo;
+// FIXME - don't do that statically here
+ ac3_config.num_output_ch = 2;
+ ac3_config.flags = 0;
+
+ imdct_init ();
+ downmix_init ();
+ memset (&syncinfo, 0, sizeof (syncinfo));
+ memset (&bsi, 0, sizeof (bsi));
+ memset (&audblk, 0, sizeof (audblk));
+ sanity_check_init (&syncinfo,&bsi,&audblk);
}
-uint_32 ac3_decode_data(uint_8 *data_start,uint_8 *data_end, int ac3reset, int *input_pointer, int *output_pointer, char *ac3_data)
+#ifdef __OMS__
+size_t ac3dec_decode_data (plugin_output_audio_t *output, uint8_t *data_start, uint8_t *data_end)
+#else
+size_t ac3dec_decode_data (uint8_t *data_start ,uint8_t *data_end, int ac3reset, int *input_pointer, int *output_pointer, char *ac3_data)
+#endif
{
- uint_32 i;
+ uint32_t i;
int datasize;
char *data;
+
if(ac3reset != 0){
syncinfo.syncword = 0xffff;
- sync_buffer_size = 0;
+ buffer_size = 0;
+ }
+
+ if (setjmp (error_jmp_mark) < 0) {
+ ac3dec_init ();
+ return 0;
}
-
- while(decode_sync_buffer_syncframe(&syncinfo,&data_start,data_end))
- {
- dprintf("(decode) begin frame %d\n",frame_count++);
- if(error_flag)
- {
- decode_mute();
- continue;
+ while (decode_buffer_syncframe (&syncinfo, &data_start, data_end)) {
+ parse_bsi (&bsi);
+
+#ifndef __OMS__
+ if(!done_banner) {
+ // stats_print_banner(&syncinfo,&bsi);
+ done_banner = 1;
}
+#endif
+
+ // compute downmix parameters
+ // downmix to tow 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 (bsi.acmod & 0x4) // have surround channels
+ dm_par.slev = smixlev_lut[bsi.surmixlev];
- parse_bsi(&bsi);
+ dm_par.unit /= 1.0 + dm_par.clev + dm_par.slev;
+ dm_par.clev *= dm_par.unit;
+ dm_par.slev *= dm_par.unit;
- for(i=0; i < 6; i++)
- {
+ for(i=0; i < 6; i++) {
//Initialize freq/time sample storage
- memset(samples,0,sizeof(float) * 256 * (bsi.nfchans + bsi.lfeon));
+ memset (samples, 0, sizeof(float) * 256 * (bsi.nfchans + bsi.lfeon));
// Extract most of the audblk info from the bitstream
// (minus the mantissas
- parse_audblk(&bsi,&audblk);
+ parse_audblk (&bsi,&audblk);
// Take the differential exponent data and turn it into
// absolute exponents
- exponent_unpack(&bsi,&audblk);
- if(error_flag)
- goto error;
+ exponent_unpack (&bsi,&audblk);
// Figure out how many bits per mantissa
- bit_allocate(syncinfo.fscod,&bsi,&audblk);
+ bit_allocate (syncinfo.fscod,&bsi,&audblk);
// Extract the mantissas from the stream and
// generate floating point frequency coefficients
- coeff_unpack(&bsi,&audblk,samples);
- if(error_flag)
- goto error;
+ coeff_unpack (&bsi,&audblk,samples);
- if(bsi.acmod == 0x2)
- rematrix(&audblk,samples);
+ if (bsi.acmod == 0x2)
+ rematrix (&audblk,samples);
// Convert the frequency samples into time samples
- imdct(&bsi,&audblk,samples);
+ imdct (&bsi,&audblk,samples, &s16_samples[i * 2 * 256], &dm_par);
// Downmix into the requested number of channels
- // and convert floating point to sint_16
- downmix(&bsi,samples,&s16_samples[i * 2 * 256]);
+ // and convert floating point to int16_t
+ // downmix(&bsi,samples,&s16_samples[i * 2 * 256]);
- sanity_check(&syncinfo,&bsi,&audblk);
- if(error_flag)
- goto error;
+ if (sanity_check(&syncinfo,&bsi,&audblk) < 0) {
+ HANDLE_ERROR ();
+ return 0;
+ }
continue;
}
-
- parse_auxdata(&syncinfo);
- /*
- if(!is_output_initialized)
- {
- ac3_output.open(16,syncinfo.sampling_rate,2);
+ if (!is_output_initialized) {
+#ifdef __OMS__
+ plugin_output_audio_attr_t attr;
+#ifdef __sun__
+ attr.format = 16;
+#else
+ attr.format = AFMT_S16_NE;
+#endif
+ attr.speed = syncinfo.sampling_rate;
+ attr.channels = 2;
+
+ // output->setup (&attr);
+#else
+ // ao_functions->open (16, syncinfo.sampling_rate, 2);
+#endif
is_output_initialized = 1;
}
- */
+
+#ifdef __OMS__
+ output->write (s16_samples, 256 * 6 * 2 * 2);
+#else
+ // ao_functions->play(s16_samples, 256 * 6 * 2);
data = (char *)s16_samples;
datasize = 0;
while(datasize < 6144){
@@ -257,13 +294,11 @@ uint_32 ac3_decode_data(uint_8 *data_start,uint_8 *data_end, int ac3reset, int *
}
}
+#endif
- //write(1, s16_samples, 256 * 6 * 2* 2);
- //ac3_output.play(s16_samples, 256 * 6 * 2);
-error:
- ;
- //find a new frame
}
+ decode_mute ();
+
return 0;
}