ref: 76caa137725af8725d869657b9c91f7a1523ea0e
parent: cd6f068af3d62ce561a146571439bfdd844ed922
author: cbagwell <cbagwell>
date: Tue Dec 7 11:57:37 EST 1999
Various updates.
--- a/libst.c
+++ b/libst.c
@@ -36,22 +36,22 @@
short sample;
{
static const unsigned char exp_lut[256] =
- {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
+ {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
int sign, exponent, mantissa;
unsigned char ulawbyte;
@@ -61,8 +61,8 @@
if ( sample > uCLIP ) sample = uCLIP; /* clip the magnitude */
/* Convert from 16 bit linear to ulaw. */
- sample = sample + uBIAS;
- exponent = exp_lut[( sample >> 7 ) & 0xFF];
+ sample += uBIAS;
+ exponent = exp_lut[sample >> 7]; /* no need to mask because uCLIP>=sample>=0 */
mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
#ifdef ZEROTRAP
@@ -92,7 +92,7 @@
st_ulaw_to_linear( ulawbyte )
unsigned char ulawbyte;
{
- static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
+ static const int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
int sign, exponent, mantissa, sample;
ulawbyte = ~ ulawbyte;
--- a/libst.h
+++ b/libst.h
@@ -22,10 +22,10 @@
extern int ulaw_exp_table[256];
extern const unsigned char ulaw_comp_table[16384];
#define st_ulaw_to_linear(ulawbyte) ulaw_exp_table[ulawbyte]
-#define st_linear_to_ulaw(linearword) ulaw_comp_table[((short)linearword / 4) & 0x3fff]
+#define st_linear_to_ulaw(linearword) ulaw_comp_table[(unsigned short)linearword >> 2]
#else
-unsigned char st_linear_to_ulaw(P1(short));
-int st_ulaw_to_linear(P1(unsigned char));
+unsigned char st_linear_to_ulaw(P1(short))REGPARM(1);
+int st_ulaw_to_linear(P1(unsigned char))REGPARM(1);
#endif
#ifdef FAST_ALAW_CONVERSION
@@ -32,9 +32,9 @@
extern const short Alaw_exp_table[256];
extern const unsigned char Alaw_comp_table[16384];
#define st_Alaw_to_linear(Alawbyte) Alaw_exp_table[Alawbyte]
-#define st_linear_to_Alaw(linearword) Alaw_comp_table[((short)linearword / 4) & 0x3fff]
+#define st_linear_to_Alaw(linearword) Alaw_comp_table[(unsigned short)linearword >> 2]
#else
-unsigned char st_linear_to_Alaw(P1(short));
-int st_Alaw_to_linear(P1(unsigned char));
+unsigned char st_linear_to_Alaw(P1(short))REGPARM(1);
+int st_Alaw_to_linear(P1(unsigned char))REGPARM(1);
#endif
--- a/src/flanger.c
+++ b/src/flanger.c
@@ -56,7 +56,6 @@
#include <math.h>
#include <string.h>
#include "st.h"
-#include "libst.h"
#define MOD_SINE 0
#define MOD_TRIANGLE 1
--- a/src/oss.c
+++ b/src/oss.c
@@ -18,11 +18,15 @@
* and on LINUX_PLAYER patches added by Greg Lee
* which was originally from Directo to Sound Blaster device driver (sbdsp.c).
* SBLAST patches by John T. Kohl.
+ *
+ * Changes:
+ *
+ * Nov. 26, 1999 Stan Brooks <stabro@megsinet.net>
+ * Moved initialization code common to startread and startwrite
+ * into a single function ossdspinit().
+ *
*/
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
@@ -36,99 +40,11 @@
#include <sys/ioctl.h>
#include "st.h"
-/*
- * Do anything required before you start reading samples.
- * Read file header.
- * Find out sampling rate,
- * size and style of samples,
- * mono/stereo/quad.
- */
-void ossdspstartread(ft)
+/* common r/w initialization code */
+static void ossdspinit(ft)
ft_t ft;
{
- int tmp;
int samplesize = 8, dsp_stereo;
-
- if (ft->info.rate == 0.0) ft->info.rate = 8000;
- if (ft->info.size == -1) ft->info.size = BYTE;
- if (ft->info.size == BYTE) {
- samplesize = 8;
- if (ft->info.style == -1)
- ft->info.style = UNSIGNED;
- if (ft->info.style != UNSIGNED) {
- fail("OSS driver only supports unsigned with bytes");
- }
- }
- else if (ft->info.size == WORD) {
- samplesize = 16;
- if (ft->info.style == -1)
- ft->info.style = SIGN2;
- if (ft->info.style != SIGN2) {
- fail("OSS driver only supports signed with words");
- }
- }
- else {
- fail("OSS driver only supports bytes and words");
- }
-
- if (ft->info.channels == -1) ft->info.channels = 1;
- else if (ft->info.channels > 2) ft->info.channels = 2;
-
- ioctl(fileno(ft->fp), SNDCTL_DSP_RESET, 0);
- ioctl (fileno(ft->fp), SNDCTL_DSP_GETBLKSIZE, &ft->file.size);
- if (ft->file.size < 4 || ft->file.size > 65536) {
- fail("Invalid audio buffer size %d", ft->file.size);
- }
- ft->file.count = 0;
- ft->file.pos = 0;
- ft->file.eof = 0;
-
- if ((ft->file.buf = malloc (ft->file.size)) == NULL) {
- fail("Unable to allocate input/output buffer of size %d", ft->file.size);
- }
-
- if (ioctl(fileno(ft->fp), SNDCTL_DSP_SYNC, NULL) < 0) {
- fail("Unable to sync dsp");
- }
-
- tmp = samplesize;
- ioctl(fileno(ft->fp), SNDCTL_DSP_SAMPLESIZE, &tmp);
- if (tmp != samplesize) {
- fail("Unable to set the sample size to %d", samplesize);
- }
-
- if (ft->info.channels == 2) dsp_stereo = 1;
- else dsp_stereo = 0;
-
- tmp = dsp_stereo;
- ioctl(fileno(ft->fp), SNDCTL_DSP_STEREO, &tmp);
- if (tmp != dsp_stereo) {
- ft->info.channels = 1;
- warn("Couldn't set to %s", dsp_stereo? "stereo":"mono");
- dsp_stereo = 0;
- }
-
- tmp = ft->info.rate;
- ioctl (fileno(ft->fp), SNDCTL_DSP_SPEED, &tmp);
- if (ft->info.rate != tmp) {
- if (ft->info.rate - tmp > tmp/10 || tmp - ft->info.rate > tmp/10)
- {
- warn("Unable to set audio speed to %d (set to %d)",
- ft->info.rate, tmp);
- ft->info.rate = tmp;
- }
- }
-
- /* Change to unbuffered mode*/
- setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * ft->file.size);
-
- sigintreg(ft); /* Prepare to catch SIGINT */
-}
-
-void ossdspstartwrite(ft)
-ft_t ft;
-{
- int samplesize = 8, dsp_stereo;
int tmp;
if (ft->info.rate == 0.0) ft->info.rate = 8000;
@@ -200,8 +116,16 @@
tmp = ft->info.rate;
ioctl (fileno(ft->fp), SNDCTL_DSP_SPEED, &tmp);
if (ft->info.rate != tmp) {
- if (ft->info.rate - tmp > tmp/10 || tmp - ft->info.rate > tmp/10)
- {
+ /* If the rate the sound card is using is not within 2% of what
+ * the user specified then override the user setting.
+ * The only reason not to always override this is because of
+ * clock-rounding problems. Sound cards will sometimes use
+ * things like 44101 when you ask for 44100. No need overriding
+ * this and having strange output file rates for something that
+ * we can't hear anyways.
+ */
+ if (ft->info.rate - tmp > (tmp * .02) ||
+ tmp - ft->info.rate > (tmp * .02)) {
warn("Unable to set audio speed to %d (set to %d)",
ft->info.rate, tmp);
ft->info.rate = tmp;
@@ -211,5 +135,23 @@
/* Change to non-buffered I/O */
setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * ft->file.size);
}
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and style of samples,
+ * mono/stereo/quad.
+ */
+void ossdspstartread(ft)
+ft_t ft;
+{
+ ossdspinit(ft);
+ sigintreg(ft); /* Prepare to catch SIGINT */
+}
+void ossdspstartwrite(ft)
+ft_t ft;
+{
+ ossdspinit(ft);
+}
#endif
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -59,7 +59,6 @@
#include <math.h>
#include <string.h>
#include "st.h"
-#include "libst.h"
#define MOD_SINE 0
#define MOD_TRIANGLE 1
--- a/src/raw.c
+++ b/src/raw.c
@@ -149,7 +149,6 @@
ft_t ft;
LONG *buf, nsamp;
{
- register LONG datum;
int done = 0;
switch(ft->info.size) {
@@ -158,6 +157,7 @@
{
case SIGN2:
while(done < nsamp) {
+ LONG datum;
datum = blockgetc(ft);
if (ft->file.eof)
return done;
@@ -168,6 +168,7 @@
return done;
case UNSIGNED:
while(done < nsamp) {
+ LONG datum;
datum = blockgetc(ft);
if (ft->file.eof)
return done;
@@ -180,6 +181,7 @@
return done;
case ULAW:
while(done < nsamp) {
+ LONG datum;
datum = blockgetc(ft);
if (ft->file.eof)
return done;
@@ -191,15 +193,15 @@
return done;
case ALAW:
while(done < nsamp) {
- datum = blockgetc(ft);
- if (ft->file.eof)
- return done;
- datum = st_Alaw_to_linear(datum);
- /* scale signed up to long's range */
- *buf++ = LEFT(datum, 16);
- done++;
+ LONG datum;
+ datum = blockgetc(ft);
+ if (ft->file.eof)
+ return done;
+ datum = st_Alaw_to_linear(datum);
+ /* scale signed up to long's range */
+ *buf++ = LEFT(datum, 16);
+ done++;
}
-
return done;
}
break;
@@ -363,7 +365,6 @@
ft_t ft;
LONG *buf, nsamp;
{
- register int datum;
int done = 0;
switch(ft->info.size) {
@@ -372,6 +373,7 @@
{
case SIGN2:
while(done < nsamp) {
+ int datum;
/* scale signed up to long's range */
datum = (int) RIGHT(*buf++, 24);
blockputc(ft, datum);
@@ -380,6 +382,7 @@
return;
case UNSIGNED:
while(done < nsamp) {
+ int datum;
/* scale signed up to long's range */
datum = (int) RIGHT(*buf++, 24);
/* Convert to unsigned */
@@ -390,6 +393,7 @@
return;
case ULAW:
while(done < nsamp) {
+ int datum;
/* scale signed up to long's range */
datum = (int) RIGHT(*buf++, 16);
/* round up to 12 bits of data */
@@ -401,6 +405,7 @@
return;
case ALAW:
while(done < nsamp) {
+ int datum;
/* scale signed up to long's range */
datum = (int) RIGHT(*buf++, 16);
/* round up to 12 bits of data */
@@ -420,6 +425,7 @@
return;
case UNSIGNED:
while(done < nsamp) {
+ int datum;
unsigned short s;
/* scale signed up to long's range */
datum = *buf++ + 0x8000; /* round for 16 bit */
--- a/src/sox.c
+++ b/src/sox.c
@@ -348,6 +348,19 @@
break;
}
}
+
+ /* SJB: fix the -X extract interval for # channels...
+ * this is not perfect re cases where channels=-1,
+ * and also indicates that info.x0, info.x1, info.x
+ * SHOULD be (long long) instead of (ULONG), for large files
+ */
+ if (ft->info.channels > 1) {
+ if (ft->info.x0 != 0)
+ ft->info.x0 *= ft->info.channels;
+ if (ft->info.x1 != MAXULONG && ft->info.x1 < MAXULONG/ft->info.channels)
+ ft->info.x1 *= ft->info.channels;
+ }
+
}
static void init(P0) {
--- a/src/st.h
+++ b/src/st.h
@@ -36,17 +36,21 @@
#endif
#define MAXLONG 0x7fffffffL
-#define MAXULONG 0xffffffff
+#define MAXULONG 0xffffffffL
/* various gcc optimizations */
#ifdef __GNUC__
#define NORET __attribute__((noreturn))
-#define REGPARM(n) __attribute__((regparm(n)))
#define INLINE inline
#else
#define NORET
-#define REGPARM(n)
#define INLINE
+#endif
+
+#ifdef USE_REGPARM
+#define REGPARM(n) __attribute__((regparm(n)))
+#else
+#define REGPARM(n)
#endif
/*
--- a/src/vibro.c
+++ b/src/vibro.c
@@ -58,7 +58,7 @@
}
/* This was very painful. We need a sine library. */
-
+/* SJB: this is somewhat different than st_sine() */
static void sine(buf, len, depth)
short *buf;
int len;
--- a/test/Makefile
+++ b/test/Makefile
@@ -10,7 +10,7 @@
all: ding model lding lmodel corr
corr: corr.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $2 $<
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
ding: ding.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
--- a/test/README
+++ b/test/README
@@ -28,16 +28,17 @@
./ltest -l resample -qs 0.80 0 >B
gnuplot plotAB
-The script gtest.pl is for testing sox's adpcm and gsm wav support.
+The script wtest.pl is for testing sox's adpcm and gsm wav support.
It accepts one of these options:
-t Use 'toast' gsm for compress/decompress
- -a Use sox (MS) ADPCM
- -i Use sox IMA ADPCM
- -g Use sox wav-gsm6.10
+ -a Use sox (MS) ADPCM
+ -i Use sox IMA ADPCM
+ -g Use sox wav-gsm6.10
If using sox, you may also append an optional effect, eg:
./wtest -g filter 0-3500 >A
will apply a lowpass filter with 6dB corner at 3500 Hz before the compression phase.
+
Then, as above, 'gnuplot plotA' will graph dB gain and dB error-level
vs. freq for you.
@@ -58,10 +59,10 @@
frequencies 0.00 0.01 ... 0.99 of the Nyquist frequency. This input
has:
400 samples samples of silence,
- 4000 samples with smooth envelope rising to volume -v0.5
- 16000 samples at -v0.5
- 4000 samples with smooth envelope falling to 0,
- 400 sample more of silence.
+ 4000 samples with smooth envelope rising to volume -v0.5
+ 16000 samples at -v0.5
+ 4000 samples with smooth envelope falling to 0,
+ 400 sample more of silence.
The rising/falling envelopes are shaped like rising, falling portions
of the (1-cos(x)) function.
@@ -76,18 +77,18 @@
step 1: the entire sample file is read in, and the center-of-gravity of
the squared samples is found. This is the time offset which should
- correspond to the center of the filtered/resampled tone-pulse.
+ correspond to the center of the filtered/resampled tone-pulse.
step 2: let N = 16000*(rate1/rate0) be the number of samples at output rate
- which would correspond to the 16000 sample duration at max volume.
- We focus on the samples between
- (center - 0.3*N) and (center + 0.9*N)
- where the transient effects of attack/release envelope should be
- small.
- We do a least-squares fit of a sinusoid at the adjusted frequency
- to this segment of 0.6*N samples, and print out the component
- s2max which can be explained, and also the rms level of the 'error'
- or unexplained part.
+ which would correspond to the 16000 sample duration at max volume.
+ We focus on the samples between
+ (center - 0.3*N) and (center + 0.9*N)
+ where the transient effects of attack/release envelope should be
+ small.
+ We do a least-squares fit of a sinusoid at the adjusted frequency
+ to this segment of 0.6*N samples, and print out the component
+ s2max which can be explained, and also the rms level of the 'error'
+ or unexplained part.
That's pretty much it... the ltest perl-script glues it together and outputs
adjusted data which the gnuplot will like.
--- a/test/wtest.pl
+++ b/test/wtest.pl
@@ -28,7 +28,7 @@
my $rate=8000; # sample rates
my $p=200; # silence before/after tonepulse
-my $env="-e400:800:400"; # attack, duration, drop
+my $env="400:800:400"; # attack, duration, drop
my ($ding,$model,$t,$rms,$lim)=("./ding","./model","sw",11585.2, 0.5);
@@ -55,7 +55,7 @@
print("by $sox -r$rate in.sw $fmt out.wav $effect\n");
}
print("# with tone pulses from 0.00 to 0.99 percent of Nyquist\n");
-print("# produced by $ding -f0.xx -v0.5 -o$p $env -p$p d/i0.xx.$t\n");
+print("# produced by $ding -f0.xx -v0.5 -e$p:$env:$p d/i0.xx.$t\n");
print("# col 1 is frequency/Nyquist\n");
print("# col 2 is (power) dB gain\n");
print("# col 3 is (power) dB level of error signal\n");
@@ -71,8 +71,8 @@
#if ($f>0.995) { $f=0.999; }
my $s=sprintf("%4.2f",$f);
- #print "$ding -v0.5 -o$p $env -p$p -f$s -d1.0 d/i$s.$t\n";
- qx{$ding -v0.5 -o$p $env -p$p -f$s -d1.0 d/i$s.$t &>/dev/null};
+ #print "$ding -f$s -v0.5 -e$p:$env:$p -d1.0 d/i$s.$t\n";
+ qx{$ding -f$s -v0.5 -e$p:$env:$p -d1.0 d/i$s.$t &>/dev/null};
if ($fmt eq '-t') {
qx{$toast -l d/i$s.$t};
@@ -86,7 +86,7 @@
unlink "d/g$s.wav";
}
- @mod = grep {/v2max/} qx{$model -f$s $env $rate d/i$s.$t 2>&1};
+ @mod = grep {/v2max/} qx{$model -f$s -e$env $rate d/i$s.$t 2>&1};
print STDERR "$s: ",@mod;
$_=shift(@mod);
if (m{s2max *([0-9.]+), *v2max *([0-9.]+), *rmserr *(-?[0-9.]+)}) {