Diffstat (limited to 'core/multimedia/opieplayer/libmad/mad.h') (more/less context) (show whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmad/mad.h | 292 |
1 files changed, 213 insertions, 79 deletions
diff --git a/core/multimedia/opieplayer/libmad/mad.h b/core/multimedia/opieplayer/libmad/mad.h index 9db9da3..9ef6cc8 100644 --- a/core/multimedia/opieplayer/libmad/mad.h +++ b/core/multimedia/opieplayer/libmad/mad.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder - * Copyright (C) 2000-2001 Robert Leslie + * libmad - MPEG audio decoder library + * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify @@ -18,12 +18,21 @@ * * If you would like to negotiate alternate licensing terms, you may do - * so by contacting the author: Robert Leslie <rob@mars.org> + * so by contacting: Underbit Technologies, Inc. <info@underbit.com> */ +# ifdef __cplusplus +extern "C" { +# endif + +# define FPM_INTEL + + + # define SIZEOF_INT 4 # define SIZEOF_LONG 4 # define SIZEOF_LONG_LONG 8 -/* Id: version.h,v 1.16 2001/04/05 04:57:11 rob Exp */ + +/* Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp */ # ifndef LIBMAD_VERSION_H @@ -31,6 +40,6 @@ # define MAD_VERSION_MAJOR 0 -# define MAD_VERSION_MINOR 13 -# define MAD_VERSION_PATCH 0 +# define MAD_VERSION_MINOR 15 +# define MAD_VERSION_PATCH 1 # define MAD_VERSION_EXTRA " (beta)" @@ -43,7 +52,7 @@ MAD_VERSION_EXTRA -# define MAD_PUBLISHYEAR "2000-2001" -# define MAD_AUTHOR "Robert Leslie" -# define MAD_EMAIL "rob@mars.org" +# define MAD_PUBLISHYEAR "2000-2004" +# define MAD_AUTHOR "Underbit Technologies, Inc." +# define MAD_EMAIL "info@underbit.com" extern char const mad_version[]; @@ -54,5 +63,5 @@ extern char const mad_build[]; # endif -/* Id: fixed.h,v 1.23 2001/04/05 04:57:11 rob Exp */ +/* Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp */ # ifndef LIBMAD_FIXED_H @@ -71,4 +80,16 @@ typedef unsigned long mad_fixed64lo_t; # endif +# if defined(_MSC_VER) +# define mad_fixed64_t signed __int64 +# elif 1 || defined(__GNUC__) +# define mad_fixed64_t signed long long +# endif + +# if defined(FPM_FLOAT) +typedef double mad_sample_t; +# else +typedef mad_fixed_t mad_sample_t; +# endif + /* * Fixed-point format: 0xABBBBBBB @@ -131,18 +152,29 @@ typedef unsigned long mad_fixed64lo_t; # define mad_f_sub(x, y) ((x) - (y)) -# if defined(FPM_64BIT) +# if defined(FPM_FLOAT) +# error "FPM_FLOAT not yet supported" + +# undef MAD_F +# define MAD_F(x) mad_f_todouble(x) + +# define mad_f_mul(x, y) ((x) * (y)) +# define mad_f_scale64 + +# undef ASO_ZEROCHECK + +# elif defined(FPM_64BIT) /* - * This version should be the most accurate if 64-bit (long long) types are - * supported by the compiler, although it may not be the most efficient. + * This version should be the most accurate if 64-bit types are supported by + * the compiler, although it may not be the most efficient. */ # if defined(OPT_ACCURACY) # define mad_f_mul(x, y) \ ((mad_fixed_t) \ - ((((signed long long) (x) * (y)) + \ + ((((mad_fixed64_t) (x) * (y)) + \ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) # else # define mad_f_mul(x, y) \ - ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS)) + ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS)) # endif @@ -153,4 +185,27 @@ typedef unsigned long mad_fixed64lo_t; # elif defined(FPM_INTEL) +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4035) /* no return value */ +static __forceinline +mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) +{ + enum { + fracbits = MAD_F_FRACBITS + }; + + __asm { + mov eax, x + imul y + shrd eax, edx, fracbits + } + + /* implicit return of eax */ +} +# pragma warning(pop) + +# define mad_f_mul mad_f_mul_inline +# define mad_f_scale64 +# else /* * This Intel version is fast and accurate; the disposition of the least @@ -199,4 +254,19 @@ typedef unsigned long mad_fixed64lo_t; __result; \ }) +# elif defined(OPT_INTEL) +/* + * Alternate Intel scaling that may or may not perform better. + */ +# define mad_f_scale64(hi, lo) \ + ({ mad_fixed_t __result; \ + asm ("shrl %3,%1\n\t" \ + "shll %4,%2\n\t" \ + "orl %2,%1" \ + : "=rm" (__result) \ + : "0" (lo), "r" (hi), \ + "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \ + : "cc"); \ + __result; \ + }) # else # define mad_f_scale64(hi, lo) \ @@ -211,4 +281,5 @@ typedef unsigned long mad_fixed64lo_t; # define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif /* --- ARM ----------------------------------------------------------------- */ @@ -222,10 +293,6 @@ typedef unsigned long mad_fixed64lo_t; # if 1 /* - * There's a bug somewhere, possibly in the compiler, that sometimes makes - * this necessary instead of the default implementation via MAD_F_MLX and - * mad_f_scale64. It may be related to the use (or lack) of - * -finline-functions and/or -fstrength-reduce. - * - * This is also apparently faster than MAD_F_MLX/mad_f_scale64. + * This is faster than the default implementation via MAD_F_MLX() and + * mad_f_scale64(). */ # define mad_f_mul(x, y) \ @@ -254,9 +321,16 @@ typedef unsigned long mad_fixed64lo_t; : "%r" (x), "r" (y)) +# define MAD_F_MLN(hi, lo) \ + asm ("rsbs %0, %2, #0\n\t" \ + "rsc %1, %3, #0" \ + : "=r" (lo), "=r" (hi) \ + : "0" (lo), "1" (hi) \ + : "cc") + # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("movs %0, %1, lsr %3\n\t" \ "adc %0, %0, %2, lsl %4" \ - : "=r" (__result) \ + : "=&r" (__result) \ : "r" (lo), "r" (hi), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ @@ -326,15 +400,22 @@ typedef unsigned long mad_fixed64lo_t; /* - * This PowerPC version is tuned for the 4xx embedded processors. It is - * effectively a tuned version of FPM_64BIT. It is a little faster and just - * as accurate. The disposition of the least significant bit depends on - * OPT_ACCURACY via mad_f_scale64(). + * This PowerPC version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ - asm ("mulhw %1, %2, %3\n\t" \ - "mullw %0, %2, %3" \ - : "=&r" (lo), "=&r" (hi) \ - : "%r" (x), "r" (y)) + do { \ + asm ("mullw %0,%1,%2" \ + : "=r" (lo) \ + : "%r" (x), "r" (y)); \ + asm ("mulhw %0,%1,%2" \ + : "=r" (hi) \ + : "%r" (x), "r" (y)); \ + } \ + while (0) +# if defined(OPT_ACCURACY) +/* + * This gives best accuracy but is not very fast. + */ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ @@ -344,26 +425,28 @@ typedef unsigned long mad_fixed64lo_t; "adde %1, %4, %5" \ : "=r" (lo), "=r" (hi) \ - : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \ + : "%r" (lo), "r" (__lo), \ + "%r" (hi), "r" (__hi) \ + : "xer"); \ }) +# endif # if defined(OPT_ACCURACY) /* - * This is accurate and ~2 - 2.5 times slower than the unrounded version. - * - * The __volatile__ improves the generated code by another 5% (fewer spills - * to memory); eventually they should be removed. + * This is slower than the truncating version below it. */ # define mad_f_scale64(hi, lo) \ - ({ mad_fixed_t __result; \ - mad_fixed64hi_t __hi_; \ - mad_fixed64lo_t __lo_; \ - asm __volatile__ ("addc %0, %2, %4\n\t" \ - "addze %1, %3" \ - : "=r" (__lo_), "=r" (__hi_) \ - : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \ - asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ - "rlwimi %0, %1,32-%3,%3,31" \ - : "=&r" (__result) \ - : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \ + ({ mad_fixed_t __result, __round; \ + asm ("rotrwi %0,%1,%2" \ + : "=r" (__result) \ + : "r" (lo), "i" (MAD_F_SCALEBITS)); \ + asm ("extrwi %0,%1,1,0" \ + : "=r" (__round) \ + : "r" (__result)); \ + asm ("insrwi %0,%1,%2,0" \ + : "+r" (__result) \ + : "r" (hi), "i" (MAD_F_SCALEBITS)); \ + asm ("add %0,%1,%2" \ + : "=r" (__result) \ + : "%r" (__result), "r" (__round)); \ __result; \ }) @@ -371,11 +454,13 @@ typedef unsigned long mad_fixed64lo_t; # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ - asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ - "rlwimi %0, %1,32-%3,%3,31" \ + asm ("rotrwi %0,%1,%2" \ : "=r" (__result) \ - : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \ + : "r" (lo), "i" (MAD_F_SCALEBITS)); \ + asm ("insrwi %0,%1,%2,0" \ + : "+r" (__result) \ + : "r" (hi), "i" (MAD_F_SCALEBITS)); \ __result; \ }) -# endif /* OPT_ACCURACY */ +# endif # define MAD_F_SCALEBITS MAD_F_FRACBITS @@ -394,6 +479,10 @@ typedef unsigned long mad_fixed64lo_t; * Pre-rounding is required to stay within the limits of compliance. */ +# if defined(OPT_SPEED) +# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) +# else # define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ (((y) + (1L << 15)) >> 16)) +# endif /* ------------------------------------------------------------------------- */ @@ -407,6 +496,6 @@ typedef unsigned long mad_fixed64lo_t; # if !defined(mad_f_mul) # define mad_f_mul(x, y) \ - ({ mad_fixed64hi_t __hi; \ - mad_fixed64lo_t __lo; \ + ({ register mad_fixed64hi_t __hi; \ + register mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ mad_f_scale64(__hi, __lo); \ @@ -417,4 +506,5 @@ typedef unsigned long mad_fixed64lo_t; # define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) # define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) +# define MAD_F_MLN(hi, lo) ((lo) = -(lo)) # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # endif @@ -424,4 +514,8 @@ typedef unsigned long mad_fixed64lo_t; # endif +# if !defined(MAD_F_MLN) +# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi)) +# endif + # if !defined(MAD_F_MLZ) # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) @@ -443,11 +537,12 @@ typedef unsigned long mad_fixed64lo_t; # endif -/* miscellaneous C routines */ +/* C routines */ mad_fixed_t mad_f_abs(mad_fixed_t); +mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t); # endif -/* Id: bit.h,v 1.7 2001/04/05 04:57:11 rob Exp */ +/* Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp */ # ifndef LIBMAD_BIT_H @@ -478,5 +573,5 @@ unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); # endif -/* Id: timer.h,v 1.10 2001/04/05 04:57:11 rob Exp */ +/* Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp */ # ifndef LIBMAD_TIMER_H @@ -540,5 +635,5 @@ enum mad_units { }; -# define mad_timer_reset(timer) (*(timer) = mad_timer_zero) +# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) int mad_timer_compare(mad_timer_t, mad_timer_t); @@ -560,13 +655,16 @@ void mad_timer_string(mad_timer_t, char *, char const *, # endif -/* Id: stream.h,v 1.12 2001/04/10 05:18:21 rob Exp */ +/* Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp */ # ifndef LIBMAD_STREAM_H # define LIBMAD_STREAM_H + # define MAD_BUFFER_GUARD 8 # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) enum mad_error { + MAD_ERROR_NONE = 0x0000, /* no error */ + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ @@ -583,4 +681,5 @@ enum mad_error { MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ @@ -621,9 +720,9 @@ struct mad_stream { enum { MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ - MAD_OPTION_HALFSAMPLERATE = 0x0002, /* generate PCM at 1/2 sample rate */ + MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ # if 0 /* not yet implemented */ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ - MAD_OPTION_SINGLECHANNEL = 0x0030, /* combine channels */ + MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ # endif }; @@ -632,5 +731,6 @@ void mad_stream_init(struct mad_stream *); void mad_stream_finish(struct mad_stream *); -# define mad_stream_options(stream, opts) ((stream)->options = (opts)) +# define mad_stream_options(stream, opts) \ + ((void) ((stream)->options = (opts))) void mad_stream_buffer(struct mad_stream *, @@ -640,11 +740,14 @@ void mad_stream_skip(struct mad_stream *, unsigned long); int mad_stream_sync(struct mad_stream *); +char const *mad_stream_errorstr(struct mad_stream const *); + # endif -/* Id: frame.h,v 1.13 2001/04/05 04:57:11 rob Exp */ +/* Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp */ # ifndef LIBMAD_FRAME_H # define LIBMAD_FRAME_H + enum mad_layer { MAD_LAYER_I = 1, /* Layer I */ @@ -663,8 +766,8 @@ enum mad_emphasis { MAD_EMPHASIS_NONE = 0, /* no emphasis */ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ - MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ + MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ }; -struct mad_frame { struct mad_header { enum mad_layer layer; /* audio layer (1, 2, or 3) */ @@ -683,5 +786,8 @@ struct mad_frame { mad_timer_t duration; /* audio playing time of frame */ - } header; +}; + +struct mad_frame { + struct mad_header header; /* MPEG audio header */ int options; /* decoding options (from stream) */ @@ -735,9 +841,17 @@ void mad_frame_mute(struct mad_frame *); # endif -/* Id: synth.h,v 1.8 2001/04/05 04:57:11 rob Exp */ +/* Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp */ # ifndef LIBMAD_SYNTH_H # define LIBMAD_SYNTH_H + +struct mad_pcm { + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ +}; + struct mad_synth { mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ @@ -746,10 +860,22 @@ struct mad_synth { unsigned int phase; /* current processing phase */ - struct mad_pcm { - unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned short channels; /* number of channels */ - unsigned short length; /* number of samples per channel */ - mad_fixed_t samples[2][1152]; /* PCM output samples */ - } pcm; + struct mad_pcm pcm; /* PCM output */ +}; + +/* single channel PCM selector */ +enum { + MAD_PCM_CHANNEL_SINGLE = 0 +}; + +/* dual channel PCM selector */ +enum { + MAD_PCM_CHANNEL_DUAL_1 = 0, + MAD_PCM_CHANNEL_DUAL_2 = 1 +}; + +/* stereo PCM selector */ +enum { + MAD_PCM_CHANNEL_STEREO_LEFT = 0, + MAD_PCM_CHANNEL_STEREO_RIGHT = 1 }; @@ -764,9 +890,10 @@ void mad_synth_frame(struct mad_synth *, struct mad_frame const *); # endif -/* Id: decoder.h,v 1.9 2001/04/05 04:57:11 rob Exp */ +/* Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp */ # ifndef LIBMAD_DECODER_H # define LIBMAD_DECODER_H + enum mad_decoder_mode { MAD_DECODER_MODE_SYNC = 0, @@ -775,8 +902,8 @@ enum mad_decoder_mode { enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, - MAD_FLOW_STOP = 0x0010, - MAD_FLOW_BREAK = 0x0011, - MAD_FLOW_IGNORE = 0x0020 + MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ + MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ + MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ + MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ }; @@ -802,5 +929,6 @@ struct mad_decoder { enum mad_flow (*input_func)(void *, struct mad_stream *); enum mad_flow (*header_func)(void *, struct mad_header const *); - enum mad_flow (*filter_func)(void *, struct mad_frame *); + enum mad_flow (*filter_func)(void *, + struct mad_stream const *, struct mad_frame *); enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *); @@ -812,5 +940,7 @@ void mad_decoder_init(struct mad_decoder *, void *, enum mad_flow (*)(void *, struct mad_stream *), enum mad_flow (*)(void *, struct mad_header const *), - enum mad_flow (*)(void *, struct mad_frame *), + enum mad_flow (*)(void *, + struct mad_stream const *, + struct mad_frame *), enum mad_flow (*)(void *, struct mad_header const *, @@ -822,5 +952,6 @@ void mad_decoder_init(struct mad_decoder *, void *, int mad_decoder_finish(struct mad_decoder *); -# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts)) +# define mad_decoder_options(decoder, opts) \ + ((void) ((decoder)->options = (opts))) int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); @@ -829,2 +960,5 @@ int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); # endif +# ifdef __cplusplus +} +# endif |