diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libmad/D.dat | 4 | ||||
-rw-r--r-- | src/libmad/Makefile.am | 9 | ||||
-rwxr-xr-x | src/libmad/bit.c | 41 | ||||
-rw-r--r-- | src/libmad/bit.h | 4 | ||||
-rw-r--r-- | src/libmad/fixed.c | 4 | ||||
-rwxr-xr-x | src/libmad/fixed.h | 102 | ||||
-rwxr-xr-x | src/libmad/frame.c | 9 | ||||
-rwxr-xr-x | src/libmad/frame.h | 62 | ||||
-rw-r--r-- | src/libmad/global.h | 17 | ||||
-rw-r--r-- | src/libmad/huffman.c | 58 | ||||
-rw-r--r-- | src/libmad/huffman.h | 24 | ||||
-rw-r--r-- | src/libmad/imdct_l_arm.S | 1000 | ||||
-rw-r--r-- | src/libmad/imdct_s.dat | 4 | ||||
-rwxr-xr-x | src/libmad/layer12.c | 4 | ||||
-rw-r--r-- | src/libmad/layer12.h | 4 | ||||
-rwxr-xr-x | src/libmad/layer3.c | 154 | ||||
-rw-r--r-- | src/libmad/layer3.h | 4 | ||||
-rw-r--r-- | src/libmad/mad.h | 832 | ||||
-rw-r--r-- | src/libmad/qc_table.dat | 4 | ||||
-rw-r--r-- | src/libmad/rq_table.dat | 4 | ||||
-rw-r--r-- | src/libmad/sf_table.dat | 4 | ||||
-rw-r--r-- | src/libmad/stream.c | 43 | ||||
-rw-r--r-- | src/libmad/stream.h | 15 | ||||
-rwxr-xr-x | src/libmad/synth.c | 330 | ||||
-rw-r--r-- | src/libmad/synth.h | 35 | ||||
-rwxr-xr-x | src/libmad/timer.c | 68 | ||||
-rwxr-xr-x | src/libmad/timer.h | 6 | ||||
-rw-r--r-- | src/libmad/version.c | 91 | ||||
-rw-r--r-- | src/libmad/version.h | 47 |
29 files changed, 1716 insertions, 1267 deletions
diff --git a/src/libmad/D.dat b/src/libmad/D.dat index ac0d43eb5..8dd6feb25 100644 --- a/src/libmad/D.dat +++ b/src/libmad/D.dat @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: D.dat,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: D.dat,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ /* diff --git a/src/libmad/Makefile.am b/src/libmad/Makefile.am index 8538636d8..87d75a4a0 100644 --- a/src/libmad/Makefile.am +++ b/src/libmad/Makefile.am @@ -1,3 +1,5 @@ +CFLAGS = @CFLAGS@ -DOPT_SPEED + LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic libdir = $(XINE_PLUGINDIR) @@ -5,14 +7,15 @@ libdir = $(XINE_PLUGINDIR) lib_LTLIBRARIES = xineplug_decode_mad.la xineplug_decode_mad_la_SOURCES = bit.c frame.c layer3.c timer.c \ - huffman.c stream.c fixed.c layer12.c synth.c xine_decoder.c + huffman.c stream.c fixed.c layer12.c synth.c version.c \ + xine_decoder.c xineplug_decode_mad_la_LDFLAGS = -avoid-version -module -noinst_HEADERS = D.dat huffman.h mad.h stream.h fixed.h \ +noinst_HEADERS = D.dat huffman.h stream.h fixed.h \ imdct_s.dat qc_table.dat synth.h bit.h frame.h layer12.h \ - rq_table.dat timer.h global.h layer3.h sf_table.dat + rq_table.dat timer.h global.h layer3.h sf_table.dat version.h ## diff --git a/src/libmad/bit.c b/src/libmad/bit.c index e7004ef2f..200e3ab77 100755 --- a/src/libmad/bit.c +++ b/src/libmad/bit.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: bit.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: bit.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -197,22 +197,39 @@ void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, unsigned short init) { - register unsigned int crc, data; + register unsigned int crc; -# if CHAR_BIT == 8 - for (crc = init; len >= 8; len -= 8) { - crc = (crc << 8) ^ - crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + for (crc = init; len >= 32; len -= 32) { + register unsigned long data; + + data = mad_bit_read(&bitptr, 32); + + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; + } + + switch (len / 8) { + case 3: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + case 2: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + case 1: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + + len %= 8; + + case 0: break; } -# else - crc = init; -# endif while (len--) { - data = mad_bit_read(&bitptr, 1) ^ (crc >> 15); + register unsigned int msb; + + msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); crc <<= 1; - if (data & 1) + if (msb & 1) crc ^= CRC_POLY; } diff --git a/src/libmad/bit.h b/src/libmad/bit.h index 9549612e0..641b026be 100644 --- a/src/libmad/bit.h +++ b/src/libmad/bit.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: bit.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: bit.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_BIT_H diff --git a/src/libmad/fixed.c b/src/libmad/fixed.c index 45662e45d..d02a7299e 100644 --- a/src/libmad/fixed.c +++ b/src/libmad/fixed.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: fixed.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: fixed.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H diff --git a/src/libmad/fixed.h b/src/libmad/fixed.h index 71d22cc5d..58ad24d2d 100755 --- a/src/libmad/fixed.h +++ b/src/libmad/fixed.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,12 +16,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: fixed.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: fixed.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_FIXED_H # define LIBMAD_FIXED_H +/* sizeof(int) must be greater or equal to 4 for every + plataform we intend to compile xine for. */ +#define SIZEOF_INT 4 # if SIZEOF_INT >= 4 typedef signed int mad_fixed_t; @@ -34,6 +37,18 @@ typedef signed long mad_fixed64hi_t; 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 * A == whole part (sign + 3 bits) @@ -94,20 +109,31 @@ typedef unsigned long mad_fixed64lo_t; # define mad_f_add(x, y) ((x) + (y)) # 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 # define MAD_F_SCALEBITS MAD_F_FRACBITS @@ -116,21 +142,44 @@ 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 * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ -# define MAD_F_MLX(hi, lo, x, y) \ +# define MAD_F_MLX(hi, lo, x, y) \ asm ("imull %3" \ : "=a" (lo), "=d" (hi) \ : "%a" (x), "rm" (y) \ : "cc") -# if defined(OPT_ACCURACY) +# if defined(OPT_ACCURACY) /* * This gives best accuracy but is not very fast. */ -# define MAD_F_MLA(hi, lo, x, y) \ +# define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ @@ -140,13 +189,13 @@ typedef unsigned long mad_fixed64lo_t; : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ : "cc"); \ }) -# endif /* OPT_ACCURACY */ +# endif /* OPT_ACCURACY */ -# if defined(OPT_ACCURACY) +# if defined(OPT_ACCURACY) /* * Surprisingly, this is faster than SHRD followed by ADC. */ -# define mad_f_scale64(hi, lo) \ +# define mad_f_scale64(hi, lo) \ ({ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ mad_fixed_t __result; \ @@ -162,8 +211,8 @@ typedef unsigned long mad_fixed64lo_t; : "cc"); \ __result; \ }) -# else -# define mad_f_scale64(hi, lo) \ +# else +# define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ @@ -171,9 +220,10 @@ typedef unsigned long mad_fixed64lo_t; : "cc"); \ __result; \ }) -# endif /* OPT_ACCURACY */ +# endif /* OPT_ACCURACY */ -# define MAD_F_SCALEBITS MAD_F_FRACBITS +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif /* --- ARM ----------------------------------------------------------------- */ @@ -217,6 +267,13 @@ typedef unsigned long mad_fixed64lo_t; : "+r" (lo), "+r" (hi) \ : "%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" \ @@ -357,8 +414,12 @@ typedef unsigned long mad_fixed64lo_t; * * Pre-rounding is required to stay within the limits of compliance. */ -# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ +# 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 /* ------------------------------------------------------------------------- */ @@ -380,6 +441,7 @@ typedef unsigned long mad_fixed64lo_t; # if !defined(MAD_F_MLA) # 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 @@ -387,6 +449,10 @@ typedef unsigned long mad_fixed64lo_t; # define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) # 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)) # endif diff --git a/src/libmad/frame.c b/src/libmad/frame.c index c75a49f48..537bc8da2 100755 --- a/src/libmad/frame.c +++ b/src/libmad/frame.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: frame.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: frame.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -373,7 +373,7 @@ int mad_header_decode(struct mad_header *header, struct mad_stream *stream) /* calculate free bit rate */ if (header->bitrate == 0) { - if ((!stream->sync || !stream->freerate) && + if ((stream->freerate == 0 || !stream->sync) && free_bitrate(stream, header) == -1) goto fail; @@ -439,9 +439,8 @@ int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) /* error_check() */ if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && - mad_header_decode(&frame->header, stream) == -1) { + mad_header_decode(&frame->header, stream) == -1) goto fail; - } /* audio_data() */ diff --git a/src/libmad/frame.h b/src/libmad/frame.h index 599d99f0c..b68777168 100755 --- a/src/libmad/frame.h +++ b/src/libmad/frame.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: frame.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: frame.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_FRAME_H @@ -45,24 +45,26 @@ enum mad_emphasis { MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */ }; -struct mad_frame { - struct mad_header { - enum mad_layer layer; /* audio layer (1, 2, or 3) */ - enum mad_mode mode; /* channel mode (see above) */ - int mode_extension; /* additional mode info */ - enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ +struct mad_header { + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned long bitrate; /* stream bitrate (bps) */ - unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ - unsigned short crc_check; /* frame CRC accumulator */ - unsigned short crc_target; /* final target CRC checksum */ + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ - int flags; /* flags (see below) */ - int private_bits; /* private bits (see below) */ + mad_timer_t duration; /* audio playing time of 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) */ @@ -77,26 +79,26 @@ struct mad_frame { ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) enum { - MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ - MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ - MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ - MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ - MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ - MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ - MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ - MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ - MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ - MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ - MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ - MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ }; enum { - MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ - MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ }; void mad_header_init(struct mad_header *); diff --git a/src/libmad/global.h b/src/libmad/global.h index 6677092c6..4bde6a82a 100644 --- a/src/libmad/global.h +++ b/src/libmad/global.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: global.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: global.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_GLOBAL_H @@ -42,4 +42,17 @@ # define OPT_SSO 1 # endif +# if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) && \ + defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK) +# define USE_ASYNC +# endif + +# if !defined(HAVE_ASSERT_H) +# if defined(NDEBUG) +# define assert(x) /* nothing */ +# else +# define assert(x) do { if (!(x)) abort(); } while (0) +# endif +# endif + # endif diff --git a/src/libmad/huffman.c b/src/libmad/huffman.c index 602003e80..58b8e7014 100644 --- a/src/libmad/huffman.c +++ b/src/libmad/huffman.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: huffman.c,v 1.2 2001/10/03 15:12:09 jkeil Exp $ + * $Id: huffman.c,v 1.3 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -28,42 +28,20 @@ # include "huffman.h" /* - * Allocation order of bitfield structure members - */ -#if WORDS_BIGENDIAN -#define BIT_FIELDS_HTOL 1 /* high bits allocated first */ -#else -#define BIT_FIELDS_HTOL 0 /* low bits allocated first */ -#endif -#define BIT_FIELDS_LTOH (!BIT_FIELDS_HTOL) - - -/* * These are the Huffman code words for Layer III. * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. * * These tables support decoding up to 4 Huffman code bits at a time. */ -#if ISO_C99 /* initialize union variants ... with ISO C99 */ -# define V(v, w, x, y, hlen) { .value = { 1, hlen, v, w, x, y } } -# define PTR(offs, bits) { .ptr = { 0, bits, offs } } -#elif __GNUC__ /* ... using a GNU C compiler extension */ -# define V(v, w, x, y, hlen) { value: { 1, hlen, v, w, x, y } } -# define PTR(offs, bits) { ptr: { 0, bits, offs } } -#else /* ... hack for non-iso-c99/non-gnu compilers */ -# if BIT_FIELDS_LTOH -# define V(v, w, x, y, hlen) { 1 | ((hlen)&7) << 1 | \ - ((v)&1) << 4 | ((w)&1) << 5 | \ - ((x)&1) << 6 | ((y)&1) << 7 } -# define PTR(offs, bits) { 0 | ((bits)&7) << 1 | ((offs)&0xfff) << 4 } +# if defined(__GNUC__) +# define PTR(offs, bits) { ptr: { 0, bits, offs } } +# define V(v, w, x, y, hlen) { value: { 1, hlen, v, w, x, y } } # else -# define V(v, w, x, y, hlen) { 0x8000 | ((hlen)&7) << 12 | \ - ((v)&1) << 11 | ((w)&1) << 10 | \ - ((x)&1) << 9 | ((y)&1) << 8 } -# define PTR(offs, bits) { 0x0000 | ((bits)&7) << 12 | ((offs)&0xfff) } +# define PTR(offs, bits) { { 0, bits, offs } } +# define V(v, w, x, y, hlen) { { 1, hlen, (v << 0) | (w << 1) | \ + (x << 2) | (y << 3) } } # endif -#endif static union huffquad const hufftabA[] = { @@ -128,23 +106,13 @@ union huffquad const hufftabB[] = { # undef V # undef PTR -#if ISO_C99 /* initialize union variants ... with ISO C99 */ -# define V(x, y, hlen) { .value = { 1, hlen, x, y } } -# define PTR(offs, bits) { .ptr = { 0, bits, offs } } -#elif __GNUC__ /* ... using a GNU C compiler extension */ -# define V(x, y, hlen) { value: { 1, hlen, x, y } } -# define PTR(offs, bits) { ptr: { 0, bits, offs } } -#else /* ... hack for non-iso-c99/non-gnu compilers */ -# if BIT_FIELDS_LTOH -# define V(x, y, hlen) { 1 | ((hlen)&7) << 1 | \ - ((x)&15) << 4 | ((y)&15) << 8 } -# define PTR(offs, bits) { 0 | ((bits)&7) << 1 | ((offs)&0xfff) << 4 } +# if defined(__GNUC__) +# define PTR(offs, bits) { ptr: { 0, bits, offs } } +# define V(x, y, hlen) { value: { 1, hlen, x, y } } # else -# define V(x, y, hlen) { 0x8000 | ((hlen)&7) << 12 | \ - ((x)&15) << 8 | ((y)&15) << 4 } -# define PTR(offs, bits) { 0x0000 | ((bits)&7) << 12 | ((offs)&0xfff) } +# define PTR(offs, bits) { { 0, bits, offs } } +# define V(x, y, hlen) { { 1, hlen, (x << 0) | (y << 4) } } # endif -#endif static union huffpair const hufftab0[] = { diff --git a/src/libmad/huffman.h b/src/libmad/huffman.h index 198f2f3cb..4a21c1cb9 100644 --- a/src/libmad/huffman.h +++ b/src/libmad/huffman.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,14 +16,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: huffman.h,v 1.2 2001/10/03 15:12:09 jkeil Exp $ + * $Id: huffman.h,v 1.3 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_HUFFMAN_H # define LIBMAD_HUFFMAN_H union huffquad { - unsigned short _; /* helper for non-gcc union initialization */ + struct { + unsigned short final : 1; + unsigned short bits : 3; + unsigned short offset : 12; + } ptr; struct { unsigned short final : 1; unsigned short hlen : 3; @@ -32,27 +36,21 @@ union huffquad { unsigned short x : 1; unsigned short y : 1; } value; + unsigned short final : 1; +}; + +union huffpair { struct { unsigned short final : 1; unsigned short bits : 3; unsigned short offset : 12; } ptr; - unsigned short final : 1; -}; - -union huffpair { - unsigned short _; /* helper for non-gcc union initialization */ struct { unsigned short final : 1; unsigned short hlen : 3; unsigned short x : 4; unsigned short y : 4; } value; - struct { - unsigned short final : 1; - unsigned short bits : 3; - unsigned short offset : 12; - } ptr; unsigned short final : 1; }; diff --git a/src/libmad/imdct_l_arm.S b/src/libmad/imdct_l_arm.S new file mode 100644 index 000000000..35b2e2626 --- /dev/null +++ b/src/libmad/imdct_l_arm.S @@ -0,0 +1,1000 @@ +/***************************************************************************** +* Copyright (C) 2000-2001 Andre McCurdy <armccurdy@yahoo.co.uk> +* +* This program is free software. you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation@ either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY, without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program@ if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +***************************************************************************** +* +* Notes: +* +* +***************************************************************************** +* +* $Id: imdct_l_arm.S,v 1.1 2002/04/30 18:46:58 miguelfreitas Exp $ +* +* 2001/03/24: Andre McCurdy <armccurdy@yahoo.co.uk> +* - Corrected PIC unsafe loading of address of 'imdct36_long_karray' +* +* 2000/09/20: Robert Leslie <rob@mars.org> +* - Added a global symbol with leading underscore per suggestion of +* Simon Burge to support linking with the a.out format. +* +* 2000/09/15: Robert Leslie <rob@mars.org> +* - Fixed a small bug where flags were changed before a conditional branch. +* +* 2000/09/15: Andre McCurdy <armccurdy@yahoo.co.uk> +* - Applied Nicolas Pitre's rounding optimisation in all remaining places. +* +* 2000/09/09: Nicolas Pitre <nico@cam.org> +* - Optimized rounding + scaling operations. +* +* 2000/08/09: Andre McCurdy <armccurdy@yahoo.co.uk> +* - Original created. +* +****************************************************************************/ + + +/* + On entry: + + r0 = pointer to 18 element input array + r1 = pointer to 36 element output array + r2 = windowing block type + + + Stack frame created during execution of the function: + + Initial Holds: + Stack + pointer + minus: + + 0 + 4 lr + 8 r11 + 12 r10 + 16 r9 + 20 r8 + 24 r7 + 28 r6 + 32 r5 + 36 r4 + + 40 r2 : windowing block type + + 44 ct00 high + 48 ct00 low + 52 ct01 high + 56 ct01 low + 60 ct04 high + 64 ct04 low + 68 ct06 high + 72 ct06 low + 76 ct05 high + 80 ct05 low + 84 ct03 high + 88 ct03 low + 92 -ct05 high + 96 -ct05 low + 100 -ct07 high + 104 -ct07 low + 108 ct07 high + 112 ct07 low + 116 ct02 high + 120 ct02 low +*/ + +#define BLOCK_MODE_NORMAL 0 +#define BLOCK_MODE_START 1 +#define BLOCK_MODE_STOP 3 + + +#define X0 0x00 +#define X1 0x04 +#define X2 0x08 +#define X3 0x0C +#define X4 0x10 +#define X5 0x14 +#define X6 0x18 +#define X7 0x1c +#define X8 0x20 +#define X9 0x24 +#define X10 0x28 +#define X11 0x2c +#define X12 0x30 +#define X13 0x34 +#define X14 0x38 +#define X15 0x3c +#define X16 0x40 +#define X17 0x44 + +#define x0 0x00 +#define x1 0x04 +#define x2 0x08 +#define x3 0x0C +#define x4 0x10 +#define x5 0x14 +#define x6 0x18 +#define x7 0x1c +#define x8 0x20 +#define x9 0x24 +#define x10 0x28 +#define x11 0x2c +#define x12 0x30 +#define x13 0x34 +#define x14 0x38 +#define x15 0x3c +#define x16 0x40 +#define x17 0x44 +#define x18 0x48 +#define x19 0x4c +#define x20 0x50 +#define x21 0x54 +#define x22 0x58 +#define x23 0x5c +#define x24 0x60 +#define x25 0x64 +#define x26 0x68 +#define x27 0x6c +#define x28 0x70 +#define x29 0x74 +#define x30 0x78 +#define x31 0x7c +#define x32 0x80 +#define x33 0x84 +#define x34 0x88 +#define x35 0x8c + +#define K00 0x0ffc19fd +#define K01 0x00b2aa3e +#define K02 0x0fdcf549 +#define K03 0x0216a2a2 +#define K04 0x0f9ee890 +#define K05 0x03768962 +#define K06 0x0f426cb5 +#define K07 0x04cfb0e2 +#define K08 0x0ec835e8 +#define K09 0x061f78aa +#define K10 0x0e313245 +#define K11 0x07635284 +#define K12 0x0d7e8807 +#define K13 0x0898c779 +#define K14 0x0cb19346 +#define K15 0x09bd7ca0 +#define K16 0x0bcbe352 +#define K17 0x0acf37ad + +#define minus_K02 0xf0230ab7 + +#define WL0 0x00b2aa3e +#define WL1 0x0216a2a2 +#define WL2 0x03768962 +#define WL3 0x04cfb0e2 +#define WL4 0x061f78aa +#define WL5 0x07635284 +#define WL6 0x0898c779 +#define WL7 0x09bd7ca0 +#define WL8 0x0acf37ad +#define WL9 0x0bcbe352 +#define WL10 0x0cb19346 +#define WL11 0x0d7e8807 +#define WL12 0x0e313245 +#define WL13 0x0ec835e8 +#define WL14 0x0f426cb5 +#define WL15 0x0f9ee890 +#define WL16 0x0fdcf549 +#define WL17 0x0ffc19fd + + +@***************************************************************************** + + + .text + .align + + .global III_imdct_l + .global _III_imdct_l + +III_imdct_l: +_III_imdct_l: + + stmdb sp!, { r2, r4 - r11, lr } @ all callee saved regs, plus arg3 + + ldr r4, =K08 @ r4 = K08 + ldr r5, =K09 @ r5 = K09 + ldr r8, [r0, #X4] @ r8 = X4 + ldr r9, [r0, #X13] @ r9 = X13 + rsb r6, r4, #0 @ r6 = -K08 + rsb r7, r5, #0 @ r7 = -K09 + + smull r2, r3, r4, r8 @ r2..r3 = (X4 * K08) + smlal r2, r3, r5, r9 @ r2..r3 = (X4 * K08) + (X13 * K09) = ct01 + + smull r10, lr, r8, r5 @ r10..lr = (X4 * K09) + smlal r10, lr, r9, r6 @ r10..lr = (X4 * K09) + (X13 * -K08) = ct00 + + ldr r8, [r0, #X7] @ r8 = X7 + ldr r9, [r0, #X16] @ r9 = X16 + + stmdb sp!, { r2, r3, r10, lr } @ stack ct00_h, ct00_l, ct01_h, ct01_l + + add r8, r8, r9 @ r8 = (X7 + X16) + ldr r9, [r0, #X1] @ r9 = X1 + + smlal r2, r3, r6, r8 @ r2..r3 = ct01 + ((X7 + X16) * -K08) + smlal r2, r3, r7, r9 @ r2..r3 += (X1 * -K09) + + ldr r7, [r0, #X10] @ r7 = X10 + + rsbs r10, r10, #0 + rsc lr, lr, #0 @ r10..lr = -ct00 + + smlal r2, r3, r5, r7 @ r2..r3 += (X10 * K09) = ct06 + + smlal r10, lr, r9, r6 @ r10..lr = -ct00 + ( X1 * -K08) + smlal r10, lr, r8, r5 @ r10..lr += ((X7 + X16) * K09) + smlal r10, lr, r7, r4 @ r10..lr += ( X10 * K08) = ct04 + + stmdb sp!, { r2, r3, r10, lr } @ stack ct04_h, ct04_l, ct06_h, ct06_l + + @---- + + ldr r7, [r0, #X0] + ldr r8, [r0, #X11] + ldr r9, [r0, #X12] + sub r7, r7, r8 + sub r7, r7, r9 @ r7 = (X0 - X11 -X12) = ct14 + + ldr r9, [r0, #X3] + ldr r8, [r0, #X8] + ldr r11, [r0, #X15] + sub r8, r8, r9 + add r8, r8, r11 @ r8 = (X8 - X3 + X15) = ct16 + + add r11, r7, r8 @ r11 = ct14 + ct16 = ct18 + + smlal r2, r3, r6, r11 @ r2..r3 = ct06 + ((X0 - X11 - X3 + X15 + X8 - X12) * -K08) + + ldr r6, [r0, #X2] + ldr r9, [r0, #X9] + ldr r12, [r0, #X14] + sub r6, r6, r9 + sub r6, r6, r12 @ r6 = (X2 - X9 - X14) = ct15 + + ldr r9, [r0, #X5] + ldr r12, [r0, #X6] + sub r9, r9, r12 + ldr r12, [r0, #X17] + sub r9, r9, r12 @ r9 = (X5 - X6 - X17) = ct17 + + add r12, r9, r6 @ r12 = ct15 + ct17 = ct19 + + smlal r2, r3, r5, r12 @ r2..r3 += ((X2 - X9 + X5 - X6 - X17 - X14) * K09) + + smlal r10, lr, r11, r5 @ r10..lr = ct04 + (ct18 * K09) + smlal r10, lr, r12, r4 @ r10..lr = ct04 + (ct18 * K09) + (ct19 * K08) + + movs r2, r2, lsr #28 + adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3 + str r2, [r1, #x22] @ store result x22 + + movs r10, r10, lsr #28 + adc r10, r10, lr, lsl #4 @ r10 = bits[59..28] of r10..lr + str r10, [r1, #x4] @ store result x4 + + @---- + + ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp) + + @ r2..r3 = ct06 + @ r4..r5 = ct04 + @ r6 = ct15 + @ r7 = ct14 + @ r8 = ct16 + @ r9 = ct17 + @ r10 = . + @ r11 = . + @ r12 = . + @ lr = . + + ldr r10, =K03 @ r10 = K03 + ldr lr, =K15 @ lr = K15 + + smlal r2, r3, r10, r7 @ r2..r3 = ct06 + (ct14 * K03) + smlal r4, r5, lr, r7 @ r4..r5 = ct04 + (ct14 * K15) + + ldr r12, =K14 @ r12 = K14 + rsb r10, r10, #0 @ r10 = -K03 + + smlal r2, r3, lr, r6 @ r2..r3 += (ct15 * K15) + smlal r4, r5, r10, r6 @ r4..r5 += (ct15 * -K03) + smlal r2, r3, r12, r8 @ r2..r3 += (ct16 * K14) + + ldr r11, =minus_K02 @ r11 = -K02 + rsb r12, r12, #0 @ r12 = -K14 + + smlal r4, r5, r12, r9 @ r4..r5 += (ct17 * -K14) + smlal r2, r3, r11, r9 @ r2..r3 += (ct17 * -K02) + smlal r4, r5, r11, r8 @ r4..r5 += (ct16 * -K02) + + movs r2, r2, lsr #28 + adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3 + str r2, [r1, #x7] @ store result x7 + + movs r4, r4, lsr #28 + adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5 + str r4, [r1, #x1] @ store result x1 + + @---- + + ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp) + + @ r2..r3 = ct06 + @ r4..r5 = ct04 + @ r6 = ct15 + @ r7 = ct14 + @ r8 = ct16 + @ r9 = ct17 + @ r10 = -K03 + @ r11 = -K02 + @ r12 = -K14 + @ lr = K15 + + rsbs r2, r2, #0 + rsc r3, r3, #0 @ r2..r3 = -ct06 + + smlal r2, r3, r12, r7 @ r2..r3 = -ct06 + (ct14 * -K14) + smlal r2, r3, r10, r8 @ r2..r3 += (ct16 * -K03) + + smlal r4, r5, r12, r6 @ r4..r5 = ct04 + (ct15 * -K14) + smlal r4, r5, r10, r9 @ r4..r5 += (ct17 * -K03) + smlal r4, r5, lr, r8 @ r4..r5 += (ct16 * K15) + smlal r4, r5, r11, r7 @ r4..r5 += (ct14 * -K02) + + rsb lr, lr, #0 @ lr = -K15 + rsb r11, r11, #0 @ r11 = K02 + + smlal r2, r3, lr, r9 @ r2..r3 += (ct17 * -K15) + smlal r2, r3, r11, r6 @ r2..r3 += (ct15 * K02) + + movs r4, r4, lsr #28 + adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5 + str r4, [r1, #x25] @ store result x25 + + movs r2, r2, lsr #28 + adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3 + str r2, [r1, #x19] @ store result x19 + + @---- + + ldr r2, [sp, #16] @ r2 = ct01_l + ldr r3, [sp, #20] @ r3 = ct01_h + + ldr r6, [r0, #X1] + ldr r8, [r0, #X7] + ldr r9, [r0, #X10] + ldr r7, [r0, #X16] + + rsbs r2, r2, #0 + rsc r3, r3, #0 @ r2..r3 = -ct01 + + mov r4, r2 + mov r5, r3 @ r4..r5 = -ct01 + + @ r2..r3 = -ct01 + @ r4..r5 = -ct01 + @ r6 = X1 + @ r7 = X16 + @ r8 = X7 + @ r9 = X10 + @ r10 = -K03 + @ r11 = K02 + @ r12 = -K14 + @ lr = -K15 + + smlal r4, r5, r12, r7 @ r4..r5 = -ct01 + (X16 * -K14) + smlal r2, r3, lr, r9 @ r2..r3 = -ct01 + (X10 * -K15) + + smlal r4, r5, r10, r8 @ r4..r5 += (X7 * -K03) + smlal r2, r3, r10, r7 @ r2..r3 += (X16 * -K03) + + smlal r4, r5, r11, r9 @ r4..r5 += (X10 * K02) + smlal r2, r3, r12, r8 @ r2..r3 += (X7 * -K14) + + rsb lr, lr, #0 @ lr = K15 + rsb r11, r11, #0 @ r11 = -K02 + + smlal r4, r5, lr, r6 @ r4..r5 += (X1 * K15) = ct05 + smlal r2, r3, r11, r6 @ r2..r3 += (X1 * -K02) = ct03 + + stmdb sp!, { r2, r3, r4, r5 } @ stack ct05_h, ct05_l, ct03_h, ct03_l + + rsbs r4, r4, #0 + rsc r5, r5, #0 @ r4..r5 = -ct05 + + stmdb sp!, { r4, r5 } @ stack -ct05_h, -ct05_l + + ldr r2, [sp, #48] @ r2 = ct00_l + ldr r3, [sp, #52] @ r3 = ct00_h + + rsb r10, r10, #0 @ r10 = K03 + + rsbs r4, r2, #0 + rsc r5, r3, #0 @ r4..r5 = -ct00 + + @ r2..r3 = ct00 + @ r4..r5 = -ct00 + @ r6 = X1 + @ r7 = X16 + @ r8 = X7 + @ r9 = X10 + @ r10 = K03 + @ r11 = -K02 + @ r12 = -K14 + @ lr = K15 + + smlal r4, r5, r10, r6 @ r4..r5 = -ct00 + (X1 * K03) + smlal r2, r3, r10, r9 @ r2..r3 = ct00 + (X10 * K03) + + smlal r4, r5, r12, r9 @ r4..r5 += (X10 * -K14) + smlal r2, r3, r12, r6 @ r2..r3 += (X1 * -K14) + + smlal r4, r5, r11, r7 @ r4..r5 += (X16 * -K02) + smlal r4, r5, lr, r8 @ r4..r5 += (X7 * K15) = ct07 + + rsb lr, lr, #0 @ lr = -K15 + rsb r11, r11, #0 @ r11 = K02 + + smlal r2, r3, r11, r8 @ r2..r3 += (X7 * K02) + smlal r2, r3, lr, r7 @ r2..r3 += (X16 * -K15) = ct02 + + rsbs r6, r4, #0 + rsc r7, r5, #0 @ r6..r7 = -ct07 + + stmdb sp!, { r2 - r7 } @ stack -ct07_h, -ct07_l, ct07_h, ct07_l, ct02_h, ct02_l + + + @---- + + add r2, pc, #(imdct36_long_karray-.-8) @ r2 = base address of Knn array (PIC safe ?) + + +loop: + ldr r12, [r0, #X0] + + ldmia r2!, { r5 - r11 } @ first 7 words from Karray element + + smull r3, r4, r5, r12 @ sum = (Kxx * X0) + ldr r12, [r0, #X2] + ldr r5, [r0, #X3] + smlal r3, r4, r6, r12 @ sum += (Kxx * X2) + ldr r12, [r0, #X5] + ldr r6, [r0, #X6] + smlal r3, r4, r7, r5 @ sum += (Kxx * X3) + smlal r3, r4, r8, r12 @ sum += (Kxx * X5) + ldr r12, [r0, #X8] + ldr r5, [r0, #X9] + smlal r3, r4, r9, r6 @ sum += (Kxx * X6) + smlal r3, r4, r10, r12 @ sum += (Kxx * X8) + smlal r3, r4, r11, r5 @ sum += (Kxx * X9) + + ldmia r2!, { r5 - r10 } @ final 6 words from Karray element + + ldr r11, [r0, #X11] + ldr r12, [r0, #X12] + smlal r3, r4, r5, r11 @ sum += (Kxx * X11) + ldr r11, [r0, #X14] + ldr r5, [r0, #X15] + smlal r3, r4, r6, r12 @ sum += (Kxx * X12) + smlal r3, r4, r7, r11 @ sum += (Kxx * X14) + ldr r11, [r0, #X17] + smlal r3, r4, r8, r5 @ sum += (Kxx * X15) + smlal r3, r4, r9, r11 @ sum += (Kxx * X17) + + add r5, sp, r10, lsr #16 @ create index back into stack for required ctxx + + ldmia r5, { r6, r7 } @ r6..r7 = ctxx + + mov r8, r10, lsl #16 @ push ctxx index off the top end + + adds r3, r3, r6 @ add low words + adc r4, r4, r7 @ add high words, with carry + movs r3, r3, lsr #28 + adc r3, r3, r4, lsl #4 @ r3 = bits[59..28] of r3..r4 + + str r3, [r1, r8, lsr #24] @ push completion flag off the bottom end + + movs r8, r8, lsl #8 @ push result location index off the top end + beq loop @ loop back if completion flag not set + b imdct_l_windowing @ branch to windowing stage if looping finished + +imdct36_long_karray: + + .word K17, -K13, K10, -K06, -K05, K01, -K00, K04, -K07, K11, K12, -K16, 0x00000000 + .word K13, K07, K16, K01, K10, -K05, K04, -K11, K00, -K17, K06, -K12, 0x00200800 + .word K11, K17, K05, K12, -K01, K06, -K07, K00, -K13, K04, -K16, K10, 0x00200c00 + .word K07, K00, -K12, K05, -K16, -K10, K11, -K17, K04, K13, K01, K06, 0x00001400 + .word K05, K10, -K00, -K17, K07, -K13, K12, K06, -K16, K01, -K11, -K04, 0x00181800 + .word K01, K05, -K07, -K11, K13, K17, -K16, -K12, K10, K06, -K04, -K00, 0x00102000 + .word -K16, K12, -K11, K07, K04, -K00, -K01, K05, -K06, K10, K13, -K17, 0x00284800 + .word -K12, K06, K17, -K00, -K11, K04, K05, -K10, K01, K16, -K07, -K13, 0x00085000 + .word -K10, K16, K04, -K13, -K00, K07, K06, -K01, -K12, -K05, K17, K11, 0x00105400 + .word -K06, -K01, K13, K04, K17, -K11, -K10, -K16, -K05, K12, K00, K07, 0x00185c00 + .word -K04, -K11, -K01, K16, K06, K12, K13, -K07, -K17, -K00, -K10, -K05, 0x00006000 + .word -K00, -K04, -K06, -K10, -K12, -K16, -K17, -K13, -K11, -K07, -K05, -K01, 0x00206801 + + + @---- + @------------------------------------------------------------------------- + @---- + +imdct_l_windowing: + + ldr r11, [sp, #80] @ fetch function parameter 3 from out of the stack + ldmia r1!, { r0, r2 - r9 } @ load 9 words from x0, update pointer + + @ r0 = x0 + @ r1 = &x[9] + @ r2 = x1 + @ r3 = x2 + @ r4 = x3 + @ r5 = x4 + @ r6 = x5 + @ r7 = x6 + @ r8 = x7 + @ r9 = x8 + @ r10 = . + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = . + @ lr = . + + cmp r11, #BLOCK_MODE_STOP @ setup flags + rsb r10, r0, #0 @ r10 = -x0 (DONT change flags !!) + beq stop_block_x0_to_x17 + + + @ start and normal blocks are treated the same for x[0]..x[17] + +normal_block_x0_to_x17: + + ldr r12, =WL9 @ r12 = window_l[9] + + rsb r0, r9, #0 @ r0 = -x8 + rsb r9, r2, #0 @ r9 = -x1 + rsb r2, r8, #0 @ r2 = -x7 + rsb r8, r3, #0 @ r8 = -x2 + rsb r3, r7, #0 @ r3 = -x6 + rsb r7, r4, #0 @ r7 = -x3 + rsb r4, r6, #0 @ r4 = -x5 + rsb r6, r5, #0 @ r6 = -x4 + + @ r0 = -x8 + @ r1 = &x[9] + @ r2 = -x7 + @ r3 = -x6 + @ r4 = -x5 + @ r5 = . + @ r6 = -x4 + @ r7 = -x3 + @ r8 = -x2 + @ r9 = -x1 + @ r10 = -x0 + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = window_l[9] + @ lr = . + + smull r5, lr, r12, r0 @ r5..lr = (window_l[9] * (x[9] == -x[8])) + ldr r12, =WL10 @ r12 = window_l[10] + movs r5, r5, lsr #28 + adc r0, r5, lr, lsl #4 @ r0 = bits[59..28] of windowed x9 + + smull r5, lr, r12, r2 @ r5..lr = (window_l[10] * (x[10] == -x[7])) + ldr r12, =WL11 @ r12 = window_l[11] + movs r5, r5, lsr #28 + adc r2, r5, lr, lsl #4 @ r2 = bits[59..28] of windowed x10 + + smull r5, lr, r12, r3 @ r5..lr = (window_l[11] * (x[11] == -x[6])) + ldr r12, =WL12 @ r12 = window_l[12] + movs r5, r5, lsr #28 + adc r3, r5, lr, lsl #4 @ r3 = bits[59..28] of windowed x11 + + smull r5, lr, r12, r4 @ r5..lr = (window_l[12] * (x[12] == -x[5])) + ldr r12, =WL13 @ r12 = window_l[13] + movs r5, r5, lsr #28 + adc r4, r5, lr, lsl #4 @ r4 = bits[59..28] of windowed x12 + + smull r5, lr, r12, r6 @ r5..lr = (window_l[13] * (x[13] == -x[4])) + ldr r12, =WL14 @ r12 = window_l[14] + movs r5, r5, lsr #28 + adc r6, r5, lr, lsl #4 @ r6 = bits[59..28] of windowed x13 + + smull r5, lr, r12, r7 @ r5..lr = (window_l[14] * (x[14] == -x[3])) + ldr r12, =WL15 @ r12 = window_l[15] + movs r5, r5, lsr #28 + adc r7, r5, lr, lsl #4 @ r7 = bits[59..28] of windowed x14 + + smull r5, lr, r12, r8 @ r5..lr = (window_l[15] * (x[15] == -x[2])) + ldr r12, =WL16 @ r12 = window_l[16] + movs r5, r5, lsr #28 + adc r8, r5, lr, lsl #4 @ r8 = bits[59..28] of windowed x15 + + smull r5, lr, r12, r9 @ r5..lr = (window_l[16] * (x[16] == -x[1])) + ldr r12, =WL17 @ r12 = window_l[17] + movs r5, r5, lsr #28 + adc r9, r5, lr, lsl #4 @ r9 = bits[59..28] of windowed x16 + + smull r5, lr, r12, r10 @ r5..lr = (window_l[17] * (x[17] == -x[0])) + ldr r12, =WL0 @ r12 = window_l[0] + movs r5, r5, lsr #28 + adc r10, r5, lr, lsl #4 @ r10 = bits[59..28] of windowed x17 + + + stmia r1, { r0, r2 - r4, r6 - r10 } @ store windowed x[9] .. x[17] + ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x0 + + + smull r10, lr, r12, r0 @ r10..lr = (window_l[0] * x[0]) + ldr r12, =WL1 @ r12 = window_l[1] + movs r10, r10, lsr #28 + adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0 + + smull r10, lr, r12, r2 @ r10..lr = (window_l[1] * x[1]) + ldr r12, =WL2 @ r12 = window_l[2] + movs r10, r10, lsr #28 + adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1 + + smull r10, lr, r12, r3 @ r10..lr = (window_l[2] * x[2]) + ldr r12, =WL3 @ r12 = window_l[3] + movs r10, r10, lsr #28 + adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2 + + smull r10, lr, r12, r4 @ r10..lr = (window_l[3] * x[3]) + ldr r12, =WL4 @ r12 = window_l[4] + movs r10, r10, lsr #28 + adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3 + + smull r10, lr, r12, r5 @ r10..lr = (window_l[4] * x[4]) + ldr r12, =WL5 @ r12 = window_l[5] + movs r10, r10, lsr #28 + adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4 + + smull r10, lr, r12, r6 @ r10..lr = (window_l[5] * x[5]) + ldr r12, =WL6 @ r12 = window_l[6] + movs r10, r10, lsr #28 + adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5 + + smull r10, lr, r12, r7 @ r10..lr = (window_l[6] * x[6]) + ldr r12, =WL7 @ r12 = window_l[7] + movs r10, r10, lsr #28 + adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6 + + smull r10, lr, r12, r8 @ r10..lr = (window_l[7] * x[7]) + ldr r12, =WL8 @ r12 = window_l[8] + movs r10, r10, lsr #28 + adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7 + + smull r10, lr, r12, r9 @ r10..lr = (window_l[8] * x[8]) + movs r10, r10, lsr #28 + adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8 + + stmia r1, { r0, r2 - r9 } @ store windowed x[0] .. x[8] + + cmp r11, #BLOCK_MODE_START + beq start_block_x18_to_x35 + + + @---- + + +normal_block_x18_to_x35: + + ldr r11, =WL3 @ r11 = window_l[3] + ldr r12, =WL4 @ r12 = window_l[4] + + add r1, r1, #(18*4) @ r1 = &x[18] + + ldmia r1!, { r0, r2 - r4, r6 - r10 } @ load 9 words from x18, update pointer + + @ r0 = x18 + @ r1 = &x[27] + @ r2 = x19 + @ r3 = x20 + @ r4 = x21 + @ r5 = . + @ r6 = x22 + @ r7 = x23 + @ r8 = x24 + @ r9 = x25 + @ r10 = x26 + @ r11 = window_l[3] + @ r12 = window_l[4] + @ lr = . + + smull r5, lr, r12, r6 @ r5..lr = (window_l[4] * (x[22] == x[31])) + movs r5, r5, lsr #28 + adc r5, r5, lr, lsl #4 @ r5 = bits[59..28] of windowed x31 + + smull r6, lr, r11, r4 @ r5..lr = (window_l[3] * (x[21] == x[32])) + ldr r12, =WL5 @ r12 = window_l[5] + movs r6, r6, lsr #28 + adc r6, r6, lr, lsl #4 @ r6 = bits[59..28] of windowed x32 + + smull r4, lr, r12, r7 @ r4..lr = (window_l[5] * (x[23] == x[30])) + ldr r11, =WL1 @ r11 = window_l[1] + ldr r12, =WL2 @ r12 = window_l[2] + movs r4, r4, lsr #28 + adc r4, r4, lr, lsl #4 @ r4 = bits[59..28] of windowed x30 + + smull r7, lr, r12, r3 @ r7..lr = (window_l[2] * (x[20] == x[33])) + ldr r12, =WL6 @ r12 = window_l[6] + movs r7, r7, lsr #28 + adc r7, r7, lr, lsl #4 @ r7 = bits[59..28] of windowed x33 + + smull r3, lr, r12, r8 @ r3..lr = (window_l[6] * (x[24] == x[29])) + movs r3, r3, lsr #28 + adc r3, r3, lr, lsl #4 @ r3 = bits[59..28] of windowed x29 + + smull r8, lr, r11, r2 @ r7..lr = (window_l[1] * (x[19] == x[34])) + ldr r12, =WL7 @ r12 = window_l[7] + ldr r11, =WL8 @ r11 = window_l[8] + movs r8, r8, lsr #28 + adc r8, r8, lr, lsl #4 @ r8 = bits[59..28] of windowed x34 + + smull r2, lr, r12, r9 @ r7..lr = (window_l[7] * (x[25] == x[28])) + ldr r12, =WL0 @ r12 = window_l[0] + movs r2, r2, lsr #28 + adc r2, r2, lr, lsl #4 @ r2 = bits[59..28] of windowed x28 + + smull r9, lr, r12, r0 @ r3..lr = (window_l[0] * (x[18] == x[35])) + movs r9, r9, lsr #28 + adc r9, r9, lr, lsl #4 @ r9 = bits[59..28] of windowed x35 + + smull r0, lr, r11, r10 @ r7..lr = (window_l[8] * (x[26] == x[27])) + ldr r11, =WL16 @ r11 = window_l[16] + ldr r12, =WL17 @ r12 = window_l[17] + movs r0, r0, lsr #28 + adc r0, r0, lr, lsl #4 @ r0 = bits[59..28] of windowed x27 + + + stmia r1, { r0, r2 - r9 } @ store windowed x[27] .. x[35] + ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x18 + + + smull r10, lr, r12, r0 @ r10..lr = (window_l[17] * x[18]) + movs r10, r10, lsr #28 + adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0 + + smull r10, lr, r11, r2 @ r10..lr = (window_l[16] * x[19]) + ldr r11, =WL14 @ r11 = window_l[14] + ldr r12, =WL15 @ r12 = window_l[15] + movs r10, r10, lsr #28 + adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1 + + smull r10, lr, r12, r3 @ r10..lr = (window_l[15] * x[20]) + movs r10, r10, lsr #28 + adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2 + + smull r10, lr, r11, r4 @ r10..lr = (window_l[14] * x[21]) + ldr r11, =WL12 @ r11 = window_l[12] + ldr r12, =WL13 @ r12 = window_l[13] + movs r10, r10, lsr #28 + adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3 + + smull r10, lr, r12, r5 @ r10..lr = (window_l[13] * x[22]) + movs r10, r10, lsr #28 + adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4 + + smull r10, lr, r11, r6 @ r10..lr = (window_l[12] * x[23]) + ldr r11, =WL10 @ r12 = window_l[10] + ldr r12, =WL11 @ r12 = window_l[11] + movs r10, r10, lsr #28 + adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5 + + smull r10, lr, r12, r7 @ r10..lr = (window_l[11] * x[24]) + movs r10, r10, lsr #28 + adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6 + + smull r10, lr, r11, r8 @ r10..lr = (window_l[10] * x[25]) + ldr r12, =WL9 @ r12 = window_l[9] + movs r10, r10, lsr #28 + adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7 + + smull r10, lr, r12, r9 @ r10..lr = (window_l[9] * x[26]) + + movs r10, r10, lsr #28 + adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8 + + stmia r1, { r0, r2 - r9 } @ store windowed x[18] .. x[26] + + @---- + @ NB there are 2 possible exits from this function - this is only one of them + @---- + + add sp, sp, #(21*4) @ return stack frame + ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return + + @---- + + +stop_block_x0_to_x17: + + @ r0 = x0 + @ r1 = &x[9] + @ r2 = x1 + @ r3 = x2 + @ r4 = x3 + @ r5 = x4 + @ r6 = x5 + @ r7 = x6 + @ r8 = x7 + @ r9 = x8 + @ r10 = -x0 + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = . + @ lr = . + + rsb r0, r6, #0 @ r0 = -x5 + rsb r6, r2, #0 @ r6 = -x1 + rsb r2, r5, #0 @ r2 = -x4 + rsb r5, r3, #0 @ r5 = -x2 + rsb r3, r4, #0 @ r3 = -x3 + + add r1, r1, #(3*4) @ r1 = &x[12] + stmia r1, { r0, r2, r3, r5, r6, r10 } @ store unchanged x[12] .. x[17] + + ldr r0, =WL1 @ r0 = window_l[1] == window_s[0] + + rsb r10, r9, #0 @ r10 = -x8 + rsb r12, r8, #0 @ r12 = -x7 + rsb lr, r7, #0 @ lr = -x6 + + @ r0 = WL1 + @ r1 = &x[12] + @ r2 = . + @ r3 = . + @ r4 = . + @ r5 = . + @ r6 = . + @ r7 = x6 + @ r8 = x7 + @ r9 = x8 + @ r10 = -x8 + @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block) + @ r12 = -x7 + @ lr = -x6 + + smull r5, r6, r0, r7 @ r5..r6 = (window_l[1] * x[6]) + ldr r2, =WL4 @ r2 = window_l[4] == window_s[1] + movs r5, r5, lsr #28 + adc r7, r5, r6, lsl #4 @ r7 = bits[59..28] of windowed x6 + + smull r5, r6, r2, r8 @ r5..r6 = (window_l[4] * x[7]) + ldr r3, =WL7 @ r3 = window_l[7] == window_s[2] + movs r5, r5, lsr #28 + adc r8, r5, r6, lsl #4 @ r8 = bits[59..28] of windowed x7 + + smull r5, r6, r3, r9 @ r5..r6 = (window_l[7] * x[8]) + ldr r4, =WL10 @ r4 = window_l[10] == window_s[3] + movs r5, r5, lsr #28 + adc r9, r5, r6, lsl #4 @ r9 = bits[59..28] of windowed x8 + + smull r5, r6, r4, r10 @ r5..r6 = (window_l[10] * (x[9] == -x[8])) + ldr r0, =WL13 @ r0 = window_l[13] == window_s[4] + movs r5, r5, lsr #28 + adc r10, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9 + + smull r5, r6, r0, r12 @ r5..r6 = (window_l[13] * (x[10] == -x[7])) + ldr r2, =WL16 @ r2 = window_l[16] == window_s[5] + movs r5, r5, lsr #28 + adc r12, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9 + + smull r5, r6, r2, lr @ r5..r6 = (window_l[16] * (x[11] == -x[6])) + + ldr r0, =0x00 + + movs r5, r5, lsr #28 + adc lr, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9 + + stmdb r1!, { r7 - r10, r12, lr } @ store windowed x[6] .. x[11] + + ldr r5, =0x00 + ldr r6, =0x00 + ldr r2, =0x00 + ldr r3, =0x00 + ldr r4, =0x00 + + stmdb r1!, { r0, r2 - r6 } @ store windowed x[0] .. x[5] + + b normal_block_x18_to_x35 + + + @---- + + +start_block_x18_to_x35: + + ldr r4, =WL1 @ r0 = window_l[1] == window_s[0] + + add r1, r1, #(24*4) @ r1 = &x[24] + + ldmia r1, { r0, r2, r3 } @ load 3 words from x24, dont update pointer + + @ r0 = x24 + @ r1 = &x[24] + @ r2 = x25 + @ r3 = x26 + @ r4 = WL1 + @ r5 = WL4 + @ r6 = WL7 + @ r7 = WL10 + @ r8 = WL13 + @ r9 = WL16 + @ r10 = . + @ r11 = . + @ r12 = . + @ lr = . + + ldr r5, =WL4 @ r5 = window_l[4] == window_s[1] + + smull r10, r11, r4, r0 @ r10..r11 = (window_l[1] * (x[24] == x[29])) + ldr r6, =WL7 @ r6 = window_l[7] == window_s[2] + movs r10, r10, lsr #28 + adc lr, r10, r11, lsl #4 @ lr = bits[59..28] of windowed x29 + + smull r10, r11, r5, r2 @ r10..r11 = (window_l[4] * (x[25] == x[28])) + ldr r7, =WL10 @ r7 = window_l[10] == window_s[3] + movs r10, r10, lsr #28 + adc r12, r10, r11, lsl #4 @ r12 = bits[59..28] of windowed x28 + + smull r10, r11, r6, r3 @ r10..r11 = (window_l[7] * (x[26] == x[27])) + ldr r8, =WL13 @ r8 = window_l[13] == window_s[4] + movs r10, r10, lsr #28 + adc r4, r10, r11, lsl #4 @ r4 = bits[59..28] of windowed x27 + + smull r10, r11, r7, r3 @ r10..r11 = (window_l[10] * x[26]) + ldr r9, =WL16 @ r9 = window_l[16] == window_s[5] + movs r10, r10, lsr #28 + adc r3, r10, r11, lsl #4 @ r3 = bits[59..28] of windowed x26 + + smull r10, r11, r8, r2 @ r10..r11 = (window_l[13] * x[25]) + ldr r5, =0x00 + movs r10, r10, lsr #28 + adc r2, r10, r11, lsl #4 @ r2 = bits[59..28] of windowed x25 + + smull r10, r11, r9, r0 @ r10..r11 = (window_l[16] * x[24]) + ldr r6, =0x00 + movs r10, r10, lsr #28 + adc r0, r10, r11, lsl #4 @ r0 = bits[59..28] of windowed x24 + + stmia r1!, { r0, r2, r3, r4, r12, lr } @ store windowed x[24] .. x[29] + + ldr r7, =0x00 + ldr r8, =0x00 + ldr r9, =0x00 + ldr r10, =0x00 + + stmia r1!, { r5 - r10 } @ store windowed x[30] .. x[35] + + @---- + @ NB there are 2 possible exits from this function - this is only one of them + @---- + + add sp, sp, #(21*4) @ return stack frame + ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return + + @---- + @END + @---- + diff --git a/src/libmad/imdct_s.dat b/src/libmad/imdct_s.dat index 63f4a829a..1974f3d3d 100644 --- a/src/libmad/imdct_s.dat +++ b/src/libmad/imdct_s.dat @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: imdct_s.dat,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: imdct_s.dat,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, diff --git a/src/libmad/layer12.c b/src/libmad/layer12.c index 1879350c5..32feab351 100755 --- a/src/libmad/layer12.c +++ b/src/libmad/layer12.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: layer12.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: layer12.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H diff --git a/src/libmad/layer12.h b/src/libmad/layer12.h index 3ba1d5f38..5518c3818 100644 --- a/src/libmad/layer12.h +++ b/src/libmad/layer12.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: layer12.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: layer12.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_LAYER12_H diff --git a/src/libmad/layer3.c b/src/libmad/layer3.c index 386fd1c68..b05dd4cbf 100755 --- a/src/libmad/layer3.c +++ b/src/libmad/layer3.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: layer3.c,v 1.2 2001/12/01 22:38:31 guenter Exp $ + * $Id: layer3.c,v 1.3 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -27,7 +27,10 @@ # include <stdlib.h> # include <string.h> -# include <assert.h> + +# ifdef HAVE_ASSERT_H +# include <assert.h> +# endif # ifdef HAVE_LIMITS_H # include <limits.h> @@ -51,6 +54,11 @@ enum { mixed_block_flag = 0x08 }; +enum { + I_STEREO = 0x1, + MS_STEREO = 0x2 +}; + struct sideinfo { unsigned int main_data_begin; unsigned int private_bits; @@ -503,7 +511,7 @@ enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, unsigned int *priv_bitlen) { unsigned int ngr, gr, ch, i; - enum mad_error result = 0; + enum mad_error result = MAD_ERROR_NONE; *data_bitlen = 0; *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); @@ -602,7 +610,7 @@ unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, index = (channel->block_type == 2) ? ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; - if (!((mode_extension & 0x1) && gr1ch)) { + if (!((mode_extension & I_STEREO) && gr1ch)) { if (scalefac_compress < 400) { slen[0] = (scalefac_compress >> 4) / 5; slen[1] = (scalefac_compress >> 4) % 5; @@ -643,7 +651,7 @@ unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, while (n < 39) channel->scalefac[n++] = 0; } - else { /* (mode_extension & 0x1) && gr1ch (i.e. ch == 1) */ + else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ scalefac_compress >>= 1; if (scalefac_compress < 180) { @@ -775,6 +783,28 @@ unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, } /* + * The Layer III formula for requantization and scaling is defined by + * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: + * + * long blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210)) * + * 2^-(scalefac_multiplier * + * (scalefac_l[sfb] + preflag * pretab[sfb])) + * + * short blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * + * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) + * + * where: + * scalefac_multiplier = (scalefac_scale + 1) / 2 + * + * The routines III_exponents() and III_requantize() facilitate this + * calculation. + */ + +/* * NAME: III_exponents() * DESCRIPTION: calculate scalefactor exponents */ @@ -856,23 +886,7 @@ mad_fixed_t III_requantize(unsigned int value, signed int exp) signed int frac; struct fixedfloat const *power; - /* - * long blocks: - * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * - * 2^((1/4) * (global_gain - 210)) * - * 2^-(scalefac_multiplier * - * (scalefac_l[sfb] + preflag * pretab[sfb])) - * - * short blocks: - * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * - * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * - * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) - * - * where: - * scalefac_multiplier = (scalefac_scale + 1) / 2 - */ - - frac = exp % 4; + frac = exp % 4; /* assumes sign(frac) == sign(exp) */ exp /= 4; power = &rq_table[value]; @@ -884,14 +898,16 @@ mad_fixed_t III_requantize(unsigned int value, signed int exp) /* underflow */ requantized = 0; } - else + else { + requantized += 1L << (-exp - 1); requantized >>= -exp; + } } else { if (exp >= 5) { /* overflow */ # if defined(DEBUG) - printf ("mad: requantize overflow (%f * 2^%d)\n", + fprintf(stderr, "requantize overflow (%f * 2^%d)\n", mad_f_todouble(requantized), exp); # endif requantized = MAD_F_MAX; @@ -1251,7 +1267,7 @@ enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], xrptr += 2; } - return 0; + return MAD_ERROR_NONE; } # undef MASK @@ -1266,37 +1282,39 @@ void III_reorder(mad_fixed_t xr[576], struct channel const *channel, unsigned char const sfbwidth[39]) { mad_fixed_t tmp[32][3][6]; - unsigned int sb, l, sfbi, f, w, sbw[3], sw[3]; + unsigned int sb, l, f, w, sbw[3], sw[3]; /* this is probably wrong for 8000 Hz mixed blocks */ - if (channel->flags & mixed_block_flag) - sb = 2, sfbi = 3 * 3; - else - sb = 0, sfbi = 0; + sb = 0; + if (channel->flags & mixed_block_flag) { + sb = 2; + + l = 0; + while (l < 36) + l += *sfbwidth++; + } for (w = 0; w < 3; ++w) { sbw[w] = sb; sw[w] = 0; } - f = sfbwidth[sfbi]; + f = *sfbwidth++; w = 0; for (l = 18 * sb; l < 576; ++l) { + if (f-- == 0) { + f = *sfbwidth++ - 1; + w = (w + 1) % 3; + } + tmp[sbw[w]][w][sw[w]++] = xr[l]; if (sw[w] == 6) { sw[w] = 0; ++sbw[w]; } - - if (--f == 0) { - if (++w == 3) - w = 0; - - f = sfbwidth[++sfbi]; - } } memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t)); @@ -1315,11 +1333,6 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], short modes[39]; unsigned int sfbi, l, n, i; - enum { - i_stereo = 0x1, - ms_stereo = 0x2 - }; - if (granule->ch[0].block_type != granule->ch[1].block_type || (granule->ch[0].flags & mixed_block_flag) != @@ -1331,7 +1344,7 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], /* intensity stereo */ - if (header->mode_extension & i_stereo) { + if (header->mode_extension & I_STEREO) { struct channel const *right_ch = &granule->ch[1]; mad_fixed_t const *right_xr = xr[1]; unsigned int is_pos; @@ -1387,14 +1400,14 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], /* long blocks */ for (i = 0; i < lower; ++i) - modes[i] = header->mode_extension & ~i_stereo; + modes[i] = header->mode_extension & ~I_STEREO; /* short blocks */ w = 0; for (i = start; i < max; ++i) { if (i < bound[w]) - modes[i] = header->mode_extension & ~i_stereo; + modes[i] = header->mode_extension & ~I_STEREO; w = (w + 1) % 3; } @@ -1417,7 +1430,7 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], } for (i = 0; i < bound; ++i) - modes[i] = header->mode_extension & ~i_stereo; + modes[i] = header->mode_extension & ~I_STEREO; } /* now do the actual processing */ @@ -1432,11 +1445,11 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (!(modes[sfbi] & i_stereo)) + if (!(modes[sfbi] & I_STEREO)) continue; if (illegal_pos[sfbi]) { - modes[sfbi] &= ~i_stereo; + modes[sfbi] &= ~I_STEREO; continue; } @@ -1468,13 +1481,13 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (!(modes[sfbi] & i_stereo)) + if (!(modes[sfbi] & I_STEREO)) continue; is_pos = right_ch->scalefac[sfbi]; if (is_pos >= 7) { /* illegal intensity position */ - modes[sfbi] &= ~i_stereo; + modes[sfbi] &= ~I_STEREO; continue; } @@ -1492,7 +1505,7 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], /* middle/side stereo */ - if (header->mode_extension & ms_stereo) { + if (header->mode_extension & MS_STEREO) { register mad_fixed_t invsqrt2; header->flags |= MAD_FLAG_MS_STEREO; @@ -1502,7 +1515,7 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (modes[sfbi] != ms_stereo) + if (modes[sfbi] != MS_STEREO) continue; for (i = 0; i < n; ++i) { @@ -1517,7 +1530,7 @@ enum mad_error III_stereo(mad_fixed_t xr[2][576], } } - return 0; + return MAD_ERROR_NONE; } /* @@ -1533,15 +1546,12 @@ void III_aliasreduce(mad_fixed_t xr[576], int lines) bound = &xr[lines]; for (xr += 18; xr < bound; xr += 18) { for (i = 0; i < 8; ++i) { - register mad_fixed_t *aptr, *bptr, a, b; + register mad_fixed_t a, b; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; - aptr = &xr[-1 - i]; - bptr = &xr[ i]; - - a = *aptr; - b = *bptr; + a = xr[-1 - i]; + b = xr[ i]; # if defined(ASO_ZEROCHECK) if (a | b) { @@ -1549,12 +1559,12 @@ void III_aliasreduce(mad_fixed_t xr[576], int lines) MAD_F_ML0(hi, lo, a, cs[i]); MAD_F_MLA(hi, lo, -b, ca[i]); - *aptr = MAD_F_MLZ(hi, lo); + xr[-1 - i] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, b, cs[i]); MAD_F_MLA(hi, lo, a, ca[i]); - *bptr = MAD_F_MLZ(hi, lo); + xr[ i] = MAD_F_MLZ(hi, lo); # if defined(ASO_ZEROCHECK) } # endif @@ -2141,8 +2151,8 @@ void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) * DESCRIPTION: decode frame main_data */ static -int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, - struct sideinfo *si, unsigned int nch) +enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, + struct sideinfo *si, unsigned int nch) { struct mad_header *header = &frame->header; unsigned int sfreqi, ngr, gr; @@ -2169,7 +2179,7 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; - unsigned char const *sfbwidth = 0; + unsigned char const *sfbwidth[2]; mad_fixed_t xr[2][576]; unsigned int ch; enum mad_error error; @@ -2178,9 +2188,9 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, struct channel *channel = &granule->ch[ch]; unsigned int part2_length; - sfbwidth = sfbwidth_table[sfreqi].l; + sfbwidth[ch] = sfbwidth_table[sfreqi].l; if (channel->block_type == 2) { - sfbwidth = (channel->flags & mixed_block_flag) ? + sfbwidth[ch] = (channel->flags & mixed_block_flag) ? sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; } @@ -2194,7 +2204,7 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, gr == 0 ? 0 : si->scfsi[ch]); } - error = III_huffdecode(ptr, xr[ch], channel, sfbwidth, part2_length); + error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); if (error) return error; } @@ -2202,7 +2212,7 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, /* joint stereo processing */ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { - error = III_stereo(xr, granule, header, sfbwidth); + error = III_stereo(xr, granule, header, sfbwidth[0]); if (error) return error; } @@ -2216,7 +2226,7 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, mad_fixed_t output[36]; if (channel->block_type == 2) { - III_reorder(xr[ch], channel, sfbwidth_table[sfreqi].s); + III_reorder(xr[ch], channel, sfbwidth[ch]); # if !defined(OPT_STRICT) /* @@ -2300,7 +2310,7 @@ int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, } } - return 0; + return MAD_ERROR_NONE; } /* diff --git a/src/libmad/layer3.h b/src/libmad/layer3.h index 30a0861a9..620ae4d94 100644 --- a/src/libmad/layer3.h +++ b/src/libmad/layer3.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: layer3.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: layer3.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_LAYER3_H diff --git a/src/libmad/mad.h b/src/libmad/mad.h deleted file mode 100644 index 33a3f5b73..000000000 --- a/src/libmad/mad.h +++ /dev/null @@ -1,832 +0,0 @@ -/* - * mad - MPEG audio decoder - * Copyright (C) 2000-2001 Robert Leslie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * If you would like to negotiate alternate licensing terms, you may do - * so by contacting the author: Robert Leslie <rob@mars.org> - */ - -# 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 */ - -# ifndef LIBMAD_VERSION_H -# define LIBMAD_VERSION_H - -# define MAD_VERSION_MAJOR 0 -# define MAD_VERSION_MINOR 13 -# define MAD_VERSION_PATCH 0 -# define MAD_VERSION_EXTRA " (beta)" - -# define MAD_VERSION_STRINGIZE(str) #str -# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) - -# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ - MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ - MAD_VERSION_STRING(MAD_VERSION_PATCH) \ - MAD_VERSION_EXTRA - -# define MAD_PUBLISHYEAR "2000-2001" -# define MAD_AUTHOR "Robert Leslie" -# define MAD_EMAIL "rob@mars.org" - -extern char const mad_version[]; -extern char const mad_copyright[]; -extern char const mad_author[]; -extern char const mad_build[]; - -# endif - -/* Id: fixed.h,v 1.23 2001/04/05 04:57:11 rob Exp */ - -# ifndef LIBMAD_FIXED_H -# define LIBMAD_FIXED_H - -# if SIZEOF_INT >= 4 -typedef signed int mad_fixed_t; - -typedef signed int mad_fixed64hi_t; -typedef unsigned int mad_fixed64lo_t; -# else -typedef signed long mad_fixed_t; - -typedef signed long mad_fixed64hi_t; -typedef unsigned long mad_fixed64lo_t; -# endif - -/* - * Fixed-point format: 0xABBBBBBB - * A == whole part (sign + 3 bits) - * B == fractional part (28 bits) - * - * Values are signed two's complement, so the effective range is: - * 0x80000000 to 0x7fffffff - * -8.0 to +7.9999999962747097015380859375 - * - * The smallest representable value is: - * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) - * - * 28 bits of fractional accuracy represent about - * 8.6 digits of decimal accuracy. - * - * Fixed-point numbers can be added or subtracted as normal - * integers, but multiplication requires shifting the 64-bit result - * from 56 fractional bits back to 28 (and rounding.) - * - * Changing the definition of MAD_F_FRACBITS is only partially - * supported, and must be done with care. - */ - -# define MAD_F_FRACBITS 28 - -# if MAD_F_FRACBITS == 28 -# define MAD_F(x) ((mad_fixed_t) (x##L)) -# else -# if MAD_F_FRACBITS < 28 -# warning "MAD_F_FRACBITS < 28" -# define MAD_F(x) ((mad_fixed_t) \ - (((x##L) + \ - (1L << (28 - MAD_F_FRACBITS - 1))) >> \ - (28 - MAD_F_FRACBITS))) -# elif MAD_F_FRACBITS > 28 -# error "MAD_F_FRACBITS > 28 not currently supported" -# define MAD_F(x) ((mad_fixed_t) \ - ((x##L) << (MAD_F_FRACBITS - 28))) -# endif -# endif - -# define MAD_F_MIN ((mad_fixed_t) -0x80000000L) -# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) - -# define MAD_F_ONE MAD_F(0x10000000) - -# define mad_f_tofixed(x) ((mad_fixed_t) \ - ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) -# define mad_f_todouble(x) ((double) \ - ((x) / (double) (1L << MAD_F_FRACBITS))) - -# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) -# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) - /* (x should be positive) */ - -# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) - -# define mad_f_add(x, y) ((x) + (y)) -# define mad_f_sub(x, y) ((x) - (y)) - -# if 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. - */ -# if defined(OPT_ACCURACY) -# define mad_f_mul(x, y) \ - ((mad_fixed_t) \ - ((((signed long long) (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)) -# endif - -# define MAD_F_SCALEBITS MAD_F_FRACBITS - -/* --- Intel --------------------------------------------------------------- */ - -# elif defined(FPM_INTEL) - -/* - * This Intel 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 ("imull %3" \ - : "=a" (lo), "=d" (hi) \ - : "%a" (x), "rm" (y) \ - : "cc") - -# 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; \ - mad_fixed64lo_t __lo; \ - MAD_F_MLX(__hi, __lo, (x), (y)); \ - asm ("addl %2,%0\n\t" \ - "adcl %3,%1" \ - : "=rm" (lo), "=rm" (hi) \ - : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ - : "cc"); \ - }) -# endif /* OPT_ACCURACY */ - -# if defined(OPT_ACCURACY) -/* - * Surprisingly, this is faster than SHRD followed by ADC. - */ -# define mad_f_scale64(hi, lo) \ - ({ mad_fixed64hi_t __hi_; \ - mad_fixed64lo_t __lo_; \ - mad_fixed_t __result; \ - asm ("addl %4,%2\n\t" \ - "adcl %5,%3" \ - : "=rm" (__lo_), "=rm" (__hi_) \ - : "0" (lo), "1" (hi), \ - "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ - : "cc"); \ - asm ("shrdl %3,%2,%1" \ - : "=rm" (__result) \ - : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ - : "cc"); \ - __result; \ - }) -# else -# define mad_f_scale64(hi, lo) \ - ({ mad_fixed_t __result; \ - asm ("shrdl %3,%2,%1" \ - : "=rm" (__result) \ - : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ - : "cc"); \ - __result; \ - }) -# endif /* OPT_ACCURACY */ - -# define MAD_F_SCALEBITS MAD_F_FRACBITS - -/* --- ARM ----------------------------------------------------------------- */ - -# elif defined(FPM_ARM) - -/* - * This ARM V4 version is as accurate as FPM_64BIT but much faster. The - * least significant bit is properly rounded at no CPU cycle cost! - */ -# 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. - */ -# define mad_f_mul(x, y) \ - ({ mad_fixed64hi_t __hi; \ - mad_fixed64lo_t __lo; \ - mad_fixed_t __result; \ - asm ("smull %0, %1, %3, %4\n\t" \ - "movs %0, %0, lsr %5\n\t" \ - "adc %2, %0, %1, lsl %6" \ - : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ - : "%r" (x), "r" (y), \ - "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ - : "cc"); \ - __result; \ - }) -# endif - -# define MAD_F_MLX(hi, lo, x, y) \ - asm ("smull %0, %1, %2, %3" \ - : "=&r" (lo), "=&r" (hi) \ - : "%r" (x), "r" (y)) - -# define MAD_F_MLA(hi, lo, x, y) \ - asm ("smlal %0, %1, %2, %3" \ - : "+r" (lo), "+r" (hi) \ - : "%r" (x), "r" (y)) - -# 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" (lo), "r" (hi), \ - "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ - : "cc"); \ - __result; \ - }) - -# define MAD_F_SCALEBITS MAD_F_FRACBITS - -/* --- MIPS ---------------------------------------------------------------- */ - -# elif defined(FPM_MIPS) - -/* - * This MIPS 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 ("mult %2,%3" \ - : "=l" (lo), "=h" (hi) \ - : "%r" (x), "r" (y)) - -# if defined(HAVE_MADD_ASM) -# define MAD_F_MLA(hi, lo, x, y) \ - asm ("madd %2,%3" \ - : "+l" (lo), "+h" (hi) \ - : "%r" (x), "r" (y)) -# elif defined(HAVE_MADD16_ASM) -/* - * This loses significant accuracy due to the 16-bit integer limit in the - * multiply/accumulate instruction. - */ -# define MAD_F_ML0(hi, lo, x, y) \ - asm ("mult %2,%3" \ - : "=l" (lo), "=h" (hi) \ - : "%r" ((x) >> 12), "r" ((y) >> 16)) -# define MAD_F_MLA(hi, lo, x, y) \ - asm ("madd16 %2,%3" \ - : "+l" (lo), "+h" (hi) \ - : "%r" ((x) >> 12), "r" ((y) >> 16)) -# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) -# endif - -# if defined(OPT_SPEED) -# define mad_f_scale64(hi, lo) \ - ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) -# define MAD_F_SCALEBITS MAD_F_FRACBITS -# endif - -/* --- SPARC --------------------------------------------------------------- */ - -# elif defined(FPM_SPARC) - -/* - * This SPARC V8 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 ("smul %2, %3, %0\n\t" \ - "rd %%y, %1" \ - : "=r" (lo), "=r" (hi) \ - : "%r" (x), "rI" (y)) - -/* --- PowerPC ------------------------------------------------------------- */ - -# elif defined(FPM_PPC) - -/* - * 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(). - */ -# 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)) - -# define MAD_F_MLA(hi, lo, x, y) \ - ({ mad_fixed64hi_t __hi; \ - mad_fixed64lo_t __lo; \ - MAD_F_MLX(__hi, __lo, (x), (y)); \ - asm ("addc %0, %2, %3\n\t" \ - "adde %1, %4, %5" \ - : "=r" (lo), "=r" (hi) \ - : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \ - }) - -# 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. - */ -# 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)); \ - __result; \ - }) -# else -# 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" \ - : "=r" (__result) \ - : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \ - __result; \ - }) -# endif /* OPT_ACCURACY */ - -# define MAD_F_SCALEBITS MAD_F_FRACBITS - -/* --- Default ------------------------------------------------------------- */ - -# elif defined(FPM_DEFAULT) - -/* - * This version is the most portable but it loses significant accuracy. - * Furthermore, accuracy is biased against the second argument, so care - * should be taken when ordering operands. - * - * The scale factors are constant as this is not used with SSO. - * - * Pre-rounding is required to stay within the limits of compliance. - */ -# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ - (((y) + (1L << 15)) >> 16)) - -/* ------------------------------------------------------------------------- */ - -# else -# error "no FPM selected" -# endif - -/* default implementations */ - -# if !defined(mad_f_mul) -# define mad_f_mul(x, y) \ - ({ mad_fixed64hi_t __hi; \ - mad_fixed64lo_t __lo; \ - MAD_F_MLX(__hi, __lo, (x), (y)); \ - mad_f_scale64(__hi, __lo); \ - }) -# endif - -# if !defined(MAD_F_MLA) -# 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_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) -# endif - -# if !defined(MAD_F_ML0) -# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) -# endif - -# if !defined(MAD_F_MLZ) -# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) -# endif - -# if !defined(mad_f_scale64) -# if defined(OPT_ACCURACY) -# define mad_f_scale64(hi, lo) \ - ((((mad_fixed_t) \ - (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ - ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) -# else -# define mad_f_scale64(hi, lo) \ - ((mad_fixed_t) \ - (((hi) << (32 - MAD_F_SCALEBITS)) | \ - ((lo) >> MAD_F_SCALEBITS))) -# endif -# define MAD_F_SCALEBITS MAD_F_FRACBITS -# endif - -/* miscellaneous C routines */ - -mad_fixed_t mad_f_abs(mad_fixed_t); - -# endif - -/* Id: bit.h,v 1.7 2001/04/05 04:57:11 rob Exp */ - -# ifndef LIBMAD_BIT_H -# define LIBMAD_BIT_H - -struct mad_bitptr { - unsigned char const *byte; - unsigned short cache; - unsigned short left; -}; - -void mad_bit_init(struct mad_bitptr *, unsigned char const *); - -# define mad_bit_finish(bitptr) /* nothing */ - -unsigned int mad_bit_length(struct mad_bitptr const *, - struct mad_bitptr const *); - -# define mad_bit_bitsleft(bitptr) ((bitptr)->left) -unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); - -void mad_bit_skip(struct mad_bitptr *, unsigned int); -unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); -void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); - -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 */ - -# ifndef LIBMAD_TIMER_H -# define LIBMAD_TIMER_H - -typedef struct { - signed long seconds; /* whole seconds */ - unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ -} mad_timer_t; - -extern mad_timer_t const mad_timer_zero; - -# define MAD_TIMER_RESOLUTION 352800000UL - -enum mad_units { - MAD_UNITS_HOURS = -2, - MAD_UNITS_MINUTES = -1, - MAD_UNITS_SECONDS = 0, - - /* metric units */ - - MAD_UNITS_DECISECONDS = 10, - MAD_UNITS_CENTISECONDS = 100, - MAD_UNITS_MILLISECONDS = 1000, - - /* audio sample units */ - - MAD_UNITS_8000_HZ = 8000, - MAD_UNITS_11025_HZ = 11025, - MAD_UNITS_12000_HZ = 12000, - - MAD_UNITS_16000_HZ = 16000, - MAD_UNITS_22050_HZ = 22050, - MAD_UNITS_24000_HZ = 24000, - - MAD_UNITS_32000_HZ = 32000, - MAD_UNITS_44100_HZ = 44100, - MAD_UNITS_48000_HZ = 48000, - - /* video frame/field units */ - - MAD_UNITS_24_FPS = 24, - MAD_UNITS_25_FPS = 25, - MAD_UNITS_30_FPS = 30, - MAD_UNITS_48_FPS = 48, - MAD_UNITS_50_FPS = 50, - MAD_UNITS_60_FPS = 60, - - /* CD audio frames */ - - MAD_UNITS_75_FPS = 75, - - /* video drop-frame units */ - - MAD_UNITS_23_976_FPS = -24, - MAD_UNITS_24_975_FPS = -25, - MAD_UNITS_29_97_FPS = -30, - MAD_UNITS_47_952_FPS = -48, - MAD_UNITS_49_95_FPS = -50, - MAD_UNITS_59_94_FPS = -60 -}; - -# define mad_timer_reset(timer) (*(timer) = mad_timer_zero) - -int mad_timer_compare(mad_timer_t, mad_timer_t); - -# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) - -void mad_timer_negate(mad_timer_t *); -mad_timer_t mad_timer_abs(mad_timer_t); - -void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); -void mad_timer_add(mad_timer_t *, mad_timer_t); -void mad_timer_multiply(mad_timer_t *, signed long); - -signed long mad_timer_count(mad_timer_t, enum mad_units); -unsigned long mad_timer_fraction(mad_timer_t, unsigned long); -void mad_timer_string(mad_timer_t, char *, char const *, - enum mad_units, enum mad_units, unsigned long); - -# endif - -/* Id: stream.h,v 1.12 2001/04/10 05:18:21 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_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ - MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ - - MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ - - MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ - MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ - MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ - MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ - MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ - - MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ - MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ - MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ - MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ - MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ - MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ - MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ - MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ - MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ - MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ - MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ - MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ -}; - -# define MAD_RECOVERABLE(error) ((error) & 0xff00) - -struct mad_stream { - unsigned char const *buffer; /* input bitstream buffer */ - unsigned char const *bufend; /* end of buffer */ - unsigned long skiplen; /* bytes to skip before next frame */ - - int sync; /* stream sync found */ - unsigned long freerate; /* free bitrate (fixed) */ - - unsigned char const *this_frame; /* start of current frame */ - unsigned char const *next_frame; /* start of next frame */ - struct mad_bitptr ptr; /* current processing bit pointer */ - - struct mad_bitptr anc_ptr; /* ancillary bits pointer */ - unsigned int anc_bitlen; /* number of ancillary bits */ - - unsigned char (*main_data)[MAD_BUFFER_MDLEN]; - /* Layer III main_data() */ - unsigned int md_len; /* bytes in main_data */ - - int options; /* decoding options (see below) */ - enum mad_error error; /* error code (see above) */ -}; - -enum { - MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ - 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 */ -# endif -}; - -void mad_stream_init(struct mad_stream *); -void mad_stream_finish(struct mad_stream *); - -# define mad_stream_options(stream, opts) ((stream)->options = (opts)) - -void mad_stream_buffer(struct mad_stream *, - unsigned char const *, unsigned long); -void mad_stream_skip(struct mad_stream *, unsigned long); - -int mad_stream_sync(struct mad_stream *); - -# endif - -/* Id: frame.h,v 1.13 2001/04/05 04:57:11 rob Exp */ - -# ifndef LIBMAD_FRAME_H -# define LIBMAD_FRAME_H - -enum mad_layer { - MAD_LAYER_I = 1, /* Layer I */ - MAD_LAYER_II = 2, /* Layer II */ - MAD_LAYER_III = 3 /* Layer III */ -}; - -enum mad_mode { - MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ - MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ - MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ - MAD_MODE_STEREO = 3 /* normal LR stereo */ -}; - -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 */ -}; - -struct mad_frame { - struct mad_header { - enum mad_layer layer; /* audio layer (1, 2, or 3) */ - enum mad_mode mode; /* channel mode (see above) */ - int mode_extension; /* additional mode info */ - enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ - - unsigned long bitrate; /* stream bitrate (bps) */ - unsigned int samplerate; /* sampling frequency (Hz) */ - - unsigned short crc_check; /* frame CRC accumulator */ - unsigned short crc_target; /* final target CRC checksum */ - - int flags; /* flags (see below) */ - int private_bits; /* private bits (see below) */ - - mad_timer_t duration; /* audio playing time of frame */ - } header; - - int options; /* decoding options (from stream) */ - - mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ - mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ -}; - -# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) -# define MAD_NSBSAMPLES(header) \ - ((header)->layer == MAD_LAYER_I ? 12 : \ - (((header)->layer == MAD_LAYER_III && \ - ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) - -enum { - MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ - MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ - - MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ - MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ - MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ - MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ - - MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ - MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ - MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ - - MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ - MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ - MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ -}; - -enum { - MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ - MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ -}; - -void mad_header_init(struct mad_header *); - -# define mad_header_finish(header) /* nothing */ - -int mad_header_decode(struct mad_header *, struct mad_stream *); - -void mad_frame_init(struct mad_frame *); -void mad_frame_finish(struct mad_frame *); - -int mad_frame_decode(struct mad_frame *, struct mad_stream *); - -void mad_frame_mute(struct mad_frame *); - -# endif - -/* Id: synth.h,v 1.8 2001/04/05 04:57:11 rob Exp */ - -# ifndef LIBMAD_SYNTH_H -# define LIBMAD_SYNTH_H - -struct mad_synth { - mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ - /* [ch][eo][peo][s][v] */ - - 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; -}; - -void mad_synth_init(struct mad_synth *); - -# define mad_synth_finish(synth) /* nothing */ - -void mad_synth_mute(struct mad_synth *); - -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 */ - -# ifndef LIBMAD_DECODER_H -# define LIBMAD_DECODER_H - -enum mad_decoder_mode { - MAD_DECODER_MODE_SYNC = 0, - MAD_DECODER_MODE_ASYNC -}; - -enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, - MAD_FLOW_STOP = 0x0010, - MAD_FLOW_BREAK = 0x0011, - MAD_FLOW_IGNORE = 0x0020 -}; - -struct mad_decoder { - enum mad_decoder_mode mode; - - int options; - - struct { - long pid; - int in; - int out; - } async; - - struct { - struct mad_stream stream; - struct mad_frame frame; - struct mad_synth synth; - } *sync; - - void *cb_data; - - 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 (*output_func)(void *, - struct mad_header const *, struct mad_pcm *); - enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); - enum mad_flow (*message_func)(void *, void *, unsigned int *); -}; - -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_header const *, - struct mad_pcm *), - enum mad_flow (*)(void *, - struct mad_stream *, - struct mad_frame *), - enum mad_flow (*)(void *, void *, unsigned int *)); -int mad_decoder_finish(struct mad_decoder *); - -# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts)) - -int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); -int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); - -# endif - diff --git a/src/libmad/qc_table.dat b/src/libmad/qc_table.dat index ff3850dfe..1848e0011 100644 --- a/src/libmad/qc_table.dat +++ b/src/libmad/qc_table.dat @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: qc_table.dat,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: qc_table.dat,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ /* diff --git a/src/libmad/rq_table.dat b/src/libmad/rq_table.dat index 5f74e679b..7db10fd33 100644 --- a/src/libmad/rq_table.dat +++ b/src/libmad/rq_table.dat @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: rq_table.dat,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: rq_table.dat,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ /* diff --git a/src/libmad/sf_table.dat b/src/libmad/sf_table.dat index 4317366e5..ea7a1c191 100644 --- a/src/libmad/sf_table.dat +++ b/src/libmad/sf_table.dat @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: sf_table.dat,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: sf_table.dat,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ /* diff --git a/src/libmad/stream.c b/src/libmad/stream.c index 8e73c043f..af794fb81 100644 --- a/src/libmad/stream.c +++ b/src/libmad/stream.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: stream.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: stream.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -54,7 +54,7 @@ void mad_stream_init(struct mad_stream *stream) stream->md_len = 0; stream->options = 0; - stream->error = 0; + stream->error = MAD_ERROR_NONE; } /* @@ -121,3 +121,40 @@ int mad_stream_sync(struct mad_stream *stream) return 0; } + +/* + * NAME: stream->errorstr() + * DESCRIPTION: return a string description of the current error condition + */ +char const *mad_stream_errorstr(struct mad_stream const *stream) +{ + switch (stream->error) { + case MAD_ERROR_NONE: return "no error"; + + case MAD_ERROR_BUFLEN: return "input buffer too small (or EOF)"; + case MAD_ERROR_BUFPTR: return "invalid (null) buffer pointer"; + + case MAD_ERROR_NOMEM: return "not enough memory"; + + case MAD_ERROR_LOSTSYNC: return "lost synchronization"; + case MAD_ERROR_BADLAYER: return "reserved header layer value"; + case MAD_ERROR_BADBITRATE: return "forbidden bitrate value"; + case MAD_ERROR_BADSAMPLERATE: return "reserved sample frequency value"; + case MAD_ERROR_BADEMPHASIS: return "reserved emphasis value"; + + case MAD_ERROR_BADCRC: return "CRC check failed"; + case MAD_ERROR_BADBITALLOC: return "forbidden bit allocation value"; + case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index"; + case MAD_ERROR_BADFRAMELEN: return "bad frame length"; + case MAD_ERROR_BADBIGVALUES: return "bad big_values count"; + case MAD_ERROR_BADBLOCKTYPE: return "reserved block_type"; + case MAD_ERROR_BADSCFSI: return "bad scalefactor selection info"; + case MAD_ERROR_BADDATAPTR: return "bad main_data_begin pointer"; + case MAD_ERROR_BADPART3LEN: return "bad audio data length"; + case MAD_ERROR_BADHUFFTABLE: return "bad Huffman table select"; + case MAD_ERROR_BADHUFFDATA: return "Huffman data overrun"; + case MAD_ERROR_BADSTEREO: return "incompatible block_type for JS"; + } + + return 0; +} diff --git a/src/libmad/stream.h b/src/libmad/stream.h index e745f5b20..b40db3197 100644 --- a/src/libmad/stream.h +++ b/src/libmad/stream.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: stream.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: stream.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_STREAM_H @@ -28,6 +28,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 */ @@ -80,18 +82,19 @@ 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 }; 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 *, unsigned char const *, unsigned long); @@ -99,4 +102,6 @@ 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 diff --git a/src/libmad/synth.c b/src/libmad/synth.c index 9e02f0185..0259f9923 100755 --- a/src/libmad/synth.c +++ b/src/libmad/synth.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: synth.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: synth.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -150,73 +150,69 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, /* costab[i] = cos(PI / (2 * 32) * i) */ # if defined(OPT_DCTO) - enum { - costab1 = MAD_F(0x7fd8878e), - costab2 = MAD_F(0x7f62368f), - costab3 = MAD_F(0x7e9d55fc), - costab4 = MAD_F(0x7d8a5f40), - costab5 = MAD_F(0x7c29fbee), - costab6 = MAD_F(0x7a7d055b), - costab7 = MAD_F(0x78848414), - costab8 = MAD_F(0x7641af3d), - costab9 = MAD_F(0x73b5ebd1), - costab10 = MAD_F(0x70e2cbc6), - costab11 = MAD_F(0x6dca0d14), - costab12 = MAD_F(0x6a6d98a4), - costab13 = MAD_F(0x66cf8120), - costab14 = MAD_F(0x62f201ac), - costab15 = MAD_F(0x5ed77c8a), - costab16 = MAD_F(0x5a82799a), - costab17 = MAD_F(0x55f5a4d2), - costab18 = MAD_F(0x5133cc94), - costab19 = MAD_F(0x4c3fdff4), - costab20 = MAD_F(0x471cece7), - costab21 = MAD_F(0x41ce1e65), - costab22 = MAD_F(0x3c56ba70), - costab23 = MAD_F(0x36ba2014), - costab24 = MAD_F(0x30fbc54d), - costab25 = MAD_F(0x2b1f34eb), - costab26 = MAD_F(0x25280c5e), - costab27 = MAD_F(0x1f19f97b), - costab28 = MAD_F(0x18f8b83c), - costab29 = MAD_F(0x12c8106f), - costab30 = MAD_F(0x0c8bd35e), - costab31 = MAD_F(0x0647d97c) - }; +# define costab1 MAD_F(0x7fd8878e) +# define costab2 MAD_F(0x7f62368f) +# define costab3 MAD_F(0x7e9d55fc) +# define costab4 MAD_F(0x7d8a5f40) +# define costab5 MAD_F(0x7c29fbee) +# define costab6 MAD_F(0x7a7d055b) +# define costab7 MAD_F(0x78848414) +# define costab8 MAD_F(0x7641af3d) +# define costab9 MAD_F(0x73b5ebd1) +# define costab10 MAD_F(0x70e2cbc6) +# define costab11 MAD_F(0x6dca0d14) +# define costab12 MAD_F(0x6a6d98a4) +# define costab13 MAD_F(0x66cf8120) +# define costab14 MAD_F(0x62f201ac) +# define costab15 MAD_F(0x5ed77c8a) +# define costab16 MAD_F(0x5a82799a) +# define costab17 MAD_F(0x55f5a4d2) +# define costab18 MAD_F(0x5133cc94) +# define costab19 MAD_F(0x4c3fdff4) +# define costab20 MAD_F(0x471cece7) +# define costab21 MAD_F(0x41ce1e65) +# define costab22 MAD_F(0x3c56ba70) +# define costab23 MAD_F(0x36ba2014) +# define costab24 MAD_F(0x30fbc54d) +# define costab25 MAD_F(0x2b1f34eb) +# define costab26 MAD_F(0x25280c5e) +# define costab27 MAD_F(0x1f19f97b) +# define costab28 MAD_F(0x18f8b83c) +# define costab29 MAD_F(0x12c8106f) +# define costab30 MAD_F(0x0c8bd35e) +# define costab31 MAD_F(0x0647d97c) # else - enum { - costab1 = MAD_F(0x0ffb10f2), /* 0.998795456 */ - costab2 = MAD_F(0x0fec46d2), /* 0.995184727 */ - costab3 = MAD_F(0x0fd3aac0), /* 0.989176510 */ - costab4 = MAD_F(0x0fb14be8), /* 0.980785280 */ - costab5 = MAD_F(0x0f853f7e), /* 0.970031253 */ - costab6 = MAD_F(0x0f4fa0ab), /* 0.956940336 */ - costab7 = MAD_F(0x0f109082), /* 0.941544065 */ - costab8 = MAD_F(0x0ec835e8), /* 0.923879533 */ - costab9 = MAD_F(0x0e76bd7a), /* 0.903989293 */ - costab10 = MAD_F(0x0e1c5979), /* 0.881921264 */ - costab11 = MAD_F(0x0db941a3), /* 0.857728610 */ - costab12 = MAD_F(0x0d4db315), /* 0.831469612 */ - costab13 = MAD_F(0x0cd9f024), /* 0.803207531 */ - costab14 = MAD_F(0x0c5e4036), /* 0.773010453 */ - costab15 = MAD_F(0x0bdaef91), /* 0.740951125 */ - costab16 = MAD_F(0x0b504f33), /* 0.707106781 */ - costab17 = MAD_F(0x0abeb49a), /* 0.671558955 */ - costab18 = MAD_F(0x0a267993), /* 0.634393284 */ - costab19 = MAD_F(0x0987fbfe), /* 0.595699304 */ - costab20 = MAD_F(0x08e39d9d), /* 0.555570233 */ - costab21 = MAD_F(0x0839c3cd), /* 0.514102744 */ - costab22 = MAD_F(0x078ad74e), /* 0.471396737 */ - costab23 = MAD_F(0x06d74402), /* 0.427555093 */ - costab24 = MAD_F(0x061f78aa), /* 0.382683432 */ - costab25 = MAD_F(0x0563e69d), /* 0.336889853 */ - costab26 = MAD_F(0x04a5018c), /* 0.290284677 */ - costab27 = MAD_F(0x03e33f2f), /* 0.242980180 */ - costab28 = MAD_F(0x031f1708), /* 0.195090322 */ - costab29 = MAD_F(0x0259020e), /* 0.146730474 */ - costab30 = MAD_F(0x01917a6c), /* 0.098017140 */ - costab31 = MAD_F(0x00c8fb30) /* 0.049067674 */ - }; +# define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */ +# define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */ +# define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */ +# define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */ +# define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */ +# define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */ +# define costab7 MAD_F(0x0f109082) /* 0.941544065 */ +# define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */ +# define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */ +# define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */ +# define costab11 MAD_F(0x0db941a3) /* 0.857728610 */ +# define costab12 MAD_F(0x0d4db315) /* 0.831469612 */ +# define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */ +# define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */ +# define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */ +# define costab16 MAD_F(0x0b504f33) /* 0.707106781 */ +# define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */ +# define costab18 MAD_F(0x0a267993) /* 0.634393284 */ +# define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */ +# define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */ +# define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */ +# define costab22 MAD_F(0x078ad74e) /* 0.471396737 */ +# define costab23 MAD_F(0x06d74402) /* 0.427555093 */ +# define costab24 MAD_F(0x061f78aa) /* 0.382683432 */ +# define costab25 MAD_F(0x0563e69d) /* 0.336889853 */ +# define costab26 MAD_F(0x04a5018c) /* 0.290284677 */ +# define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */ +# define costab28 MAD_F(0x031f1708) /* 0.195090322 */ +# define costab29 MAD_F(0x0259020e) /* 0.146730474 */ +# define costab30 MAD_F(0x01917a6c) /* 0.098017140 */ +# define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */ # endif t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); @@ -327,7 +323,7 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t67 = t121 + t122; - t49 = (t67 << 1) - t32; + t49 = (t67 * 2) - t32; /* 3 */ hi[12][slot] = SHIFT(t49); @@ -343,7 +339,7 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t98 = t128 + t129; - t68 = (t98 << 1) - t49; + t68 = (t98 * 2) - t49; /* 5 */ hi[10][slot] = SHIFT(t68); @@ -352,7 +348,7 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t104 = t132 + t133; - t82 = (t104 << 1) - t58; + t82 = (t104 * 2) - t58; /* 6 */ hi[ 9][slot] = SHIFT(t82); @@ -361,9 +357,9 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t110 = t136 + t137; - t87 = (t110 << 1) - t67; + t87 = (t110 * 2) - t67; - t77 = (t87 << 1) - t68; + t77 = (t87 * 2) - t68; /* 7 */ hi[ 8][slot] = SHIFT(t77); @@ -373,13 +369,13 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, /* 8 */ hi[ 7][slot] = SHIFT(t143); /* 24 */ lo[ 8][slot] = - SHIFT((MUL(t141 - t142, costab16) << 1) - t143); + SHIFT((MUL(t141 - t142, costab16) * 2) - t143); t144 = MUL(t73 - t74, costab8); t145 = MUL(t75 - t76, costab24); t146 = t144 + t145; - t88 = (t146 << 1) - t77; + t88 = (t146 * 2) - t77; /* 9 */ hi[ 6][slot] = SHIFT(t88); @@ -387,7 +383,7 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t149 = MUL(t80 - t81, costab24); t150 = t148 + t149; - t105 = (t150 << 1) - t82; + t105 = (t150 * 2) - t82; /* 10 */ hi[ 5][slot] = SHIFT(t105); @@ -395,9 +391,9 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t153 = MUL(t85 - t86, costab24); t154 = t152 + t153; - t111 = (t154 << 1) - t87; + t111 = (t154 * 2) - t87; - t99 = (t111 << 1) - t88; + t99 = (t111 * 2) - t88; /* 11 */ hi[ 4][slot] = SHIFT(t99); @@ -405,106 +401,106 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t158 = MUL(t91 - t92, costab24); t159 = t157 + t158; - t127 = (t159 << 1) - t93; + t127 = (t159 * 2) - t93; /* 12 */ hi[ 3][slot] = SHIFT(t127); - t160 = (MUL(t125 - t126, costab16) << 1) - t127; + t160 = (MUL(t125 - t126, costab16) * 2) - t127; /* 20 */ lo[ 4][slot] = SHIFT(t160); /* 28 */ lo[12][slot] = - SHIFT((((MUL(t157 - t158, costab16) << 1) - t159) << 1) - t160); + SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160); t161 = MUL(t94 - t95, costab8); t162 = MUL(t96 - t97, costab24); t163 = t161 + t162; - t130 = (t163 << 1) - t98; + t130 = (t163 * 2) - t98; - t112 = (t130 << 1) - t99; + t112 = (t130 * 2) - t99; /* 13 */ hi[ 2][slot] = SHIFT(t112); - t164 = (MUL(t128 - t129, costab16) << 1) - t130; + t164 = (MUL(t128 - t129, costab16) * 2) - t130; t166 = MUL(t100 - t101, costab8); t167 = MUL(t102 - t103, costab24); t168 = t166 + t167; - t134 = (t168 << 1) - t104; + t134 = (t168 * 2) - t104; - t120 = (t134 << 1) - t105; + t120 = (t134 * 2) - t105; /* 14 */ hi[ 1][slot] = SHIFT(t120); - t135 = (MUL(t118 - t119, costab16) << 1) - t120; + t135 = (MUL(t118 - t119, costab16) * 2) - t120; /* 18 */ lo[ 2][slot] = SHIFT(t135); - t169 = (MUL(t132 - t133, costab16) << 1) - t134; + t169 = (MUL(t132 - t133, costab16) * 2) - t134; - t151 = (t169 << 1) - t135; + t151 = (t169 * 2) - t135; /* 22 */ lo[ 6][slot] = SHIFT(t151); - t170 = (((MUL(t148 - t149, costab16) << 1) - t150) << 1) - t151; + t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151; /* 26 */ lo[10][slot] = SHIFT(t170); /* 30 */ lo[14][slot] = - SHIFT((((((MUL(t166 - t167, costab16) << 1) - - t168) << 1) - t169) << 1) - t170); + SHIFT((((((MUL(t166 - t167, costab16) * 2) - + t168) * 2) - t169) * 2) - t170); t171 = MUL(t106 - t107, costab8); t172 = MUL(t108 - t109, costab24); t173 = t171 + t172; - t138 = (t173 << 1) - t110; + t138 = (t173 * 2) - t110; - t123 = (t138 << 1) - t111; + t123 = (t138 * 2) - t111; - t139 = (MUL(t121 - t122, costab16) << 1) - t123; + t139 = (MUL(t121 - t122, costab16) * 2) - t123; - t117 = (t123 << 1) - t112; + t117 = (t123 * 2) - t112; /* 15 */ hi[ 0][slot] = SHIFT(t117); - t124 = (MUL(t115 - t116, costab16) << 1) - t117; + t124 = (MUL(t115 - t116, costab16) * 2) - t117; /* 17 */ lo[ 1][slot] = SHIFT(t124); - t131 = (t139 << 1) - t124; + t131 = (t139 * 2) - t124; /* 19 */ lo[ 3][slot] = SHIFT(t131); - t140 = (t164 << 1) - t131; + t140 = (t164 * 2) - t131; /* 21 */ lo[ 5][slot] = SHIFT(t140); - t174 = (MUL(t136 - t137, costab16) << 1) - t138; + t174 = (MUL(t136 - t137, costab16) * 2) - t138; - t155 = (t174 << 1) - t139; + t155 = (t174 * 2) - t139; - t147 = (t155 << 1) - t140; + t147 = (t155 * 2) - t140; /* 23 */ lo[ 7][slot] = SHIFT(t147); - t156 = (((MUL(t144 - t145, costab16) << 1) - t146) << 1) - t147; + t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147; /* 25 */ lo[ 9][slot] = SHIFT(t156); - t175 = (((MUL(t152 - t153, costab16) << 1) - t154) << 1) - t155; + t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155; - t165 = (t175 << 1) - t156; + t165 = (t175 * 2) - t156; /* 27 */ lo[11][slot] = SHIFT(t165); - t176 = (((((MUL(t161 - t162, costab16) << 1) - - t163) << 1) - t164) << 1) - t165; + t176 = (((((MUL(t161 - t162, costab16) * 2) - + t163) * 2) - t164) * 2) - t165; /* 29 */ lo[13][slot] = SHIFT(t176); /* 31 */ lo[15][slot] = - SHIFT((((((((MUL(t171 - t172, costab16) << 1) - - t173) << 1) - t174) << 1) - t175) << 1) - t176); + SHIFT((((((((MUL(t171 - t172, costab16) * 2) - + t173) * 2) - t174) * 2) - t175) * 2) - t176); /* * Totals: @@ -526,12 +522,14 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, # endif # define ML0(hi, lo, x, y) ((lo) = (x) * (y)) # define MLA(hi, lo, x, y) ((lo) += (x) * (y)) +# define MLN(hi, lo) ((lo) = -(lo)) # define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # define SHIFT(x) ((x) >> 2) # define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14) # else # define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y)) # define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y)) +# define MLN(hi, lo) MAD_F_MLN((hi), (lo)) # define MLZ(hi, lo) MAD_F_MLZ((hi), (lo)) # define SHIFT(x) (x) # if defined(MAD_F_SCALEBITS) @@ -589,8 +587,19 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame, Dptr = &D[0]; + ptr = *Dptr + po; + ML0(hi, lo, (*fx)[0], ptr[ 0]); + MLA(hi, lo, (*fx)[1], ptr[14]); + MLA(hi, lo, (*fx)[2], ptr[12]); + MLA(hi, lo, (*fx)[3], ptr[10]); + MLA(hi, lo, (*fx)[4], ptr[ 8]); + MLA(hi, lo, (*fx)[5], ptr[ 6]); + MLA(hi, lo, (*fx)[6], ptr[ 4]); + MLA(hi, lo, (*fx)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); @@ -599,16 +608,6 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame, MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); - ptr = *Dptr + po; - MLA(hi, lo, (*fx)[0], -ptr[ 0]); - MLA(hi, lo, (*fx)[1], -ptr[14]); - MLA(hi, lo, (*fx)[2], -ptr[12]); - MLA(hi, lo, (*fx)[3], -ptr[10]); - MLA(hi, lo, (*fx)[4], -ptr[ 8]); - MLA(hi, lo, (*fx)[5], -ptr[ 6]); - MLA(hi, lo, (*fx)[6], -ptr[ 4]); - MLA(hi, lo, (*fx)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 30; @@ -619,8 +618,19 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame, /* D[32 - sb][i] == -D[sb][31 - i] */ + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); @@ -629,30 +639,10 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame, MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); - ptr = *Dptr + po; - MLA(hi, lo, (*fo)[0], -ptr[ 0]); - MLA(hi, lo, (*fo)[1], -ptr[14]); - MLA(hi, lo, (*fo)[2], -ptr[12]); - MLA(hi, lo, (*fo)[3], -ptr[10]); - MLA(hi, lo, (*fo)[4], -ptr[ 8]); - MLA(hi, lo, (*fo)[5], -ptr[ 6]); - MLA(hi, lo, (*fo)[6], -ptr[ 4]); - MLA(hi, lo, (*fo)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); - ptr = *Dptr - po; - ML0(hi, lo, (*fo)[7], ptr[31 - 2]); - MLA(hi, lo, (*fo)[6], ptr[31 - 4]); - MLA(hi, lo, (*fo)[5], ptr[31 - 6]); - MLA(hi, lo, (*fo)[4], ptr[31 - 8]); - MLA(hi, lo, (*fo)[3], ptr[31 - 10]); - MLA(hi, lo, (*fo)[2], ptr[31 - 12]); - MLA(hi, lo, (*fo)[1], ptr[31 - 14]); - MLA(hi, lo, (*fo)[0], ptr[31 - 16]); - ptr = *Dptr - pe; - MLA(hi, lo, (*fe)[0], ptr[31 - 16]); + ML0(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); @@ -661,6 +651,16 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame, MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); + ptr = *Dptr - po; + MLA(hi, lo, (*fo)[7], ptr[31 - 2]); + MLA(hi, lo, (*fo)[6], ptr[31 - 4]); + MLA(hi, lo, (*fo)[5], ptr[31 - 6]); + MLA(hi, lo, (*fo)[4], ptr[31 - 8]); + MLA(hi, lo, (*fo)[3], ptr[31 - 10]); + MLA(hi, lo, (*fo)[2], ptr[31 - 12]); + MLA(hi, lo, (*fo)[1], ptr[31 - 14]); + MLA(hi, lo, (*fo)[0], ptr[31 - 16]); + *pcm2-- = SHIFT(MLZ(hi, lo)); ++fo; @@ -724,8 +724,19 @@ void synth_half(struct mad_synth *synth, struct mad_frame const *frame, Dptr = &D[0]; + ptr = *Dptr + po; + ML0(hi, lo, (*fx)[0], ptr[ 0]); + MLA(hi, lo, (*fx)[1], ptr[14]); + MLA(hi, lo, (*fx)[2], ptr[12]); + MLA(hi, lo, (*fx)[3], ptr[10]); + MLA(hi, lo, (*fx)[4], ptr[ 8]); + MLA(hi, lo, (*fx)[5], ptr[ 6]); + MLA(hi, lo, (*fx)[6], ptr[ 4]); + MLA(hi, lo, (*fx)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); @@ -734,16 +745,6 @@ void synth_half(struct mad_synth *synth, struct mad_frame const *frame, MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); - ptr = *Dptr + po; - MLA(hi, lo, (*fx)[0], -ptr[ 0]); - MLA(hi, lo, (*fx)[1], -ptr[14]); - MLA(hi, lo, (*fx)[2], -ptr[12]); - MLA(hi, lo, (*fx)[3], -ptr[10]); - MLA(hi, lo, (*fx)[4], -ptr[ 8]); - MLA(hi, lo, (*fx)[5], -ptr[ 6]); - MLA(hi, lo, (*fx)[6], -ptr[ 4]); - MLA(hi, lo, (*fx)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 14; @@ -755,8 +756,19 @@ void synth_half(struct mad_synth *synth, struct mad_frame const *frame, /* D[32 - sb][i] == -D[sb][31 - i] */ if (!(sb & 1)) { + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); @@ -765,16 +777,6 @@ void synth_half(struct mad_synth *synth, struct mad_frame const *frame, MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); - ptr = *Dptr + po; - MLA(hi, lo, (*fo)[0], -ptr[ 0]); - MLA(hi, lo, (*fo)[1], -ptr[14]); - MLA(hi, lo, (*fo)[2], -ptr[12]); - MLA(hi, lo, (*fo)[3], -ptr[10]); - MLA(hi, lo, (*fo)[4], -ptr[ 8]); - MLA(hi, lo, (*fo)[5], -ptr[ 6]); - MLA(hi, lo, (*fo)[6], -ptr[ 4]); - MLA(hi, lo, (*fo)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); ptr = *Dptr - po; diff --git a/src/libmad/synth.h b/src/libmad/synth.h index 87471c423..bf27b882f 100644 --- a/src/libmad/synth.h +++ b/src/libmad/synth.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: synth.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: synth.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_SYNTH_H @@ -25,18 +25,37 @@ # include "fixed.h" # include "frame.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 */ /* [ch][eo][peo][s][v] */ 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 }; void mad_synth_init(struct mad_synth *); diff --git a/src/libmad/timer.c b/src/libmad/timer.c index 9deffc0a5..7c45a2556 100755 --- a/src/libmad/timer.c +++ b/src/libmad/timer.c @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: timer.c,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: timer.c,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifdef HAVE_CONFIG_H @@ -26,7 +26,10 @@ # include "global.h" # include <stdio.h> -# include <assert.h> + +# ifdef HAVE_ASSERT_H +# include <assert.h> +# endif # include "timer.h" @@ -150,68 +153,69 @@ unsigned long scale_rational(unsigned long numer, unsigned long denom, /* * NAME: timer->set() - * DESCRIPTION: set timer to specific value + * DESCRIPTION: set timer to specific (positive) value */ void mad_timer_set(mad_timer_t *timer, unsigned long seconds, - unsigned long fraction, unsigned long fracparts) + unsigned long numer, unsigned long denom) { timer->seconds = seconds; - - if (fraction == 0) - fracparts = 0; - else if (fracparts == 0) { - fracparts = fraction; - fraction = 1; + if (numer >= denom && denom > 0) { + timer->seconds += numer / denom; + numer %= denom; } - switch (fracparts) { + switch (denom) { case 0: + case 1: timer->fraction = 0; break; case MAD_TIMER_RESOLUTION: - timer->fraction = fraction; + timer->fraction = numer; + break; + + case 1000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); break; case 8000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 8000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); break; case 11025: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 11025); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); break; case 12000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 12000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); break; case 16000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 16000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); break; case 22050: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 22050); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); break; case 24000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 24000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); break; case 32000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 32000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); break; case 44100: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 44100); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); break; case 48000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 48000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); break; default: - timer->fraction = - scale_rational(fraction, fracparts, MAD_TIMER_RESOLUTION); + timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); break; } @@ -243,8 +247,8 @@ void mad_timer_multiply(mad_timer_t *timer, signed long scalar) factor = scalar; if (scalar < 0) { - mad_timer_negate(timer); factor = -scalar; + mad_timer_negate(timer); } addend = *timer; @@ -317,11 +321,11 @@ signed long mad_timer_count(mad_timer_t timer, enum mad_units units) * NAME: timer->fraction() * DESCRIPTION: return fractional part of timer in arbitrary terms */ -unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long fracparts) +unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) { timer = mad_timer_abs(timer); - switch (fracparts) { + switch (denom) { case 0: return MAD_TIMER_RESOLUTION / timer.fraction; @@ -329,7 +333,7 @@ unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long fracparts) return timer.fraction; default: - return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, fracparts); + return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); } } @@ -377,12 +381,12 @@ void mad_timer_string(mad_timer_t timer, case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: { - unsigned long fracparts; + unsigned long denom; - fracparts = MAD_TIMER_RESOLUTION / fracunits; + denom = MAD_TIMER_RESOLUTION / fracunits; - frac = timer.fraction / fracparts; - sub = scale_rational(timer.fraction % fracparts, fracparts, subparts); + frac = timer.fraction / denom; + sub = scale_rational(timer.fraction % denom, denom, subparts); } break; diff --git a/src/libmad/timer.h b/src/libmad/timer.h index 82f3319b7..64e8d58d3 100755 --- a/src/libmad/timer.h +++ b/src/libmad/timer.h @@ -1,5 +1,5 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify @@ -16,7 +16,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: timer.h,v 1.1 2001/08/12 02:57:55 guenter Exp $ + * $Id: timer.h,v 1.2 2002/04/30 18:46:58 miguelfreitas Exp $ */ # ifndef LIBMAD_TIMER_H @@ -79,7 +79,7 @@ enum mad_units { MAD_UNITS_59_94_FPS = -60 }; -# 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); diff --git a/src/libmad/version.c b/src/libmad/version.c new file mode 100644 index 000000000..ca9e71518 --- /dev/null +++ b/src/libmad/version.c @@ -0,0 +1,91 @@ +/* + * libmad - MPEG audio decoder library + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: version.c,v 1.1 2002/04/30 18:46:58 miguelfreitas Exp $ + */ + +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif + +# include "global.h" + +# include "version.h" + +char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION; +char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR; +char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; + +char const mad_build[] = "" +# if defined(FPM_64BIT) + "FPM_64BIT " +# elif defined(FPM_INTEL) + "FPM_INTEL " +# elif defined(FPM_ARM) + "FPM_ARM " +# elif defined(FPM_MIPS) + "FPM_MIPS " +# elif defined(FPM_SPARC) + "FPM_SPARC " +# elif defined(FPM_PPC) + "FPM_PPC " +# elif defined(FPM_DEFAULT) + "FPM_DEFAULT " +# endif + +# if defined(ASO_IMDCT) + "ASO_IMDCT " +# endif +# if defined(ASO_INTERLEAVE1) + "ASO_INTERLEAVE1 " +# endif +# if defined(ASO_INTERLEAVE2) + "ASO_INTERLEAVE2 " +# endif +# if defined(ASO_ZEROCHECK) + "ASO_ZEROCHECK " +# endif + +# if defined(OPT_SPEED) + "OPT_SPEED " +# elif defined(OPT_ACCURACY) + "OPT_ACCURACY " +# endif + +# if defined(OPT_SSO) + "OPT_SSO " +# endif + +# if defined(OPT_DCTO) /* never defined here */ + "OPT_DCTO " +# endif + +# if defined(OPT_STRICT) + "OPT_STRICT " +# endif + +# if defined(EXPERIMENTAL) + "EXPERIMENTAL " +# endif + +# if defined(DEBUG) + "DEBUG " +# elif defined(NDEBUG) + "NDEBUG " +# endif +; diff --git a/src/libmad/version.h b/src/libmad/version.h new file mode 100644 index 000000000..c786006d2 --- /dev/null +++ b/src/libmad/version.h @@ -0,0 +1,47 @@ +/* + * libmad - MPEG audio decoder library + * Copyright (C) 2000-2001 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: version.h,v 1.1 2002/04/30 18:46:58 miguelfreitas Exp $ + */ + +# ifndef LIBMAD_VERSION_H +# define LIBMAD_VERSION_H + +# define MAD_VERSION_MAJOR 0 +# define MAD_VERSION_MINOR 14 +# define MAD_VERSION_PATCH 2 +# define MAD_VERSION_EXTRA " (beta)" + +# define MAD_VERSION_STRINGIZE(str) #str +# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) + +# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ + MAD_VERSION_STRING(MAD_VERSION_PATCH) \ + MAD_VERSION_EXTRA + +# define MAD_PUBLISHYEAR "2000-2001" +# define MAD_AUTHOR "Robert Leslie" +# define MAD_EMAIL "rob@mars.org" + +extern char const mad_version[]; +extern char const mad_copyright[]; +extern char const mad_author[]; +extern char const mad_build[]; + +# endif |