diff -ruN sox/Makefile.in sox-patched/Makefile.in
--- sox/Makefile.in	Wed Jan 23 18:32:57 2002
+++ sox-patched/Makefile.in	Wed Jan 23 18:37:45 2002
@@ -46,7 +46,7 @@
 
 FOBJ	= 8svx.o adpcm.o aiff.o au.o auto.o avr.o cdr.o \
 	  cvsd.o dat.o g711.o g721.o g723_16.o g723_24.o g723_40.o \
-	  g72x.o gsm.o hcom.o ima_rw.o maud.o nulfile.o raw.o sf.o \
+	  g72x.o gsm.o hcom.o ima_rw.o maud.o mp3.o nulfile.o raw.o sf.o \
 	  smp.o sndrtool.o sphere.o tx16w.o voc.o vorbis.o \
 	  wav.o wve.o
 
diff -ruN sox/configure.in sox-patched/configure.in
--- sox/configure.in	Wed Jan 23 18:33:33 2002
+++ sox-patched/configure.in	Wed Jan 23 18:37:45 2002
@@ -49,6 +49,16 @@
 	[ogg_vorbisinc="$withval"],
 	[ogg_vorbisinc=auto])
 
+AC_ARG_WITH(madlib,
+	[  --with-madlib    Location of MAD (MP3 Audio Decoder) libraries (=dir)],
+	[madlib="$withval"],
+	[madlib=auto])
+
+AC_ARG_WITH(madinc,
+	[  --with-madinc    Location of MAD (MP3 Audio Decoder) headers (=dir)],
+	[madinc="$withval"],
+	[madinc=auto])
+
 dnl Checks for programs.
 AC_PROG_CC
 AC_PROG_RANLIB
@@ -128,6 +138,36 @@
   AC_CHECK_LIB(vorbis, vorbis_analysis_init,
                LIBS="$LIBS -logg -lvorbis -lvorbisfile -lvorbisenc"
                AC_DEFINE([HAVE_LIBVORBIS], 1, [Define if you have Ogg Vorbis Library installed]))
+fi
+CPPFLAGS="$ac_save_CPPFLAGS"
+
+dnl Test for MAD libraries.
+
+if test "madlib" != auto  && test "madlib" != no
+then
+  LIBS="$LIBS -L$madlib"
+fi
+
+dnl Need to tell preprocess where to look for MAD include files
+dnl when they are not in system directories.  Because of this make
+dnl a backup copy of the CPPFLAGS.
+ac_save_CPPFLAGS="$CPPFLAGS"
+
+if test "madinc" != auto && test "madinc" != no
+then
+  CFLAGS="$CFLAGS -I$madinc"
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  if test \! -z "$madinc" ; then
+    CPPFLAGS="$CPPFLAGS -I$madinc"
+  fi
+fi
+
+AC_CHECK_HEADER(mad.h, madinc=yes, madinc=no)
+if test "$madinc" = yes
+then
+  AC_CHECK_LIB(mad, mad_stream_buffer,
+               LIBS="$LIBS -lmad"
+               AC_DEFINE([HAVE_LIBMAD], 1, [Define if you have MAD (MP3 Audio Decoder) Library installed]))
 fi
 CPPFLAGS="$ac_save_CPPFLAGS"
 
diff -ruN sox/handlers.c sox-patched/handlers.c
--- sox/handlers.c	Wed Jan 23 18:34:05 2002
+++ sox-patched/handlers.c	Wed Jan 23 18:37:45 2002
@@ -111,6 +111,12 @@
         (char *) 0,
 };
 
+/* MP3 */
+static char *mp3names[] = {
+        "mp3",
+        (char *) 0,
+};
+
 static char *nulnames[] = {
         "nul",
         (char *) 0,
@@ -293,6 +299,9 @@
     {maudnames, ST_FILE_STEREO,
 	st_maudstartread, st_maudread, st_maudstopread,
 	st_maudstartwrite, st_maudwrite, st_maudstopwrite, st_format_nothing_seek},
+    {mp3names, ST_FILE_STEREO,
+	st_mp3startread, st_mp3read, st_mp3stopread,
+	st_mp3startwrite, st_mp3write, st_mp3stopwrite, st_format_nothing_seek},
     {nulnames, ST_FILE_STEREO,
 	st_nulstartread, st_nulread, st_nulstopread,
 	st_nulstartwrite, st_nulwrite, st_nulstopwrite, st_format_nothing_seek},
diff -ruN sox/mp3.c sox-patched/mp3.c
--- sox/mp3.c	Thu Jan  1 01:00:00 1970
+++ sox-patched/mp3.c	Wed Jan 23 18:39:59 2002
@@ -0,0 +1,273 @@
+/*
+ * MP3 support for SoX
+ * Uses libmad for MP3 decoding
+ * Written by Fabrizio Gennari <fabrizio.ge@tiscali.it>
+ * with the invaluable help of Bertrand Petit <madlld@phoe.fmug.org>,
+ * author of the decoder-tutorial program madlld
+ */
+
+#include "st_i.h"
+
+#include <string.h>
+
+#if defined(HAVE_LIBMAD)
+#include <mad.h>
+#endif
+
+#ifndef MIN
+#define MIN(s1,s2) ((s1)<(s2)?(s1):(s2))
+#endif
+
+#define INPUT_BUFFER_SIZE	(5*8192)
+
+/* Private data */
+struct mp3priv {
+#if defined(HAVE_LIBMAD)
+	struct mad_stream	*Stream;
+	struct mad_frame	*Frame;
+	struct mad_synth	*Synth;
+	mad_timer_t		*Timer;
+        unsigned char		*InputBuffer;
+        st_ssize_t              cursamp;
+	unsigned long		FrameCount;
+#endif /*HAVE_LIBMAD*/
+};
+
+#if defined(HAVE_LIBMAD)
+
+#include "mad.h"
+
+int st_mp3startread(ft_t ft) 
+{
+	struct mp3priv *p = (struct mp3priv *) ft->priv;
+	size_t ReadSize;
+
+	p->Stream=malloc(sizeof(struct mad_stream));
+	if (p->Stream == NULL){
+	  st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+	  return ST_EOF;
+	}
+	
+	p->Frame=malloc(sizeof(struct mad_frame));
+	if (p->Frame == NULL){
+	  st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+	  return ST_EOF;
+	}
+	
+	p->Synth=malloc(sizeof(struct mad_synth));
+	if (p->Synth == NULL){
+	  st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+	  return ST_EOF;
+	}
+	
+	p->Timer=malloc(sizeof(mad_timer_t));
+	if (p->Timer == NULL){
+	  st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+	  return ST_EOF;
+	}
+	
+	p->InputBuffer=malloc(INPUT_BUFFER_SIZE);
+	if (p->InputBuffer == NULL){
+	  st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+	  return ST_EOF;
+	}
+	
+	mad_stream_init(p->Stream);
+	mad_frame_init(p->Frame);
+	mad_synth_init(p->Synth);
+	mad_timer_reset(p->Timer);
+
+	ft->info.encoding = ST_ENCODING_MP3;
+	ft->info.size = ST_SIZE_WORD;
+
+	/* We need to decode the first frame,
+	 * so we know the output format */
+
+	ReadSize=fread(p->InputBuffer,1,INPUT_BUFFER_SIZE,ft->fp);
+	if(ReadSize<=0)
+	{
+		if(ferror(ft->fp))
+			st_fail_errno(ft,ST_EOF,"read error on bitstream");
+		if(feof(ft->fp))
+			st_fail_errno(ft,ST_EOF,"end of input stream");
+		return(ST_EOF);
+	}
+	
+	mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize);
+	p->Stream->error = 0;
+
+	if(mad_frame_decode(p->Frame,p->Stream)) {
+
+	  /* we assume that, if the first frame fails, the file is not an MP3 file */
+
+	  st_fail_errno(ft,ST_EOF,"The file is not an MP3 file or it is corrupted");
+	  return ST_EOF;
+	}
+
+	switch(p->Frame->header.mode)
+	{
+		case MAD_MODE_SINGLE_CHANNEL:
+		case MAD_MODE_DUAL_CHANNEL:
+		case MAD_MODE_JOINT_STEREO:
+		case MAD_MODE_STEREO:
+		  ft->info.channels = MAD_NCHANNELS(&p->Frame->header);
+		  break;
+		default:
+		  st_fail_errno(ft,ST_EFMT,"Cannot determine number of channels");
+		  return ST_EOF;
+	}
+
+	p->FrameCount=1;
+	ft->info.rate=p->Frame->header.samplerate;
+	ft->info.size=ST_SIZE_DWORD;
+	ft->info.encoding=ST_ENCODING_SIGN2;
+
+	mad_timer_add(p->Timer,p->Frame->header.duration);
+	mad_synth_frame(p->Synth,p->Frame);
+	p->cursamp = 0;
+
+	return ST_SUCCESS;
+}
+
+/*
+ * Read up to len samples from p->Synth
+ * If needed, read some more MP3 data, decode them and synth them
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+st_ssize_t st_mp3read(ft_t ft, st_sample_t *buf, st_ssize_t len)
+{
+  struct mp3priv *p = (struct mp3priv *) ft->priv;
+  st_ssize_t donow,i,done=0;
+  int chan;
+
+  do{
+    donow=MIN(len,(p->Synth->pcm.length - p->cursamp)*ft->info.channels);
+    i=0;
+    while(i<donow){
+      for(chan=0;chan<ft->info.channels;chan++){
+
+	/* We can assign the sample given by mad to sox because
+	 * sox's signed 32-bit format is compatible with mad's
+	 * fixed-point format...as long as mad's format uses 32 bits.
+	 * mad's format uses 1 but for sign, 3 bits for integer part and
+	 * MAD_F_FRACBITS bits for the fractional part. If MAD_F_FRACBITS
+	 * is 28 everything's well. Should we paranoically check
+	 * whether MAD_F_FRACBITS is actually 28? */	   
+	   
+	*buf++=(st_sample_t)p->Synth->pcm.samples[chan][p->cursamp];
+	i++;
+      }
+      p->cursamp++;
+    };
+
+    len-=donow;
+    done+=donow;
+
+    if (len==0) break;
+
+    /* check whether input buffer needs a refill */
+
+    if(p->Stream->error==MAD_ERROR_BUFLEN)
+      {
+	size_t		ReadSize, Remaining;
+	
+			/* libmad does not consume all the buffer it's given. Some
+			 * datas, part of a truncated frame, is left unused at the
+			 * end of the buffer. Those datas must be put back at the
+			 * beginning of the buffer and taken in account for
+			 * refilling the buffer. This means that the input buffer
+			 * must be large enough to hold a complete frame at the
+			 * highest observable bit-rate (currently 448 kb/s). XXX=XXX
+			 * Is 2016 bytes the size of the largest frame?
+			 * (448000*(1152/32000))/8
+			 */
+	
+	Remaining=p->Stream->bufend - p->Stream->next_frame;
+	memmove(p->InputBuffer,p->Stream->next_frame,Remaining);
+
+	ReadSize=fread(p->InputBuffer+Remaining,1,INPUT_BUFFER_SIZE-Remaining,ft->fp);
+	if(ReadSize == 0)
+	  return done;
+
+	mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize+Remaining);
+	p->Stream->error=0;
+      }
+    if(mad_frame_decode(p->Frame,p->Stream)){
+      if(MAD_RECOVERABLE(p->Stream->error))
+	{ 
+	  continue;
+	}
+      else
+	if(p->Stream->error==MAD_ERROR_BUFLEN)
+	  continue;
+	else
+	  {
+	    st_warn("unrecoverable frame level error (%s).\n",
+		    mad_stream_errorstr(p->Stream));
+	    return done;
+	  }
+    }
+    p->FrameCount++;
+    mad_timer_add(p->Timer,p->Frame->header.duration);
+    mad_synth_frame(p->Synth,p->Frame);
+    p->cursamp=0;
+  }while(1);
+
+  return done;
+}
+
+int st_mp3stopread(ft_t ft)
+{
+  struct mp3priv *p=(struct mp3priv*) ft->priv;
+
+  mad_synth_finish(p->Synth);
+  mad_frame_finish(p->Frame);
+  mad_stream_finish(p->Stream);
+
+  free(p->Stream);
+  free(p->Frame);
+  free(p->Synth);
+  free(p->Timer);
+  free(p->InputBuffer);
+
+  return ST_SUCCESS;
+}
+#else /*HAVE_LIBMAD*/
+int st_mp3startread(ft_t ft)
+{
+  st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+  return ST_EOF;
+}
+
+st_ssize_t st_mp3read(ft_t ft, st_sample_t *buf, st_ssize_t samp)
+{
+  st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+  return ST_EOF;
+}
+
+int st_mp3stopread(ft_t ft)
+{
+  st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+  return ST_EOF;
+}
+#endif /*HAVE_LIBMAD*/
+
+int st_mp3startwrite(ft_t ft)
+{
+  st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+  return ST_EOF;
+}
+
+st_ssize_t st_mp3write(ft_t ft, st_sample_t *buf, st_ssize_t samp)
+{
+  st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+  return ST_EOF;
+}
+
+int st_mp3stopwrite(ft_t ft)
+{
+  st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+  return ST_EOF;
+}
diff -ruN sox/st.h sox-patched/st.h
--- sox/st.h	Wed Jan 23 18:34:38 2002
+++ sox-patched/st.h	Wed Jan 23 18:37:45 2002
@@ -192,7 +192,8 @@
 #define ST_ENCODING_GSM         8 /* GSM 6.10 33byte frame lossy compression */
 #define ST_ENCODING_INV_ULAW    9 /* Inversed bit-order u-law */
 #define ST_ENCODING_INV_ALAW    10/* Inversed bit-order A-law */
-#define ST_ENCODING_MAX         10 
+#define ST_ENCODING_MP3         11/* MP3 compression */
+#define ST_ENCODING_MAX         11 
 
 /* declared in misc.c */
 extern const char *st_sizes_str[];
diff -ruN sox/st_i.h sox-patched/st_i.h
--- sox/st_i.h	Wed Jan 23 18:34:39 2002
+++ sox-patched/st_i.h	Wed Jan 23 18:37:45 2002
@@ -229,6 +229,13 @@
 int st_maudstartwrite(ft_t ft);
 int st_maudstopwrite(ft_t ft);
 
+int st_mp3startread(ft_t ft);
+st_ssize_t st_mp3read(ft_t ft, st_sample_t *buf, st_ssize_t len);
+int st_mp3stopread(ft_t ft);
+st_ssize_t st_mp3write(ft_t ft, st_sample_t *buf, st_ssize_t len);
+int st_mp3startwrite(ft_t ft);
+int st_mp3stopwrite(ft_t ft);
+
 int st_nulstartread(ft_t ft);
 st_ssize_t st_nulread(ft_t ft, st_sample_t *buf, st_ssize_t len);
 int st_nulstopread(ft_t ft);
diff -ruN sox/stconfig.h.in sox-patched/stconfig.h.in
--- sox/stconfig.h.in	Wed Jan 23 18:34:41 2002
+++ sox-patched/stconfig.h.in	Wed Jan 23 18:37:45 2002
@@ -21,6 +21,9 @@
 /* Define if you have the `m' library (-lm). */
 #undef HAVE_LIBM
 
+/* Define if you have MAD (MP3 Audio Decoder) Library installed */
+#undef HAVE_LIBMAD
+
 /* Define if you have Ogg Vorbis Library installed */
 #undef HAVE_LIBVORBIS
 
