shithub: sox

Download patch

ref: 94d88fc3653246d4680a73de95e331faa161fec3
parent: 10bfbe260ac55bf7d8430fdf7564673947da966f
author: cbagwell <cbagwell>
date: Wed Nov 28 21:24:19 EST 2001

Added ST_BUFSIZ.  Bugfix trim more.  Add install-lib for gsm. Rename nul.

--- a/Changelog
+++ b/Changelog
@@ -13,6 +13,10 @@
     as the device is open and the buffered data can be in a
     wrong format.
   o trim wasn't accounting for # of channels and was generally broken.
+  o Jeff Bonggren fixed trim bugs were it was failing when triming
+    data that equaled to BUFSIZ.  Also, trim now immediately returns
+    ST_EOF when its done instead of requiring an extra call that
+    returns no data.
   o auto effect wasn't rewinding the file if the file was less then
     132 bytes.  Changed auto parsing of header to be incremental
     instead of reading in a large buffer.
--- a/Makefile.dos
+++ b/Makefile.dos
@@ -13,7 +13,7 @@
 FOBJ	= 8svx.obj adpcm.obj aiff.obj alsa.obj au.obj auto.obj \
           avr.obj cdr.obj cvsd.obj dat.obj g721.obj g723_16.obj \
 	  g723_24.obj g723_40.obj g72x.obj gsm.obj \
-	  hcom.obj ima_rw.obj maud.obj nul.obj oss.obj raw.obj \
+	  hcom.obj ima_rw.obj maud.obj nulfile.obj oss.obj raw.obj \
 	  sf.obj smp.obj sndrtool.obj sphere.obj sunaudio.obj \
 	  tx16w.obj voc.obj wav.obj wve.obj
 
--- a/Makefile.gcc
+++ b/Makefile.gcc
@@ -30,7 +30,7 @@
 
 FOBJ	= 8svx.o adpcm.o aiff.o alsa.o au.o auto.o avr.o cdr.o cvsd.o dat.o \
 	  g721.o g723_16.o g723_24.o g723_40.o g72x.o gsm.o hcom.o \
-	  ima_rw.o maud.o nul.o oss.o raw.o sf.o smp.o sndrtool.o \
+	  ima_rw.o maud.o nulfile.o oss.o raw.o sf.o smp.o sndrtool.o \
 	  sphere.o sunaudio.o tx16w.o voc.o wav.o wve.o
 
 EOBJ    = avg.o band.o bandpass.o breject.o btrworth.o chorus.o compand.o \
--- a/TODO
+++ b/TODO
@@ -3,6 +3,9 @@
 
   o Get nul effect and oss driver compiling under latest cygwin.
 
+  o Several files are using hard-coded #'s instead of ST_SAMPLE_MIN/MAX.
+    Change these.
+
   o Make a global version of MIN/MAX instead of sprinkled min/max/MIN/MAX
 
   o Make a global version of clip() instead of sprinked in all files.
--- a/nul.c
+++ /dev/null
@@ -1,128 +1,0 @@
-/*
- * July 5, 1991
- * Copyright 1991 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose.  This copyright notice must be maintained. 
- * Lance Norskog And Sundry Contributors are not responsible for 
- * the consequences of using this software.
- */
-
-/*
- * Sound Tools nul file format driver.
- * Written by Carsten Borchardt 
- * The author is not responsible for the consequences 
- * of using this software
- *
- */
-
-#include <math.h>
-#include "st_i.h"
-
-/* Private data for nul file */
-typedef struct nulstuff {
-	int	rest;			/* bytes remaining in current block */
-    unsigned long readsamples;
-    unsigned long writesamples;
-} *nul_t;
-
-/*
- * Do anything required before you start reading samples.
- * Read file header. 
- *	Find out sampling rate, 
- *	size and encoding of samples, 
- *	mono/stereo/quad.
- */
-int st_nulstartread(ft_t ft) 
-{
-	nul_t sk = (nul_t) ft->priv;
-	/* no samples read yet */
-	sk->readsamples=0;
-
-	/* if no input rate is given as parameter, switch to 
-	 * default parameter
-	 */
-	if(ft->info.rate == 0){
-	    /* input rate not set, switch to default */
-	    ft->info.rate = 44100;
-	    ft->info.size = ST_SIZE_WORD;
-	    ft->info.encoding = ST_ENCODING_SIGN2;
-	    ft->info.channels = 2;
-	}
-	ft->comment = "nul file";
-	
-	/* only SIGINT will stop us from reading nul data.. 
-	 *
-	 */
-	sigintreg(ft);	/* Prepare to catch SIGINT */
-
-	return (ST_SUCCESS);
-}
-
-/*
- * Read up to len samples, we read always '0'
- * Convert to signed longs.
- * Place in buf[].
- * Return number of samples read.
- */
-
-st_ssize_t st_nulread(ft_t ft, st_sample_t *buf, st_ssize_t len) 
-{
-	nul_t sk = (nul_t) ft->priv;
-	int done = 0;
-	st_sample_t l;
-	for(; done < len; done++) {
-	    if (ft->file.eof)
-		break;
-	    l = 0; /* nul samples are always 0 */
-	    sk->readsamples++;
-	    *buf++ = l;
-	}
-	return done;
-}
-
-/*
- * Do anything required when you stop reading samples.  
- * Don't close input file! 
- * .. nothing to be done
- */
-int st_nulstopread(ft_t ft) 
-{ 
-    return (ST_SUCCESS);
-}
-
-int st_nulstartwrite(ft_t ft) 
-{
-	nul_t sk = (nul_t) ft->priv;
-	sk->writesamples=0;
-	return(ST_SUCCESS);
-	
-}
-
-st_ssize_t st_nulwrite(ft_t ft, st_sample_t *buf, st_ssize_t len) 
-{
-	nul_t sk = (nul_t) ft->priv;
-	while(len--)
-	    sk->writesamples++;
-	st_writeb(ft, (*buf++ >> 24) ^ 0x80);
-	return (ST_SUCCESS);
-	
-}
-
-int st_nulstopwrite(ft_t ft) 
-{
-    /* nothing to do */
-    return (ST_SUCCESS);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/src/8svx.c
+++ b/src/8svx.c
@@ -229,7 +229,7 @@
 			if (feof(p->ch[i]))
 				return done;
 			/* scale signed up to long's range */
-			*buf++ = LEFT(datum, 24);
+			*buf++ = ST_SIGNED_BYTE_TO_SAMPLE(datum);
 		}
 		done += ft->info.channels;
 	}
@@ -303,7 +303,7 @@
 
 	while(done < len) {
 		for (i = 0; i < ft->info.channels; i++) {
-			datum = RIGHT(*buf++, 24);
+			datum = ST_SAMPLE_TO_SIGNED_BYTE(*buf++);
 			/* FIXME: Needs to pass ft struct and not FILE */
 			putc(datum, p->ch[i]);
 		}
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -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 nul.o raw.o sf.o \
+	  g72x.o gsm.o hcom.o ima_rw.o maud.o nulfile.o raw.o sf.o \
 	  smp.o sndrtool.o sphere.o tx16w.o voc.o vorbis.o \
 	  wav.o wve.o
 
--- a/src/au.c
+++ b/src/au.c
@@ -321,9 +321,9 @@
 		return st_rawread(ft, buf, samp);
 	done = 0;
 	while (samp > 0 && unpack_input(ft, &code) >= 0) {
-		*buf++ = LEFT((*p->dec_routine)(code, AUDIO_ENCODING_LINEAR,
-						&p->state),
-			      16);
+		*buf++ = ST_SIGNED_WORD_TO_SAMPLE(
+			(*p->dec_routine)(code, AUDIO_ENCODING_LINEAR,
+	  				  &p->state));
 		samp--;
 		done++;
 	}
--- a/src/gsm.c
+++ b/src/gsm.c
@@ -114,7 +114,8 @@
 	while (done < samp)
 	{
 		while (p->samplePtr < p->sampleTop && done < samp)
-			buf[done++] = LEFT(*(p->samplePtr)++, 16);
+			buf[done++] = 
+			    ST_SIGNED_WORD_TO_SAMPLE(*(p->samplePtr)++);
 
 		if (done>=samp) break;
 
@@ -187,7 +188,8 @@
 	while (done < samp)
 	{
 		while ((p->samplePtr < p->sampleTop) && (done < samp))
-			*(p->samplePtr)++ = RIGHT(buf[done++], 16);
+			*(p->samplePtr)++ = 
+			    ST_SAMPLE_TO_SIGNED_WORD(buf[done++]);
 
 		if (p->samplePtr == p->sampleTop)
 		{
--- a/src/gsm/Makefile.in
+++ b/src/gsm/Makefile.in
@@ -8,9 +8,11 @@
 
 VPATH = @srcdir@
 srcdir = @srcdir@
+top_srcdir = @top_srcdir@
 prefix = @prefix@
 exec_prefix = @exec_prefix@
 libdir = @libdir@
+mandir = @mandir@
 
 # Shell commands.
 
@@ -76,6 +78,14 @@
 libgsm.a: $(LIBOBJS)
 	$(AR) libgsm.a $(LIBOBJS)
 	$(RANLIB) libgsm.a
+
+install-lib: libgsm.a
+	$(top_srcdir)/mkinstalldirs $(libdir)
+	$(top_srcdir)/mkinstalldirs $(mandir)/man3
+	$(INSTALL) -c -m 644 libgsm.a $(libdir)
+	$(RANLIB) $(libdir)/libgsm.a
+	$(INSTALL) -c -m 644 gsm.3 $(mandir)/man3
+	$(INSTALL) -c -m 644 gsm_option.3 $(mandir)/man3
 
 clean:
 	$(RM) *.o
--- /dev/null
+++ b/src/gsm/gsm.3
@@ -1,0 +1,105 @@
+.\"
+.\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH GSM 3 
+.SH NAME
+gsm_create, gsm_destroy, gsm_encode, gsm_decode \(em GSM\ 06.10 lossy sound compression
+.SH SYNOPSIS
+.PP
+#include "gsm.h"
+.PP
+gsm gsm_create();
+.PP
+void gsm_encode(handle, src, dst)
+.br
+gsm handle;
+.br
+gsm_signal src[160];
+.br
+gsm_frame dst;
+.PP
+int gsm_decode(handle, src, dst)
+.br
+gsm handle;
+.br
+gsm_frame src;
+.br
+gsm_signal dst[160];
+.PP
+void gsm_destroy(handle)
+.br
+gsm handle;
+.br
+.SH "DESCRIPTION"
+Gsm is an implementation of the final draft GSM 06.10
+standard for full-rate speech transcoding.
+.PP
+gsm_create() initializes a gsm pass and returns a 'gsm' object
+which can be used as a handle in subsequent calls to gsm_decode(),
+gsm_encode() or gsm_destroy().
+.PP
+gsm_encode() encodes an array of 160 13-bit samples (given as
+gsm_signal's, signed integral values of at least 16 bits) into
+a gsm_frame of 33 bytes.
+(gsm_frame is a type defined as an array of 33 gsm_bytes in gsm.h.)
+.PP
+gsm_decode() decodes a gsm_frame into an array of 160 13-bit samples
+(given as gsm_signals), which sound rather like what you handed to
+gsm_encode() on the other side of the wire.
+.PP
+gsm_destroy() finishes a gsm pass and frees all storage associated
+with it.
+.SS "Sample format"
+The following scaling is assumed for input to the algorithm:
+.br
+.nf
+   0  1                             11 12
+   S..v..v..v..v..v..v..v..v..v..v..v..v..*..*..*
+.nf
+.br
+Only the top 13 bits are used as a signed input value.
+The output of gsm_decode() has the three lower bits set to zero.
+.\" .SH OPTIONS
+.SH "RETURN VALUE"
+gsm_create() returns an opaque handle object of type gsm, or 0 on error.
+gsm_decode() returns -1 if the passed frame is invalid, else 0.
+.SH EXAMPLE
+.nf
+#include "gsm.h"
+
+gsm handle;
+gsm_frame buf;
+gsm_signal sample[160];
+int cc, soundfd;
+
+play() {	/* read compressed data from standard input, write to soundfd */
+
+	if (!(handle = gsm_create())) error...
+	while (cc = read(0, (char *)buf, sizeof buf)) {
+		if (cc != sizeof buf) error...
+		if (gsm_decode(handle, buf, sample) < 0) error... 
+		if (write(soundfd, sample, sizeof sample) != sizeof sample)
+			error...
+	}
+	gsm_destroy(handle);
+}
+
+record() {	/* read from soundfd, write compressed to standard output */
+
+	if (!(handle = gsm_create())) error...
+	while (cc = read(soundfd, sample, sizeof sample)) {
+		if (cc != sizeof sample) error...
+		gsm_encode(handle, sample, buf);
+		if (write(1, (char *)buf, sizeof buf) != sizeof sample) 
+			error...
+	}
+	gsm_destroy(handle);
+}
+.nf
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
+.SH "SEE ALSO"
+toast(1), gsm_print(3), gsm_explode(3), gsm_option(3)
--- a/src/gsm/gsm.h
+++ b/src/gsm/gsm.h
@@ -4,7 +4,7 @@
  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  */
 
-/*$Header: /cvsroot/sox/sox/src/gsm/Attic/gsm.h,v 1.1 2001/11/14 03:31:26 cbagwell Exp $*/
+/*$Header: /cvsroot/sox/sox/src/gsm/Attic/gsm.h,v 1.2 2001/11/29 02:24:19 cbagwell Exp $*/
 
 #ifndef	GSM_H
 #define	GSM_H
@@ -57,14 +57,10 @@
 extern gsm  gsm_create 	GSM_P((void));
 extern void gsm_destroy GSM_P((gsm));	
 
-extern int  gsm_print   GSM_P((FILE *, gsm, gsm_byte  *));
 extern int  gsm_option  GSM_P((gsm, int, int *));
 
 extern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));
 extern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));
-
-extern int  gsm_explode GSM_P((gsm, gsm_byte   *, gsm_signal *));
-extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte   *));
 
 #undef	GSM_P
 
--- /dev/null
+++ b/src/gsm/gsm_option.3
@@ -1,0 +1,183 @@
+.\"
+.\" Copyright 1992-1995 by Jutta Degener and Carsten Bormann, Technische
+.\" Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+.\" details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+.\"
+.PU
+.TH GSM_OPTION 3 
+.SH NAME
+gsm_option \(em customizing the GSM 06.10 implementation
+.SH SYNOPSIS
+#include "gsm.h"
+.PP
+int gsm_option(handle, option, valueP);
+.br
+gsm handle;
+.br
+int option;
+.br
+int * valueP;
+.SH "DESCRIPTION"
+The gsm library is an implementation of the final draft GSM 06.10
+standard for full-rate speech transcoding, a lossy
+speech compression algorithm.
+.PP
+The gsm_option() function can be used to set and query various
+options or flags that are not needed for regular GSM 06.10 encoding
+or decoding, but might be of interest in special cases.
+.PP
+The second argument to gsm_option specifies what parameter
+should be changed or queried.
+The third argument is either a null pointer, in which case
+the current value of that parameter is returned;
+or it is a pointer to an integer containing the value
+you want to set, in which case the previous value will
+be returned.
+.PP
+The following options are defined:
+.PP
+.I GSM_OPT_VERBOSE
+Verbosity level.
+.br
+.in+5
+This option is only supported if the library was compiled
+with debugging turned on, and may be used by developers of
+compression algorithms to aid debugging.
+.br
+The verbosity level can be changed at any time during encoding or decoding.
+.in-5
+.sp
+.PP
+.I GSM_OPT_FAST
+Faster compression algorithm.
+.br
+.in+5
+This implementation offers a not strictly standard-compliant, but
+faster compression algorithm that is compatible with the regular
+method and does not noticably degrade audio quality.
+.br
+The value passed to 
+.br
+.nf
+	gsm_option(handle, GSM_OPT_FAST, & value)
+.fi
+.br 
+functions as a boolean flag; if it is zero, the regular algorithm
+will be used, if not, the faster version will be used.
+.br
+The availability of this option depends on the hardware used;
+if it is not available, gsm_option will return -1 on an attempt
+to set or query it.
+.br
+This option can be set any time during encoding or decoding.
+.in-5
+.ne 5
+.sp
+.PP
+.I GSM_OPT_LTP_CUT
+Enable, disable, or query the LTP cut-off optimization.
+.br
+.in+5
+During encoding, the search for the long-term correlation
+lag forms the bottleneck of the algorithm. 
+The ltp-cut option enables an approximation that disregards most
+of the samples for purposes of finding that correlation,
+and hence speeds up the encoding at a noticable loss in quality.
+.br
+The value passed to 
+.br
+.nf
+	gsm_option(handle, GSM_OPT_LTP_CUT, & value)
+.fi
+.br 
+turns the optimization on if nonzero, and off if zero.
+.br
+This option can be set any time during encoding
+or decoding; it will only affect the encoding pass, not
+the decoding.
+.sp
+.PP
+.I GSM_OPT_WAV49
+WAV-style byte ordering.
+.br
+.in+5
+A WAV file of type #49 contains GSM 06.10-encoded frames.
+Unfortunately, the framing and code ordering of the WAV version
+are incompatible with the native ones of this GSM 06.10 library.
+The GSM_OPT_WAV49 option turns on a different packing
+algorithm that produces alternating frames of 32 and 33 bytes
+(or makes it consume alternating frames of 33 and 32 bytes, note
+the opposite order of the two numbers) which, when concatenated,
+can be used in the body of a WAV #49 frame.
+It is up to the user program to write a WAV header, if any;
+neither the library itself nor the toast program produce
+complete WAV files.
+.br
+The value passed to 
+.br
+.nf
+	gsm_option(handle, GSM_OPT_WAV49, & value)
+.fi
+.br 
+functions as a boolean flag; if it is zero, the library's native
+framing algorithm will be used, if nonzero, WAV-type packing is in effect.
+.br
+This option should be used before any frames are encoded.
+Whether or not it is supported at all depends on a
+compile-time switch, WAV49.
+Both option and compile time switch are new to the library
+as of patchlevel 9, and are considerably less tested than the
+well-worn rest of the it.
+.br
+Thanks to Jeff Chilton for the detective work and first free
+implementation of this version of the GSM 06.10 encoding.
+.sp
+.PP
+.I GSM_OPT_FRAME_CHAIN
+Query or set the chaining byte.
+.br
+.in+5
+Between the two frames of a WAV-style encoding, the GSM 06.10 library
+must keep track of one half-byte that is technically part of the first
+frame, but will be written as the first four bits of the second.
+This half-byte are the lowest four bits of the value returned by,
+and optionally set by,
+.br
+.nf
+	gsm_option(handle, GSM_OPT_FRAME_CHAIN, & value)
+.fi
+.br 
+This option can be queried and set at any time.
+.sp
+.PP
+.I GSM_OPT_FRAME_INDEX
+Query or set the current frame's index in a format's
+alternating list of frames.
+.br
+.in+5
+The WAV #49 framing uses two alternating types of frames.
+Which type the next GSM-coded frame belongs to can be queried, or,
+when decoding, announced, using
+.br
+.nf
+	gsm_option(handle, GSM_OPT_FRAME_INDEX, & value)
+.fi
+.br 
+For WAV-style framing, the value should be 0 or 1; the first frame
+of an encoding has an index of 0. 
+At library initialization, the index is set to zero.
+.br 
+The frame index can be queried and set at any time.
+Used in combination with the
+.IR GSM_OPT_FRAME_CHAIN ,
+option, it can be used to position on arbitrary GSM frames
+within a format like WAV #49 (not accounting for the lost
+internal GSM state).
+.in-5
+.SH "RETURN VALUE"
+gsm_option() returns -1 if an option is not supported, the
+previous value of the option otherwise.
+.SH BUGS
+Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de.
+.SH "SEE ALSO"
+toast(1), gsm(3), gsm_explode(3), gsm_print(3)
--- /dev/null
+++ b/src/nulfile.c
@@ -1,0 +1,128 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained. 
+ * Lance Norskog And Sundry Contributors are not responsible for 
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools nul file format driver.
+ * Written by Carsten Borchardt 
+ * The author is not responsible for the consequences 
+ * of using this software
+ *
+ */
+
+#include <math.h>
+#include "st_i.h"
+
+/* Private data for nul file */
+typedef struct nulstuff {
+	int	rest;			/* bytes remaining in current block */
+    unsigned long readsamples;
+    unsigned long writesamples;
+} *nul_t;
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header. 
+ *	Find out sampling rate, 
+ *	size and encoding of samples, 
+ *	mono/stereo/quad.
+ */
+int st_nulstartread(ft_t ft) 
+{
+	nul_t sk = (nul_t) ft->priv;
+	/* no samples read yet */
+	sk->readsamples=0;
+
+	/* if no input rate is given as parameter, switch to 
+	 * default parameter
+	 */
+	if(ft->info.rate == 0){
+	    /* input rate not set, switch to default */
+	    ft->info.rate = 44100;
+	    ft->info.size = ST_SIZE_WORD;
+	    ft->info.encoding = ST_ENCODING_SIGN2;
+	    ft->info.channels = 2;
+	}
+	ft->comment = "nul file";
+	
+	/* only SIGINT will stop us from reading nul data.. 
+	 *
+	 */
+	sigintreg(ft);	/* Prepare to catch SIGINT */
+
+	return (ST_SUCCESS);
+}
+
+/*
+ * Read up to len samples, we read always '0'
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+st_ssize_t st_nulread(ft_t ft, st_sample_t *buf, st_ssize_t len) 
+{
+	nul_t sk = (nul_t) ft->priv;
+	int done = 0;
+	st_sample_t l;
+	for(; done < len; done++) {
+	    if (ft->file.eof)
+		break;
+	    l = 0; /* nul samples are always 0 */
+	    sk->readsamples++;
+	    *buf++ = l;
+	}
+	return done;
+}
+
+/*
+ * Do anything required when you stop reading samples.  
+ * Don't close input file! 
+ * .. nothing to be done
+ */
+int st_nulstopread(ft_t ft) 
+{ 
+    return (ST_SUCCESS);
+}
+
+int st_nulstartwrite(ft_t ft) 
+{
+	nul_t sk = (nul_t) ft->priv;
+	sk->writesamples=0;
+	return(ST_SUCCESS);
+	
+}
+
+st_ssize_t st_nulwrite(ft_t ft, st_sample_t *buf, st_ssize_t len) 
+{
+	nul_t sk = (nul_t) ft->priv;
+	while(len--)
+	    sk->writesamples++;
+	st_writeb(ft, (*buf++ >> 24) ^ 0x80);
+	return (ST_SUCCESS);
+	
+}
+
+int st_nulstopwrite(ft_t ft) 
+{
+    /* nothing to do */
+    return (ST_SUCCESS);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
--- a/src/raw.c
+++ b/src/raw.c
@@ -65,13 +65,13 @@
 
 int st_rawstartread(ft_t ft)
 {
-    ft->file.buf = malloc(BUFSIZ);
+    ft->file.buf = malloc(ST_BUFSIZ);
     if (!ft->file.buf)
     {
         st_fail_errno(ft,ST_ENOMEM,"Unable to alloc resources");
         return(ST_EOF);
     }
-    ft->file.size = BUFSIZ;
+    ft->file.size = ST_BUFSIZ;
     ft->file.count = 0;
     ft->file.pos = 0;
     ft->file.eof = 0;
@@ -81,13 +81,13 @@
 
 int st_rawstartwrite(ft_t ft)
 {
-    ft->file.buf = malloc(BUFSIZ);
+    ft->file.buf = malloc(ST_BUFSIZ);
     if (!ft->file.buf)
     {
         st_fail_errno(ft,ST_ENOMEM,"Unable to alloc resources");
         return(ST_EOF);
     }
-    ft->file.size = BUFSIZ;
+    ft->file.size = ST_BUFSIZ;
     ft->file.pos = 0;
     ft->file.eof = 0;
 
--- a/src/smp.c
+++ b/src/smp.c
@@ -327,7 +327,7 @@
 	for(; done < len && smp->NoOfSamps; done++, smp->NoOfSamps--) {
 		st_readw(ft, &datum);
 		/* scale signed up to long's range */
-		*buf++ = LEFT(datum, 16);
+		*buf++ = ST_SIGNED_WORD_TO_SAMPLE(datum);
 	}
 	return done;
 }
@@ -389,7 +389,7 @@
 	st_ssize_t done = 0;
 
 	while(done < len) {
-		datum = (int) RIGHT(*buf++, 16);
+		datum = (int) ST_SAMPLE_TO_SIGNED_WORD(*buf++);
 		st_writew(ft, datum);
 		smp->NoOfSamps++;
 		done++;
--- a/src/sox.c
+++ b/src/sox.c
@@ -64,10 +64,10 @@
 static int writing = 0;         /* are we writing to a file? */
 static int soxpreview = 0;      /* preview mode */
 
-static st_sample_t ibufl[BUFSIZ/2];    /* Left/right interleave buffers */
-static st_sample_t ibufr[BUFSIZ/2];
-static st_sample_t obufl[BUFSIZ/2];
-static st_sample_t obufr[BUFSIZ/2];
+static st_sample_t ibufl[ST_BUFSIZ/2];    /* Left/right interleave buffers */
+static st_sample_t ibufr[ST_BUFSIZ/2];
+static st_sample_t obufl[ST_BUFSIZ/2];
+static st_sample_t obufr[ST_BUFSIZ/2];
 
 /* local forward declarations */
 static void doopts(ft_t, int, char **);
@@ -382,7 +382,7 @@
 
             /* stdout tends to be line-buffered.  Override this */
             /* to be Full Buffering. */
-            if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*BUFSIZ))
+            if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*ST_BUFSIZ))
             {
                 st_fail("Can't set write buffer");
             }
@@ -397,7 +397,7 @@
 
             /* stdout tends to be line-buffered.  Override this */
             /* to be Full Buffering. */
-            if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*BUFSIZ))
+            if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*ST_BUFSIZ))
             {
                 st_fail("Can't set write buffer");
             }
@@ -630,7 +630,8 @@
     /* Reserve an output buffer for all effects */
     for(e = 0; e < neffects; e++)
     {
-        efftab[e].obuf = (st_sample_t *) malloc(BUFSIZ * sizeof(st_sample_t));
+        efftab[e].obuf = (st_sample_t *) malloc(ST_BUFSIZ * 
+		                                sizeof(st_sample_t));
         if (efftab[e].obuf == NULL)
         {
             st_fail("could not allocate memory");
@@ -637,7 +638,7 @@
         }
         if (efftabR[e].name)
         {
-            efftabR[e].obuf = (st_sample_t *) malloc(BUFSIZ * 
+            efftabR[e].obuf = (st_sample_t *) malloc(ST_BUFSIZ * 
 		                                     sizeof(st_sample_t));
             if (efftabR[e].obuf == NULL)
             {
@@ -649,7 +650,7 @@
 #ifdef SOXMIX
     for (f = 0; f < MAX_INPUT_FILES; f++)
     {
-        ibuf[f] = (st_sample_t *)malloc(BUFSIZ * sizeof(st_sample_t));
+        ibuf[f] = (st_sample_t *)malloc(ST_BUFSIZ * sizeof(st_sample_t));
         if (!ibuf[f])
         {
             st_fail("could not allocate memory");
@@ -671,13 +672,13 @@
 #ifndef SOXMIX
         efftab[0].olen = (*informat[0]->h->read)(informat[0],
                                                  efftab[0].obuf, 
-						 (st_ssize_t)BUFSIZ);
+						 (st_ssize_t)ST_BUFSIZ);
 #else
         for (f = 0; f < input_count; f++)
         {
             ilen[f] = (*informat[f]->h->read)(informat[f],
                                               ibuf[f], 
-					      (st_ssize_t)BUFSIZ);
+					      (st_ssize_t)ST_BUFSIZ);
         }
 
         efftab[0].olen = 0;
@@ -746,7 +747,7 @@
                 (* outformat->h->write)(outformat, efftab[neffects-1].obuf,
                                        (st_ssize_t) efftab[neffects-1].olen);
 
-            if (efftab[f].olen != BUFSIZ)
+            if (efftab[f].olen != ST_BUFSIZ)
                 break;
         }
     }
@@ -849,7 +850,7 @@
          * run effect over entire buffer.
          */
         idone = efftab[e-1].olen - efftab[e-1].odone;
-        odone = BUFSIZ;
+        odone = ST_BUFSIZ;
         effstatus = (* efftab[e].h->flow)(&efftab[e],
                                           &efftab[e-1].obuf[efftab[e-1].odone],
                                           efftab[e].obuf, &idone, &odone);
@@ -863,7 +864,7 @@
          * on each of them.
          */
         idone = efftab[e-1].olen - efftab[e-1].odone;
-        odone = BUFSIZ;
+        odone = ST_BUFSIZ;
         ibuf = &efftab[e-1].obuf[efftab[e-1].odone];
         for(i = 0; i < idone; i += 2) {
             ibufl[i/2] = *ibuf++;
@@ -909,12 +910,12 @@
     st_sample_t *obuf;
 
     if (! efftabR[e].name) {
-        efftab[e].olen = BUFSIZ;
+        efftab[e].olen = ST_BUFSIZ;
         (* efftab[e].h->drain)(&efftab[e],efftab[e].obuf,
                                &efftab[e].olen);
     }
     else {
-        olen = BUFSIZ;
+        olen = ST_BUFSIZ;
 
         /* left */
         olenl = olen/2;
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -109,9 +109,6 @@
  */
 #define ST_MAXRATE      50L * 1024 /* maximum sample rate in library */
 
-#define RIGHT(datum, bits)      ((datum) >> bits)
-#define LEFT(datum, bits)       ((datum) << bits)
-
 #ifndef M_PI
 #define M_PI    3.14159265358979323846
 #endif
@@ -123,6 +120,12 @@
 #define ST_INT16_MAX (32676)
 #define ST_INT32_MAX (2147483647)
 #define ST_INT64_MAX (9223372036854775807)
+
+/* The following is used at times in libst when alloc()ing buffers
+ * to perform file I/O.  It can be useful to pass in similar sized
+ * data to get max performance.
+ */
+#define ST_BUFSIZ 8192
 
 /*=============================================================================
  * File Handlers
--- a/src/stat.c
+++ b/src/stat.c
@@ -217,7 +217,7 @@
                 /* work in scaled levels for both sample and delta */
                 lsamp = *ibuf++;
                 samp = (double)lsamp/stat->scale;
-                stat->bin[RIGHT(lsamp,30)+2]++;
+                stat->bin[(lsamp>>30)+2]++;
                 *obuf++ = lsamp;
 
 
--- a/src/trim.c
+++ b/src/trim.c
@@ -32,7 +32,6 @@
     /* internal stuff */
     st_size_t index;
     st_size_t trimmed;
-    int done;
 } * trim_t;
 
 /*
@@ -116,7 +115,6 @@
     /* Account for # of channels */
     trim->length *= effp->ininfo.channels;
 
-    trim->done = 0;
     trim->index = 0;
     trim->trimmed = 0;
 
@@ -132,9 +130,10 @@
 int st_trim_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
-    int done;
-    int offset;
+    int finished = 0;
     int start_trim = 0;
+    int offset = 0;
+    int done;
 
     trim_t trim = (trim_t) effp->priv;
 
@@ -141,51 +140,36 @@
     /* Compute the most samples we can process this time */
     done = ((*isamp < *osamp) ? *isamp : *osamp);
 
-    /* Always report that we've read everything for default case */
-    *isamp = done;
-
-    /* Don't bother doing work if we are done */
-    if (trim->done) {
-	*osamp = 0;
-	return (ST_EOF);
-    }
-
-    /* Default to assuming we will read all input data possible */
-    trim->index += done;
-    offset = 0;
-
     /* Quick check to see if we are trimming off the back side yet.
      * If so then we can skip trimming from the front side.
      */
-    if (! trim->trimmed) {
-	if (trim->start > trim->index) {
+    if (!trim->trimmed) {
+	if ((trim->index+done) <= trim->start) {
 	    /* If we haven't read more then "start" samples, return that
 	     * we've read all this buffer without outputing anything
 	     */
 	    *osamp = 0;
+	    *isamp = done;
+	    trim->index += done;
 	    return (ST_SUCCESS);
 	} else {
 	    start_trim = 1;
 	    /* We've read at least "start" samples.  Now find
-	     * out if we've read to much and if so compute a location
-	     * to start copying data from.  Also use this going forward
-	     * as the amount of data read during trimmed check.
+	     * out where our target data begins and subtract that
+	     * from the total to be copied this round.
 	     */
-	    offset = done - (trim->index - trim->start);
-	    done = trim->index - trim->start;
+	    offset = trim->start - trim->index;
+	    done -= offset;
 	}
     } /* !trimmed */
 
-    if (trim->trimmed || start_trim ) {
-
-	if (trim->length && ( (trim->trimmed+done) > trim->length)) {
-	    /* Compute the amount of unprocessed data left in this
-	     * buffer and remove from isamp count and amount done.
+    if (trim->trimmed || start_trim) {
+	if (trim->length && ((trim->trimmed+done) >= trim->length)) {
+	    /* Since we know the end is in this block, we set done
+	     * to the desired length less the amount already read.
 	     */
-	    *isamp -= ((trim->trimmed+done) - trim->length);
-	    done -= ((trim->trimmed+done) - trim->length);
-	    *osamp = done;
-	    trim->done = 1;
+	    done = trim->length - trim->trimmed;
+	    finished = 1;
 	}
 
 	trim->trimmed += done;
@@ -192,8 +176,15 @@
     }
 
     memcpy(obuf, ibuf+offset, done * sizeof(st_sample_t));
+
     *osamp = done;
-    return (ST_SUCCESS);
+    *isamp = offset + done;
+    trim->index += done;
+
+    if (finished)
+	return (ST_EOF);
+    else
+	return (ST_SUCCESS);
 }
 
 /*
--- a/src/voc.c
+++ b/src/voc.c
@@ -233,7 +233,7 @@
         vs_t v = (vs_t) ft->priv;
         int done = 0;
         int rc;
-        unsigned short us;
+        int16_t sw;
         unsigned char uc;
 
         if (v->rest == 0)
@@ -260,11 +260,10 @@
                                     v->rest = 0;
                                     return done;
                                 }
-                                uc ^= 0x80;     /* convert to signed */
-                                *buf++ = LEFT(uc, 24);
+                                *buf++ = ST_UNSIGNED_BYTE_TO_SAMPLE(uc);
                                 break;
                             case ST_SIZE_WORD:
-                                st_readw(ft, &us);
+                                st_readw(ft, &sw);
                                 if (feof(ft->fp))
                                 {
                                     st_warn("VOC input: short file");
@@ -271,7 +270,7 @@
                                     v->rest = 0;
                                     return done;
                                 }
-                                *buf++ = LEFT(us, 16);
+                                *buf++ = ST_SIGNED_WORD_TO_SAMPLE(sw);
                                 v->rest--; /* Processed 2 bytes so update */
                                 break;
                         }
@@ -336,7 +335,7 @@
 {
         vs_t v = (vs_t) ft->priv;
         unsigned char uc;
-        int sw;
+        int16_t sw;
         st_ssize_t done = 0;
 
         if (v->samples == 0) {
@@ -347,11 +346,10 @@
         v->samples += len;
         while(done < len) {
           if (ft->info.size == ST_SIZE_BYTE) {
-            uc = RIGHT(*buf++, 24);
-            uc ^= 0x80;
+            uc = ST_SAMPLE_TO_UNSIGNED_BYTE(*buf++);
             st_writeb(ft, uc);
           } else {
-                sw = (int) RIGHT(*buf++, 16);
+            sw = (int) ST_SAMPLE_TO_SIGNED_WORD(*buf++);
             st_writew(ft,sw);
           }
           done++;
--- a/src/vorbis.c
+++ b/src/vorbis.c
@@ -237,8 +237,8 @@
 			}
 		}
 
-		l = LEFT(vb->buf[vb->start+1],24) 
-			| (0xffffff &  LEFT(vb->buf[vb->start], 16));
+		l = (vb->buf[vb->start+1]<<24) 
+			| (0xffffff &  (vb->buf[vb->start]<<16));
 		*(buf + i) = l;
 		vb->start += 2;
 	}
--- a/src/wav.c
+++ b/src/wav.c
@@ -288,7 +288,7 @@
 
   /* copy out any samples left from the last call */
     while(wav->gsmindex && (wav->gsmindex<160*2) && (done < len))
-	buf[done++]=LEFT(wav->gsmsample[wav->gsmindex++],16);
+	buf[done++]=ST_SIGNED_WORD_TO_SAMPLE(wav->gsmsample[wav->gsmindex++]);
 
   /* read and decode loop, possibly leaving some samples in wav->gsmsample */
     while (done < len) {
@@ -314,7 +314,7 @@
 	}
 
 	while ((wav->gsmindex <160*2) && (done < len)){
-	    buf[done++]=LEFT(wav->gsmsample[(wav->gsmindex)++],16);
+	    buf[done++]=ST_SIGNED_WORD_TO_SAMPLE(wav->gsmsample[(wav->gsmindex)++]);
 	}
     }
 
@@ -365,7 +365,8 @@
 
     while (done < len) {
 	while ((wav->gsmindex < 160*2) && (done < len))
-	    wav->gsmsample[(wav->gsmindex)++] = RIGHT(buf[done++], 16);
+	    wav->gsmsample[(wav->gsmindex)++] = 
+		ST_SAMPLE_TO_SIGNED_WORD(buf[done++]);
 
 	if (wav->gsmindex < 160*2)
 	    break;
@@ -1014,7 +1015,7 @@
 		    top = p+ct;
 		    /* Output is already signed */
 		    while (p<top)
-			*buf++ = LEFT((*p++), 16);
+			*buf++ = ST_SIGNED_WORD_TO_SAMPLE((*p++));
 
 		    wav->samplePtr = p;
 		}