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