diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-05-26 15:07:18 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-05-26 15:07:18 +0000 |
commit | 2bb1b8f3a4984075743b17fbe1d00b1af9917254 (patch) | |
tree | 06aa3a03497e938d80a7146013fef96324ef073c /src/libac3/decode.c | |
parent | 65480cd3d11b465f0ede5f6c3d1b9f12e06dc98b (diff) | |
download | xine-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.c | 299 |
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; } - |