vdr/xine-lib-vdr/src/libmad D.dat Makefile.am Makefile.in bit.c bit.h fixed.c fixed.h frame.c frame.h global.h huffman.c huffman.h imdct_l_arm.S imdct_s.dat layer12.c layer12.h layer3.c layer3.h qc_table.dat rq_table.dat sf_table.dat stream.c stream.h synth.c synth.h timer.c timer.h version.c version.h xine_decoder.c

Darren Salt pkg-vdr-dvb-changes@lists.alioth.debian.org
Mon, 04 Apr 2005 22:32:50 +0000


Update of /cvsroot/pkg-vdr-dvb/vdr/xine-lib-vdr/src/libmad
In directory haydn:/tmp/cvs-serv3673/src/libmad

Added Files:
	D.dat Makefile.am Makefile.in bit.c bit.h fixed.c fixed.h 
	frame.c frame.h global.h huffman.c huffman.h imdct_l_arm.S 
	imdct_s.dat layer12.c layer12.h layer3.c layer3.h qc_table.dat 
	rq_table.dat sf_table.dat stream.c stream.h synth.c synth.h 
	timer.c timer.h version.c version.h xine_decoder.c 
Log Message:
Import of VDR-patched xine-lib.

--- NEW FILE: layer3.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: layer3.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
[...2659 lines suppressed...]
      extra = si.main_data_begin - md_len;
      if (extra + frame_free > next_md_begin)
	extra = next_md_begin - frame_free;

      if (extra < stream->md_len) {
	memmove(*stream->main_data,
		*stream->main_data + stream->md_len - extra, extra);
	stream->md_len = extra;
      }
    }
    else
      stream->md_len = 0;

    memcpy(*stream->main_data + stream->md_len,
	   stream->next_frame - frame_free, frame_free);
    stream->md_len += frame_free;
  }

  return result;
}

--- NEW FILE: layer12.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: layer12.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_LAYER12_H
# define LIBMAD_LAYER12_H

# include "stream.h"
# include "frame.h"

int mad_layer_I(struct mad_stream *, struct mad_frame *);
int mad_layer_II(struct mad_stream *, struct mad_frame *);

# endif

--- NEW FILE: version.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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 2005/04/04 22:32:48 dsalt-guest 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(DEBUG)
  "DEBUG "
# elif defined(NDEBUG)
  "NDEBUG "
# endif

# if defined(EXPERIMENTAL)
  "EXPERIMENTAL "
# endif

# 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
;

--- NEW FILE: global.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: global.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_GLOBAL_H
# define LIBMAD_GLOBAL_H

/* conditional debugging */

# if defined(DEBUG) && defined(NDEBUG)
#  error "cannot define both DEBUG and NDEBUG"
# endif

# if defined(DEBUG)
#  include <stdio.h>
# endif

/* conditional features */

# if defined(OPT_SPEED) && defined(OPT_ACCURACY)
#  error "cannot optimize for both speed and accuracy"
# endif

# if defined(OPT_SPEED) && !defined(OPT_SSO)
#  define OPT_SSO
# 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

--- NEW FILE: version.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_VERSION_H
# define LIBMAD_VERSION_H

# define MAD_VERSION_MAJOR	0
# define MAD_VERSION_MINOR	15
# define MAD_VERSION_PATCH	1
# 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-2004"
# define MAD_AUTHOR		"Underbit Technologies, Inc."
# define MAD_EMAIL		"info@underbit.com"

extern char const mad_version[];
extern char const mad_copyright[];
extern char const mad_author[];
extern char const mad_build[];

# endif

--- NEW FILE: layer12.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: layer12.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# ifdef HAVE_LIMITS_H
#  include <limits.h>
# else
#  define CHAR_BIT  8
# endif

# include "fixed.h"
# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "layer12.h"

/*
 * scalefactor table
 * used in both Layer I and Layer II decoding
 */
static
mad_fixed_t const sf_table[64] = {
# include "sf_table.dat"
};

/* --- Layer I ------------------------------------------------------------- */

/* linear scaling table */
static
mad_fixed_t const linear_table[14] = {
  MAD_F(0x15555555),  /* 2^2  / (2^2  - 1) == 1.33333333333333 */
  MAD_F(0x12492492),  /* 2^3  / (2^3  - 1) == 1.14285714285714 */
  MAD_F(0x11111111),  /* 2^4  / (2^4  - 1) == 1.06666666666667 */
  MAD_F(0x10842108),  /* 2^5  / (2^5  - 1) == 1.03225806451613 */
  MAD_F(0x10410410),  /* 2^6  / (2^6  - 1) == 1.01587301587302 */
  MAD_F(0x10204081),  /* 2^7  / (2^7  - 1) == 1.00787401574803 */
  MAD_F(0x10101010),  /* 2^8  / (2^8  - 1) == 1.00392156862745 */
  MAD_F(0x10080402),  /* 2^9  / (2^9  - 1) == 1.00195694716243 */
  MAD_F(0x10040100),  /* 2^10 / (2^10 - 1) == 1.00097751710655 */
  MAD_F(0x10020040),  /* 2^11 / (2^11 - 1) == 1.00048851978505 */
  MAD_F(0x10010010),  /* 2^12 / (2^12 - 1) == 1.00024420024420 */
  MAD_F(0x10008004),  /* 2^13 / (2^13 - 1) == 1.00012208521548 */
  MAD_F(0x10004001),  /* 2^14 / (2^14 - 1) == 1.00006103888177 */
  MAD_F(0x10002000)   /* 2^15 / (2^15 - 1) == 1.00003051850948 */
};

/*
 * NAME:	I_sample()
 * DESCRIPTION:	decode one requantized Layer I sample from a bitstream
 */
static
mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb)
{
  mad_fixed_t sample;

  sample = mad_bit_read(ptr, nb);

  /* invert most significant bit, extend sign, then scale to fixed format */

  sample ^= 1 << (nb - 1);
  sample |= -(sample & (1 << (nb - 1)));

  sample <<= MAD_F_FRACBITS - (nb - 1);

  /* requantize the sample */

  /* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */

  sample += MAD_F_ONE >> (nb - 1);

  return mad_f_mul(sample, linear_table[nb - 2]);

  /* s' = factor * s'' */
  /* (to be performed by caller) */
}

/*
 * NAME:	layer->I()
 * DESCRIPTION:	decode a single Layer I frame
 */
int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
{
  struct mad_header *header = &frame->header;
  unsigned int nch, bound, ch, s, sb, nb;
  unsigned char allocation[2][32], scalefactor[2][32];

  nch = MAD_NCHANNELS(header);

  bound = 32;
  if (header->mode == MAD_MODE_JOINT_STEREO) {
    header->flags |= MAD_FLAG_I_STEREO;
    bound = 4 + header->mode_extension * 4;
  }

  /* check CRC word */

  if (header->flags & MAD_FLAG_PROTECTION) {
    header->crc_check =
      mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
		  header->crc_check);

    if (header->crc_check != header->crc_target &&
	!(frame->options & MAD_OPTION_IGNORECRC)) {
      stream->error = MAD_ERROR_BADCRC;
      return -1;
    }
  }

  /* decode bit allocations */

  for (sb = 0; sb < bound; ++sb) {
    for (ch = 0; ch < nch; ++ch) {
      nb = mad_bit_read(&stream->ptr, 4);

      if (nb == 15) {
	stream->error = MAD_ERROR_BADBITALLOC;
	return -1;
      }

      allocation[ch][sb] = nb ? nb + 1 : 0;
    }
  }

  for (sb = bound; sb < 32; ++sb) {
    nb = mad_bit_read(&stream->ptr, 4);

    if (nb == 15) {
      stream->error = MAD_ERROR_BADBITALLOC;
      return -1;
    }

    allocation[0][sb] =
    allocation[1][sb] = nb ? nb + 1 : 0;
  }

  /* decode scalefactors */

  for (sb = 0; sb < 32; ++sb) {
    for (ch = 0; ch < nch; ++ch) {
      if (allocation[ch][sb]) {
	scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);

# if defined(OPT_STRICT)
	/*
	 * Scalefactor index 63 does not appear in Table B.1 of
	 * ISO/IEC 11172-3. Nonetheless, other implementations accept it,
	 * so we only reject it if OPT_STRICT is defined.
	 */
	if (scalefactor[ch][sb] == 63) {
	  stream->error = MAD_ERROR_BADSCALEFACTOR;
	  return -1;
	}
# endif
      }
    }
  }

  /* decode samples */

  for (s = 0; s < 12; ++s) {
    for (sb = 0; sb < bound; ++sb) {
      for (ch = 0; ch < nch; ++ch) {
	nb = allocation[ch][sb];
	frame->sbsample[ch][s][sb] = nb ?
	  mad_f_mul(I_sample(&stream->ptr, nb),
		    sf_table[scalefactor[ch][sb]]) : 0;
      }
    }

    for (sb = bound; sb < 32; ++sb) {
      if ((nb = allocation[0][sb])) {
	mad_fixed_t sample;

	sample = I_sample(&stream->ptr, nb);

	for (ch = 0; ch < nch; ++ch) {
	  frame->sbsample[ch][s][sb] =
	    mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
	}
      }
      else {
	for (ch = 0; ch < nch; ++ch)
	  frame->sbsample[ch][s][sb] = 0;
      }
    }
  }

  return 0;
}

/* --- Layer II ------------------------------------------------------------ */

/* possible quantization per subband table */
static
struct {
  unsigned int sblimit;
  unsigned char const offsets[30];
} const sbquant_table[5] = {
  /* ISO/IEC 11172-3 Table B.2a */
  { 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3,	/* 0 */
	  3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } },
  /* ISO/IEC 11172-3 Table B.2b */
  { 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3,	/* 1 */
	  3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } },
  /* ISO/IEC 11172-3 Table B.2c */
  {  8, { 5, 5, 2, 2, 2, 2, 2, 2 } },				/* 2 */
  /* ISO/IEC 11172-3 Table B.2d */
  { 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } },		/* 3 */
  /* ISO/IEC 13818-3 Table B.1 */
  { 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,	/* 4 */
	  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }
};

/* bit allocation table */
static
struct {
  unsigned short nbal;
  unsigned short offset;
} const bitalloc_table[8] = {
  { 2, 0 },  /* 0 */
  { 2, 3 },  /* 1 */
  { 3, 3 },  /* 2 */
  { 3, 1 },  /* 3 */
  { 4, 2 },  /* 4 */
  { 4, 3 },  /* 5 */
  { 4, 4 },  /* 6 */
  { 4, 5 }   /* 7 */
};

/* offsets into quantization class table */
static
unsigned char const offset_table[6][15] = {
  { 0, 1, 16                                             },  /* 0 */
  { 0, 1,  2, 3, 4, 5, 16                                },  /* 1 */
  { 0, 1,  2, 3, 4, 5,  6, 7,  8,  9, 10, 11, 12, 13, 14 },  /* 2 */
  { 0, 1,  3, 4, 5, 6,  7, 8,  9, 10, 11, 12, 13, 14, 15 },  /* 3 */
  { 0, 1,  2, 3, 4, 5,  6, 7,  8,  9, 10, 11, 12, 13, 16 },  /* 4 */
  { 0, 2,  4, 5, 6, 7,  8, 9, 10, 11, 12, 13, 14, 15, 16 }   /* 5 */
};

/* quantization class table */
static
struct quantclass {
  unsigned short nlevels;
  unsigned char group;
  unsigned char bits;
  mad_fixed_t C;
  mad_fixed_t D;
} const qc_table[17] = {
# include "qc_table.dat"
};

/*
 * NAME:	II_samples()
 * DESCRIPTION:	decode three requantized Layer II samples from a bitstream
 */
static
void II_samples(struct mad_bitptr *ptr,
		struct quantclass const *quantclass,
		mad_fixed_t output[3])
{
  unsigned int nb, s, sample[3];

  if ((nb = quantclass->group)) {
    unsigned int c, nlevels;

    /* degrouping */
    c = mad_bit_read(ptr, quantclass->bits);
    nlevels = quantclass->nlevels;

    for (s = 0; s < 3; ++s) {
      sample[s] = c % nlevels;
      c /= nlevels;
    }
  }
  else {
    nb = quantclass->bits;

    for (s = 0; s < 3; ++s)
      sample[s] = mad_bit_read(ptr, nb);
  }

  for (s = 0; s < 3; ++s) {
    mad_fixed_t requantized;

    /* invert most significant bit, extend sign, then scale to fixed format */

    requantized  = sample[s] ^ (1 << (nb - 1));
    requantized |= -(requantized & (1 << (nb - 1)));

    requantized <<= MAD_F_FRACBITS - (nb - 1);

    /* requantize the sample */

    /* s'' = C * (s''' + D) */

    output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C);

    /* s' = factor * s'' */
    /* (to be performed by caller) */
  }
}

/*
 * NAME:	layer->II()
 * DESCRIPTION:	decode a single Layer II frame
 */
int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
{
  struct mad_header *header = &frame->header;
  struct mad_bitptr start;
  unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb;
  unsigned char const *offsets;
  unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
  mad_fixed_t samples[3];

  nch = MAD_NCHANNELS(header);

  if (header->flags & MAD_FLAG_LSF_EXT)
    index = 4;
  else if (header->flags & MAD_FLAG_FREEFORMAT)
    goto freeformat;
  else {
    unsigned long bitrate_per_channel;

    bitrate_per_channel = header->bitrate;
    if (nch == 2) {
      bitrate_per_channel /= 2;

# if defined(OPT_STRICT)
      /*
       * ISO/IEC 11172-3 allows only single channel mode for 32, 48, 56, and
       * 80 kbps bitrates in Layer II, but some encoders ignore this
       * restriction. We enforce it if OPT_STRICT is defined.
       */
      if (bitrate_per_channel <= 28000 || bitrate_per_channel == 40000) {
	stream->error = MAD_ERROR_BADMODE;
	return -1;
      }
# endif
    }
    else {  /* nch == 1 */
      if (bitrate_per_channel > 192000) {
	/*
	 * ISO/IEC 11172-3 does not allow single channel mode for 224, 256,
	 * 320, or 384 kbps bitrates in Layer II.
	 */
	stream->error = MAD_ERROR_BADMODE;
	return -1;
      }
    }

    if (bitrate_per_channel <= 48000)
      index = (header->samplerate == 32000) ? 3 : 2;
    else if (bitrate_per_channel <= 80000)
      index = 0;
    else {
    freeformat:
      index = (header->samplerate == 48000) ? 0 : 1;
    }
  }

  sblimit = sbquant_table[index].sblimit;
  offsets = sbquant_table[index].offsets;

  bound = 32;
  if (header->mode == MAD_MODE_JOINT_STEREO) {
    header->flags |= MAD_FLAG_I_STEREO;
    bound = 4 + header->mode_extension * 4;
  }

  if (bound > sblimit)
    bound = sblimit;

  start = stream->ptr;

  /* decode bit allocations */

  for (sb = 0; sb < bound; ++sb) {
    nbal = bitalloc_table[offsets[sb]].nbal;

    for (ch = 0; ch < nch; ++ch)
      allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
  }

  for (sb = bound; sb < sblimit; ++sb) {
    nbal = bitalloc_table[offsets[sb]].nbal;

    allocation[0][sb] =
    allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
  }

  /* decode scalefactor selection info */

  for (sb = 0; sb < sblimit; ++sb) {
    for (ch = 0; ch < nch; ++ch) {
      if (allocation[ch][sb])
	scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
    }
  }

  /* check CRC word */

  if (header->flags & MAD_FLAG_PROTECTION) {
    header->crc_check =
      mad_bit_crc(start, mad_bit_length(&start, &stream->ptr),
		  header->crc_check);

    if (header->crc_check != header->crc_target &&
	!(frame->options & MAD_OPTION_IGNORECRC)) {
      stream->error = MAD_ERROR_BADCRC;
      return -1;
    }
  }

  /* decode scalefactors */

  for (sb = 0; sb < sblimit; ++sb) {
    for (ch = 0; ch < nch; ++ch) {
      if (allocation[ch][sb]) {
	scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);

	switch (scfsi[ch][sb]) {
	case 2:
	  scalefactor[ch][sb][2] =
	  scalefactor[ch][sb][1] =
	  scalefactor[ch][sb][0];
	  break;

	case 0:
	  scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
	  /* fall through */

	case 1:
	case 3:
	  scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
	}

	if (scfsi[ch][sb] & 1)
	  scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1];

# if defined(OPT_STRICT)
	/*
	 * Scalefactor index 63 does not appear in Table B.1 of
	 * ISO/IEC 11172-3. Nonetheless, other implementations accept it,
	 * so we only reject it if OPT_STRICT is defined.
	 */
	if (scalefactor[ch][sb][0] == 63 ||
	    scalefactor[ch][sb][1] == 63 ||
	    scalefactor[ch][sb][2] == 63) {
	  stream->error = MAD_ERROR_BADSCALEFACTOR;
	  return -1;
	}
# endif
      }
    }
  }

  /* decode samples */

  for (gr = 0; gr < 12; ++gr) {
    for (sb = 0; sb < bound; ++sb) {
      for (ch = 0; ch < nch; ++ch) {
	if ((index = allocation[ch][sb])) {
	  index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];

	  II_samples(&stream->ptr, &qc_table[index], samples);

	  for (s = 0; s < 3; ++s) {
	    frame->sbsample[ch][3 * gr + s][sb] =
	      mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
	  }
	}
	else {
	  for (s = 0; s < 3; ++s)
	    frame->sbsample[ch][3 * gr + s][sb] = 0;
	}
      }
    }

    for (sb = bound; sb < sblimit; ++sb) {
      if ((index = allocation[0][sb])) {
	index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];

	II_samples(&stream->ptr, &qc_table[index], samples);

	for (ch = 0; ch < nch; ++ch) {
	  for (s = 0; s < 3; ++s) {
	    frame->sbsample[ch][3 * gr + s][sb] =
	      mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
	  }
	}
      }
      else {
	for (ch = 0; ch < nch; ++ch) {
	  for (s = 0; s < 3; ++s)
	    frame->sbsample[ch][3 * gr + s][sb] = 0;
	}
      }
    }

    for (ch = 0; ch < nch; ++ch) {
      for (s = 0; s < 3; ++s) {
	for (sb = sblimit; sb < 32; ++sb)
	  frame->sbsample[ch][3 * gr + s][sb] = 0;
      }
    }
  }

  return 0;
}

--- NEW FILE: layer3.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: layer3.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_LAYER3_H
# define LIBMAD_LAYER3_H

# include "stream.h"
# include "frame.h"

int mad_layer_III(struct mad_stream *, struct mad_frame *);

# endif

--- NEW FILE: Makefile.am ---
include $(top_srcdir)/misc/Makefile.common

AM_CFLAGS = -DOPT_SPEED

EXTRA_DIST = imdct_l_arm.S

libdir = $(XINE_PLUGINDIR)

lib_LTLIBRARIES = xineplug_decode_mad.la

xineplug_decode_mad_la_SOURCES = \
	bit.c \
	fixed.c \
	frame.c \
	huffman.c \
	layer12.c \
	layer3.c \
	stream.c \
	synth.c \
	timer.c \
	version.c \
	xine_decoder.c

xineplug_decode_mad_la_LIBADD = $(XINE_LIB)
xineplug_decode_mad_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@

noinst_HEADERS = \
	D.dat \
	imdct_s.dat \
	qc_table.dat \
	rq_table.dat \
	sf_table.dat \
	bit.h \
	fixed.h \
	frame.h \
	global.h \
	huffman.h \
	layer12.h \
	layer3.h \
	stream.h \
	synth.h \
	timer.h \
	version.h

--- NEW FILE: fixed.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: fixed.h,v 1.1 2005/04/04 22:32:48 dsalt-guest 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

# 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)
 * 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_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 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)  \
     ((((mad_fixed64_t) (x) * (y)) +  \
       (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
#  else
#   define mad_f_mul(x, y)  \
    ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
#  endif

#  define MAD_F_SCALEBITS  MAD_F_FRACBITS

/* --- Intel --------------------------------------------------------------- */

# 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)  \
    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;  \
    })
#   elif defined(OPT_INTEL)
/*
 * Alternate Intel scaling that may or may not perform better.
 */
#    define mad_f_scale64(hi, lo)  \
    ({ mad_fixed_t __result;  \
       asm ("shrl %3,%1\n\t"  \
	    "shll %4,%2\n\t"  \
	    "orl %2,%1"  \
	    : "=rm" (__result)  \
	    : "0" (lo), "r" (hi),  \
	      "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS)  \
	    : "cc");  \
       __result;  \
    })
#   else
#    define mad_f_scale64(hi, lo)  \
    ({ 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
#  endif

/* --- 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
/*
 * This is faster than the default implementation via MAD_F_MLX() and
 * 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_MLN(hi, lo)  \
    asm ("rsbs	%0, %2, #0\n\t"  \
	 "rsc	%1, %3, #0"  \
	 : "=r" (lo), "=r" (hi)  \
	 : "0" (lo), "1" (hi)  \
	 : "cc")

#  define mad_f_scale64(hi, lo)  \
    ({ mad_fixed_t __result;  \
       asm ("movs	%0, %1, lsr %3\n\t"  \
	    "adc	%0, %0, %2, lsl %4"  \
	    : "=&r" (__result)  \
	    : "r" (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 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)  \
    do {  \
      asm ("mullw %0,%1,%2"  \
	   : "=r" (lo)  \
	   : "%r" (x), "r" (y));  \
      asm ("mulhw %0,%1,%2"  \
	   : "=r" (hi)  \
	   : "%r" (x), "r" (y));  \
    }  \
    while (0)

#  if defined(OPT_ACCURACY)
/*
 * This gives best accuracy but is not very fast.
 */
#   define MAD_F_MLA(hi, lo, x, y)  \
    ({ mad_fixed64hi_t __hi;  \
       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), "r" (__lo),  \
	      "%r" (hi), "r" (__hi)  \
	    : "xer");  \
    })
#  endif

#  if defined(OPT_ACCURACY)
/*
 * This is slower than the truncating version below it.
 */
#   define mad_f_scale64(hi, lo)  \
    ({ mad_fixed_t __result, __round;  \
       asm ("rotrwi %0,%1,%2"  \
	    : "=r" (__result)  \
	    : "r" (lo), "i" (MAD_F_SCALEBITS));  \
       asm ("extrwi %0,%1,1,0"  \
	    : "=r" (__round)  \
	    : "r" (__result));  \
       asm ("insrwi %0,%1,%2,0"  \
	    : "+r" (__result)  \
	    : "r" (hi), "i" (MAD_F_SCALEBITS));  \
       asm ("add %0,%1,%2"  \
	    : "=r" (__result)  \
	    : "%r" (__result), "r" (__round));  \
       __result;  \
    })
#  else
#   define mad_f_scale64(hi, lo)  \
    ({ mad_fixed_t __result;  \
       asm ("rotrwi %0,%1,%2"  \
	    : "=r" (__result)  \
	    : "r" (lo), "i" (MAD_F_SCALEBITS));  \
       asm ("insrwi %0,%1,%2,0"  \
	    : "+r" (__result)  \
	    : "r" (hi), "i" (MAD_F_SCALEBITS));  \
       __result;  \
    })
#  endif

#  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.
 */
#  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

/* ------------------------------------------------------------------------- */

# else
#  error "no FPM selected"
# endif

/* default implementations */

# if !defined(mad_f_mul)
#  define mad_f_mul(x, y)  \
    ({ register mad_fixed64hi_t __hi;  \
       register 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_MLN(hi, lo)		((lo)  = -(lo))
#  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_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

# 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

/* C routines */

mad_fixed_t mad_f_abs(mad_fixed_t);
mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t);

# endif

--- NEW FILE: frame.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: frame.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# include <stdlib.h>

# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "timer.h"
# include "layer12.h"
# include "layer3.h"

static
unsigned long const bitrate_table[5][15] = {
  /* MPEG-1 */
  { 0,  32000,  64000,  96000, 128000, 160000, 192000, 224000,  /* Layer I   */
       256000, 288000, 320000, 352000, 384000, 416000, 448000 },
  { 0,  32000,  48000,  56000,  64000,  80000,  96000, 112000,  /* Layer II  */
       128000, 160000, 192000, 224000, 256000, 320000, 384000 },
  { 0,  32000,  40000,  48000,  56000,  64000,  80000,  96000,  /* Layer III */
       112000, 128000, 160000, 192000, 224000, 256000, 320000 },

  /* MPEG-2 LSF */
  { 0,  32000,  48000,  56000,  64000,  80000,  96000, 112000,  /* Layer I   */
       128000, 144000, 160000, 176000, 192000, 224000, 256000 },
  { 0,   8000,  16000,  24000,  32000,  40000,  48000,  56000,  /* Layers    */
        64000,  80000,  96000, 112000, 128000, 144000, 160000 } /* II & III  */
};

static
unsigned int const samplerate_table[3] = { 44100, 48000, 32000 };

static
int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = {
  mad_layer_I,
  mad_layer_II,
  mad_layer_III
};

/*
 * NAME:	header->init()
 * DESCRIPTION:	initialize header struct
 */
void mad_header_init(struct mad_header *header)
{
  header->layer          = 0;
  header->mode           = 0;
  header->mode_extension = 0;
  header->emphasis       = 0;

  header->bitrate        = 0;
  header->samplerate     = 0;

  header->crc_check      = 0;
  header->crc_target     = 0;

  header->flags          = 0;
  header->private_bits   = 0;

  header->duration       = mad_timer_zero;
}

/*
 * NAME:	frame->init()
 * DESCRIPTION:	initialize frame struct
 */
void mad_frame_init(struct mad_frame *frame)
{
  mad_header_init(&frame->header);

  frame->options = 0;

  frame->overlap = 0;
  mad_frame_mute(frame);
}

/*
 * NAME:	frame->finish()
 * DESCRIPTION:	deallocate any dynamic memory associated with frame
 */
void mad_frame_finish(struct mad_frame *frame)
{
  mad_header_finish(&frame->header);

  if (frame->overlap) {
    free(frame->overlap);
    frame->overlap = 0;
  }
}

/*
 * NAME:	decode_header()
 * DESCRIPTION:	read header data and following CRC word
 */
static
int decode_header(struct mad_header *header, struct mad_stream *stream)
{
  unsigned int index;

  header->flags        = 0;
  header->private_bits = 0;

  /* header() */

  /* syncword */
  mad_bit_skip(&stream->ptr, 11);

  /* MPEG 2.5 indicator (really part of syncword) */
  if (mad_bit_read(&stream->ptr, 1) == 0)
    header->flags |= MAD_FLAG_MPEG_2_5_EXT;

  /* ID */
  if (mad_bit_read(&stream->ptr, 1) == 0)
    header->flags |= MAD_FLAG_LSF_EXT;
  else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) {
    stream->error = MAD_ERROR_LOSTSYNC;
    return -1;
  }

  /* layer */
  header->layer = 4 - mad_bit_read(&stream->ptr, 2);

  if (header->layer == 4) {
    stream->error = MAD_ERROR_BADLAYER;
    return -1;
  }

  /* protection_bit */
  if (mad_bit_read(&stream->ptr, 1) == 0) {
    header->flags    |= MAD_FLAG_PROTECTION;
    header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff);
  }

  /* bitrate_index */
  index = mad_bit_read(&stream->ptr, 4);

  if (index == 15) {
    stream->error = MAD_ERROR_BADBITRATE;
    return -1;
  }

  if (header->flags & MAD_FLAG_LSF_EXT)
    header->bitrate = bitrate_table[3 + (header->layer >> 1)][index];
  else
    header->bitrate = bitrate_table[header->layer - 1][index];

  /* sampling_frequency */
  index = mad_bit_read(&stream->ptr, 2);

  if (index == 3) {
    stream->error = MAD_ERROR_BADSAMPLERATE;
    return -1;
  }

  header->samplerate = samplerate_table[index];

  if (header->flags & MAD_FLAG_LSF_EXT) {
    header->samplerate /= 2;

    if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
      header->samplerate /= 2;
  }

  /* padding_bit */
  if (mad_bit_read(&stream->ptr, 1))
    header->flags |= MAD_FLAG_PADDING;

  /* private_bit */
  if (mad_bit_read(&stream->ptr, 1))
    header->private_bits |= MAD_PRIVATE_HEADER;

  /* mode */
  header->mode = 3 - mad_bit_read(&stream->ptr, 2);

  /* mode_extension */
  header->mode_extension = mad_bit_read(&stream->ptr, 2);

  /* copyright */
  if (mad_bit_read(&stream->ptr, 1))
    header->flags |= MAD_FLAG_COPYRIGHT;

  /* original/copy */
  if (mad_bit_read(&stream->ptr, 1))
    header->flags |= MAD_FLAG_ORIGINAL;

  /* emphasis */
  header->emphasis = mad_bit_read(&stream->ptr, 2);

# if defined(OPT_STRICT)
  /*
   * ISO/IEC 11172-3 says this is a reserved emphasis value, but
   * streams exist which use it anyway. Since the value is not important
   * to the decoder proper, we allow it unless OPT_STRICT is defined.
   */
  if (header->emphasis == MAD_EMPHASIS_RESERVED) {
    stream->error = MAD_ERROR_BADEMPHASIS;
    return -1;
  }
# endif

  /* error_check() */

  /* crc_check */
  if (header->flags & MAD_FLAG_PROTECTION)
    header->crc_target = mad_bit_read(&stream->ptr, 16);

  return 0;
}

/*
 * NAME:	free_bitrate()
 * DESCRIPTION:	attempt to discover the bitstream's free bitrate
 */
static
int free_bitrate(struct mad_stream *stream, struct mad_header const *header)
{
  struct mad_bitptr keep_ptr;
  unsigned long rate = 0;
  unsigned int pad_slot, slots_per_frame;
  unsigned char const *ptr = 0;

  keep_ptr = stream->ptr;

  pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
  slots_per_frame = (header->layer == MAD_LAYER_III &&
		     (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;

  while (mad_stream_sync(stream) == 0) {
    struct mad_stream peek_stream;
    struct mad_header peek_header;

    peek_stream = *stream;
    peek_header = *header;

    if (decode_header(&peek_header, &peek_stream) == 0 &&
	peek_header.layer == header->layer &&
	peek_header.samplerate == header->samplerate) {
      unsigned int N;

      ptr = mad_bit_nextbyte(&stream->ptr);

      N = ptr - stream->this_frame;

      if (header->layer == MAD_LAYER_I) {
	rate = (unsigned long) header->samplerate *
	  (N - 4 * pad_slot + 4) / 48 / 1000;
      }
      else {
	rate = (unsigned long) header->samplerate *
	  (N - pad_slot + 1) / slots_per_frame / 1000;
      }

      if (rate >= 8)
	break;
    }

    mad_bit_skip(&stream->ptr, 8);
  }

  stream->ptr = keep_ptr;

  if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) {
    stream->error = MAD_ERROR_LOSTSYNC;
    return -1;
  }

  stream->freerate = rate * 1000;

  return 0;
}

/*
 * NAME:	header->decode()
 * DESCRIPTION:	read the next frame header from the stream
 */
int mad_header_decode(struct mad_header *header, struct mad_stream *stream)
{
  register unsigned char const *ptr, *end;
  unsigned int pad_slot, N;

  ptr = stream->next_frame;
  end = stream->bufend;

  if (ptr == 0) {
    stream->error = MAD_ERROR_BUFPTR;
    goto fail;
  }

  /* stream skip */
  if (stream->skiplen) {
    if (!stream->sync)
      ptr = stream->this_frame;

    if (end - ptr < stream->skiplen) {
      stream->skiplen   -= end - ptr;
      stream->next_frame = end;

      stream->error = MAD_ERROR_BUFLEN;
      goto fail;
    }

    ptr += stream->skiplen;
    stream->skiplen = 0;

    stream->sync = 1;
  }

 sync:
  /* synchronize */
  if (stream->sync) {
    if (end - ptr < MAD_BUFFER_GUARD) {
      stream->next_frame = ptr;

      stream->error = MAD_ERROR_BUFLEN;
      goto fail;
    }
    else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
      /* mark point where frame sync word was expected */
      stream->this_frame = ptr;
      stream->next_frame = ptr + 1;

      stream->error = MAD_ERROR_LOSTSYNC;
      goto fail;
    }
  }
  else {
    mad_bit_init(&stream->ptr, ptr);

    if (mad_stream_sync(stream) == -1) {
      if (end - stream->next_frame >= MAD_BUFFER_GUARD)
	stream->next_frame = end - MAD_BUFFER_GUARD;

      stream->error = MAD_ERROR_BUFLEN;
      goto fail;
    }

    ptr = mad_bit_nextbyte(&stream->ptr);
  }

  /* begin processing */
  stream->this_frame = ptr;
  stream->next_frame = ptr + 1;  /* possibly bogus sync word */

  mad_bit_init(&stream->ptr, stream->this_frame);

  if (decode_header(header, stream) == -1)
    goto fail;

  /* calculate frame duration */
  mad_timer_set(&header->duration, 0,
		32 * MAD_NSBSAMPLES(header), header->samplerate);

  /* calculate free bit rate */
  if (header->bitrate == 0) {
    if ((stream->freerate == 0 || !stream->sync ||
	 (header->layer == MAD_LAYER_III && stream->freerate > 640000)) &&
	free_bitrate(stream, header) == -1)
      goto fail;

    header->bitrate = stream->freerate;
    header->flags  |= MAD_FLAG_FREEFORMAT;
  }

  /* calculate beginning of next frame */
  pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;

  if (header->layer == MAD_LAYER_I)
    N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4;
  else {
    unsigned int slots_per_frame;

    slots_per_frame = (header->layer == MAD_LAYER_III &&
		       (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;

    N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot;
  }

  /* verify there is enough data left in buffer to decode this frame */
  if (N + MAD_BUFFER_GUARD > end - stream->this_frame) {
    stream->next_frame = stream->this_frame;

    stream->error = MAD_ERROR_BUFLEN;
    goto fail;
  }

  stream->next_frame = stream->this_frame + N;

  if (!stream->sync) {
    /* check that a valid frame header follows this frame */

    ptr = stream->next_frame;
    if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
      ptr = stream->next_frame = stream->this_frame + 1;
      goto sync;
    }

    stream->sync = 1;
  }

  header->flags |= MAD_FLAG_INCOMPLETE;

  return 0;

 fail:
  stream->sync = 0;

  return -1;
}

/*
 * NAME:	frame->decode()
 * DESCRIPTION:	decode a single frame from a bitstream
 */
int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
{
  frame->options = stream->options;

  /* header() */
  /* error_check() */

  if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) &&
      mad_header_decode(&frame->header, stream) == -1)
    goto fail;

  /* audio_data() */

  frame->header.flags &= ~MAD_FLAG_INCOMPLETE;

  if (decoder_table[frame->header.layer - 1](stream, frame) == -1) {
    if (!MAD_RECOVERABLE(stream->error))
      stream->next_frame = stream->this_frame;

    goto fail;
  }

  /* ancillary_data() */

  if (frame->header.layer != MAD_LAYER_III) {
    struct mad_bitptr next_frame;

    mad_bit_init(&next_frame, stream->next_frame);

    stream->anc_ptr    = stream->ptr;
    stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame);

    mad_bit_finish(&next_frame);
  }

  return 0;

 fail:
  stream->anc_bitlen = 0;
  return -1;
}

/*
 * NAME:	frame->mute()
 * DESCRIPTION:	zero all subband values so the frame becomes silent
 */
void mad_frame_mute(struct mad_frame *frame)
{
  unsigned int s, sb;

  for (s = 0; s < 36; ++s) {
    for (sb = 0; sb < 32; ++sb) {
      frame->sbsample[0][s][sb] =
      frame->sbsample[1][s][sb] = 0;
    }
  }

  if (frame->overlap) {
    for (s = 0; s < 18; ++s) {
      for (sb = 0; sb < 32; ++sb) {
	(*frame->overlap)[0][sb][s] =
	(*frame->overlap)[1][sb][s] = 0;
      }
    }
  }
}

--- NEW FILE: qc_table.dat ---
/*
 * 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: qc_table.dat,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

/*
 * These are the Layer II classes of quantization.
 * The table is derived from Table B.4 of ISO/IEC 11172-3.
 */

  {     3, 2,  5,
    MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e  0.00000000124 */,
    MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e  0.00000000000 */ },
  {     5, 3,  7,
    MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */,
    MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e  0.00000000000 */ },
  {     7, 0,  3,
    MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e  0.00000000107 */,
    MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e  0.00000000000 */ },
  {     9, 4, 10,
    MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e  0.00000000165 */,
    MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e  0.00000000000 */ },
  {    15, 0,  4,
    MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e  0.00000000024 */,
    MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e  0.00000000000 */ },
  {    31, 0,  5,
    MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e  0.00000000097 */,
    MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e  0.00000000000 */ },
  {    63, 0,  6,
    MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e  0.00000000094 */,
    MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e  0.00000000000 */ },
  {   127, 0,  7,
    MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e  0.00000000003 */,
    MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e  0.00000000000 */ },
  {   255, 0,  8,
    MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e  0.00000000024 */,
    MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e  0.00000000000 */ },
  {   511, 0,  9,
    MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e  0.00000000001 */,
    MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e  0.00000000000 */ },
  {  1023, 0, 10,
    MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e  0.00000000094 */,
    MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e  0.00000000000 */ },
  {  2047, 0, 11,
    MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e  0.00000000012 */,
    MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e  0.00000000000 */ },
  {  4095, 0, 12,
    MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e  0.00000000001 */,
    MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e  0.00000000000 */ },
  {  8191, 0, 13,
    MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e  0.00000000001 */,
    MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e  0.00000000000 */ },
  { 16383, 0, 14,
    MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */,
    MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ },
  { 32767, 0, 15,
    MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e  0.00000000093 */,
    MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e  0.00000000000 */ },
  { 65535, 0, 16,
    MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e  0.00000000023 */,
    MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e  0.00000000000 */ }

--- NEW FILE: stream.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: stream.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_STREAM_H
# define LIBMAD_STREAM_H

# include "bit.h"

# define MAD_BUFFER_GUARD	8
# define MAD_BUFFER_MDLEN	(511 + 2048 + MAD_BUFFER_GUARD)

enum mad_error {
  MAD_ERROR_NONE	   = 0x0000,	/* no error */

  MAD_ERROR_BUFLEN	   = 0x0001,	/* input buffer too small (or EOF) */
  MAD_ERROR_BUFPTR	   = 0x0002,	/* invalid (null) buffer pointer */

  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_BADMODE        = 0x0222,	/* bad bitrate/mode combination */
  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)  \
    ((void) ((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 *);

char const *mad_stream_errorstr(struct mad_stream const *);

# endif

--- NEW FILE: timer.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: timer.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# include <stdio.h>

# ifdef HAVE_ASSERT_H
#  include <assert.h>
# endif

# include "timer.h"

mad_timer_t const mad_timer_zero = { 0, 0 };

/*
 * NAME:	timer->compare()
 * DESCRIPTION:	indicate relative order of two timers
 */
int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
{
  signed long diff;

  diff = timer1.seconds - timer2.seconds;
  if (diff < 0)
    return -1;
  else if (diff > 0)
    return +1;

  diff = timer1.fraction - timer2.fraction;
  if (diff < 0)
    return -1;
  else if (diff > 0)
    return +1;

  return 0;
}

/*
 * NAME:	timer->negate()
 * DESCRIPTION:	invert the sign of a timer
 */
void mad_timer_negate(mad_timer_t *timer)
{
  timer->seconds = -timer->seconds;

  if (timer->fraction) {
    timer->seconds -= 1;
    timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
  }
}

/*
 * NAME:	timer->abs()
 * DESCRIPTION:	return the absolute value of a timer
 */
mad_timer_t mad_timer_abs(mad_timer_t timer)
{
  if (timer.seconds < 0)
    mad_timer_negate(&timer);

  return timer;
}

/*
 * NAME:	reduce_timer()
 * DESCRIPTION:	carry timer fraction into seconds
 */
static
void reduce_timer(mad_timer_t *timer)
{
  timer->seconds  += timer->fraction / MAD_TIMER_RESOLUTION;
  timer->fraction %= MAD_TIMER_RESOLUTION;
}

/*
 * NAME:	gcd()
 * DESCRIPTION:	compute greatest common denominator
 */
static
unsigned long gcd(unsigned long num1, unsigned long num2)
{
  unsigned long tmp;

  while (num2) {
    tmp  = num2;
    num2 = num1 % num2;
    num1 = tmp;
  }

  return num1;
}

/*
 * NAME:	reduce_rational()
 * DESCRIPTION:	convert rational expression to lowest terms
 */
static
void reduce_rational(unsigned long *numer, unsigned long *denom)
{
  unsigned long factor;

  factor = gcd(*numer, *denom);

  assert(factor != 0);

  *numer /= factor;
  *denom /= factor;
}

/*
 * NAME:	scale_rational()
 * DESCRIPTION:	solve numer/denom == ?/scale avoiding overflowing
 */
static
unsigned long scale_rational(unsigned long numer, unsigned long denom,
			     unsigned long scale)
{
  reduce_rational(&numer, &denom);
  reduce_rational(&scale, &denom);

  assert(denom != 0);

  if (denom < scale)
    return numer * (scale / denom) + numer * (scale % denom) / denom;
  if (denom < numer)
    return scale * (numer / denom) + scale * (numer % denom) / denom;

  return numer * scale / denom;
}

/*
 * NAME:	timer->set()
 * DESCRIPTION:	set timer to specific (positive) value
 */
void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
		   unsigned long numer, unsigned long denom)
{
  timer->seconds = seconds;
  if (numer >= denom && denom > 0) {
    timer->seconds += numer / denom;
    numer %= denom;
  }

  switch (denom) {
  case 0:
  case 1:
    timer->fraction = 0;
    break;

  case MAD_TIMER_RESOLUTION:
    timer->fraction = numer;
    break;

  case 1000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION /  1000);
    break;

  case 8000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION /  8000);
    break;

  case 11025:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
    break;

  case 12000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
    break;

  case 16000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
    break;

  case 22050:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
    break;

  case 24000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
    break;

  case 32000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
    break;

  case 44100:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
    break;

  case 48000:
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
    break;

  default:
    timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
    break;
  }

  if (timer->fraction >= MAD_TIMER_RESOLUTION)
    reduce_timer(timer);
}

/*
 * NAME:	timer->add()
 * DESCRIPTION:	add one timer to another
 */
void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
{
  timer->seconds  += incr.seconds;
  timer->fraction += incr.fraction;

  if (timer->fraction >= MAD_TIMER_RESOLUTION)
    reduce_timer(timer);
}

/*
 * NAME:	timer->multiply()
 * DESCRIPTION:	multiply a timer by a scalar value
 */
void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
{
  mad_timer_t addend;
  unsigned long factor;

  factor = scalar;
  if (scalar < 0) {
    factor = -scalar;
    mad_timer_negate(timer);
  }

  addend = *timer;
  *timer = mad_timer_zero;

  while (factor) {
    if (factor & 1)
      mad_timer_add(timer, addend);

    mad_timer_add(&addend, addend);
    factor >>= 1;
  }
}

/*
 * NAME:	timer->count()
 * DESCRIPTION:	return timer value in selected units
 */
signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
{
  switch (units) {
  case MAD_UNITS_HOURS:
    return timer.seconds / 60 / 60;

  case MAD_UNITS_MINUTES:
    return timer.seconds / 60;

  case MAD_UNITS_SECONDS:
    return timer.seconds;

  case MAD_UNITS_DECISECONDS:
  case MAD_UNITS_CENTISECONDS:
  case MAD_UNITS_MILLISECONDS:

  case MAD_UNITS_8000_HZ:
  case MAD_UNITS_11025_HZ:
  case MAD_UNITS_12000_HZ:
  case MAD_UNITS_16000_HZ:
  case MAD_UNITS_22050_HZ:
  case MAD_UNITS_24000_HZ:
  case MAD_UNITS_32000_HZ:
  case MAD_UNITS_44100_HZ:
  case MAD_UNITS_48000_HZ:

  case MAD_UNITS_24_FPS:
  case MAD_UNITS_25_FPS:
  case MAD_UNITS_30_FPS:
  case MAD_UNITS_48_FPS:
  case MAD_UNITS_50_FPS:
  case MAD_UNITS_60_FPS:
  case MAD_UNITS_75_FPS:
    return timer.seconds * (signed long) units +
      (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
				   units);

  case MAD_UNITS_23_976_FPS:
  case MAD_UNITS_24_975_FPS:
  case MAD_UNITS_29_97_FPS:
  case MAD_UNITS_47_952_FPS:
  case MAD_UNITS_49_95_FPS:
  case MAD_UNITS_59_94_FPS:
    return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
  }

  /* unsupported units */
  return 0;
}

/*
 * NAME:	timer->fraction()
 * DESCRIPTION:	return fractional part of timer in arbitrary terms
 */
unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
{
  timer = mad_timer_abs(timer);

  switch (denom) {
  case 0:
    return timer.fraction ?
      MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;

  case MAD_TIMER_RESOLUTION:
    return timer.fraction;

  default:
    return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
  }
}

/*
 * NAME:	timer->string()
 * DESCRIPTION:	write a string representation of a timer using a template
 */
void mad_timer_string(mad_timer_t timer,
		      char *dest, char const *format, enum mad_units units,
		      enum mad_units fracunits, unsigned long subparts)
{
  unsigned long hours, minutes, seconds, sub;
  unsigned int frac;

  timer = mad_timer_abs(timer);

  seconds = timer.seconds;
  frac = sub = 0;

  switch (fracunits) {
  case MAD_UNITS_HOURS:
  case MAD_UNITS_MINUTES:
  case MAD_UNITS_SECONDS:
    break;

  case MAD_UNITS_DECISECONDS:
  case MAD_UNITS_CENTISECONDS:
  case MAD_UNITS_MILLISECONDS:

  case MAD_UNITS_8000_HZ:
  case MAD_UNITS_11025_HZ:
  case MAD_UNITS_12000_HZ:
  case MAD_UNITS_16000_HZ:
  case MAD_UNITS_22050_HZ:
  case MAD_UNITS_24000_HZ:
  case MAD_UNITS_32000_HZ:
  case MAD_UNITS_44100_HZ:
  case MAD_UNITS_48000_HZ:

  case MAD_UNITS_24_FPS:
  case MAD_UNITS_25_FPS:
  case MAD_UNITS_30_FPS:
  case MAD_UNITS_48_FPS:
  case MAD_UNITS_50_FPS:
  case MAD_UNITS_60_FPS:
  case MAD_UNITS_75_FPS:
    {
      unsigned long denom;

      denom = MAD_TIMER_RESOLUTION / fracunits;

      frac = timer.fraction / denom;
      sub  = scale_rational(timer.fraction % denom, denom, subparts);
    }
    break;

  case MAD_UNITS_23_976_FPS:
  case MAD_UNITS_24_975_FPS:
  case MAD_UNITS_29_97_FPS:
  case MAD_UNITS_47_952_FPS:
  case MAD_UNITS_49_95_FPS:
  case MAD_UNITS_59_94_FPS:
    /* drop-frame encoding */
    /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
    {
      unsigned long frame, cycle, d, m;

      frame = mad_timer_count(timer, fracunits);

      cycle = -fracunits * 60 * 10 - (10 - 1) * 2;

      d = frame / cycle;
      m = frame % cycle;
      frame += (10 - 1) * 2 * d;
      if (m > 2)
	frame += 2 * ((m - 2) / (cycle / 10));

      frac    = frame % -fracunits;
      seconds = frame / -fracunits;
    }
    break;
  }

  switch (units) {
  case MAD_UNITS_HOURS:
    minutes = seconds / 60;
    hours   = minutes / 60;

    sprintf(dest, format,
	    hours,
	    (unsigned int) (minutes % 60),
	    (unsigned int) (seconds % 60),
	    frac, sub);
    break;

  case MAD_UNITS_MINUTES:
    minutes = seconds / 60;

    sprintf(dest, format,
	    minutes,
	    (unsigned int) (seconds % 60),
	    frac, sub);
    break;

  case MAD_UNITS_SECONDS:
    sprintf(dest, format,
	    seconds,
	    frac, sub);
    break;

  case MAD_UNITS_23_976_FPS:
  case MAD_UNITS_24_975_FPS:
  case MAD_UNITS_29_97_FPS:
  case MAD_UNITS_47_952_FPS:
  case MAD_UNITS_49_95_FPS:
  case MAD_UNITS_59_94_FPS:
    if (fracunits < 0) {
      /* not yet implemented */
      sub = 0;
    }

    /* fall through */

  case MAD_UNITS_DECISECONDS:
  case MAD_UNITS_CENTISECONDS:
  case MAD_UNITS_MILLISECONDS:

  case MAD_UNITS_8000_HZ:
  case MAD_UNITS_11025_HZ:
  case MAD_UNITS_12000_HZ:
  case MAD_UNITS_16000_HZ:
  case MAD_UNITS_22050_HZ:
  case MAD_UNITS_24000_HZ:
  case MAD_UNITS_32000_HZ:
  case MAD_UNITS_44100_HZ:
  case MAD_UNITS_48000_HZ:

  case MAD_UNITS_24_FPS:
  case MAD_UNITS_25_FPS:
  case MAD_UNITS_30_FPS:
  case MAD_UNITS_48_FPS:
  case MAD_UNITS_50_FPS:
  case MAD_UNITS_60_FPS:
  case MAD_UNITS_75_FPS:
    sprintf(dest, format, mad_timer_count(timer, units), sub);
    break;
  }
}

--- NEW FILE: frame.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: frame.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_FRAME_H
# define LIBMAD_FRAME_H

# include "fixed.h"
# include "timer.h"
# include "stream.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 */
  MAD_EMPHASIS_RESERVED   = 2		/* unknown emphasis */
};

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 */
};

struct mad_frame {
  struct mad_header header;		/* MPEG audio 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

--- NEW FILE: timer.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: timer.h,v 1.1 2005/04/04 22:32:48 dsalt-guest 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)	((void) (*(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

--- NEW FILE: stream.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: stream.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# include <stdlib.h>

# include "bit.h"
# include "stream.h"

/*
 * NAME:	stream->init()
 * DESCRIPTION:	initialize stream struct
 */
void mad_stream_init(struct mad_stream *stream)
{
  stream->buffer     = 0;
  stream->bufend     = 0;
  stream->skiplen    = 0;

  stream->sync       = 0;
  stream->freerate   = 0;

  stream->this_frame = 0;
  stream->next_frame = 0;
  mad_bit_init(&stream->ptr, 0);

  mad_bit_init(&stream->anc_ptr, 0);
  stream->anc_bitlen = 0;

  stream->main_data  = 0;
  stream->md_len     = 0;

  stream->options    = 0;
  stream->error      = MAD_ERROR_NONE;
}

/*
 * NAME:	stream->finish()
 * DESCRIPTION:	deallocate any dynamic memory associated with stream
 */
void mad_stream_finish(struct mad_stream *stream)
{
  if (stream->main_data) {
    free(stream->main_data);
    stream->main_data = 0;
  }

  mad_bit_finish(&stream->anc_ptr);
  mad_bit_finish(&stream->ptr);
}

/*
 * NAME:	stream->buffer()
 * DESCRIPTION:	set stream buffer pointers
 */
void mad_stream_buffer(struct mad_stream *stream,
		       unsigned char const *buffer, unsigned long length)
{
  stream->buffer = buffer;
  stream->bufend = buffer + length;

  stream->this_frame = buffer;
  stream->next_frame = buffer;

  stream->sync = 1;

  mad_bit_init(&stream->ptr, buffer);
}

/*
 * NAME:	stream->skip()
 * DESCRIPTION:	arrange to skip bytes before the next frame
 */
void mad_stream_skip(struct mad_stream *stream, unsigned long length)
{
  stream->skiplen += length;
}

/*
 * NAME:	stream->sync()
 * DESCRIPTION:	locate the next stream sync word
 */
int mad_stream_sync(struct mad_stream *stream)
{
  register unsigned char const *ptr, *end;

  ptr = mad_bit_nextbyte(&stream->ptr);
  end = stream->bufend;

  while (ptr < end - 1 &&
	 !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0))
    ++ptr;

  if (end - ptr < MAD_BUFFER_GUARD)
    return -1;

  mad_bit_init(&stream->ptr, ptr);

  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_BADMODE:	 return "bad bitrate/mode combination";
  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;
}

--- NEW FILE: huffman.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: huffman.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_HUFFMAN_H
# define LIBMAD_HUFFMAN_H

union huffquad {
  struct {
    unsigned short final  :  1;
    unsigned short bits   :  3;
    unsigned short offset : 12;
  } ptr;
  struct {
    unsigned short final  :  1;
    unsigned short hlen   :  3;
    unsigned short v      :  1;
    unsigned short w      :  1;
    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;
  struct {
    unsigned short final  :  1;
    unsigned short hlen   :  3;
    unsigned short x      :  4;
    unsigned short y      :  4;
  } value;
  unsigned short final    :  1;
};

struct hufftable {
  union huffpair const *table;
  unsigned short linbits;
  unsigned short startbits;
};

extern union huffquad const *const mad_huff_quad_table[2];
extern struct hufftable const mad_huff_pair_table[32];

# endif

--- NEW FILE: rq_table.dat ---
/*
 * 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: rq_table.dat,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
[...8708 lines suppressed...]
  /* 8188 */  { MAD_F(0x050951bc) /* 0.314775214 */, 19 },
  /* 8189 */  { MAD_F(0x0509877c) /* 0.314826473 */, 19 },
  /* 8190 */  { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 },
  /* 8191 */  { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 },

  /* 8192 */  { MAD_F(0x050a28be) /* 0.314980262 */, 19 },
  /* 8193 */  { MAD_F(0x050a5e80) /* 0.315031530 */, 19 },
  /* 8194 */  { MAD_F(0x050a9443) /* 0.315082799 */, 19 },
  /* 8195 */  { MAD_F(0x050aca06) /* 0.315134071 */, 19 },
  /* 8196 */  { MAD_F(0x050affc9) /* 0.315185344 */, 19 },
  /* 8197 */  { MAD_F(0x050b358e) /* 0.315236620 */, 19 },
  /* 8198 */  { MAD_F(0x050b6b52) /* 0.315287898 */, 19 },
  /* 8199 */  { MAD_F(0x050ba118) /* 0.315339178 */, 19 },
  /* 8200 */  { MAD_F(0x050bd6de) /* 0.315390460 */, 19 },
  /* 8201 */  { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 },
  /* 8202 */  { MAD_F(0x050c426b) /* 0.315493030 */, 19 },
  /* 8203 */  { MAD_F(0x050c7833) /* 0.315544318 */, 19 },
  /* 8204 */  { MAD_F(0x050cadfb) /* 0.315595608 */, 19 },
  /* 8205 */  { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 },
  /* 8206 */  { MAD_F(0x050d198d) /* 0.315698195 */, 19 }

--- NEW FILE: fixed.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: fixed.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# include "fixed.h"

/*
 * NAME:	fixed->abs()
 * DESCRIPTION:	return absolute value of a fixed-point number
 */
mad_fixed_t mad_f_abs(mad_fixed_t x)
{
  return x < 0 ? -x : x;
}

/*
 * NAME:	fixed->div()
 * DESCRIPTION:	perform division using fixed-point math
 */
mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y)
{
  mad_fixed_t q, r;
  unsigned int bits;

  q = mad_f_abs(x / y);

  if (x < 0) {
    x = -x;
    y = -y;
  }

  r = x % y;

  if (y < 0) {
    x = -x;
    y = -y;
  }

  if (q > mad_f_intpart(MAD_F_MAX) &&
      !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0)))
    return 0;

  for (bits = MAD_F_FRACBITS; bits && r; --bits) {
    q <<= 1, r <<= 1;
    if (r >= y)
      r -= y, ++q;
  }

  /* round */
  if (2 * r >= y)
    ++q;

  /* fix sign */
  if ((x < 0) != (y < 0))
    q = -q;

  return q << bits;
}

--- NEW FILE: huffman.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: huffman.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
[...3070 lines suppressed...]
  /* 13 */ { hufftab13,  0, 4 },
  /* 14 */ { 0 /* not used */ },
  /* 15 */ { hufftab15,  0, 4 },
  /* 16 */ { hufftab16,  1, 4 },
  /* 17 */ { hufftab16,  2, 4 },
  /* 18 */ { hufftab16,  3, 4 },
  /* 19 */ { hufftab16,  4, 4 },
  /* 20 */ { hufftab16,  6, 4 },
  /* 21 */ { hufftab16,  8, 4 },
  /* 22 */ { hufftab16, 10, 4 },
  /* 23 */ { hufftab16, 13, 4 },
  /* 24 */ { hufftab24,  4, 4 },
  /* 25 */ { hufftab24,  5, 4 },
  /* 26 */ { hufftab24,  6, 4 },
  /* 27 */ { hufftab24,  7, 4 },
  /* 28 */ { hufftab24,  8, 4 },
  /* 29 */ { hufftab24,  9, 4 },
  /* 30 */ { hufftab24, 11, 4 },
  /* 31 */ { hufftab24, 13, 4 }
};

--- NEW FILE: sf_table.dat ---
/*
 * 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: sf_table.dat,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

/*
 * These are the scalefactor values for Layer I and Layer II.
 * The values are from Table B.1 of ISO/IEC 11172-3.
 *
 * There is some error introduced by the 32-bit fixed-point representation;
 * the amount of error is shown. For 16-bit PCM output, this shouldn't be
 * too much of a problem.
 */

  MAD_F(0x20000000),  /* 2.000000000000 => 2.000000000000, e  0.000000000000 */
  MAD_F(0x1965fea5),  /* 1.587401051968 => 1.587401051074, e  0.000000000894 */
  MAD_F(0x1428a2fa),  /* 1.259921049895 => 1.259921051562, e -0.000000001667 */
  MAD_F(0x10000000),  /* 1.000000000000 => 1.000000000000, e  0.000000000000 */
  MAD_F(0x0cb2ff53),  /* 0.793700525984 => 0.793700527400, e -0.000000001416 */
  MAD_F(0x0a14517d),  /* 0.629960524947 => 0.629960525781, e -0.000000000833 */
  MAD_F(0x08000000),  /* 0.500000000000 => 0.500000000000, e  0.000000000000 */
  MAD_F(0x06597fa9),  /* 0.396850262992 => 0.396850261837, e  0.000000001155 */

  MAD_F(0x050a28be),  /* 0.314980262474 => 0.314980261028, e  0.000000001446 */
  MAD_F(0x04000000),  /* 0.250000000000 => 0.250000000000, e  0.000000000000 */
  MAD_F(0x032cbfd5),  /* 0.198425131496 => 0.198425132781, e -0.000000001285 */
  MAD_F(0x0285145f),  /* 0.157490131237 => 0.157490130514, e  0.000000000723 */
  MAD_F(0x02000000),  /* 0.125000000000 => 0.125000000000, e  0.000000000000 */
  MAD_F(0x01965fea),  /* 0.099212565748 => 0.099212564528, e  0.000000001220 */
  MAD_F(0x01428a30),  /* 0.078745065618 => 0.078745067120, e -0.000000001501 */
  MAD_F(0x01000000),  /* 0.062500000000 => 0.062500000000, e  0.000000000000 */

  MAD_F(0x00cb2ff5),  /* 0.049606282874 => 0.049606282264, e  0.000000000610 */
  MAD_F(0x00a14518),  /* 0.039372532809 => 0.039372533560, e -0.000000000751 */
  MAD_F(0x00800000),  /* 0.031250000000 => 0.031250000000, e  0.000000000000 */
  MAD_F(0x006597fb),  /* 0.024803141437 => 0.024803142995, e -0.000000001558 */
  MAD_F(0x0050a28c),  /* 0.019686266405 => 0.019686266780, e -0.000000000375 */
  MAD_F(0x00400000),  /* 0.015625000000 => 0.015625000000, e  0.000000000000 */
  MAD_F(0x0032cbfd),  /* 0.012401570719 => 0.012401569635, e  0.000000001084 */
  MAD_F(0x00285146),  /* 0.009843133202 => 0.009843133390, e -0.000000000188 */

  MAD_F(0x00200000),  /* 0.007812500000 => 0.007812500000, e  0.000000000000 */
  MAD_F(0x001965ff),  /* 0.006200785359 => 0.006200786680, e -0.000000001321 */
  MAD_F(0x001428a3),  /* 0.004921566601 => 0.004921566695, e -0.000000000094 */
  MAD_F(0x00100000),  /* 0.003906250000 => 0.003906250000, e  0.000000000000 */
  MAD_F(0x000cb2ff),  /* 0.003100392680 => 0.003100391477, e  0.000000001202 */
  MAD_F(0x000a1451),  /* 0.002460783301 => 0.002460781485, e  0.000000001816 */
  MAD_F(0x00080000),  /* 0.001953125000 => 0.001953125000, e  0.000000000000 */
  MAD_F(0x00065980),  /* 0.001550196340 => 0.001550197601, e -0.000000001262 */

  MAD_F(0x00050a29),  /* 0.001230391650 => 0.001230392605, e -0.000000000955 */
  MAD_F(0x00040000),  /* 0.000976562500 => 0.000976562500, e  0.000000000000 */
  MAD_F(0x00032cc0),  /* 0.000775098170 => 0.000775098801, e -0.000000000631 */
  MAD_F(0x00028514),  /* 0.000615195825 => 0.000615194440, e  0.000000001385 */
  MAD_F(0x00020000),  /* 0.000488281250 => 0.000488281250, e  0.000000000000 */
  MAD_F(0x00019660),  /* 0.000387549085 => 0.000387549400, e -0.000000000315 */
  MAD_F(0x0001428a),  /* 0.000307597913 => 0.000307597220, e  0.000000000693 */
  MAD_F(0x00010000),  /* 0.000244140625 => 0.000244140625, e  0.000000000000 */

  MAD_F(0x0000cb30),  /* 0.000193774542 => 0.000193774700, e -0.000000000158 */
  MAD_F(0x0000a145),  /* 0.000153798956 => 0.000153798610, e  0.000000000346 */
  MAD_F(0x00008000),  /* 0.000122070313 => 0.000122070313, e  0.000000000000 */
  MAD_F(0x00006598),  /* 0.000096887271 => 0.000096887350, e -0.000000000079 */
  MAD_F(0x000050a3),  /* 0.000076899478 => 0.000076901168, e -0.000000001689 */
  MAD_F(0x00004000),  /* 0.000061035156 => 0.000061035156, e  0.000000000000 */
  MAD_F(0x000032cc),  /* 0.000048443636 => 0.000048443675, e -0.000000000039 */
  MAD_F(0x00002851),  /* 0.000038449739 => 0.000038448721, e  0.000000001018 */

  MAD_F(0x00002000),  /* 0.000030517578 => 0.000030517578, e  0.000000000000 */
  MAD_F(0x00001966),  /* 0.000024221818 => 0.000024221838, e -0.000000000020 */
  MAD_F(0x00001429),  /* 0.000019224870 => 0.000019226223, e -0.000000001354 */
  MAD_F(0x00001000),  /* 0.000015258789 => 0.000015258789, e -0.000000000000 */
  MAD_F(0x00000cb3),  /* 0.000012110909 => 0.000012110919, e -0.000000000010 */
  MAD_F(0x00000a14),  /* 0.000009612435 => 0.000009611249, e  0.000000001186 */
  MAD_F(0x00000800),  /* 0.000007629395 => 0.000007629395, e -0.000000000000 */
  MAD_F(0x00000659),  /* 0.000006055454 => 0.000006053597, e  0.000000001858 */

  MAD_F(0x0000050a),  /* 0.000004806217 => 0.000004805624, e  0.000000000593 */
  MAD_F(0x00000400),  /* 0.000003814697 => 0.000003814697, e  0.000000000000 */
  MAD_F(0x0000032d),  /* 0.000003027727 => 0.000003028661, e -0.000000000934 */
  MAD_F(0x00000285),  /* 0.000002403109 => 0.000002402812, e  0.000000000296 */
  MAD_F(0x00000200),  /* 0.000001907349 => 0.000001907349, e -0.000000000000 */
  MAD_F(0x00000196),  /* 0.000001513864 => 0.000001512468, e  0.000000001396 */
  MAD_F(0x00000143)   /* 0.000001201554 => 0.000001203269, e -0.000000001714 */

--- NEW FILE: imdct_l_arm.S ---
/*****************************************************************************
* 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
*
*****************************************************************************
*
[...961 lines suppressed...]
    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
    @----


--- NEW FILE: D.dat ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: D.dat,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

/*
 * These are the coefficients for the subband synthesis window. This is a
 * reordered version of Table B.3 from ISO/IEC 11172-3.
 *
 * Every value is parameterized so that shift optimizations can be made at
 * compile-time. For example, every value can be right-shifted 12 bits to
 * minimize multiply instruction times without any loss of accuracy.
 */

  {  PRESHIFT(0x00000000) /*  0.000000000 */,	/*  0 */
    -PRESHIFT(0x0001d000) /* -0.000442505 */,
     PRESHIFT(0x000d5000) /*  0.003250122 */,
    -PRESHIFT(0x001cb000) /* -0.007003784 */,
     PRESHIFT(0x007f5000) /*  0.031082153 */,
    -PRESHIFT(0x01421000) /* -0.078628540 */,
     PRESHIFT(0x019ae000) /*  0.100311279 */,
    -PRESHIFT(0x09271000) /* -0.572036743 */,
     PRESHIFT(0x1251e000) /*  1.144989014 */,
     PRESHIFT(0x09271000) /*  0.572036743 */,
     PRESHIFT(0x019ae000) /*  0.100311279 */,
     PRESHIFT(0x01421000) /*  0.078628540 */,
     PRESHIFT(0x007f5000) /*  0.031082153 */,
     PRESHIFT(0x001cb000) /*  0.007003784 */,
     PRESHIFT(0x000d5000) /*  0.003250122 */,
     PRESHIFT(0x0001d000) /*  0.000442505 */,

     PRESHIFT(0x00000000) /*  0.000000000 */,
    -PRESHIFT(0x0001d000) /* -0.000442505 */,
     PRESHIFT(0x000d5000) /*  0.003250122 */,
    -PRESHIFT(0x001cb000) /* -0.007003784 */,
     PRESHIFT(0x007f5000) /*  0.031082153 */,
    -PRESHIFT(0x01421000) /* -0.078628540 */,
     PRESHIFT(0x019ae000) /*  0.100311279 */,
    -PRESHIFT(0x09271000) /* -0.572036743 */,
     PRESHIFT(0x1251e000) /*  1.144989014 */,
     PRESHIFT(0x09271000) /*  0.572036743 */,
     PRESHIFT(0x019ae000) /*  0.100311279 */,
     PRESHIFT(0x01421000) /*  0.078628540 */,
     PRESHIFT(0x007f5000) /*  0.031082153 */,
     PRESHIFT(0x001cb000) /*  0.007003784 */,
     PRESHIFT(0x000d5000) /*  0.003250122 */,
     PRESHIFT(0x0001d000) /*  0.000442505 */ },

  { -PRESHIFT(0x00001000) /* -0.000015259 */,	/*  1 */
    -PRESHIFT(0x0001f000) /* -0.000473022 */,
     PRESHIFT(0x000da000) /*  0.003326416 */,
    -PRESHIFT(0x00207000) /* -0.007919312 */,
     PRESHIFT(0x007d0000) /*  0.030517578 */,
    -PRESHIFT(0x0158d000) /* -0.084182739 */,
     PRESHIFT(0x01747000) /*  0.090927124 */,
    -PRESHIFT(0x099a8000) /* -0.600219727 */,
     PRESHIFT(0x124f0000) /*  1.144287109 */,
     PRESHIFT(0x08b38000) /*  0.543823242 */,
     PRESHIFT(0x01bde000) /*  0.108856201 */,
     PRESHIFT(0x012b4000) /*  0.073059082 */,
     PRESHIFT(0x0080f000) /*  0.031478882 */,
     PRESHIFT(0x00191000) /*  0.006118774 */,
     PRESHIFT(0x000d0000) /*  0.003173828 */,
     PRESHIFT(0x0001a000) /*  0.000396729 */,

    -PRESHIFT(0x00001000) /* -0.000015259 */,
    -PRESHIFT(0x0001f000) /* -0.000473022 */,
     PRESHIFT(0x000da000) /*  0.003326416 */,
    -PRESHIFT(0x00207000) /* -0.007919312 */,
     PRESHIFT(0x007d0000) /*  0.030517578 */,
    -PRESHIFT(0x0158d000) /* -0.084182739 */,
     PRESHIFT(0x01747000) /*  0.090927124 */,
    -PRESHIFT(0x099a8000) /* -0.600219727 */,
     PRESHIFT(0x124f0000) /*  1.144287109 */,
     PRESHIFT(0x08b38000) /*  0.543823242 */,
     PRESHIFT(0x01bde000) /*  0.108856201 */,
     PRESHIFT(0x012b4000) /*  0.073059082 */,
     PRESHIFT(0x0080f000) /*  0.031478882 */,
     PRESHIFT(0x00191000) /*  0.006118774 */,
     PRESHIFT(0x000d0000) /*  0.003173828 */,
     PRESHIFT(0x0001a000) /*  0.000396729 */ },

  { -PRESHIFT(0x00001000) /* -0.000015259 */,	/*  2 */
    -PRESHIFT(0x00023000) /* -0.000534058 */,
     PRESHIFT(0x000de000) /*  0.003387451 */,
    -PRESHIFT(0x00245000) /* -0.008865356 */,
     PRESHIFT(0x007a0000) /*  0.029785156 */,
    -PRESHIFT(0x016f7000) /* -0.089706421 */,
     PRESHIFT(0x014a8000) /*  0.080688477 */,
    -PRESHIFT(0x0a0d8000) /* -0.628295898 */,
     PRESHIFT(0x12468000) /*  1.142211914 */,
     PRESHIFT(0x083ff000) /*  0.515609741 */,
     PRESHIFT(0x01dd8000) /*  0.116577148 */,
     PRESHIFT(0x01149000) /*  0.067520142 */,
     PRESHIFT(0x00820000) /*  0.031738281 */,
     PRESHIFT(0x0015b000) /*  0.005294800 */,
     PRESHIFT(0x000ca000) /*  0.003082275 */,
     PRESHIFT(0x00018000) /*  0.000366211 */,

    -PRESHIFT(0x00001000) /* -0.000015259 */,
    -PRESHIFT(0x00023000) /* -0.000534058 */,
     PRESHIFT(0x000de000) /*  0.003387451 */,
    -PRESHIFT(0x00245000) /* -0.008865356 */,
     PRESHIFT(0x007a0000) /*  0.029785156 */,
    -PRESHIFT(0x016f7000) /* -0.089706421 */,
     PRESHIFT(0x014a8000) /*  0.080688477 */,
    -PRESHIFT(0x0a0d8000) /* -0.628295898 */,
     PRESHIFT(0x12468000) /*  1.142211914 */,
     PRESHIFT(0x083ff000) /*  0.515609741 */,
     PRESHIFT(0x01dd8000) /*  0.116577148 */,
     PRESHIFT(0x01149000) /*  0.067520142 */,
     PRESHIFT(0x00820000) /*  0.031738281 */,
     PRESHIFT(0x0015b000) /*  0.005294800 */,
     PRESHIFT(0x000ca000) /*  0.003082275 */,
     PRESHIFT(0x00018000) /*  0.000366211 */ },

  { -PRESHIFT(0x00001000) /* -0.000015259 */,	/*  3 */
    -PRESHIFT(0x00026000) /* -0.000579834 */,
     PRESHIFT(0x000e1000) /*  0.003433228 */,
    -PRESHIFT(0x00285000) /* -0.009841919 */,
     PRESHIFT(0x00765000) /*  0.028884888 */,
    -PRESHIFT(0x0185d000) /* -0.095169067 */,
     PRESHIFT(0x011d1000) /*  0.069595337 */,
    -PRESHIFT(0x0a7fe000) /* -0.656219482 */,
     PRESHIFT(0x12386000) /*  1.138763428 */,
     PRESHIFT(0x07ccb000) /*  0.487472534 */,
     PRESHIFT(0x01f9c000) /*  0.123474121 */,
     PRESHIFT(0x00fdf000) /*  0.061996460 */,
     PRESHIFT(0x00827000) /*  0.031845093 */,
     PRESHIFT(0x00126000) /*  0.004486084 */,
     PRESHIFT(0x000c4000) /*  0.002990723 */,
     PRESHIFT(0x00015000) /*  0.000320435 */,

    -PRESHIFT(0x00001000) /* -0.000015259 */,
    -PRESHIFT(0x00026000) /* -0.000579834 */,
     PRESHIFT(0x000e1000) /*  0.003433228 */,
    -PRESHIFT(0x00285000) /* -0.009841919 */,
     PRESHIFT(0x00765000) /*  0.028884888 */,
    -PRESHIFT(0x0185d000) /* -0.095169067 */,
     PRESHIFT(0x011d1000) /*  0.069595337 */,
    -PRESHIFT(0x0a7fe000) /* -0.656219482 */,
     PRESHIFT(0x12386000) /*  1.138763428 */,
     PRESHIFT(0x07ccb000) /*  0.487472534 */,
     PRESHIFT(0x01f9c000) /*  0.123474121 */,
     PRESHIFT(0x00fdf000) /*  0.061996460 */,
     PRESHIFT(0x00827000) /*  0.031845093 */,
     PRESHIFT(0x00126000) /*  0.004486084 */,
     PRESHIFT(0x000c4000) /*  0.002990723 */,
     PRESHIFT(0x00015000) /*  0.000320435 */ },

  { -PRESHIFT(0x00001000) /* -0.000015259 */,	/*  4 */
    -PRESHIFT(0x00029000) /* -0.000625610 */,
     PRESHIFT(0x000e3000) /*  0.003463745 */,
    -PRESHIFT(0x002c7000) /* -0.010848999 */,
     PRESHIFT(0x0071e000) /*  0.027801514 */,
    -PRESHIFT(0x019bd000) /* -0.100540161 */,
     PRESHIFT(0x00ec0000) /*  0.057617187 */,
    -PRESHIFT(0x0af15000) /* -0.683914185 */,
     PRESHIFT(0x12249000) /*  1.133926392 */,
     PRESHIFT(0x075a0000) /*  0.459472656 */,
     PRESHIFT(0x0212c000) /*  0.129577637 */,
     PRESHIFT(0x00e79000) /*  0.056533813 */,
     PRESHIFT(0x00825000) /*  0.031814575 */,
     PRESHIFT(0x000f4000) /*  0.003723145 */,
     PRESHIFT(0x000be000) /*  0.002899170 */,
     PRESHIFT(0x00013000) /*  0.000289917 */,

    -PRESHIFT(0x00001000) /* -0.000015259 */,
    -PRESHIFT(0x00029000) /* -0.000625610 */,
     PRESHIFT(0x000e3000) /*  0.003463745 */,
    -PRESHIFT(0x002c7000) /* -0.010848999 */,
     PRESHIFT(0x0071e000) /*  0.027801514 */,
    -PRESHIFT(0x019bd000) /* -0.100540161 */,
     PRESHIFT(0x00ec0000) /*  0.057617187 */,
    -PRESHIFT(0x0af15000) /* -0.683914185 */,
     PRESHIFT(0x12249000) /*  1.133926392 */,
     PRESHIFT(0x075a0000) /*  0.459472656 */,
     PRESHIFT(0x0212c000) /*  0.129577637 */,
     PRESHIFT(0x00e79000) /*  0.056533813 */,
     PRESHIFT(0x00825000) /*  0.031814575 */,
     PRESHIFT(0x000f4000) /*  0.003723145 */,
     PRESHIFT(0x000be000) /*  0.002899170 */,
     PRESHIFT(0x00013000) /*  0.000289917 */ },

  { -PRESHIFT(0x00001000) /* -0.000015259 */,	/*  5 */
    -PRESHIFT(0x0002d000) /* -0.000686646 */,
     PRESHIFT(0x000e4000) /*  0.003479004 */,
    -PRESHIFT(0x0030b000) /* -0.011886597 */,
     PRESHIFT(0x006cb000) /*  0.026535034 */,
    -PRESHIFT(0x01b17000) /* -0.105819702 */,
     PRESHIFT(0x00b77000) /*  0.044784546 */,
    -PRESHIFT(0x0b619000) /* -0.711318970 */,
     PRESHIFT(0x120b4000) /*  1.127746582 */,
     PRESHIFT(0x06e81000) /*  0.431655884 */,
     PRESHIFT(0x02288000) /*  0.134887695 */,
     PRESHIFT(0x00d17000) /*  0.051132202 */,
     PRESHIFT(0x0081b000) /*  0.031661987 */,
     PRESHIFT(0x000c5000) /*  0.003005981 */,
     PRESHIFT(0x000b7000) /*  0.002792358 */,
     PRESHIFT(0x00011000) /*  0.000259399 */,

    -PRESHIFT(0x00001000) /* -0.000015259 */,
    -PRESHIFT(0x0002d000) /* -0.000686646 */,
     PRESHIFT(0x000e4000) /*  0.003479004 */,
    -PRESHIFT(0x0030b000) /* -0.011886597 */,
     PRESHIFT(0x006cb000) /*  0.026535034 */,
    -PRESHIFT(0x01b17000) /* -0.105819702 */,
     PRESHIFT(0x00b77000) /*  0.044784546 */,
    -PRESHIFT(0x0b619000) /* -0.711318970 */,
     PRESHIFT(0x120b4000) /*  1.127746582 */,
     PRESHIFT(0x06e81000) /*  0.431655884 */,
     PRESHIFT(0x02288000) /*  0.134887695 */,
     PRESHIFT(0x00d17000) /*  0.051132202 */,
     PRESHIFT(0x0081b000) /*  0.031661987 */,
     PRESHIFT(0x000c5000) /*  0.003005981 */,
     PRESHIFT(0x000b7000) /*  0.002792358 */,
     PRESHIFT(0x00011000) /*  0.000259399 */ },

  { -PRESHIFT(0x00001000) /* -0.000015259 */,	/*  6 */
    -PRESHIFT(0x00031000) /* -0.000747681 */,
     PRESHIFT(0x000e4000) /*  0.003479004 */,
    -PRESHIFT(0x00350000) /* -0.012939453 */,
     PRESHIFT(0x0066c000) /*  0.025085449 */,
    -PRESHIFT(0x01c67000) /* -0.110946655 */,
     PRESHIFT(0x007f5000) /*  0.031082153 */,
    -PRESHIFT(0x0bd06000) /* -0.738372803 */,
     PRESHIFT(0x11ec7000) /*  1.120223999 */,
     PRESHIFT(0x06772000) /*  0.404083252 */,
     PRESHIFT(0x023b3000) /*  0.139450073 */,
     PRESHIFT(0x00bbc000) /*  0.045837402 */,
     PRESHIFT(0x00809000) /*  0.031387329 */,
     PRESHIFT(0x00099000) /*  0.002334595 */,
     PRESHIFT(0x000b0000) /*  0.002685547 */,
     PRESHIFT(0x00010000) /*  0.000244141 */,

    -PRESHIFT(0x00001000) /* -0.000015259 */,
    -PRESHIFT(0x00031000) /* -0.000747681 */,
     PRESHIFT(0x000e4000) /*  0.003479004 */,
    -PRESHIFT(0x00350000) /* -0.012939453 */,
     PRESHIFT(0x0066c000) /*  0.025085449 */,
    -PRESHIFT(0x01c67000) /* -0.110946655 */,
     PRESHIFT(0x007f5000) /*  0.031082153 */,
    -PRESHIFT(0x0bd06000) /* -0.738372803 */,
     PRESHIFT(0x11ec7000) /*  1.120223999 */,
     PRESHIFT(0x06772000) /*  0.404083252 */,
     PRESHIFT(0x023b3000) /*  0.139450073 */,
     PRESHIFT(0x00bbc000) /*  0.045837402 */,
     PRESHIFT(0x00809000) /*  0.031387329 */,
     PRESHIFT(0x00099000) /*  0.002334595 */,
     PRESHIFT(0x000b0000) /*  0.002685547 */,
     PRESHIFT(0x00010000) /*  0.000244141 */ },

  { -PRESHIFT(0x00002000) /* -0.000030518 */,	/*  7 */
    -PRESHIFT(0x00035000) /* -0.000808716 */,
     PRESHIFT(0x000e3000) /*  0.003463745 */,
    -PRESHIFT(0x00397000) /* -0.014022827 */,
     PRESHIFT(0x005ff000) /*  0.023422241 */,
    -PRESHIFT(0x01dad000) /* -0.115921021 */,
     PRESHIFT(0x0043a000) /*  0.016510010 */,
    -PRESHIFT(0x0c3d9000) /* -0.765029907 */,
     PRESHIFT(0x11c83000) /*  1.111373901 */,
     PRESHIFT(0x06076000) /*  0.376800537 */,
     PRESHIFT(0x024ad000) /*  0.143264771 */,
     PRESHIFT(0x00a67000) /*  0.040634155 */,
     PRESHIFT(0x007f0000) /*  0.031005859 */,
     PRESHIFT(0x0006f000) /*  0.001693726 */,
     PRESHIFT(0x000a9000) /*  0.002578735 */,
     PRESHIFT(0x0000e000) /*  0.000213623 */,

    -PRESHIFT(0x00002000) /* -0.000030518 */,
    -PRESHIFT(0x00035000) /* -0.000808716 */,
     PRESHIFT(0x000e3000) /*  0.003463745 */,
    -PRESHIFT(0x00397000) /* -0.014022827 */,
     PRESHIFT(0x005ff000) /*  0.023422241 */,
    -PRESHIFT(0x01dad000) /* -0.115921021 */,
     PRESHIFT(0x0043a000) /*  0.016510010 */,
    -PRESHIFT(0x0c3d9000) /* -0.765029907 */,
     PRESHIFT(0x11c83000) /*  1.111373901 */,
     PRESHIFT(0x06076000) /*  0.376800537 */,
     PRESHIFT(0x024ad000) /*  0.143264771 */,
     PRESHIFT(0x00a67000) /*  0.040634155 */,
     PRESHIFT(0x007f0000) /*  0.031005859 */,
     PRESHIFT(0x0006f000) /*  0.001693726 */,
     PRESHIFT(0x000a9000) /*  0.002578735 */,
     PRESHIFT(0x0000e000) /*  0.000213623 */ },

  { -PRESHIFT(0x00002000) /* -0.000030518 */,	/*  8 */
    -PRESHIFT(0x0003a000) /* -0.000885010 */,
     PRESHIFT(0x000e0000) /*  0.003417969 */,
    -PRESHIFT(0x003df000) /* -0.015121460 */,
     PRESHIFT(0x00586000) /*  0.021575928 */,
    -PRESHIFT(0x01ee6000) /* -0.120697021 */,
     PRESHIFT(0x00046000) /*  0.001068115 */,
    -PRESHIFT(0x0ca8d000) /* -0.791213989 */,
     PRESHIFT(0x119e9000) /*  1.101211548 */,
     PRESHIFT(0x05991000) /*  0.349868774 */,
     PRESHIFT(0x02578000) /*  0.146362305 */,
     PRESHIFT(0x0091a000) /*  0.035552979 */,
     PRESHIFT(0x007d1000) /*  0.030532837 */,
     PRESHIFT(0x00048000) /*  0.001098633 */,
     PRESHIFT(0x000a1000) /*  0.002456665 */,
     PRESHIFT(0x0000d000) /*  0.000198364 */,

    -PRESHIFT(0x00002000) /* -0.000030518 */,
    -PRESHIFT(0x0003a000) /* -0.000885010 */,
     PRESHIFT(0x000e0000) /*  0.003417969 */,
    -PRESHIFT(0x003df000) /* -0.015121460 */,
     PRESHIFT(0x00586000) /*  0.021575928 */,
    -PRESHIFT(0x01ee6000) /* -0.120697021 */,
     PRESHIFT(0x00046000) /*  0.001068115 */,
    -PRESHIFT(0x0ca8d000) /* -0.791213989 */,
     PRESHIFT(0x119e9000) /*  1.101211548 */,
     PRESHIFT(0x05991000) /*  0.349868774 */,
     PRESHIFT(0x02578000) /*  0.146362305 */,
     PRESHIFT(0x0091a000) /*  0.035552979 */,
     PRESHIFT(0x007d1000) /*  0.030532837 */,
     PRESHIFT(0x00048000) /*  0.001098633 */,
     PRESHIFT(0x000a1000) /*  0.002456665 */,
     PRESHIFT(0x0000d000) /*  0.000198364 */ },

  { -PRESHIFT(0x00002000) /* -0.000030518 */,	/*  9 */
    -PRESHIFT(0x0003f000) /* -0.000961304 */,
     PRESHIFT(0x000dd000) /*  0.003372192 */,
    -PRESHIFT(0x00428000) /* -0.016235352 */,
     PRESHIFT(0x00500000) /*  0.019531250 */,
    -PRESHIFT(0x02011000) /* -0.125259399 */,
    -PRESHIFT(0x003e6000) /* -0.015228271 */,
    -PRESHIFT(0x0d11e000) /* -0.816864014 */,
     PRESHIFT(0x116fc000) /*  1.089782715 */,
     PRESHIFT(0x052c5000) /*  0.323318481 */,
     PRESHIFT(0x02616000) /*  0.148773193 */,
     PRESHIFT(0x007d6000) /*  0.030609131 */,
     PRESHIFT(0x007aa000) /*  0.029937744 */,
     PRESHIFT(0x00024000) /*  0.000549316 */,
     PRESHIFT(0x0009a000) /*  0.002349854 */,
     PRESHIFT(0x0000b000) /*  0.000167847 */,

    -PRESHIFT(0x00002000) /* -0.000030518 */,
    -PRESHIFT(0x0003f000) /* -0.000961304 */,
     PRESHIFT(0x000dd000) /*  0.003372192 */,
    -PRESHIFT(0x00428000) /* -0.016235352 */,
     PRESHIFT(0x00500000) /*  0.019531250 */,
    -PRESHIFT(0x02011000) /* -0.125259399 */,
    -PRESHIFT(0x003e6000) /* -0.015228271 */,
    -PRESHIFT(0x0d11e000) /* -0.816864014 */,
     PRESHIFT(0x116fc000) /*  1.089782715 */,
     PRESHIFT(0x052c5000) /*  0.323318481 */,
     PRESHIFT(0x02616000) /*  0.148773193 */,
     PRESHIFT(0x007d6000) /*  0.030609131 */,
     PRESHIFT(0x007aa000) /*  0.029937744 */,
     PRESHIFT(0x00024000) /*  0.000549316 */,
     PRESHIFT(0x0009a000) /*  0.002349854 */,
     PRESHIFT(0x0000b000) /*  0.000167847 */ },

  { -PRESHIFT(0x00002000) /* -0.000030518 */,	/* 10 */
    -PRESHIFT(0x00044000) /* -0.001037598 */,
     PRESHIFT(0x000d7000) /*  0.003280640 */,
    -PRESHIFT(0x00471000) /* -0.017349243 */,
     PRESHIFT(0x0046b000) /*  0.017257690 */,
    -PRESHIFT(0x0212b000) /* -0.129562378 */,
    -PRESHIFT(0x0084a000) /* -0.032379150 */,
    -PRESHIFT(0x0d78a000) /* -0.841949463 */,
     PRESHIFT(0x113be000) /*  1.077117920 */,
     PRESHIFT(0x04c16000) /*  0.297210693 */,
     PRESHIFT(0x02687000) /*  0.150497437 */,
     PRESHIFT(0x0069c000) /*  0.025817871 */,
     PRESHIFT(0x0077f000) /*  0.029281616 */,
     PRESHIFT(0x00002000) /*  0.000030518 */,
     PRESHIFT(0x00093000) /*  0.002243042 */,
     PRESHIFT(0x0000a000) /*  0.000152588 */,

    -PRESHIFT(0x00002000) /* -0.000030518 */,
    -PRESHIFT(0x00044000) /* -0.001037598 */,
     PRESHIFT(0x000d7000) /*  0.003280640 */,
    -PRESHIFT(0x00471000) /* -0.017349243 */,
     PRESHIFT(0x0046b000) /*  0.017257690 */,
    -PRESHIFT(0x0212b000) /* -0.129562378 */,
    -PRESHIFT(0x0084a000) /* -0.032379150 */,
    -PRESHIFT(0x0d78a000) /* -0.841949463 */,
     PRESHIFT(0x113be000) /*  1.077117920 */,
     PRESHIFT(0x04c16000) /*  0.297210693 */,
     PRESHIFT(0x02687000) /*  0.150497437 */,
     PRESHIFT(0x0069c000) /*  0.025817871 */,
     PRESHIFT(0x0077f000) /*  0.029281616 */,
     PRESHIFT(0x00002000) /*  0.000030518 */,
     PRESHIFT(0x00093000) /*  0.002243042 */,
     PRESHIFT(0x0000a000) /*  0.000152588 */ },

  { -PRESHIFT(0x00003000) /* -0.000045776 */,	/* 11 */
    -PRESHIFT(0x00049000) /* -0.001113892 */,
     PRESHIFT(0x000d0000) /*  0.003173828 */,
    -PRESHIFT(0x004ba000) /* -0.018463135 */,
     PRESHIFT(0x003ca000) /*  0.014801025 */,
    -PRESHIFT(0x02233000) /* -0.133590698 */,
    -PRESHIFT(0x00ce4000) /* -0.050354004 */,
    -PRESHIFT(0x0ddca000) /* -0.866363525 */,
     PRESHIFT(0x1102f000) /*  1.063217163 */,
     PRESHIFT(0x04587000) /*  0.271591187 */,
     PRESHIFT(0x026cf000) /*  0.151596069 */,
     PRESHIFT(0x0056c000) /*  0.021179199 */,
     PRESHIFT(0x0074e000) /*  0.028533936 */,
    -PRESHIFT(0x0001d000) /* -0.000442505 */,
     PRESHIFT(0x0008b000) /*  0.002120972 */,
     PRESHIFT(0x00009000) /*  0.000137329 */,

    -PRESHIFT(0x00003000) /* -0.000045776 */,
    -PRESHIFT(0x00049000) /* -0.001113892 */,
     PRESHIFT(0x000d0000) /*  0.003173828 */,
    -PRESHIFT(0x004ba000) /* -0.018463135 */,
     PRESHIFT(0x003ca000) /*  0.014801025 */,
    -PRESHIFT(0x02233000) /* -0.133590698 */,
    -PRESHIFT(0x00ce4000) /* -0.050354004 */,
    -PRESHIFT(0x0ddca000) /* -0.866363525 */,
     PRESHIFT(0x1102f000) /*  1.063217163 */,
     PRESHIFT(0x04587000) /*  0.271591187 */,
     PRESHIFT(0x026cf000) /*  0.151596069 */,
     PRESHIFT(0x0056c000) /*  0.021179199 */,
     PRESHIFT(0x0074e000) /*  0.028533936 */,
    -PRESHIFT(0x0001d000) /* -0.000442505 */,
     PRESHIFT(0x0008b000) /*  0.002120972 */,
     PRESHIFT(0x00009000) /*  0.000137329 */ },

  { -PRESHIFT(0x00003000) /* -0.000045776 */,	/* 12 */
    -PRESHIFT(0x0004f000) /* -0.001205444 */,
     PRESHIFT(0x000c8000) /*  0.003051758 */,
    -PRESHIFT(0x00503000) /* -0.019577026 */,
     PRESHIFT(0x0031a000) /*  0.012115479 */,
    -PRESHIFT(0x02326000) /* -0.137298584 */,
    -PRESHIFT(0x011b5000) /* -0.069168091 */,
    -PRESHIFT(0x0e3dd000) /* -0.890090942 */,
     PRESHIFT(0x10c54000) /*  1.048156738 */,
     PRESHIFT(0x03f1b000) /*  0.246505737 */,
     PRESHIFT(0x026ee000) /*  0.152069092 */,
     PRESHIFT(0x00447000) /*  0.016708374 */,
     PRESHIFT(0x00719000) /*  0.027725220 */,
    -PRESHIFT(0x00039000) /* -0.000869751 */,
     PRESHIFT(0x00084000) /*  0.002014160 */,
     PRESHIFT(0x00008000) /*  0.000122070 */,

    -PRESHIFT(0x00003000) /* -0.000045776 */,
    -PRESHIFT(0x0004f000) /* -0.001205444 */,
     PRESHIFT(0x000c8000) /*  0.003051758 */,
    -PRESHIFT(0x00503000) /* -0.019577026 */,
     PRESHIFT(0x0031a000) /*  0.012115479 */,
    -PRESHIFT(0x02326000) /* -0.137298584 */,
    -PRESHIFT(0x011b5000) /* -0.069168091 */,
    -PRESHIFT(0x0e3dd000) /* -0.890090942 */,
     PRESHIFT(0x10c54000) /*  1.048156738 */,
     PRESHIFT(0x03f1b000) /*  0.246505737 */,
     PRESHIFT(0x026ee000) /*  0.152069092 */,
     PRESHIFT(0x00447000) /*  0.016708374 */,
     PRESHIFT(0x00719000) /*  0.027725220 */,
    -PRESHIFT(0x00039000) /* -0.000869751 */,
     PRESHIFT(0x00084000) /*  0.002014160 */,
     PRESHIFT(0x00008000) /*  0.000122070 */ },

  { -PRESHIFT(0x00004000) /* -0.000061035 */,	/* 13 */
    -PRESHIFT(0x00055000) /* -0.001296997 */,
     PRESHIFT(0x000bd000) /*  0.002883911 */,
    -PRESHIFT(0x0054c000) /* -0.020690918 */,
     PRESHIFT(0x0025d000) /*  0.009231567 */,
    -PRESHIFT(0x02403000) /* -0.140670776 */,
    -PRESHIFT(0x016ba000) /* -0.088775635 */,
    -PRESHIFT(0x0e9be000) /* -0.913055420 */,
     PRESHIFT(0x1082d000) /*  1.031936646 */,
     PRESHIFT(0x038d4000) /*  0.221984863 */,
     PRESHIFT(0x026e7000) /*  0.151962280 */,
     PRESHIFT(0x0032e000) /*  0.012420654 */,
     PRESHIFT(0x006df000) /*  0.026840210 */,
    -PRESHIFT(0x00053000) /* -0.001266479 */,
     PRESHIFT(0x0007d000) /*  0.001907349 */,
     PRESHIFT(0x00007000) /*  0.000106812 */,

    -PRESHIFT(0x00004000) /* -0.000061035 */,
    -PRESHIFT(0x00055000) /* -0.001296997 */,
     PRESHIFT(0x000bd000) /*  0.002883911 */,
    -PRESHIFT(0x0054c000) /* -0.020690918 */,
     PRESHIFT(0x0025d000) /*  0.009231567 */,
    -PRESHIFT(0x02403000) /* -0.140670776 */,
    -PRESHIFT(0x016ba000) /* -0.088775635 */,
    -PRESHIFT(0x0e9be000) /* -0.913055420 */,
     PRESHIFT(0x1082d000) /*  1.031936646 */,
     PRESHIFT(0x038d4000) /*  0.221984863 */,
     PRESHIFT(0x026e7000) /*  0.151962280 */,
     PRESHIFT(0x0032e000) /*  0.012420654 */,
     PRESHIFT(0x006df000) /*  0.026840210 */,
    -PRESHIFT(0x00053000) /* -0.001266479 */,
     PRESHIFT(0x0007d000) /*  0.001907349 */,
     PRESHIFT(0x00007000) /*  0.000106812 */ },

  { -PRESHIFT(0x00004000) /* -0.000061035 */,	/* 14 */
    -PRESHIFT(0x0005b000) /* -0.001388550 */,
     PRESHIFT(0x000b1000) /*  0.002700806 */,
    -PRESHIFT(0x00594000) /* -0.021789551 */,
     PRESHIFT(0x00192000) /*  0.006134033 */,
    -PRESHIFT(0x024c8000) /* -0.143676758 */,
    -PRESHIFT(0x01bf2000) /* -0.109161377 */,
    -PRESHIFT(0x0ef69000) /* -0.935195923 */,
     PRESHIFT(0x103be000) /*  1.014617920 */,
     PRESHIFT(0x032b4000) /*  0.198059082 */,
     PRESHIFT(0x026bc000) /*  0.151306152 */,
     PRESHIFT(0x00221000) /*  0.008316040 */,
     PRESHIFT(0x006a2000) /*  0.025909424 */,
    -PRESHIFT(0x0006a000) /* -0.001617432 */,
     PRESHIFT(0x00075000) /*  0.001785278 */,
     PRESHIFT(0x00007000) /*  0.000106812 */,

    -PRESHIFT(0x00004000) /* -0.000061035 */,
    -PRESHIFT(0x0005b000) /* -0.001388550 */,
     PRESHIFT(0x000b1000) /*  0.002700806 */,
    -PRESHIFT(0x00594000) /* -0.021789551 */,
     PRESHIFT(0x00192000) /*  0.006134033 */,
    -PRESHIFT(0x024c8000) /* -0.143676758 */,
    -PRESHIFT(0x01bf2000) /* -0.109161377 */,
    -PRESHIFT(0x0ef69000) /* -0.935195923 */,
     PRESHIFT(0x103be000) /*  1.014617920 */,
     PRESHIFT(0x032b4000) /*  0.198059082 */,
     PRESHIFT(0x026bc000) /*  0.151306152 */,
     PRESHIFT(0x00221000) /*  0.008316040 */,
     PRESHIFT(0x006a2000) /*  0.025909424 */,
    -PRESHIFT(0x0006a000) /* -0.001617432 */,
     PRESHIFT(0x00075000) /*  0.001785278 */,
     PRESHIFT(0x00007000) /*  0.000106812 */ },

  { -PRESHIFT(0x00005000) /* -0.000076294 */,	/* 15 */
    -PRESHIFT(0x00061000) /* -0.001480103 */,
     PRESHIFT(0x000a3000) /*  0.002487183 */,
    -PRESHIFT(0x005da000) /* -0.022857666 */,
     PRESHIFT(0x000b9000) /*  0.002822876 */,
    -PRESHIFT(0x02571000) /* -0.146255493 */,
    -PRESHIFT(0x0215c000) /* -0.130310059 */,
    -PRESHIFT(0x0f4dc000) /* -0.956481934 */,
     PRESHIFT(0x0ff0a000) /*  0.996246338 */,
     PRESHIFT(0x02cbf000) /*  0.174789429 */,
     PRESHIFT(0x0266e000) /*  0.150115967 */,
     PRESHIFT(0x00120000) /*  0.004394531 */,
     PRESHIFT(0x00662000) /*  0.024932861 */,
    -PRESHIFT(0x0007f000) /* -0.001937866 */,
     PRESHIFT(0x0006f000) /*  0.001693726 */,
     PRESHIFT(0x00006000) /*  0.000091553 */,

    -PRESHIFT(0x00005000) /* -0.000076294 */,
    -PRESHIFT(0x00061000) /* -0.001480103 */,
     PRESHIFT(0x000a3000) /*  0.002487183 */,
    -PRESHIFT(0x005da000) /* -0.022857666 */,
     PRESHIFT(0x000b9000) /*  0.002822876 */,
    -PRESHIFT(0x02571000) /* -0.146255493 */,
    -PRESHIFT(0x0215c000) /* -0.130310059 */,
    -PRESHIFT(0x0f4dc000) /* -0.956481934 */,
     PRESHIFT(0x0ff0a000) /*  0.996246338 */,
     PRESHIFT(0x02cbf000) /*  0.174789429 */,
     PRESHIFT(0x0266e000) /*  0.150115967 */,
     PRESHIFT(0x00120000) /*  0.004394531 */,
     PRESHIFT(0x00662000) /*  0.024932861 */,
    -PRESHIFT(0x0007f000) /* -0.001937866 */,
     PRESHIFT(0x0006f000) /*  0.001693726 */,
     PRESHIFT(0x00006000) /*  0.000091553 */ },

  { -PRESHIFT(0x00005000) /* -0.000076294 */,	/* 16 */
    -PRESHIFT(0x00068000) /* -0.001586914 */,
     PRESHIFT(0x00092000) /*  0.002227783 */,
    -PRESHIFT(0x0061f000) /* -0.023910522 */,
    -PRESHIFT(0x0002d000) /* -0.000686646 */,
    -PRESHIFT(0x025ff000) /* -0.148422241 */,
    -PRESHIFT(0x026f7000) /* -0.152206421 */,
    -PRESHIFT(0x0fa13000) /* -0.976852417 */,
     PRESHIFT(0x0fa13000) /*  0.976852417 */,
     PRESHIFT(0x026f7000) /*  0.152206421 */,
     PRESHIFT(0x025ff000) /*  0.148422241 */,
     PRESHIFT(0x0002d000) /*  0.000686646 */,
     PRESHIFT(0x0061f000) /*  0.023910522 */,
    -PRESHIFT(0x00092000) /* -0.002227783 */,
     PRESHIFT(0x00068000) /*  0.001586914 */,
     PRESHIFT(0x00005000) /*  0.000076294 */,

    -PRESHIFT(0x00005000) /* -0.000076294 */,
    -PRESHIFT(0x00068000) /* -0.001586914 */,
     PRESHIFT(0x00092000) /*  0.002227783 */,
    -PRESHIFT(0x0061f000) /* -0.023910522 */,
    -PRESHIFT(0x0002d000) /* -0.000686646 */,
    -PRESHIFT(0x025ff000) /* -0.148422241 */,
    -PRESHIFT(0x026f7000) /* -0.152206421 */,
    -PRESHIFT(0x0fa13000) /* -0.976852417 */,
     PRESHIFT(0x0fa13000) /*  0.976852417 */,
     PRESHIFT(0x026f7000) /*  0.152206421 */,
     PRESHIFT(0x025ff000) /*  0.148422241 */,
     PRESHIFT(0x0002d000) /*  0.000686646 */,
     PRESHIFT(0x0061f000) /*  0.023910522 */,
    -PRESHIFT(0x00092000) /* -0.002227783 */,
     PRESHIFT(0x00068000) /*  0.001586914 */,
     PRESHIFT(0x00005000) /*  0.000076294 */ }

--- NEW FILE: synth.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: synth.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# include "fixed.h"
# include "frame.h"
# include "synth.h"

/*
 * NAME:	synth->init()
 * DESCRIPTION:	initialize synth struct
 */
void mad_synth_init(struct mad_synth *synth)
{
  mad_synth_mute(synth);

  synth->phase = 0;

  synth->pcm.samplerate = 0;
  synth->pcm.channels   = 0;
  synth->pcm.length     = 0;
}

/*
 * NAME:	synth->mute()
 * DESCRIPTION:	zero all polyphase filterbank values, resetting synthesis
 */
void mad_synth_mute(struct mad_synth *synth)
{
  unsigned int ch, s, v;

  for (ch = 0; ch < 2; ++ch) {
    for (s = 0; s < 16; ++s) {
      for (v = 0; v < 8; ++v) {
	synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] =
	synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0;
      }
    }
  }
}

/*
 * An optional optimization called here the Subband Synthesis Optimization
 * (SSO) improves the performance of subband synthesis at the expense of
 * accuracy.
 *
 * The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such
 * that extra scaling and rounding are not necessary. This often allows the
 * compiler to use faster 32-bit multiply-accumulate instructions instead of
 * explicit 64-bit multiply, shift, and add instructions.
 *
 * SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t
 * values requires the result to be right-shifted 28 bits to be properly
 * scaled to the same fixed-point format. Right shifts can be applied at any
 * time to either operand or to the result, so the optimization involves
 * careful placement of these shifts to minimize the loss of accuracy.
 *
 * First, a 14-bit shift is applied with rounding at compile-time to the D[]
 * table of coefficients for the subband synthesis window. This only loses 2
 * bits of accuracy because the lower 12 bits are always zero. A second
 * 12-bit shift occurs after the DCT calculation. This loses 12 bits of
 * accuracy. Finally, a third 2-bit shift occurs just before the sample is
 * saved in the PCM buffer. 14 + 12 + 2 == 28 bits.
 */

/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */

# if defined(FPM_DEFAULT) && !defined(OPT_SSO)
#  define OPT_SSO
# endif

/* second SSO shift, with rounding */

# if defined(OPT_SSO)
#  define SHIFT(x)  (((x) + (1L << 11)) >> 12)
# else
#  define SHIFT(x)  (x)
# endif

/* possible DCT speed optimization */

# if defined(OPT_SPEED) && defined(MAD_F_MLX)
#  define OPT_DCTO
#  define MUL(x, y)  \
    ({ mad_fixed64hi_t hi;  \
       mad_fixed64lo_t lo;  \
       MAD_F_MLX(hi, lo, (x), (y));  \
       hi << (32 - MAD_F_SCALEBITS - 3);  \
    })
# else
#  undef OPT_DCTO
#  define MUL(x, y)  mad_f_mul((x), (y))
# endif

/*
 * NAME:	dct32()
 * DESCRIPTION:	perform fast in[32]->out[32] DCT
 */
static
void dct32(mad_fixed_t const in[32], unsigned int slot,
	   mad_fixed_t lo[16][8], mad_fixed_t hi[16][8])
{
  mad_fixed_t t0,   t1,   t2,   t3,   t4,   t5,   t6,   t7;
  mad_fixed_t t8,   t9,   t10,  t11,  t12,  t13,  t14,  t15;
  mad_fixed_t t16,  t17,  t18,  t19,  t20,  t21,  t22,  t23;
  mad_fixed_t t24,  t25,  t26,  t27,  t28,  t29,  t30,  t31;
  mad_fixed_t t32,  t33,  t34,  t35,  t36,  t37,  t38,  t39;
  mad_fixed_t t40,  t41,  t42,  t43,  t44,  t45,  t46,  t47;
  mad_fixed_t t48,  t49,  t50,  t51,  t52,  t53,  t54,  t55;
  mad_fixed_t t56,  t57,  t58,  t59,  t60,  t61,  t62,  t63;
  mad_fixed_t t64,  t65,  t66,  t67,  t68,  t69,  t70,  t71;
  mad_fixed_t t72,  t73,  t74,  t75,  t76,  t77,  t78,  t79;
  mad_fixed_t t80,  t81,  t82,  t83,  t84,  t85,  t86,  t87;
  mad_fixed_t t88,  t89,  t90,  t91,  t92,  t93,  t94,  t95;
  mad_fixed_t t96,  t97,  t98,  t99,  t100, t101, t102, t103;
  mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111;
  mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119;
  mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127;
  mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135;
  mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143;
  mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151;
  mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159;
  mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167;
  mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175;
  mad_fixed_t t176;

  /* costab[i] = cos(PI / (2 * 32) * i) */

# if defined(OPT_DCTO)
#  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
#  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);
  t1   = in[15] + in[16];  t17  = MUL(in[15] - in[16], costab31);

  t41  = t16 + t17;
  t59  = MUL(t16 - t17, costab2);
  t33  = t0  + t1;
  t50  = MUL(t0  - t1,  costab2);

  t2   = in[7]  + in[24];  t18  = MUL(in[7]  - in[24], costab15);
  t3   = in[8]  + in[23];  t19  = MUL(in[8]  - in[23], costab17);

  t42  = t18 + t19;
  t60  = MUL(t18 - t19, costab30);
  t34  = t2  + t3;
  t51  = MUL(t2  - t3,  costab30);

  t4   = in[3]  + in[28];  t20  = MUL(in[3]  - in[28], costab7);
  t5   = in[12] + in[19];  t21  = MUL(in[12] - in[19], costab25);

  t43  = t20 + t21;
  t61  = MUL(t20 - t21, costab14);
  t35  = t4  + t5;
  t52  = MUL(t4  - t5,  costab14);

  t6   = in[4]  + in[27];  t22  = MUL(in[4]  - in[27], costab9);
  t7   = in[11] + in[20];  t23  = MUL(in[11] - in[20], costab23);

  t44  = t22 + t23;
  t62  = MUL(t22 - t23, costab18);
  t36  = t6  + t7;
  t53  = MUL(t6  - t7,  costab18);

  t8   = in[1]  + in[30];  t24  = MUL(in[1]  - in[30], costab3);
  t9   = in[14] + in[17];  t25  = MUL(in[14] - in[17], costab29);

  t45  = t24 + t25;
  t63  = MUL(t24 - t25, costab6);
  t37  = t8  + t9;
  t54  = MUL(t8  - t9,  costab6);

  t10  = in[6]  + in[25];  t26  = MUL(in[6]  - in[25], costab13);
  t11  = in[9]  + in[22];  t27  = MUL(in[9]  - in[22], costab19);

  t46  = t26 + t27;
  t64  = MUL(t26 - t27, costab26);
  t38  = t10 + t11;
  t55  = MUL(t10 - t11, costab26);

  t12  = in[2]  + in[29];  t28  = MUL(in[2]  - in[29], costab5);
  t13  = in[13] + in[18];  t29  = MUL(in[13] - in[18], costab27);

  t47  = t28 + t29;
  t65  = MUL(t28 - t29, costab10);
  t39  = t12 + t13;
  t56  = MUL(t12 - t13, costab10);

  t14  = in[5]  + in[26];  t30  = MUL(in[5]  - in[26], costab11);
  t15  = in[10] + in[21];  t31  = MUL(in[10] - in[21], costab21);

  t48  = t30 + t31;
  t66  = MUL(t30 - t31, costab22);
  t40  = t14 + t15;
  t57  = MUL(t14 - t15, costab22);

  t69  = t33 + t34;  t89  = MUL(t33 - t34, costab4);
  t70  = t35 + t36;  t90  = MUL(t35 - t36, costab28);
  t71  = t37 + t38;  t91  = MUL(t37 - t38, costab12);
  t72  = t39 + t40;  t92  = MUL(t39 - t40, costab20);
  t73  = t41 + t42;  t94  = MUL(t41 - t42, costab4);
  t74  = t43 + t44;  t95  = MUL(t43 - t44, costab28);
  t75  = t45 + t46;  t96  = MUL(t45 - t46, costab12);
  t76  = t47 + t48;  t97  = MUL(t47 - t48, costab20);

  t78  = t50 + t51;  t100 = MUL(t50 - t51, costab4);
  t79  = t52 + t53;  t101 = MUL(t52 - t53, costab28);
  t80  = t54 + t55;  t102 = MUL(t54 - t55, costab12);
  t81  = t56 + t57;  t103 = MUL(t56 - t57, costab20);

  t83  = t59 + t60;  t106 = MUL(t59 - t60, costab4);
  t84  = t61 + t62;  t107 = MUL(t61 - t62, costab28);
  t85  = t63 + t64;  t108 = MUL(t63 - t64, costab12);
  t86  = t65 + t66;  t109 = MUL(t65 - t66, costab20);

  t113 = t69  + t70;
  t114 = t71  + t72;

  /*  0 */ hi[15][slot] = SHIFT(t113 + t114);
  /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16));

  t115 = t73  + t74;
  t116 = t75  + t76;

  t32  = t115 + t116;

  /*  1 */ hi[14][slot] = SHIFT(t32);

  t118 = t78  + t79;
  t119 = t80  + t81;

  t58  = t118 + t119;

  /*  2 */ hi[13][slot] = SHIFT(t58);

  t121 = t83  + t84;
  t122 = t85  + t86;

  t67  = t121 + t122;

  t49  = (t67 * 2) - t32;

  /*  3 */ hi[12][slot] = SHIFT(t49);

  t125 = t89  + t90;
  t126 = t91  + t92;

  t93  = t125 + t126;

  /*  4 */ hi[11][slot] = SHIFT(t93);

  t128 = t94  + t95;
  t129 = t96  + t97;

  t98  = t128 + t129;

  t68  = (t98 * 2) - t49;

  /*  5 */ hi[10][slot] = SHIFT(t68);

  t132 = t100 + t101;
  t133 = t102 + t103;

  t104 = t132 + t133;

  t82  = (t104 * 2) - t58;

  /*  6 */ hi[ 9][slot] = SHIFT(t82);

  t136 = t106 + t107;
  t137 = t108 + t109;

  t110 = t136 + t137;

  t87  = (t110 * 2) - t67;

  t77  = (t87 * 2) - t68;

  /*  7 */ hi[ 8][slot] = SHIFT(t77);

  t141 = MUL(t69 - t70, costab8);
  t142 = MUL(t71 - t72, costab24);
  t143 = t141 + t142;

  /*  8 */ hi[ 7][slot] = SHIFT(t143);
  /* 24 */ lo[ 8][slot] =
	     SHIFT((MUL(t141 - t142, costab16) * 2) - t143);

  t144 = MUL(t73 - t74, costab8);
  t145 = MUL(t75 - t76, costab24);
  t146 = t144 + t145;

  t88  = (t146 * 2) - t77;

  /*  9 */ hi[ 6][slot] = SHIFT(t88);

  t148 = MUL(t78 - t79, costab8);
  t149 = MUL(t80 - t81, costab24);
  t150 = t148 + t149;

  t105 = (t150 * 2) - t82;

  /* 10 */ hi[ 5][slot] = SHIFT(t105);

  t152 = MUL(t83 - t84, costab8);
  t153 = MUL(t85 - t86, costab24);
  t154 = t152 + t153;

  t111 = (t154 * 2) - t87;

  t99  = (t111 * 2) - t88;

  /* 11 */ hi[ 4][slot] = SHIFT(t99);

  t157 = MUL(t89 - t90, costab8);
  t158 = MUL(t91 - t92, costab24);
  t159 = t157 + t158;

  t127 = (t159 * 2) - t93;

  /* 12 */ hi[ 3][slot] = SHIFT(t127);

  t160 = (MUL(t125 - t126, costab16) * 2) - t127;

  /* 20 */ lo[ 4][slot] = SHIFT(t160);
  /* 28 */ lo[12][slot] =
	     SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160);

  t161 = MUL(t94 - t95, costab8);
  t162 = MUL(t96 - t97, costab24);
  t163 = t161 + t162;

  t130 = (t163 * 2) - t98;

  t112 = (t130 * 2) - t99;

  /* 13 */ hi[ 2][slot] = SHIFT(t112);

  t164 = (MUL(t128 - t129, costab16) * 2) - t130;

  t166 = MUL(t100 - t101, costab8);
  t167 = MUL(t102 - t103, costab24);
  t168 = t166 + t167;

  t134 = (t168 * 2) - t104;

  t120 = (t134 * 2) - t105;

  /* 14 */ hi[ 1][slot] = SHIFT(t120);

  t135 = (MUL(t118 - t119, costab16) * 2) - t120;

  /* 18 */ lo[ 2][slot] = SHIFT(t135);

  t169 = (MUL(t132 - t133, costab16) * 2) - t134;

  t151 = (t169 * 2) - t135;

  /* 22 */ lo[ 6][slot] = SHIFT(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) * 2) -
		       t168) * 2) - t169) * 2) - t170);

  t171 = MUL(t106 - t107, costab8);
  t172 = MUL(t108 - t109, costab24);
  t173 = t171 + t172;

  t138 = (t173 * 2) - t110;

  t123 = (t138 * 2) - t111;

  t139 = (MUL(t121 - t122, costab16) * 2) - t123;

  t117 = (t123 * 2) - t112;

  /* 15 */ hi[ 0][slot] = SHIFT(t117);

  t124 = (MUL(t115 - t116, costab16) * 2) - t117;

  /* 17 */ lo[ 1][slot] = SHIFT(t124);

  t131 = (t139 * 2) - t124;

  /* 19 */ lo[ 3][slot] = SHIFT(t131);

  t140 = (t164 * 2) - t131;

  /* 21 */ lo[ 5][slot] = SHIFT(t140);

  t174 = (MUL(t136 - t137, costab16) * 2) - t138;

  t155 = (t174 * 2) - t139;

  t147 = (t155 * 2) - t140;

  /* 23 */ lo[ 7][slot] = SHIFT(t147);

  t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147;

  /* 25 */ lo[ 9][slot] = SHIFT(t156);

  t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155;

  t165 = (t175 * 2) - t156;

  /* 27 */ lo[11][slot] = SHIFT(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) * 2) -
			 t173) * 2) - t174) * 2) - t175) * 2) - t176);

  /*
   * Totals:
   *  80 multiplies
   *  80 additions
   * 119 subtractions
   *  49 shifts (not counting SSO)
   */
}

# undef MUL
# undef SHIFT

/* third SSO shift and/or D[] optimization preshift */

# if defined(OPT_SSO)
#  if MAD_F_FRACBITS != 28
#   error "MAD_F_FRACBITS must be 28 to use OPT_SSO"
#  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)
#   undef  MAD_F_SCALEBITS
#   define MAD_F_SCALEBITS	(MAD_F_FRACBITS - 12)
#   define PRESHIFT(x)		(MAD_F(x) >> 12)
#  else
#   define PRESHIFT(x)		MAD_F(x)
#  endif
# endif

static
mad_fixed_t const D[17][32] = {
# include "D.dat"
};

# if defined(ASO_SYNTH)
void synth_full(struct mad_synth *, struct mad_frame const *,
		unsigned int, unsigned int);
# else
/*
 * NAME:	synth->full()
 * DESCRIPTION:	perform full frequency PCM synthesis
 */
static
void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
		unsigned int nch, unsigned int ns)
{
  unsigned int phase, ch, s, sb, pe, po;
  mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
  mad_fixed_t const (*sbsample)[36][32];
  register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
  register mad_fixed_t const (*Dptr)[32], *ptr;
  register mad_fixed64hi_t hi;
  register mad_fixed64lo_t lo;

  for (ch = 0; ch < nch; ++ch) {
    sbsample = &frame->sbsample[ch];
    filter   = &synth->filter[ch];
    phase    = synth->phase;
    pcm1     = synth->pcm.samples[ch];

    for (s = 0; s < ns; ++s) {
      dct32((*sbsample)[s], phase >> 1,
	    (*filter)[0][phase & 1], (*filter)[1][phase & 1]);

      pe = phase & ~1;
      po = ((phase - 1) & 0xf) | 1;

      /* calculate 32 samples */

      fe = &(*filter)[0][ phase & 1][0];
      fx = &(*filter)[0][~phase & 1][0];
      fo = &(*filter)[1][~phase & 1][0];

      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;
      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]);
      MLA(hi, lo, (*fe)[4], ptr[ 8]);
      MLA(hi, lo, (*fe)[5], ptr[ 6]);
      MLA(hi, lo, (*fe)[6], ptr[ 4]);
      MLA(hi, lo, (*fe)[7], ptr[ 2]);

      *pcm1++ = SHIFT(MLZ(hi, lo));

      pcm2 = pcm1 + 30;

      for (sb = 1; sb < 16; ++sb) {
	++fe;
	++Dptr;

	/* 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;
	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]);
	MLA(hi, lo, (*fe)[3], ptr[10]);
	MLA(hi, lo, (*fe)[2], ptr[12]);
	MLA(hi, lo, (*fe)[1], ptr[14]);
	MLA(hi, lo, (*fe)[0], ptr[ 0]);

	*pcm1++ = SHIFT(MLZ(hi, lo));

	ptr = *Dptr - pe;
	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]);
	MLA(hi, lo, (*fe)[4], ptr[31 -  8]);
	MLA(hi, lo, (*fe)[5], ptr[31 -  6]);
	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;
      }

      ++Dptr;

      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]);

      *pcm1 = SHIFT(-MLZ(hi, lo));
      pcm1 += 16;

      phase = (phase + 1) % 16;
    }
  }
}
# endif

/*
 * NAME:	synth->half()
 * DESCRIPTION:	perform half frequency PCM synthesis
 */
static
void synth_half(struct mad_synth *synth, struct mad_frame const *frame,
		unsigned int nch, unsigned int ns)
{
  unsigned int phase, ch, s, sb, pe, po;
  mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
  mad_fixed_t const (*sbsample)[36][32];
  register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
  register mad_fixed_t const (*Dptr)[32], *ptr;
  register mad_fixed64hi_t hi;
  register mad_fixed64lo_t lo;

  for (ch = 0; ch < nch; ++ch) {
    sbsample = &frame->sbsample[ch];
    filter   = &synth->filter[ch];
    phase    = synth->phase;
    pcm1     = synth->pcm.samples[ch];

    for (s = 0; s < ns; ++s) {
      dct32((*sbsample)[s], phase >> 1,
	    (*filter)[0][phase & 1], (*filter)[1][phase & 1]);

      pe = phase & ~1;
      po = ((phase - 1) & 0xf) | 1;

      /* calculate 16 samples */

      fe = &(*filter)[0][ phase & 1][0];
      fx = &(*filter)[0][~phase & 1][0];
      fo = &(*filter)[1][~phase & 1][0];

      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;
      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]);
      MLA(hi, lo, (*fe)[4], ptr[ 8]);
      MLA(hi, lo, (*fe)[5], ptr[ 6]);
      MLA(hi, lo, (*fe)[6], ptr[ 4]);
      MLA(hi, lo, (*fe)[7], ptr[ 2]);

      *pcm1++ = SHIFT(MLZ(hi, lo));

      pcm2 = pcm1 + 14;

      for (sb = 1; sb < 16; ++sb) {
	++fe;
	++Dptr;

	/* 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;
	  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]);
	  MLA(hi, lo, (*fe)[3], ptr[10]);
	  MLA(hi, lo, (*fe)[2], ptr[12]);
	  MLA(hi, lo, (*fe)[1], ptr[14]);
	  MLA(hi, lo, (*fe)[0], ptr[ 0]);

	  *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]);
	  MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
	  MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
	  MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
	  MLA(hi, lo, (*fe)[4], ptr[31 -  8]);
	  MLA(hi, lo, (*fe)[5], ptr[31 -  6]);
	  MLA(hi, lo, (*fe)[6], ptr[31 -  4]);
	  MLA(hi, lo, (*fe)[7], ptr[31 -  2]);

	  *pcm2-- = SHIFT(MLZ(hi, lo));
	}

	++fo;
      }

      ++Dptr;

      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]);

      *pcm1 = SHIFT(-MLZ(hi, lo));
      pcm1 += 8;

      phase = (phase + 1) % 16;
    }
  }
}

/*
 * NAME:	synth->frame()
 * DESCRIPTION:	perform PCM synthesis of frame subband samples
 */
void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame)
{
  unsigned int nch, ns;
  void (*synth_frame)(struct mad_synth *, struct mad_frame const *,
		      unsigned int, unsigned int);

  nch = MAD_NCHANNELS(&frame->header);
  ns  = MAD_NSBSAMPLES(&frame->header);

  synth->pcm.samplerate = frame->header.samplerate;
  synth->pcm.channels   = nch;
  synth->pcm.length     = 32 * ns;

  synth_frame = synth_full;

  if (frame->options & MAD_OPTION_HALFSAMPLERATE) {
    synth->pcm.samplerate /= 2;
    synth->pcm.length     /= 2;

    synth_frame = synth_half;
  }

  synth_frame(synth, frame, nch, ns);

  synth->phase = (synth->phase + ns) % 16;
}

--- NEW FILE: imdct_s.dat ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: imdct_s.dat,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

  /*  0 */  {  MAD_F(0x09bd7ca0) /*  0.608761429 */,
	      -MAD_F(0x0ec835e8) /* -0.923879533 */,
	      -MAD_F(0x0216a2a2) /* -0.130526192 */,
	       MAD_F(0x0fdcf549) /*  0.991444861 */,
	      -MAD_F(0x061f78aa) /* -0.382683432 */,
	      -MAD_F(0x0cb19346) /* -0.793353340 */ },

  /*  6 */  { -MAD_F(0x0cb19346) /* -0.793353340 */,
	       MAD_F(0x061f78aa) /*  0.382683432 */,
	       MAD_F(0x0fdcf549) /*  0.991444861 */,
	       MAD_F(0x0216a2a2) /*  0.130526192 */,
	      -MAD_F(0x0ec835e8) /* -0.923879533 */,
	      -MAD_F(0x09bd7ca0) /* -0.608761429 */ },

  /*  1 */  {  MAD_F(0x061f78aa) /*  0.382683432 */,
	      -MAD_F(0x0ec835e8) /* -0.923879533 */,
	       MAD_F(0x0ec835e8) /*  0.923879533 */,
	      -MAD_F(0x061f78aa) /* -0.382683432 */,
	      -MAD_F(0x061f78aa) /* -0.382683432 */,
	       MAD_F(0x0ec835e8) /*  0.923879533 */ },

  /*  7 */  { -MAD_F(0x0ec835e8) /* -0.923879533 */,
	      -MAD_F(0x061f78aa) /* -0.382683432 */,
	       MAD_F(0x061f78aa) /*  0.382683432 */,
	       MAD_F(0x0ec835e8) /*  0.923879533 */,
	       MAD_F(0x0ec835e8) /*  0.923879533 */,
	       MAD_F(0x061f78aa) /*  0.382683432 */ },

  /*  2 */  {  MAD_F(0x0216a2a2) /*  0.130526192 */,
	      -MAD_F(0x061f78aa) /* -0.382683432 */,
	       MAD_F(0x09bd7ca0) /*  0.608761429 */,
	      -MAD_F(0x0cb19346) /* -0.793353340 */,
	       MAD_F(0x0ec835e8) /*  0.923879533 */,
	      -MAD_F(0x0fdcf549) /* -0.991444861 */ },

  /*  8 */  { -MAD_F(0x0fdcf549) /* -0.991444861 */,
	      -MAD_F(0x0ec835e8) /* -0.923879533 */,
	      -MAD_F(0x0cb19346) /* -0.793353340 */,
	      -MAD_F(0x09bd7ca0) /* -0.608761429 */,
	      -MAD_F(0x061f78aa) /* -0.382683432 */,
	      -MAD_F(0x0216a2a2) /* -0.130526192 */ }

--- NEW FILE: bit.c ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: bit.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# ifdef HAVE_LIMITS_H
#  include <limits.h>
# else
#  define CHAR_BIT  8
# endif

# include "bit.h"

/*
 * This is the lookup table for computing the CRC-check word.
 * As described in section 2.4.3.1 and depicted in Figure A.9
 * of ISO/IEC 11172-3, the generator polynomial is:
 *
 * G(X) = X^16 + X^15 + X^2 + 1
 */
static
unsigned short const crc_table[256] = {
  0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
  0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
  0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
  0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
  0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
  0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
  0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
  0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,

  0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
  0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
  0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
  0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
  0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
  0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
  0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
  0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,

  0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
  0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
  0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
  0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
  0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
  0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
  0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
  0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,

  0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
  0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
  0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
  0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
  0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
  0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
  0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
  0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
};

# define CRC_POLY  0x8005

/*
 * NAME:	bit->init()
 * DESCRIPTION:	initialize bit pointer struct
 */
void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte)
{
  bitptr->byte  = byte;
  bitptr->cache = 0;
  bitptr->left  = CHAR_BIT;
}

/*
 * NAME:	bit->length()
 * DESCRIPTION:	return number of bits between start and end points
 */
unsigned int mad_bit_length(struct mad_bitptr const *begin,
			    struct mad_bitptr const *end)
{
  return begin->left +
    CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left);
}

/*
 * NAME:	bit->nextbyte()
 * DESCRIPTION:	return pointer to next unprocessed byte
 */
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr)
{
  return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1;
}

/*
 * NAME:	bit->skip()
 * DESCRIPTION:	advance bit pointer
 */
void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len)
{
  bitptr->byte += len / CHAR_BIT;
  bitptr->left -= len % CHAR_BIT;

  if (bitptr->left > CHAR_BIT) {
    bitptr->byte++;
    bitptr->left += CHAR_BIT;
  }

  if (bitptr->left < CHAR_BIT)
    bitptr->cache = *bitptr->byte;
}

/*
 * NAME:	bit->read()
 * DESCRIPTION:	read an arbitrary number of bits and return their UIMSBF value
 */
unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
{
  register unsigned long value;

  if (bitptr->left == CHAR_BIT)
    bitptr->cache = *bitptr->byte;

  if (len < bitptr->left) {
    value = (bitptr->cache & ((1 << bitptr->left) - 1)) >>
      (bitptr->left - len);
    bitptr->left -= len;

    return value;
  }

  /* remaining bits in current byte */

  value = bitptr->cache & ((1 << bitptr->left) - 1);
  len  -= bitptr->left;

  bitptr->byte++;
  bitptr->left = CHAR_BIT;

  /* more bytes */

  while (len >= CHAR_BIT) {
    value = (value << CHAR_BIT) | *bitptr->byte++;
    len  -= CHAR_BIT;
  }

  if (len > 0) {
    bitptr->cache = *bitptr->byte;

    value = (value << len) | (bitptr->cache >> (CHAR_BIT - len));
    bitptr->left -= len;
  }

  return value;
}

# if 0
/*
 * NAME:	bit->write()
 * DESCRIPTION:	write an arbitrary number of bits
 */
void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len,
		   unsigned long value)
{
  unsigned char *ptr;

  ptr = (unsigned char *) bitptr->byte;

  /* ... */
}
# endif

/*
 * NAME:	bit->crc()
 * DESCRIPTION:	compute CRC-check word
 */
unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len,
			   unsigned short init)
{
  register unsigned int crc;

  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;
  }

  while (len--) {
    register unsigned int msb;

    msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15);

    crc <<= 1;
    if (msb & 1)
      crc ^= CRC_POLY;
  }

  return crc & 0xffff;
}

--- NEW FILE: Makefile.in ---
# Makefile.in generated by automake 1.9.3 from Makefile.am.
# @configure_input@

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004  Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@


SOURCES = $(xineplug_decode_mad_la_SOURCES)

srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
	$(srcdir)/Makefile.in $(top_srcdir)/misc/Makefile.common
subdir = src/libmad
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/_xine.m4 $(top_srcdir)/m4/aa.m4 \
	$(top_srcdir)/m4/alsa.m4 $(top_srcdir)/m4/arts.m4 \
	$(top_srcdir)/m4/as.m4 $(top_srcdir)/m4/caca.m4 \
	$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/directx.m4 \
	$(top_srcdir)/m4/dl.m4 $(top_srcdir)/m4/dvdnav.m4 \
	$(top_srcdir)/m4/esd.m4 $(top_srcdir)/m4/ffmpeg.m4 \
	$(top_srcdir)/m4/freetype2.m4 $(top_srcdir)/m4/gettext.m4 \
	$(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \
	$(top_srcdir)/m4/irixal.m4 $(top_srcdir)/m4/lcmessage.m4 \
	$(top_srcdir)/m4/libFLAC.m4 $(top_srcdir)/m4/libfame.m4 \
	$(top_srcdir)/m4/ogg.m4 $(top_srcdir)/m4/opengl.m4 \
	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/progtest.m4 \
	$(top_srcdir)/m4/sdl.m4 $(top_srcdir)/m4/speex.m4 \
	$(top_srcdir)/m4/theora.m4 $(top_srcdir)/m4/vorbis.m4 \
	$(top_srcdir)/m4/xv.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
    *) f=$$p;; \
  esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 = $(top_builddir)/src/xine-engine/libxine.la
xineplug_decode_mad_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_xineplug_decode_mad_la_OBJECTS = bit.lo fixed.lo frame.lo \
	huffman.lo layer12.lo layer3.lo stream.lo synth.lo timer.lo \
	version.lo xine_decoder.lo
xineplug_decode_mad_la_OBJECTS = $(am_xineplug_decode_mad_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(xineplug_decode_mad_la_SOURCES)
DIST_SOURCES = $(xineplug_decode_mad_la_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
AAINFO = @AAINFO@
AALIB_CFLAGS = @AALIB_CFLAGS@
AALIB_CONFIG = @AALIB_CONFIG@
AALIB_LIBS = @AALIB_LIBS@
ACLOCAL = @ACLOCAL@
ACLOCAL_DIR = @ACLOCAL_DIR@
ALLOCA = @ALLOCA@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
ALSA_STATIC_LIB = @ALSA_STATIC_LIB@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
ARTS_CFLAGS = @ARTS_CFLAGS@
ARTS_CONFIG = @ARTS_CONFIG@
ARTS_LIBS = @ARTS_LIBS@
AS = @AS@
ASFLAGS = @ASFLAGS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_ASF_FALSE = @BUILD_ASF_FALSE@
BUILD_ASF_TRUE = @BUILD_ASF_TRUE@
BUILD_DHA_KMOD_FALSE = @BUILD_DHA_KMOD_FALSE@
BUILD_DHA_KMOD_TRUE = @BUILD_DHA_KMOD_TRUE@
BUILD_FAAD_FALSE = @BUILD_FAAD_FALSE@
BUILD_FAAD_TRUE = @BUILD_FAAD_TRUE@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CACA_CFLAGS = @CACA_CFLAGS@
CACA_CONFIG = @CACA_CONFIG@
CACA_LIBS = @CACA_LIBS@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCAS = @CCAS@
CCASCOMPILE = @CCASCOMPILE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
DEBUG_CFLAGS = @DEBUG_CFLAGS@
DEFS = @DEFS@
DEPCOMP = @DEPCOMP@
DEPDIR = @DEPDIR@
DEPMOD = @DEPMOD@
DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
DIRECTFB_LIBS = @DIRECTFB_LIBS@
DIRECTX_AUDIO_LIBS = @DIRECTX_AUDIO_LIBS@
DIRECTX_CPPFLAGS = @DIRECTX_CPPFLAGS@
DIRECTX_VIDEO_LIBS = @DIRECTX_VIDEO_LIBS@
DLLTOOL = @DLLTOOL@
DVDNAV_CFLAGS = @DVDNAV_CFLAGS@
DVDNAV_CONFIG = @DVDNAV_CONFIG@
DVDNAV_LIBS = @DVDNAV_LIBS@
DYNAMIC_LD_LIBS = @DYNAMIC_LD_LIBS@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_VCD_FALSE = @ENABLE_VCD_FALSE@
ENABLE_VCD_TRUE = @ENABLE_VCD_TRUE@
ESD_CFLAGS = @ESD_CFLAGS@
ESD_CONFIG = @ESD_CONFIG@
ESD_LIBS = @ESD_LIBS@
EXEEXT = @EXEEXT@
EXTRA_X_CFLAGS = @EXTRA_X_CFLAGS@
EXTRA_X_LIBS = @EXTRA_X_LIBS@
F77 = @F77@
FFLAGS = @FFLAGS@
FFMPEG_CPPFLAGS = @FFMPEG_CPPFLAGS@
FFMPEG_LIBS = @FFMPEG_LIBS@
FIG2DEV = @FIG2DEV@
FREETYPE_CONFIG = @FREETYPE_CONFIG@
FT2_CFLAGS = @FT2_CFLAGS@
FT2_LIBS = @FT2_LIBS@
GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GLUT_LIBS = @GLUT_LIBS@
GLU_LIBS = @GLU_LIBS@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GNOME_VFS_CFLAGS = @GNOME_VFS_CFLAGS@
GNOME_VFS_LIBS = @GNOME_VFS_LIBS@
GOOM_LIBS = @GOOM_LIBS@
HAVE_AA_FALSE = @HAVE_AA_FALSE@
HAVE_AA_TRUE = @HAVE_AA_TRUE@
HAVE_ALSA09_FALSE = @HAVE_ALSA09_FALSE@
HAVE_ALSA09_TRUE = @HAVE_ALSA09_TRUE@
HAVE_ALSA_FALSE = @HAVE_ALSA_FALSE@
HAVE_ALSA_TRUE = @HAVE_ALSA_TRUE@
HAVE_ARMV4L_FALSE = @HAVE_ARMV4L_FALSE@
HAVE_ARMV4L_TRUE = @HAVE_ARMV4L_TRUE@
HAVE_ARTS_FALSE = @HAVE_ARTS_FALSE@
HAVE_ARTS_TRUE = @HAVE_ARTS_TRUE@
HAVE_BSDI_CDROM = @HAVE_BSDI_CDROM@
HAVE_CACA_FALSE = @HAVE_CACA_FALSE@
HAVE_CACA_TRUE = @HAVE_CACA_TRUE@
HAVE_CDROM_IOCTLS_FALSE = @HAVE_CDROM_IOCTLS_FALSE@
HAVE_CDROM_IOCTLS_TRUE = @HAVE_CDROM_IOCTLS_TRUE@
HAVE_COREAUDIO_FALSE = @HAVE_COREAUDIO_FALSE@
HAVE_COREAUDIO_TRUE = @HAVE_COREAUDIO_TRUE@
HAVE_DARWIN_CDROM = @HAVE_DARWIN_CDROM@
HAVE_DIRECTFB_FALSE = @HAVE_DIRECTFB_FALSE@
HAVE_DIRECTFB_TRUE = @HAVE_DIRECTFB_TRUE@
HAVE_DIRECTX_FALSE = @HAVE_DIRECTX_FALSE@
HAVE_DIRECTX_TRUE = @HAVE_DIRECTX_TRUE@
HAVE_DVDNAV_FALSE = @HAVE_DVDNAV_FALSE@
HAVE_DVDNAV_TRUE = @HAVE_DVDNAV_TRUE@
HAVE_DXR3_FALSE = @HAVE_DXR3_FALSE@
HAVE_DXR3_TRUE = @HAVE_DXR3_TRUE@
HAVE_ESD_FALSE = @HAVE_ESD_FALSE@
HAVE_ESD_TRUE = @HAVE_ESD_TRUE@
HAVE_FB_FALSE = @HAVE_FB_FALSE@
HAVE_FB_TRUE = @HAVE_FB_TRUE@
HAVE_FFMMX_FALSE = @HAVE_FFMMX_FALSE@
HAVE_FFMMX_TRUE = @HAVE_FFMMX_TRUE@
HAVE_FFMPEG_FALSE = @HAVE_FFMPEG_FALSE@
HAVE_FFMPEG_TRUE = @HAVE_FFMPEG_TRUE@
HAVE_FIG2DEV_FALSE = @HAVE_FIG2DEV_FALSE@
HAVE_FIG2DEV_TRUE = @HAVE_FIG2DEV_TRUE@
HAVE_FLAC_FALSE = @HAVE_FLAC_FALSE@
HAVE_FLAC_TRUE = @HAVE_FLAC_TRUE@
HAVE_FREEBSD_CDROM = @HAVE_FREEBSD_CDROM@
HAVE_GNOME_VFS_FALSE = @HAVE_GNOME_VFS_FALSE@
HAVE_GNOME_VFS_TRUE = @HAVE_GNOME_VFS_TRUE@
HAVE_IRIXAL_FALSE = @HAVE_IRIXAL_FALSE@
HAVE_IRIXAL_TRUE = @HAVE_IRIXAL_TRUE@
HAVE_LIBFAME_FALSE = @HAVE_LIBFAME_FALSE@
HAVE_LIBFAME_TRUE = @HAVE_LIBFAME_TRUE@
HAVE_LIBMNG_FALSE = @HAVE_LIBMNG_FALSE@
HAVE_LIBMNG_TRUE = @HAVE_LIBMNG_TRUE@
HAVE_LIBPNG_FALSE = @HAVE_LIBPNG_FALSE@
HAVE_LIBPNG_TRUE = @HAVE_LIBPNG_TRUE@
HAVE_LIBRTE_FALSE = @HAVE_LIBRTE_FALSE@
HAVE_LIBRTE_TRUE = @HAVE_LIBRTE_TRUE@
HAVE_LIBSMBCLIENT_FALSE = @HAVE_LIBSMBCLIENT_FALSE@
HAVE_LIBSMBCLIENT_TRUE = @HAVE_LIBSMBCLIENT_TRUE@
HAVE_LINUX_CDROM = @HAVE_LINUX_CDROM@
HAVE_LINUX_FALSE = @HAVE_LINUX_FALSE@
HAVE_LINUX_TRUE = @HAVE_LINUX_TRUE@
HAVE_MACOSX_VIDEO_FALSE = @HAVE_MACOSX_VIDEO_FALSE@
HAVE_MACOSX_VIDEO_TRUE = @HAVE_MACOSX_VIDEO_TRUE@
HAVE_MLIB_FALSE = @HAVE_MLIB_FALSE@
HAVE_MLIB_TRUE = @HAVE_MLIB_TRUE@
HAVE_OPENGL_FALSE = @HAVE_OPENGL_FALSE@
HAVE_OPENGL_TRUE = @HAVE_OPENGL_TRUE@
HAVE_OSS_FALSE = @HAVE_OSS_FALSE@
HAVE_OSS_TRUE = @HAVE_OSS_TRUE@
HAVE_POLYPAUDIO_FALSE = @HAVE_POLYPAUDIO_FALSE@
HAVE_POLYPAUDIO_TRUE = @HAVE_POLYPAUDIO_TRUE@
HAVE_SDL_FALSE = @HAVE_SDL_FALSE@
HAVE_SDL_TRUE = @HAVE_SDL_TRUE@
HAVE_SGMLTOOLS_FALSE = @HAVE_SGMLTOOLS_FALSE@
HAVE_SGMLTOOLS_TRUE = @HAVE_SGMLTOOLS_TRUE@
HAVE_SOLARIS_CDROM = @HAVE_SOLARIS_CDROM@
HAVE_SPEEX_FALSE = @HAVE_SPEEX_FALSE@
HAVE_SPEEX_TRUE = @HAVE_SPEEX_TRUE@
HAVE_STK_FALSE = @HAVE_STK_FALSE@
HAVE_STK_TRUE = @HAVE_STK_TRUE@
HAVE_SUNAUDIO_FALSE = @HAVE_SUNAUDIO_FALSE@
HAVE_SUNAUDIO_TRUE = @HAVE_SUNAUDIO_TRUE@
HAVE_SUNDGA_FALSE = @HAVE_SUNDGA_FALSE@
HAVE_SUNDGA_TRUE = @HAVE_SUNDGA_TRUE@
HAVE_SUNFB_FALSE = @HAVE_SUNFB_FALSE@
HAVE_SUNFB_TRUE = @HAVE_SUNFB_TRUE@
HAVE_SYNCFB_FALSE = @HAVE_SYNCFB_FALSE@
HAVE_SYNCFB_TRUE = @HAVE_SYNCFB_TRUE@
HAVE_THEORA_FALSE = @HAVE_THEORA_FALSE@
HAVE_THEORA_TRUE = @HAVE_THEORA_TRUE@
HAVE_V4L_FALSE = @HAVE_V4L_FALSE@
HAVE_V4L_TRUE = @HAVE_V4L_TRUE@
HAVE_VCDNAV_FALSE = @HAVE_VCDNAV_FALSE@
HAVE_VCDNAV_TRUE = @HAVE_VCDNAV_TRUE@
HAVE_VIDIX_FALSE = @HAVE_VIDIX_FALSE@
HAVE_VIDIX_TRUE = @HAVE_VIDIX_TRUE@
HAVE_VLDXVMC_FALSE = @HAVE_VLDXVMC_FALSE@
HAVE_VLDXVMC_TRUE = @HAVE_VLDXVMC_TRUE@
HAVE_VORBIS_FALSE = @HAVE_VORBIS_FALSE@
HAVE_VORBIS_TRUE = @HAVE_VORBIS_TRUE@
HAVE_W32DLL_FALSE = @HAVE_W32DLL_FALSE@
HAVE_W32DLL_TRUE = @HAVE_W32DLL_TRUE@
HAVE_WIN32_CDROM = @HAVE_WIN32_CDROM@
HAVE_X11_FALSE = @HAVE_X11_FALSE@
HAVE_X11_TRUE = @HAVE_X11_TRUE@
HAVE_XVMC_FALSE = @HAVE_XVMC_FALSE@
HAVE_XVMC_TRUE = @HAVE_XVMC_TRUE@
HAVE_XV_FALSE = @HAVE_XV_FALSE@
HAVE_XV_TRUE = @HAVE_XV_TRUE@
HAVE_XXMC_FALSE = @HAVE_XXMC_FALSE@
HAVE_XXMC_TRUE = @HAVE_XXMC_TRUE@
HAVE_ZLIB_FALSE = @HAVE_ZLIB_FALSE@
HAVE_ZLIB_TRUE = @HAVE_ZLIB_TRUE@
HOST_OS_DARWIN_FALSE = @HOST_OS_DARWIN_FALSE@
HOST_OS_DARWIN_TRUE = @HOST_OS_DARWIN_TRUE@
INCLUDED_INTL_FALSE = @INCLUDED_INTL_FALSE@
INCLUDED_INTL_TRUE = @INCLUDED_INTL_TRUE@
INCLUDES = @INCLUDES@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_M4_FALSE = @INSTALL_M4_FALSE@
INSTALL_M4_TRUE = @INSTALL_M4_TRUE@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLDIR = @INTLDIR@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
IRIXAL_CFLAGS = @IRIXAL_CFLAGS@
IRIXAL_LIBS = @IRIXAL_LIBS@
IRIXAL_STATIC_LIB = @IRIXAL_STATIC_LIB@
KSTAT_LIBS = @KSTAT_LIBS@
LDFLAGS = @LDFLAGS@
LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@
LIBCDIO_LIBS = @LIBCDIO_LIBS@
LIBFAME_CFLAGS = @LIBFAME_CFLAGS@
LIBFAME_CONFIG = @LIBFAME_CONFIG@
LIBFAME_LIBS = @LIBFAME_LIBS@
LIBFFMPEG_CFLAGS = @LIBFFMPEG_CFLAGS@
LIBFLAC_CFLAGS = @LIBFLAC_CFLAGS@
LIBFLAC_LIBS = @LIBFLAC_LIBS@
LIBICONV = @LIBICONV@
LIBISO9660_LIBS = @LIBISO9660_LIBS@
LIBMODPLUG_CFLAGS = @LIBMODPLUG_CFLAGS@
LIBMODPLUG_LIBS = @LIBMODPLUG_LIBS@
LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@
LIBNAME = @LIBNAME@
LIBOBJS = @LIBOBJS@
LIBPNG_CONFIG = @LIBPNG_CONFIG@
LIBS = @LIBS@
LIBSMBCLIENT_LIBS = @LIBSMBCLIENT_LIBS@
LIBSTK_CFLAGS = @LIBSTK_CFLAGS@
LIBSTK_LIBS = @LIBSTK_LIBS@
LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBVCDINFO_LIBS = @LIBVCDINFO_LIBS@
LIBVCD_CFLAGS = @LIBVCD_CFLAGS@
LIBVCD_LIBS = @LIBVCD_LIBS@
LIBVCD_SYSDEP = @LIBVCD_SYSDEP@
LINUX_CDROM_TIMEOUT = @LINUX_CDROM_TIMEOUT@
LINUX_INCLUDE = @LINUX_INCLUDE@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@
LT_REVISION = @LT_REVISION@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
MKNOD = @MKNOD@
MLIB_CFLAGS = @MLIB_CFLAGS@
MLIB_LIBS = @MLIB_LIBS@
MNG_LIBS = @MNG_LIBS@
MSGFMT = @MSGFMT@
NET_LIBS = @NET_LIBS@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJCFLAGS = @OBJCFLAGS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
OPENGL_CFLAGS = @OPENGL_CFLAGS@
OPENGL_LIBS = @OPENGL_LIBS@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PASS1_CFLAGS = @PASS1_CFLAGS@
PASS2_CFLAGS = @PASS2_CFLAGS@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PNG_CFLAGS = @PNG_CFLAGS@
PNG_LIBS = @PNG_LIBS@
POFILES = @POFILES@
POLYPAUDIO_CFLAGS = @POLYPAUDIO_CFLAGS@
POLYPAUDIO_LIBS = @POLYPAUDIO_LIBS@
POSUB = @POSUB@
PPC_ARCH_FALSE = @PPC_ARCH_FALSE@
PPC_ARCH_TRUE = @PPC_ARCH_TRUE@
RANLIB = @RANLIB@
RT_LIBS = @RT_LIBS@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SGMLTOOLS = @SGMLTOOLS@
SHELL = @SHELL@
SPEC_VERSION = @SPEC_VERSION@
SPEEX_CFLAGS = @SPEEX_CFLAGS@
SPEEX_LIBS = @SPEEX_LIBS@
STATIC = @STATIC@
STRIP = @STRIP@
SUNDGA_CFLAGS = @SUNDGA_CFLAGS@
SUNDGA_LIBS = @SUNDGA_LIBS@
TAR_NAME = @TAR_NAME@
THEORAENC_LIBS = @THEORAENC_LIBS@
THEORAFILE_LIBS = @THEORAFILE_LIBS@
THEORA_CFLAGS = @THEORA_CFLAGS@
THEORA_LIBS = @THEORA_LIBS@
THREAD_CFLAGS = @THREAD_CFLAGS@
THREAD_CFLAGS_CONFIG = @THREAD_CFLAGS_CONFIG@
THREAD_INCLUDES = @THREAD_INCLUDES@
THREAD_LIBS = @THREAD_LIBS@
THREAD_LIBS_CONFIG = @THREAD_LIBS_CONFIG@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
W32DLL_DEP = @W32DLL_DEP@
W32_NO_OPTIMIZE = @W32_NO_OPTIMIZE@
WIN32_CPPFLAGS = @WIN32_CPPFLAGS@
WIN32_FALSE = @WIN32_FALSE@
WIN32_TRUE = @WIN32_TRUE@
XGETTEXT = @XGETTEXT@
XINE_ACFLAGS = @XINE_ACFLAGS@
XINE_BIN_AGE = @XINE_BIN_AGE@
XINE_BUILD_CC = @XINE_BUILD_CC@
XINE_BUILD_DATE = @XINE_BUILD_DATE@
XINE_BUILD_OS = @XINE_BUILD_OS@
XINE_CONFIG_PREFIX = @XINE_CONFIG_PREFIX@
XINE_DATADIR = @XINE_DATADIR@
XINE_FONTDIR = @XINE_FONTDIR@
XINE_FONTPATH = @XINE_FONTPATH@
XINE_IFACE_AGE = @XINE_IFACE_AGE@
XINE_LOCALEDIR = @XINE_LOCALEDIR@
XINE_LOCALEPATH = @XINE_LOCALEPATH@
XINE_MAJOR = @XINE_MAJOR@
XINE_MINOR = @XINE_MINOR@
XINE_PLUGINDIR = @XINE_PLUGINDIR@
XINE_PLUGINPATH = @XINE_PLUGINPATH@
XINE_PLUGIN_MIN_SYMS = @XINE_PLUGIN_MIN_SYMS@
XINE_SCRIPTPATH = @XINE_SCRIPTPATH@
XINE_SUB = @XINE_SUB@
XVMC_LIB = @XVMC_LIB@
XV_LIB = @XV_LIB@
XXMC_LIB = @XXMC_LIB@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
ZLIB_INCLUDES = @ZLIB_INCLUDES@
ZLIB_LIBS = @ZLIB_LIBS@
ZLIB_LIBS_CONFIG = @ZLIB_LIBS_CONFIG@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DLLTOOL = @ac_ct_DLLTOOL@
ac_ct_F77 = @ac_ct_F77@
ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__fastdepOBJC_FALSE = @am__fastdepOBJC_FALSE@
am__fastdepOBJC_TRUE = @am__fastdepOBJC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = $(XINE_PLUGINDIR)
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
w32_path = @w32_path@
XINE_LIB = $(top_builddir)/src/xine-engine/libxine.la
AM_CFLAGS = -DOPT_SPEED
EXTRA_DIST = imdct_l_arm.S
lib_LTLIBRARIES = xineplug_decode_mad.la
xineplug_decode_mad_la_SOURCES = \
	bit.c \
	fixed.c \
	frame.c \
	huffman.c \
	layer12.c \
	layer3.c \
	stream.c \
	synth.c \
	timer.c \
	version.c \
	xine_decoder.c

xineplug_decode_mad_la_LIBADD = $(XINE_LIB)
xineplug_decode_mad_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
noinst_HEADERS = \
	D.dat \
	imdct_s.dat \
	qc_table.dat \
	rq_table.dat \
	sf_table.dat \
	bit.h \
	fixed.h \
	frame.h \
	global.h \
	huffman.h \
	layer12.h \
	layer3.h \
	stream.h \
	synth.h \
	timer.h \
	version.h

all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(top_srcdir)/misc/Makefile.common $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
		&& exit 0; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/libmad/Makefile'; \
	cd $(top_srcdir) && \
	  $(AUTOMAKE) --gnu  src/libmad/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
	@$(NORMAL_INSTALL)
	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    f=$(am__strip_dir) \
	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
	  else :; fi; \
	done

uninstall-libLTLIBRARIES:
	@$(NORMAL_UNINSTALL)
	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  p=$(am__strip_dir) \
	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
	done

clean-libLTLIBRARIES:
	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
	  test "$$dir" != "$$p" || dir=.; \
	  echo "rm -f \"$${dir}/so_locations\""; \
	  rm -f "$${dir}/so_locations"; \
	done
xineplug_decode_mad.la: $(xineplug_decode_mad_la_OBJECTS) $(xineplug_decode_mad_la_DEPENDENCIES) 
	$(LINK) -rpath $(libdir) $(xineplug_decode_mad_la_LDFLAGS) $(xineplug_decode_mad_la_OBJECTS) $(xineplug_decode_mad_la_LIBADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layer12.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layer3.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synth.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xine_decoder.Plo@am__quote@

.c.o:
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(COMPILE) -c $<

.c.obj:
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`

.c.lo:
@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

distclean-libtool:
	-rm -f libtool
uninstall-info-am:

ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	mkid -fID $$unique
tags: TAGS

TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	tags=; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	    $$tags $$unique; \
	fi
ctags: CTAGS
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	tags=; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	test -z "$(CTAGS_ARGS)$$tags$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$tags $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && cd $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) $$here

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir: $(DISTFILES)
	$(mkdir_p) $(distdir)/../../misc
	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
	list='$(DISTFILES)'; for file in $$list; do \
	  case $$file in \
	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
	  esac; \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
	    dir="/$$dir"; \
	    $(mkdir_p) "$(distdir)$$dir"; \
	  else \
	    dir=''; \
	  fi; \
	  if test -d $$d/$$file; then \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
	    fi; \
	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
	  else \
	    test -f $(distdir)/$$file \
	    || cp -p $$d/$$file $(distdir)/$$file \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
	for dir in "$(DESTDIR)$(libdir)"; do \
	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
	done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	  `test -z '$(STRIP)' || \
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
clean: clean-am

clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
	mostlyclean-am

distclean: distclean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-libtool distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

info: info-am

info-am:

install-data-am:
	@$(NORMAL_INSTALL)
	$(MAKE) $(AM_MAKEFLAGS) install-data-hook

install-exec-am: install-libLTLIBRARIES

install-info: install-info-am

install-man:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
	@$(NORMAL_INSTALL)
	$(MAKE) $(AM_MAKEFLAGS) uninstall-hook

.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
	clean-libLTLIBRARIES clean-libtool ctags distclean \
	distclean-compile distclean-generic distclean-libtool \
	distclean-tags distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am \
	install-data-hook install-exec install-exec-am install-info \
	install-info-am install-libLTLIBRARIES install-man \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
	pdf pdf-am ps ps-am tags uninstall uninstall-am uninstall-hook \
	uninstall-info-am uninstall-libLTLIBRARIES


$(XINE_LIB):
	@cd $(top_srcdir)/src/xine-engine && $(MAKE)

install-data-hook:
	@if test $$MAKELEVEL -le 4 ; then \
	  if test -x "$(top_srcdir)/post-install.sh" ; then \
	    $(top_srcdir)/post-install.sh ; \
	  fi \
	fi

pass1:
	@$(MAKE) MULTIPASS_CFLAGS="$(PASS1_CFLAGS)"

pass2:
	@$(MAKE) MULTIPASS_CFLAGS="$(PASS2_CFLAGS)"

debug:
	@$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"

install-debug: debug
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
	@list='$(SUBDIRS)'; for subdir in $$list; do \
	  (cd $$subdir && $(MAKE) $@) || exit; \
	done;
	$(MAKE) $(AM_MAKEFLAGS) install-data-hook

install-includeHEADERS: $(include_HEADERS)
	@$(NORMAL_INSTALL)
	$(install_sh) -d $(DESTDIR)$(includedir)/xine
	@list='$(include_HEADERS)'; for p in $$list; do \
	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
	done

uninstall-includeHEADERS:
	@$(NORMAL_UNINSTALL)
	list='$(include_HEADERS)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(includedir)/xine/$$p; \
	done

uninstall-hook:
	@if echo '$(libdir)' | egrep ^'$(XINE_PLUGINDIR)' >/dev/null; then \
	  list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	    p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \
	    echo " rm -f $(DESTDIR)$(libdir)/$$p"; \
	    rm -f $(DESTDIR)$(libdir)/$$p; \
	  done; \
	fi

mostlyclean-generic:
	-rm -f *~ \#* .*~ .\#*

maintainer-clean-generic:
	-@echo "This command is intended for maintainers to use;"
	-@echo "it deletes files that may require special tools to rebuild."
	-rm -f Makefile.in
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

--- NEW FILE: synth.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: synth.h,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 */

# ifndef LIBMAD_SYNTH_H
# define LIBMAD_SYNTH_H

# 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 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 *);

# 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

--- NEW FILE: xine_decoder.c ---
/* 
 * Copyright (C) 2000-2003 the xine project
 * 
 * This file is part of xine, a free video player.
 * 
 * xine 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.
 * 
 * xine 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: xine_decoder.c,v 1.1 2005/04/04 22:32:48 dsalt-guest Exp $
 *
 * stuff needed to turn libmad into a xine decoder plugin
 */

#include <stdlib.h>
#include <string.h>

#define LOG_MODULE "mad_decoder"
#define LOG_VERBOSE
/*
#define LOG
*/

#include "xine_internal.h"
#include "audio_out.h"
#include "buffer.h"
#include "frame.h"
#include "synth.h"
#include "xineutils.h"

#define INPUT_BUF_SIZE  16384

typedef struct {
  audio_decoder_class_t   decoder_class;
} mad_class_t;

typedef struct mad_decoder_s {
  audio_decoder_t   audio_decoder;

  xine_stream_t    *xstream;

  int64_t           pts;

  struct mad_synth  synth; 
  struct mad_stream stream;
  struct mad_frame  frame;

  int               output_sampling_rate;
  int               output_open;
  int               output_mode;

  uint8_t           buffer[INPUT_BUF_SIZE];
  int               bytes_in_buffer;
  int               preview_mode;

} mad_decoder_t;

static void mad_reset (audio_decoder_t *this_gen) {

  mad_decoder_t *this = (mad_decoder_t *) this_gen;

  mad_synth_finish (&this->synth);
  mad_frame_finish (&this->frame);
  mad_stream_finish(&this->stream);

  this->pts = 0;
  this->bytes_in_buffer = 0;
  this->preview_mode = 0;

  mad_synth_init  (&this->synth);
  mad_stream_init (&this->stream);
  this->stream.options = MAD_OPTION_IGNORECRC;
  mad_frame_init  (&this->frame);
}


static void mad_discontinuity (audio_decoder_t *this_gen) {

  mad_decoder_t *this = (mad_decoder_t *) this_gen;
  
  this->pts = 0;
}

/* utility to scale and round samples to 16 bits */

static inline
signed int scale(mad_fixed_t sample)
{
  /* round */
  sample += (1L << (MAD_F_FRACBITS - 16));

  /* clip */
  if (sample >= MAD_F_ONE)
    sample = MAD_F_ONE - 1;
  else if (sample < -MAD_F_ONE)
    sample = -MAD_F_ONE;

  /* quantize */
  return sample >> (MAD_F_FRACBITS + 1 - 16);
}

/*
static int head_check(mad_decoder_t *this) {

  if( (this->header & 0xffe00000) != 0xffe00000)
    return 0;
  if(!((this->header>>17)&3))
    return 0;
  if( ((this->header>>12)&0xf) == 0xf)
    return 0;
  if( ((this->header>>10)&0x3) == 0x3 )
    return 0;
  return 1;
}
*/

static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {

  mad_decoder_t *this = (mad_decoder_t *) this_gen;

  lprintf ("decode data, decoder_flags: %d\n", buf->decoder_flags);
  
  if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) {
    xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG,
	     "libmad: ALERT input buffer too small (%d bytes, %d avail)!\n",
	     buf->size, INPUT_BUF_SIZE-this->bytes_in_buffer);
    buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer;
  }
  
  if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) {

    /* reset decoder on leaving preview mode */
    if ((buf->decoder_flags & BUF_FLAG_PREVIEW) == 0) {
      if (this->preview_mode) {
	mad_reset (this_gen);
      }
    } else {
      this->preview_mode = 1;
    }

    xine_fast_memcpy (&this->buffer[this->bytes_in_buffer], 
                        buf->content, buf->size);
    this->bytes_in_buffer += buf->size;
    
    /*
    printf ("libmad: decode data - doing it\n");
    */

    mad_stream_buffer (&this->stream, this->buffer, 
		       this->bytes_in_buffer);

    while (1) {

      if (mad_frame_decode (&this->frame, &this->stream) != 0) {

	if (this->stream.next_frame) {
	  int num_bytes =
	    this->buffer + this->bytes_in_buffer - this->stream.next_frame;
	  
	  /* printf("libmad: MAD_ERROR_BUFLEN\n"); */

	  memmove(this->buffer, this->stream.next_frame, num_bytes);
	  this->bytes_in_buffer = num_bytes;
	}

	switch (this->stream.error) {

	case MAD_ERROR_BUFLEN:
	  return;

	default: 
	  mad_stream_buffer (&this->stream, this->buffer, 
			     this->bytes_in_buffer);
	}

      } else {
	int mode = (this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? AO_CAP_MODE_MONO : AO_CAP_MODE_STEREO;

	if (!this->output_open 
	    || (this->output_sampling_rate != this->frame.header.samplerate)
	    || (this->output_mode != mode)) {

	  lprintf ("audio sample rate %d mode %08x\n", this->frame.header.samplerate, mode);

          /* the mpeg audio demuxer can set audio bitrate */
          if (! _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE)) {
            _x_stream_info_set(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE,
                               this->frame.header.bitrate);
          }

          /* the mpeg audio demuxer can set this meta info */
          if (! _x_meta_info_get(this->xstream, XINE_META_INFO_AUDIOCODEC)) {
            switch (this->frame.header.layer) {
            case MAD_LAYER_I:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, 
                "MPEG audio layer 1 (lib: MAD)");
              break;
            case MAD_LAYER_II:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, 
                "MPEG audio layer 2 (lib: MAD)");
              break;
            case MAD_LAYER_III:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, 
                "MPEG audio layer 3 (lib: MAD)");
              break;
            default:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC, 
                "MPEG audio (lib: MAD)");
            }
          }
	  
	  if (this->output_open) {
	    this->xstream->audio_out->close (this->xstream->audio_out, this->xstream);
	    this->output_open = 0;
          }
          if (!this->output_open) {
	    this->output_open = this->xstream->audio_out->open(this->xstream->audio_out,
				   this->xstream, 16,
				   this->frame.header.samplerate, 
			           mode) ;
          }
          if (!this->output_open) {
            return;
          }
	  this->output_sampling_rate = this->frame.header.samplerate;
	  this->output_mode = mode;
	}

	mad_synth_frame (&this->synth, &this->frame);

	if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) {
        
	  unsigned int         nchannels, nsamples;
	  mad_fixed_t const   *left_ch, *right_ch;
	  struct mad_pcm      *pcm = &this->synth.pcm;
	  audio_buffer_t      *audio_buffer;
	  uint16_t            *output;

	  audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out);
	  output = audio_buffer->mem;

	  nchannels = pcm->channels;
	  nsamples  = pcm->length;
	  left_ch   = pcm->samples[0];
	  right_ch  = pcm->samples[1];
	  
	  while (nsamples--) {
	    /* output sample(s) in 16-bit signed little-endian PCM */
	    
	    *output++ = scale(*left_ch++);
	    
	    if (nchannels == 2) 
	      *output++ = scale(*right_ch++);

	  }

	  audio_buffer->num_frames = pcm->length;
	  audio_buffer->vpts       = buf->pts;

	  this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream);

	  buf->pts = 0;

	}

	lprintf ("decode worked\n"); 
      }
    } 

  }
}

static void mad_dispose (audio_decoder_t *this_gen) {

  mad_decoder_t *this = (mad_decoder_t *) this_gen; 

  mad_synth_finish (&this->synth);
  mad_frame_finish (&this->frame);
  mad_stream_finish(&this->stream);

  if (this->output_open) { 
    this->xstream->audio_out->close (this->xstream->audio_out, this->xstream);
    this->output_open = 0;
  }

  free (this_gen);
}

static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) {

  mad_decoder_t *this ;

  this = (mad_decoder_t *) xine_xmalloc (sizeof (mad_decoder_t));

  this->audio_decoder.decode_data         = mad_decode_data;
  this->audio_decoder.reset               = mad_reset;
  this->audio_decoder.discontinuity       = mad_discontinuity;
  this->audio_decoder.dispose             = mad_dispose;

  this->output_open     = 0;
  this->bytes_in_buffer = 0;
  this->preview_mode    = 0;

  this->xstream         = stream;

  mad_synth_init  (&this->synth);
  mad_stream_init (&this->stream);
  mad_frame_init  (&this->frame);

  this->stream.options = MAD_OPTION_IGNORECRC;

  lprintf ("init\n"); 

  return &this->audio_decoder;
}

/*
 * mad plugin class
 */

static char *get_identifier (audio_decoder_class_t *this) {
  return "mad";
}

static char *get_description (audio_decoder_class_t *this) {
  return "libmad based mpeg audio layer 1/2/3 decoder plugin";
}

static void dispose_class (audio_decoder_class_t *this) {
  free (this);
}

static void *init_plugin (xine_t *xine, void *data) {

  mad_class_t *this;
  
  this = (mad_class_t *) xine_xmalloc (sizeof (mad_class_t));

  this->decoder_class.open_plugin     = open_plugin;
  this->decoder_class.get_identifier  = get_identifier;
  this->decoder_class.get_description = get_description;
  this->decoder_class.dispose         = dispose_class;

  return this;
}

static uint32_t audio_types[] = { 
  BUF_AUDIO_MPEG, 0
};

static decoder_info_t dec_info_audio = {
  audio_types,         /* supported types */
  7                    /* priority        */
};

plugin_info_t xine_plugin_info[] = {
  /* type, API, "name", version, special_info, init_function */  
  { PLUGIN_AUDIO_DECODER, 15, "mad", XINE_VERSION_CODE, &dec_info_audio, init_plugin },
  { PLUGIN_NONE, 0, "", 0, NULL, NULL }
};

--- NEW FILE: bit.h ---
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * 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: bit.h,v 1.1 2005/04/04 22:32:48 dsalt-guest 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