diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-07-20 22:37:56 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-07-20 22:37:56 +0000 |
commit | 74534c743117a45b7f62c939f24270f7b5d549c5 (patch) | |
tree | db28648ffc13941bad8276bf843659d15ff590bb | |
parent | 5254a0d8747c08ef38b0963c85485246b2b5a8e1 (diff) | |
download | xine-lib-74534c743117a45b7f62c939f24270f7b5d549c5.tar.gz xine-lib-74534c743117a45b7f62c939f24270f7b5d549c5.tar.bz2 |
latest libac3 update from walken including lfe support
CVS patchset: 314
CVS date: 2001/07/20 22:37:56
-rw-r--r-- | src/audio_out/audio_oss_out.c | 16 | ||||
-rw-r--r-- | src/libac3/ac3.h | 26 | ||||
-rw-r--r-- | src/libac3/ac3_internal.h | 18 | ||||
-rw-r--r-- | src/libac3/bit_allocate.c | 5 | ||||
-rw-r--r-- | src/libac3/bitstream.h | 2 | ||||
-rw-r--r-- | src/libac3/downmix.c | 103 | ||||
-rw-r--r-- | src/libac3/imdct.c | 59 | ||||
-rw-r--r-- | src/libac3/imdct_mlib.c | 41 | ||||
-rw-r--r-- | src/libac3/parse.c | 61 | ||||
-rw-r--r-- | src/libac3/tables.h | 75 | ||||
-rw-r--r-- | src/libac3/xine_decoder.c | 83 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 18 |
12 files changed, 276 insertions, 231 deletions
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c index fb5906776..8d36ae818 100644 --- a/src/audio_out/audio_oss_out.c +++ b/src/audio_out/audio_oss_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_oss_out.c,v 1.20 2001/07/14 17:45:06 jcdutton Exp $ + * $Id: audio_oss_out.c,v 1.21 2001/07/20 22:37:56 guenter Exp $ */ /* required for swab() */ @@ -198,6 +198,11 @@ static int ao_open(ao_functions_t *this_gen, ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); this->num_channels = tmp; break; + case AO_CAP_MODE_5_1CHANNEL: + tmp = 6; + ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); + this->num_channels = tmp; + break; case AO_CAP_MODE_AC3: tmp = AFMT_AC3; ioctl(this->audio_fd,SNDCTL_DSP_SETFMT,&tmp); @@ -586,6 +591,15 @@ ao_functions_t *init_audio_out_plugin (config_values_t *config) { } else printf ("(5-channel not enabled in .xinerc) " ); } + num_channels = 6; + status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels); + if ( (status != -1) && (num_channels==6) ) { + if (config->lookup_int (config, "five_lfe_channel", 0)) { + this->capabilities |= AO_CAP_MODE_5_1CHANNEL; + printf ("5.1-channel "); + } else + printf ("(5.1-channel not enabled in .xinerc) " ); + } ioctl(audio_fd,SNDCTL_DSP_GETFMTS,&caps); if (caps & AFMT_AC3) { diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h index 305a10e49..03b849357 100644 --- a/src/libac3/ac3.h +++ b/src/libac3/ac3.h @@ -22,24 +22,28 @@ * */ +typedef float sample_t; + 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 + 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 { + sample_t * delay; // delay samples for imdct + 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 + sample_t clev; // centre channel mix level + sample_t slev; // surround channels mix level uint8_t lfeon; // coded lfe channel int output; // type of output - float level; // output level - float bias; // output bias + sample_t level; // output level + sample_t bias; // output bias uint16_t cplinu; // coupling in use uint16_t chincpl[5]; // channel coupled @@ -47,7 +51,7 @@ typedef struct ac3_state_s { 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 + sample_t cplco[5][18]; // coupling coordinates // derived information uint16_t cplstrtbnd; // coupling start band (for bit allocation) @@ -101,5 +105,5 @@ 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); + sample_t * level, sample_t bias, sample_t * delay); +int ac3_block (ac3_state_t * state, sample_t samples[][256]); diff --git a/src/libac3/ac3_internal.h b/src/libac3/ac3_internal.h index b414578bd..065ccbb36 100644 --- a/src/libac3/ac3_internal.h +++ b/src/libac3/ac3_internal.h @@ -26,29 +26,27 @@ #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) -/* samples work structure */ -typedef float stream_samples_t[6][256]; - 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); +int downmix_init (int input, int flags, sample_t * level, + sample_t clev, sample_t slev); +void downmix (sample_t * samples, int acmod, int output, + sample_t level, sample_t bias, sample_t clev, sample_t slev); void imdct_init (void); -extern void (* imdct_256) (float data[], float delay[]); -extern void (* imdct_512) (float data[], float delay[]); +extern void (* imdct_256) (sample_t * data, sample_t * delay); +extern void (* imdct_512) (sample_t * data, sample_t * delay); +void imdct_do_256_mlib (sample_t * data, sample_t * delay); +void imdct_do_512_mlib (sample_t * data, sample_t * delay); diff --git a/src/libac3/bit_allocate.c b/src/libac3/bit_allocate.c index 307c0074c..f3eaa1def 100644 --- a/src/libac3/bit_allocate.c +++ b/src/libac3/bit_allocate.c @@ -21,9 +21,10 @@ * */ +#include "config.h" + #include <inttypes.h> -#include <stdlib.h> -#include <string.h> + #include "ac3.h" #include "ac3_internal.h" diff --git a/src/libac3/bitstream.h b/src/libac3/bitstream.h index f290f7f66..84f3287c8 100644 --- a/src/libac3/bitstream.h +++ b/src/libac3/bitstream.h @@ -21,8 +21,6 @@ * */ -#include "config.h" - //My new and improved vego-matic endian swapping routine //(stolen from the kernel) #ifdef WORDS_BIGENDIAN diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c index 9e7fbfb8b..498471798 100644 --- a/src/libac3/downmix.c +++ b/src/libac3/downmix.c @@ -25,18 +25,18 @@ * */ +#include "config.h" + #include <inttypes.h> -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <string.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) +int downmix_init (int input, int flags, sample_t * level, + sample_t clev, sample_t slev) { static uint8_t table[11][8] = { {AC3_CHANNEL, AC3_DOLBY, AC3_STEREO, AC3_STEREO, @@ -150,12 +150,12 @@ int downmix_init (int input, int flags, float * level, float clev, float slev) case CONVERT (AC3_3F2R, AC3_DOLBY): *level *= 1 / (1 + 3 * LEVEL_3DB); break; - } + } return output; } -static void mix1to1 (float * samples, float level, float bias) +static void mix1to1 (sample_t * samples, sample_t level, sample_t bias) { int i; @@ -163,7 +163,8 @@ static void mix1to1 (float * samples, float level, float bias) samples[i] = samples[i] * level + bias; } -static void move1to1 (float * src, float * dest, float level, float bias) +static void move1to1 (sample_t * src, sample_t * dest, + sample_t level, sample_t bias) { int i; @@ -171,7 +172,7 @@ static void move1to1 (float * src, float * dest, float level, float bias) dest[i] = src[i] * level + bias; } -static void mix2to1 (float * samples, float level, float bias) +static void mix2to1 (sample_t * samples, sample_t level, sample_t bias) { int i; @@ -179,7 +180,8 @@ static void mix2to1 (float * samples, float level, float bias) samples[i] = (samples[i] + samples[i + 256]) * level + bias; } -static void move2to1 (float * src, float * dest, float level, float bias) +static void move2to1 (sample_t * src, sample_t * dest, + sample_t level, sample_t bias) { int i; @@ -187,7 +189,8 @@ static void move2to1 (float * src, float * dest, float level, float bias) dest[i] = (src[i] + src[i + 256]) * level + bias; } -static void mix3to1 (float * samples, float level, float clev, float bias) +static void mix3to1 (sample_t * samples, sample_t level, sample_t clev, + sample_t bias) { int i; @@ -196,7 +199,8 @@ static void mix3to1 (float * samples, float level, float clev, float bias) samples[i + 256] * clev + bias); } -static void mix21to1 (float * samples, float level, float slev, float bias) +static void mix21to1 (sample_t * samples, sample_t level, sample_t slev, + sample_t bias) { int i; @@ -205,8 +209,8 @@ static void mix21to1 (float * samples, float level, float slev, float bias) samples[i + 512] * slev + bias); } -static void mix31to1 (float * samples, float level, float clev, float slev, - float bias) +static void mix31to1 (sample_t * samples, sample_t level, + sample_t clev, sample_t slev, sample_t bias) { int i; @@ -216,7 +220,8 @@ static void mix31to1 (float * samples, float level, float clev, float slev, bias); } -static void mix22to1 (float * samples, float level, float slev, float bias) +static void mix22to1 (sample_t * samples, sample_t level, sample_t slev, + sample_t bias) { int i; @@ -225,8 +230,8 @@ static void mix22to1 (float * samples, float level, float slev, float bias) (samples[i + 512] + samples[i + 768]) * slev + bias); } -static void mix32to1 (float * samples, float level, float clev, float slev, - float bias) +static void mix32to1 (sample_t * samples, sample_t level, + sample_t clev, sample_t slev, sample_t bias) { int i; @@ -236,7 +241,8 @@ static void mix32to1 (float * samples, float level, float clev, float slev, (samples[i + 768] + samples[i + 1024]) * slev + bias); } -static void mix1to2 (float * src, float * dest, float level, float bias) +static void mix1to2 (sample_t * src, sample_t * dest, + sample_t level, sample_t bias) { int i; @@ -244,10 +250,11 @@ static void mix1to2 (float * src, float * dest, float level, float bias) dest[i] = src[i] = src[i] * level + bias; } -static void mix3to2 (float * samples, float level, float clev, float bias) +static void mix3to2 (sample_t * samples, sample_t level, sample_t clev, + sample_t bias) { int i; - float common; + sample_t common; for (i = 0; i < 256; i++) { common = samples[i + 256] * clev + bias; @@ -256,11 +263,11 @@ static void mix3to2 (float * samples, float level, float clev, float bias) } } -static void mix21to2 (float * left, float * right, float level, float slev, - float bias) +static void mix21to2 (sample_t * left, sample_t * right, + sample_t level, sample_t slev, sample_t bias) { int i; - float common; + sample_t common; for (i = 0; i < 256; i++) { common = right[i + 256] * slev + bias; @@ -269,8 +276,8 @@ static void mix21to2 (float * left, float * right, float level, float slev, } } -static void mix11to1 (float * front, float * rear, float level, float slev, - float bias) +static void mix11to1 (sample_t * front, sample_t * rear, + sample_t level, sample_t slev, sample_t bias) { int i; @@ -278,11 +285,11 @@ static void mix11to1 (float * front, float * rear, float level, float slev, front[i] = front[i] * level + rear[i] * slev + bias; } -static void mix31to2 (float * samples, float level, float clev, float slev, - float bias) +static void mix31to2 (sample_t * samples, sample_t level, + sample_t clev, sample_t slev, sample_t bias) { int i; - float common; + sample_t common; for (i = 0; i < 256; i++) { common = samples[i + 256] * clev + samples[i + 768] * slev + bias; @@ -291,11 +298,11 @@ static void mix31to2 (float * samples, float level, float clev, float slev, } } -static void mix32to2 (float * samples, float level, float clev, float slev, - float bias) +static void mix32to2 (sample_t * samples, sample_t level, + sample_t clev, sample_t slev, sample_t bias) { int i; - float common; + sample_t common; for (i = 0; i < 256; i++) { common = samples[i + 256] * clev + bias; @@ -305,10 +312,11 @@ static void mix32to2 (float * samples, float level, float clev, float slev, } } -static void mix21toS (float * samples, float level, float level3db, float bias) +static void mix21toS (sample_t * samples, + sample_t level, sample_t level3db, sample_t bias) { int i; - float surround; + sample_t surround; for (i = 0; i < 256; i++) { surround = samples[i + 512] * level3db; @@ -317,10 +325,11 @@ static void mix21toS (float * samples, float level, float level3db, float bias) } } -static void mix22toS (float * samples, float level, float level3db, float bias) +static void mix22toS (sample_t * samples, + sample_t level, sample_t level3db, sample_t bias) { int i; - float surround; + sample_t surround; for (i = 0; i < 256; i++) { surround = (samples[i + 512] + samples[i + 768]) * level3db; @@ -329,10 +338,11 @@ static void mix22toS (float * samples, float level, float level3db, float bias) } } -static void mix31toS (float * samples, float level, float level3db, float bias) +static void mix31toS (sample_t * samples, + sample_t level, sample_t level3db, sample_t bias) { int i; - float common, surround; + sample_t common, surround; for (i = 0; i < 256; i++) { common = samples[i + 256] * level3db + bias; @@ -342,10 +352,11 @@ static void mix31toS (float * samples, float level, float level3db, float bias) } } -static void mix32toS (float * samples, float level, float level3db, float bias) +static void mix32toS (sample_t * samples, + sample_t level, sample_t level3db, sample_t bias) { int i; - float common, surround; + sample_t common, surround; for (i = 0; i < 256; i++) { common = samples[i + 256] * level3db + bias; @@ -355,8 +366,8 @@ static void mix32toS (float * samples, float level, float level3db, float bias) } } -void downmix (float * samples, int acmod, int output, float level, float bias, - float clev, float slev) +void downmix (sample_t * samples, int acmod, int output, + sample_t level, sample_t bias, sample_t clev, sample_t slev) { switch (CONVERT (acmod, output & AC3_CHANNEL_MASK)) { @@ -380,8 +391,7 @@ void downmix (float * samples, int acmod, int output, float level, float bias, break; case CONVERT (AC3_CHANNEL, AC3_CHANNEL2): - mix_1to1_b: - mix1to1 (samples + 256, level, bias); + move1to1 (samples + 256, samples, level, bias); break; case CONVERT (AC3_STEREO, AC3_MONO): @@ -490,7 +500,8 @@ void downmix (float * samples, int acmod, int output, float level, float bias, goto mix_3to3; mix11to1 (samples, samples + 768, level, level * slev, bias); mix11to1 (samples + 512, samples + 1024, level, level * slev, bias); - goto mix_1to1_b; + mix1to1 (samples + 256, level, bias); + break; case CONVERT (AC3_2F1R, AC3_2F2R): mix1to2 (samples + 512, samples + 768, level * LEVEL_3DB, bias); @@ -528,6 +539,8 @@ void downmix (float * samples, int acmod, int output, float level, float bias, move1to1 (samples + 768, samples + 512, level, bias); move1to1 (samples + 1024, samples + 768, level, bias); break; - } + + if (output & AC3_LFE) + mix1to1 (samples - 256, level, bias); } diff --git a/src/libac3/imdct.c b/src/libac3/imdct.c index 030026a54..7cc221c89 100644 --- a/src/libac3/imdct.c +++ b/src/libac3/imdct.c @@ -25,19 +25,17 @@ #include "config.h" #include <inttypes.h> -#include <stdlib.h> -#include <stdio.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[]); +void (* imdct_256) (sample_t data[], sample_t delay[]); +void (* imdct_512) (sample_t data[], sample_t delay[]); -typedef struct complex_s -{ - float real; - float imag; +typedef struct complex_s { + sample_t real; + sample_t imag; } complex_t; @@ -83,13 +81,13 @@ 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]; +static sample_t xcos1[128]; +static sample_t xsin1[128]; +static sample_t xcos2[64]; +static sample_t xsin2[64]; /* Windowing function for Modified DCT - Thank you acroread */ -float imdct_window[] = { +sample_t 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, @@ -146,7 +144,7 @@ static inline complex_t cmplx_mult(complex_t a, complex_t b) } void -imdct_do_512(float data[],float delay[]) +imdct_do_512(sample_t data[],sample_t delay[]) { int i,k; int p,q; @@ -154,14 +152,14 @@ imdct_do_512(float data[],float delay[]) int two_m; int two_m_plus_one; - float tmp_a_i; - float tmp_a_r; - float tmp_b_i; - float tmp_b_r; + sample_t tmp_a_i; + sample_t tmp_a_r; + sample_t tmp_b_i; + sample_t tmp_b_r; - float *data_ptr; - float *delay_ptr; - float *window_ptr; + sample_t *data_ptr; + sample_t *delay_ptr; + sample_t *window_ptr; // // 512 IMDCT with source and dest data in 'data' @@ -245,7 +243,7 @@ imdct_do_512(float data[],float delay[]) } void -imdct_do_256(float data[],float delay[]) +imdct_do_256(sample_t data[],sample_t delay[]) { int i,k; int p,q; @@ -253,14 +251,14 @@ imdct_do_256(float data[],float delay[]) int two_m; int two_m_plus_one; - float tmp_a_i; - float tmp_a_r; - float tmp_b_i; - float tmp_b_r; + sample_t tmp_a_i; + sample_t tmp_a_r; + sample_t tmp_b_i; + sample_t tmp_b_r; - float *data_ptr; - float *delay_ptr; - float *window_ptr; + sample_t *data_ptr; + sample_t *delay_ptr; + sample_t *window_ptr; complex_t *buf_1, *buf_2; @@ -375,9 +373,6 @@ imdct_do_256(float data[],float delay[]) 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 diff --git a/src/libac3/imdct_mlib.c b/src/libac3/imdct_mlib.c index eca0139ee..1ba783359 100644 --- a/src/libac3/imdct_mlib.c +++ b/src/libac3/imdct_mlib.c @@ -24,29 +24,28 @@ #ifdef LIBAC3_MLIB -#include <stdlib.h> -#include <stdio.h> -#include <math.h> - +#include <inttypes.h> #include <mlib_types.h> #include <mlib_status.h> #include <mlib_signal.h> +#include "ac3.h" +#include "ac3_internal.h" -extern float imdct_window[]; +extern sample_t imdct_window[]; void -imdct_do_512_mlib(float data[], float delay[]) +imdct_do_512_mlib(sample_t data[], sample_t delay[]) { - float *buf_real; - float *buf_imag; - float *data_ptr; - float *delay_ptr; - float *window_ptr; - float tmp[256] __attribute__ ((__aligned__ (16))); + sample_t *buf_real; + sample_t *buf_imag; + sample_t *data_ptr; + sample_t *delay_ptr; + sample_t *window_ptr; + sample_t tmp[256] __attribute__ ((__aligned__ (16))); int i; - memcpy(tmp, data, 256 * sizeof(float)); + memcpy(tmp, data, 256 * sizeof(sample_t)); if(mlib_SignalIMDCT_F32(tmp) != MLIB_SUCCESS) { fprintf(stderr, "mediaLib failure\n"); exit(-1); @@ -88,17 +87,17 @@ imdct_do_512_mlib(float data[], float delay[]) } void -imdct_do_256_mlib(float data[], float delay[]) +imdct_do_256_mlib(sample_t data[], sample_t delay[]) { - float *buf1_real, *buf1_imag; - float *buf2_real, *buf2_imag; - float *data_ptr; - float *delay_ptr; - float *window_ptr; - float tmp[256] __attribute__ ((__aligned__ (16))); + sample_t *buf1_real, *buf1_imag; + sample_t *buf2_real, *buf2_imag; + sample_t *data_ptr; + sample_t *delay_ptr; + sample_t *window_ptr; + sample_t tmp[256] __attribute__ ((__aligned__ (16))); int i; - memcpy(tmp, data, 256 * sizeof(float)); + memcpy(tmp, data, 256 * sizeof(sample_t)); if(mlib_SignalIMDCT_F32(tmp) != MLIB_SUCCESS) { fprintf(stderr, "mediaLib failure\n"); exit(-1); diff --git a/src/libac3/parse.c b/src/libac3/parse.c index 98ee09012..d200a2be1 100644 --- a/src/libac3/parse.c +++ b/src/libac3/parse.c @@ -22,18 +22,16 @@ * */ +#include "config.h" + #include <inttypes.h> #include <string.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 (); @@ -62,8 +60,8 @@ int ac3_syncinfo (uint8_t * buf, int * flags, // acmod, dsurmod and lfeon acmod = buf[6] >> 5; - *flags = (((buf[6] & 0xf8) == 0x50) ? AC3_DOLBY : acmod) | - ((buf[6] & lfeon[acmod]) ? AC3_LFE : 0); + *flags = ((((buf[6] & 0xf8) == 0x50) ? AC3_DOLBY : acmod) | + ((buf[6] & lfeon[acmod]) ? AC3_LFE : 0)); frmsizecod = buf[4] & 63; if (frmsizecod >= 38) @@ -86,11 +84,11 @@ int ac3_syncinfo (uint8_t * buf, int * flags, } } -int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, float * level, - float bias) +int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, + sample_t * level, sample_t bias, sample_t * delay) { - static float clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB}; - static float slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB}; + static sample_t clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB}; + static sample_t slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB}; int chaninfo; int acmod; @@ -114,12 +112,16 @@ int ac3_frame (ac3_state_t * state, uint8_t * buf, int * flags, float * level, state->output = downmix_init (acmod, *flags, level, state->clev, state->slev); - if (state->output < 0) { + if (state->output < 0) return 1; + if (state->lfeon && (*flags & AC3_LFE)) { + state->output |= AC3_LFE; + delay += 256; } *flags = state->output; state->level = *level; state->bias = bias; + state->delay = delay; chaninfo = !acmod; do { @@ -242,9 +244,9 @@ static inline int zero_snr_offsets (int nfchans, ac3_state_t * state) return 1; } -static float q_1[2]; -static float q_2[2]; -static float q_4; +static sample_t q_1[2]; +static sample_t q_2[2]; +static sample_t q_4; static int q_1_pointer; static int q_2_pointer; static int q_4_pointer; @@ -333,7 +335,7 @@ static inline int16_t dither_gen(void) return ((state * (int) (LEVEL_3DB * 256)) >> 8); } -static void coeff_get (float * coeff, uint8_t * exp, int8_t * bap, +static void coeff_get (sample_t * coeff, uint8_t * exp, int8_t * bap, int dither, int end) { int i; @@ -360,7 +362,7 @@ static void coeff_get (float * coeff, uint8_t * exp, int8_t * bap, i++; \ continue; -int ac3_block (ac3_state_t * state) +int ac3_block (ac3_state_t * state, sample_t samples[][256]) { static const uint8_t nfchans_tbl[8] = {2, 1, 2, 3, 3, 4, 4, 5}; static int rematrix_band[4] = {25, 37, 61, 253}; @@ -585,6 +587,9 @@ int ac3_block (ac3_state_t * state) bitstream_get (8); } + if (state->output & AC3_LFE) + samples++; // shift for LFE channel + q_1_pointer = q_2_pointer = q_4_pointer = -1; done_cpl = 0; @@ -597,7 +602,7 @@ int ac3_block (ac3_state_t * state) if (state->cplinu && state->chincpl[i]) { if (!done_cpl) { int i, i_end, bnd, sub_bnd, ch; - float cplcoeff; + sample_t cplcoeff; done_cpl = 1; @@ -649,7 +654,7 @@ int ac3_block (ac3_state_t * state) if (band > end) band = end; do { - float tmp0, tmp1; + sample_t tmp0, tmp1; tmp0 = samples[0][j]; tmp1 = samples[1][j]; @@ -660,23 +665,19 @@ int ac3_block (ac3_state_t * state) } 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 + coeff_get (samples[-1], state->lfe_exp, state->lfe_bap, 0, 7); + if (state->output & AC3_LFE) { + for (i = 7; i < 256; i++) + samples[-1][i] = 0; + imdct_512 (samples[-1], state->delay - 256); + } } for (i = 0; i < nfchans; i++) if (blksw[i]) - imdct_256 (samples[i], delay[i]); + imdct_256 (samples[i], state->delay + i * 256); else - imdct_512 (samples[i], delay[i]); - -#if 0 - if (state->lfeon) - imdct_512 (samples[5], delay[5]); -#endif + imdct_512 (samples[i], state->delay + i * 256); downmix (*samples, state->acmod, state->output, state->level, state->bias, state->clev, state->slev); diff --git a/src/libac3/tables.h b/src/libac3/tables.h index 5825f9326..28f030895 100644 --- a/src/libac3/tables.h +++ b/src/libac3/tables.h @@ -51,21 +51,21 @@ static int8_t exp_3[128] = { #define Q1 (0) #define Q2 ((2 << 15) / 3.0) -static const float q_1_0[ 32 ] = { +static const sample_t 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 ] = { +static const sample_t 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 ] = { +static const sample_t 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, @@ -82,7 +82,7 @@ static const float q_1_2[ 32 ] = { #define Q3 ((2 << 15) / 5.0) #define Q4 ((4 << 15) / 5.0) -static const float q_2_0[ 128 ] = { +static const sample_t 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, @@ -91,7 +91,7 @@ static const float q_2_0[ 128 ] = { 0,0,0 }; -static const float q_2_1[ 128 ] = { +static const sample_t 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, @@ -100,7 +100,7 @@ static const float q_2_1[ 128 ] = { 0,0,0 }; -static const float q_2_2[ 128 ] = { +static const sample_t 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, @@ -115,7 +115,7 @@ static const float q_2_2[ 128 ] = { #undef Q3 #undef Q4 -static const float q_3[8] = { +static const sample_t 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 }; @@ -132,7 +132,7 @@ static const float q_3[8] = { #define Q9 ((8 << 15) / 11.0) #define QA ((10 << 15) / 11.0) -static const float q_4_0[ 128 ] = { +static const sample_t 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, @@ -147,7 +147,7 @@ static const float q_4_0[ 128 ] = { 0, 0, 0, 0, 0, 0, 0 }; -static const float q_4_1[ 128 ] = { +static const sample_t 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, @@ -174,7 +174,7 @@ static const float q_4_1[ 128 ] = { #undef Q9 #undef QA -static const float q_5[16] = { +static const sample_t 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, @@ -183,37 +183,34 @@ static const float q_5[16] = { 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 sample_t scale_factor[25] = { + 0.000030517578125, + 0.0000152587890625, + 0.00000762939453125, + 0.000003814697265625, + 0.0000019073486328125, + 0.00000095367431640625, + 0.000000476837158203125, + 0.0000002384185791015625, + 0.00000011920928955078125, + 0.000000059604644775390625, + 0.0000000298023223876953125, + 0.00000001490116119384765625, + 0.000000007450580596923828125, + 0.0000000037252902984619140625, + 0.00000000186264514923095703125, + 0.000000000931322574615478515625, + 0.0000000004656612873077392578125, + 0.00000000023283064365386962890625, + 0.000000000116415321826934814453125, + 0.0000000000582076609134674072265625, + 0.00000000002910383045673370361328125, + 0.000000000014551915228366851806640625, + 0.0000000000072759576141834259033203125, + 0.00000000000363797880709171295166015625, + 0.000000000001818989403545856475830078125 }; -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, diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c index 72909c58e..0bd12e5e2 100644 --- a/src/libac3/xine_decoder.c +++ b/src/libac3/xine_decoder.c @@ -17,15 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.15 2001/07/17 15:22:20 jkeil Exp $ + * $Id: xine_decoder.c,v 1.16 2001/07/20 22:37:56 guenter Exp $ * * stuff needed to turn libac3 into a xine decoder plugin */ -/* - * FIXME: libac3 uses global variables (that are written to) - */ - #include <stdlib.h> #include <unistd.h> @@ -42,9 +38,7 @@ #define FRAME_SIZE 4096 -stream_samples_t samples; - -/* int ac3file; */ +int ac3file; typedef struct ac3dec_decoder_s { audio_decoder_t audio_decoder; @@ -63,11 +57,14 @@ typedef struct ac3dec_decoder_s { int ac3_bit_rate; int ac3_sample_rate; float ac3_level; + int have_lfe; int ac3_flags_map[8]; int ao_flags_map[8]; - int16_t samples [6 * 256]; + int16_t int_samples [6 * 256]; + sample_t delay[6*256]; + sample_t samples[6][256]; ao_functions_t *audio_out; int audio_caps; @@ -125,7 +122,14 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_STEREO; /* find best mode */ - if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { + if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { + + this->ac3_flags_map[AC3_2F2R] = AC3_2F2R; + this->ac3_flags_map[AC3_3F2R] = AC3_3F2R | AC3_LFE; + this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { this->ac3_flags_map[AC3_2F2R] = AC3_2F2R; this->ac3_flags_map[AC3_3F2R] = AC3_3F2R; @@ -167,7 +171,7 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { for (i = 0; i<8; i++) this->ac3_flags_map[i] |= AC3_ADJUST_LEVEL; */ - /* ac3file = open ("test.ac3", O_CREAT); */ + ac3file = open ("test.ac3", O_CREAT | O_WRONLY | O_TRUNC, 0644); } @@ -214,12 +218,16 @@ static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) { if (ac3_frame (&this->ac3_state, this->frame_buffer, &ac3_output_flags, - &level, 384)) { + &level, 384, this->delay)) { printf ("libac3: ac3_frame error\n"); return; } - output_mode = this->ao_flags_map[ac3_output_flags]; + this->have_lfe = ac3_output_flags & AC3_LFE; + if (this->have_lfe) + output_mode = AO_CAP_MODE_5_1CHANNEL; + else + output_mode = this->ao_flags_map[ac3_output_flags]; /* * (re-)open output device @@ -250,31 +258,39 @@ static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) { */ for (i = 0; i < 6; i++) { - if (ac3_block (&this->ac3_state)) { + if (ac3_block (&this->ac3_state, this->samples)) { printf ("libac3: ac3_block error\n"); - return; + return; } switch (output_mode) { case AO_CAP_MODE_MONO: - float_to_int (*samples, this->samples, 1); + float_to_int (this->samples[0], this->int_samples, 1); break; case AO_CAP_MODE_STEREO: - float_to_int (samples[0], this->samples, 2); - float_to_int (samples[1], this->samples+1, 2); + float_to_int (this->samples[0], this->int_samples, 2); + float_to_int (this->samples[1], this->int_samples+1, 2); break; case AO_CAP_MODE_4CHANNEL: - float_to_int (samples[0], this->samples, 4); - float_to_int (samples[1], this->samples+1, 4); - float_to_int (samples[2], this->samples+2, 4); - float_to_int (samples[3], this->samples+3, 4); + float_to_int (this->samples[0], this->int_samples, 4); + float_to_int (this->samples[1], this->int_samples+1, 4); + float_to_int (this->samples[2], this->int_samples+2, 4); + float_to_int (this->samples[3], this->int_samples+3, 4); break; case AO_CAP_MODE_5CHANNEL: - float_to_int (samples[0], this->samples, 5); - float_to_int (samples[1], this->samples+1, 5); - float_to_int (samples[2], this->samples+2, 5); - float_to_int (samples[3], this->samples+3, 5); - float_to_int (samples[4], this->samples+4, 5); + float_to_int (this->samples[0], this->int_samples, 5); + float_to_int (this->samples[1], this->int_samples+1, 5); + float_to_int (this->samples[2], this->int_samples+2, 5); + float_to_int (this->samples[3], this->int_samples+3, 5); + float_to_int (this->samples[4], this->int_samples+4, 5); + break; + case AO_CAP_MODE_5_1CHANNEL: + float_to_int (this->samples[0], this->int_samples, 6); + float_to_int (this->samples[1], this->int_samples+1, 6); + float_to_int (this->samples[2], this->int_samples+2, 6); + float_to_int (this->samples[3], this->int_samples+3, 6); + float_to_int (this->samples[4], this->int_samples+4, 6); + float_to_int (this->samples[5], this->int_samples+5, 6); break; default: printf ("libac3: help - unsupported mode %08x\n", output_mode); @@ -283,7 +299,7 @@ static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) { /* output decoded samples */ this->audio_out->write_audio_data (this->audio_out, - this->samples, + this->int_samples, 256, pts); pts = 0; @@ -341,6 +357,7 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if ( (this->sync_todo == 0) && (this->frame_todo == 0) ) { ac3dec_decode_frame (this, this->pts); + write (ac3file, this->frame_buffer, this->frame_length); this->pts = 0; this->sync_todo = 7; this->syncword = 0; @@ -374,7 +391,13 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { &this->ac3_flags, &this->ac3_sample_rate, &this->ac3_bit_rate); - this->frame_todo = this->frame_length - 7; + if (this->frame_length) { + this->frame_todo = this->frame_length - 7; + } else { + this->sync_todo = 7; + this->syncword = 0; + printf ("libac3: skip frame of zero length\n"); + } } @@ -406,7 +429,7 @@ void ac3dec_close (audio_decoder_t *this_gen) { this->output_open = 0; - /* close (ac3file); */ + close (ac3file); } static char *ac3dec_get_id(void) { diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index e66419271..c3e1fffbc 100644 --- a/src/xine-engine/audio_out.h +++ b/src/xine-engine/audio_out.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_out.h,v 1.7 2001/07/18 21:38:17 f1rmb Exp $ + * $Id: audio_out.h,v 1.8 2001/07/20 22:37:56 guenter Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -132,17 +132,19 @@ struct ao_functions_s { #define AO_CAP_NOCAP 0x00000000 /* driver has no capabilities */ #define AO_CAP_MODE_AC3 0x00000001 /* driver supports AC3 output */ #define AO_CAP_MODE_AC5 0x00000002 /* driver supports AC5 output */ -/* 1 sample == 2 bytes */ +/* 1 sample == 2 bytes (C) */ #define AO_CAP_MODE_MONO 0x00000004 /* driver supports mono output */ - /* 1 sample == 4 bytes */ +/* 1 sample == 4 bytes (L,R) */ #define AO_CAP_MODE_STEREO 0x00000008 /* driver supports stereo output */ - /* 1 sample == 8 bytes */ +/* 1 sample == 8 bytes (L,R,LR,RR) */ #define AO_CAP_MODE_4CHANNEL 0x00000010 /* driver supports 4 channels */ -/* 1 sample == 10 bytes */ +/* 1 sample == 10 bytes (L,R,LR,RR,C) */ #define AO_CAP_MODE_5CHANNEL 0x00000020 /* driver supports 5 channels */ -#define AO_CAP_MIXER_VOL 0x00000040 /* driver supports mixer control */ -#define AO_CAP_PCM_VOL 0x00000080 /* driver supports pcm control */ -#define AO_CAP_MUTE_VOL 0x00000100 /* driver can mute volume */ +/* 1 sample == 12 bytes (L,R,LR,RR,C,LFE) */ +#define AO_CAP_MODE_5_1CHANNEL 0x00000040 /* driver supports 5.1 channels */ +#define AO_CAP_MIXER_VOL 0x00000080 /* driver supports mixer control */ +#define AO_CAP_PCM_VOL 0x00000100 /* driver supports pcm control */ +#define AO_CAP_MUTE_VOL 0x00000200 /* driver can mute volume */ /* properties supported by get/set_property() */ #define AO_PROP_MIXER_VOL 0 |