ref: 1f70a30a0d51cfd6499c4d76be8a593a91fd5a3d
parent: bd403cd4de5fd397e4d103f0e1b42d54c408bcb8
author: robs <robs>
date: Wed Jan 21 17:11:51 EST 2009
--guard, & associated changes
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,7 @@
Deprec- Feature [O(ption)] Removal
ated in [F(ormat)] [E(ffect)] Replacement due after
------- ---------------------- ---------------------- -------
+ 14.3.0 E norm -b, norm -i gain -B, gain -en 14.3.0 + 1 year
14.3.0 F flac: libFLAC 1.1.2,3 libFLAC > 1.1.3 14.3.0 + 6 months
Previously deprecated features (to be removed in future):
@@ -59,11 +60,18 @@
o Fix [2404566] segfault when converting from MS ADPCM wav file. (robs)
o Fix slight FLAC seek inaccuracy e.g. when using `trim' effect. (robs)
+Audio device drivers:
+
+ o New native OpenBSD audio handler for play/recording. (Alexandre Ratchov)
+ o 24-bit support for ALSA handler. (robs)
+ o Warn if ALSA under/overrun. (robs)
+
Effects:
o New `overdrive' effect. (robs)
o New `pluck' and `tpdf' types for `synth'. (robs)
o Can now set common parameters for multiple `synth' channels. (robs)
+ o Richer gain/normalise options. (robs)
o Fix [2487589] `dither' clipping detection & handling. (robs)
o Fix `repeat' sometimes stopping repeating too soon. (robs)
o Fix `repeat' sometimes repeating wrong audio segments. (robs)
@@ -75,14 +83,13 @@
Other new features:
- o New native OpenBSD audio handler for play/recording. (Alexandre Ratchov)
- o 24-bit support for ALSA handler. (robs)
- o Warn if ALSA under/overrun. (robs)
+ o Added ability to create shared DLL's on cygwin (cbagwell)
+ o New `--guard' & `--norm' options; use temporary files to guard against
+ clipping for many, but not currently all, effects. (robs)
o New `--ignore-length' option to ignore length in input file
header (for simple encodings); instead, read to end of file. (robs)
- o Added ability to create shared DLL's on cygwin (cbagwell)
- o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs)
o New `--temp DIRECTORY' option. (robs)
+ o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs)
o New bitrate, time in seconds, & total options for soxi. (robs)
Other bug fixes:
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -1,5 +1,4 @@
Makefile Makefile.in
-sox_sample_test
example0 example1 example2
soxconfig.h.in soxconfig.h soxstdint.h
.deps
--- a/src/8svx.c
+++ b/src/8svx.c
@@ -254,7 +254,6 @@
static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t len)
{
priv_t * p = (priv_t * ) ft->priv;
- SOX_SAMPLE_LOCALS;
unsigned char datum;
size_t done = 0, i;
@@ -263,7 +262,7 @@
while(done < len) {
for (i = 0; i < ft->signal.channels; i++) {
- datum = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++, ft->clips);
+ datum = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++);
/* FIXME: Needs to pass ft struct and not FILE */
putc(datum, p->ch[i]);
}
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,16 +28,16 @@
# Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'
set(effects_srcs
- bend dither lowfir phaser stat
- biquad earwax mcompand rate stretch
- biquads echo mixer remix swap
- chorus echos noiseprof repeat synth
- compand fade noisered reverb tempo
- compandt fft4g normalise reverse tremolo
+ bend dither loudness phaser stat
+ biquad earwax lowfir rate stretch
+ biquads echo mcompand remix swap
+ chorus echos mixer repeat synth
+ compand fade noiseprof reverb tempo
+ compandt fft4g noisered reverse tremolo
contrast filter output silence trim
dcshift flanger overdrive skeleff vol
- delay input pad speed
- dft_filter loudness pan splice
+ delay gain pad speed
+ dft_filter input pan splice
)
set(formats_srcs
8svx dat ima-fmt s3-fmt u3-fmt
@@ -62,7 +62,6 @@
)
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.c)
target_link_libraries(${PROJECT_NAME} lib${PROJECT_NAME} lpc10 ${optional_libs})
-add_executable(sox_sample_test sox_sample_test.c)
add_executable(example0 example0.c)
target_link_libraries(example0 lib${PROJECT_NAME} lpc10 ${optional_libs})
add_executable(example1 example1.c)
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,7 +28,7 @@
#########################
bin_PROGRAMS = sox
-EXTRA_PROGRAMS = example0 example1 example2 sox_sample_test
+EXTRA_PROGRAMS = example0 example1 example2
lib_LTLIBRARIES = libsox.la
include_HEADERS = sox.h
nodist_include_HEADERS = soxstdint.h
@@ -37,7 +37,6 @@
example0_SOURCES = example0.c
example1_SOURCES = example1.c
example2_SOURCES = example2.c
-sox_sample_test_SOURCES = sox_sample_test.c sox_sample_test.h
###############################################
# libsox - Dynamic Libraries for File Formats #
@@ -274,7 +273,7 @@
dither_fir.h dither_iir.h earwax.c echo.c echos.c effects.c effects.h \
effects_i.c fade.c fft4g.c fft4g.h fifo.h filter.c flanger.c input.c \
ladspa.c loudness.c mcompand.c mcompand_xover.h mixer.c noiseprof.c \
- noisered.c noisered.h normalise.c output.c pad.c pan.c phaser.c \
+ noisered.c noisered.h gain.c output.c pad.c pan.c phaser.c \
rate.c rate_filters.h rate_half_fir.h \
rate_poly_fir0.h rate_poly_fir.h remix.c repeat.c reverb.c \
reverse.c silence.c skeleff.c speed.c splice.c stat.c swap.c stretch.c \
@@ -400,7 +399,7 @@
CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake \
tests.sh testall.sh tests.bat testall.bat test-comments
-all: sox$(EXEEXT) play rec soxi sox_sample_test$(EXEEXT) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT)
+all: sox$(EXEEXT) play rec soxi example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT)
play rec: sox$(EXEEXT)
if test "$(PLAYRECLINKS)" = "yes"; then \
@@ -430,7 +429,6 @@
clean-local:
$(RM) play rec soxi
- $(RM) sox_sample_test$(EXEEXT)
$(RM) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT)
distclean-local:
--- a/src/adpcms.c
+++ b/src/adpcms.c
@@ -251,8 +251,7 @@
short word;
while (count < length) {
- SOX_SAMPLE_LOCALS;
- word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++, ft->clips);
+ word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++);
byte <<= 4;
byte |= lsx_adpcm_encode(word, &state->encoder) & 0x0F;
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -187,7 +187,6 @@
priv_t * p = (priv_t *)ft->priv;
size_t done, i, n;
snd_pcm_sframes_t actual;
- SOX_SAMPLE_LOCALS;
for (done = 0; done < len; done += n) {
i = n = min(len - done, p->buf_len);
@@ -194,38 +193,38 @@
switch (p->format) {
case SND_PCM_FORMAT_S8: {
int8_t * buf1 = (int8_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++, ft->clips);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++);
break;
}
case SND_PCM_FORMAT_U8: {
uint8_t * buf1 = (uint8_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++);
break;
}
case SND_PCM_FORMAT_S16: {
int16_t * buf1 = (int16_t *)p->buf;
if (ft->encoding.reverse_bytes) while (i--)
- *buf1++ = lsx_swapw(SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips));
+ *buf1++ = lsx_swapw(SOX_SAMPLE_TO_SIGNED_16BIT(*buf++));
else
- while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
break;
}
case SND_PCM_FORMAT_U16: {
uint16_t * buf1 = (uint16_t *)p->buf;
if (ft->encoding.reverse_bytes) while (i--)
- *buf1++ = lsx_swapw(SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips));
+ *buf1++ = lsx_swapw(SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++));
else
- while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++);
break;
}
case SND_PCM_FORMAT_S24: {
int24_t * buf1 = (int24_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_24BIT(*buf++, ft->clips);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_24BIT(*buf++);
break;
}
case SND_PCM_FORMAT_U24: {
uint24_t * buf1 = (uint24_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_24BIT(*buf++, ft->clips);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_24BIT(*buf++);
break;
}
}
--- a/src/amr.h
+++ b/src/amr.h
@@ -117,8 +117,7 @@
size_t done;
for (done = 0; done < len; ++done) {
- SOX_SAMPLE_LOCALS;
- p->pcm[p->pcm_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
+ p->pcm[p->pcm_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
if (p->pcm_index == AMR_FRAME) {
p->pcm_index = 0;
if (!encode_1_frame(ft))
--- a/src/ao.c
+++ b/src/ao.c
@@ -74,12 +74,11 @@
return SOX_SUCCESS;
}
-static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, size_t len, sox_bool swap, size_t * clips)
+static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, size_t len, sox_bool swap)
{
while (len--)
{
- SOX_SAMPLE_LOCALS;
- uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++, *clips);
+ uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++);
if (swap)
datum = lsx_swapw(datum);
*(uint16_t *)buf1 = datum;
@@ -97,8 +96,7 @@
aobuf_size = (ft->encoding.bits_per_sample >> 3) * len;
- sox_sw_write_buf(ao->buf, buf, len, ft->encoding.reverse_bytes,
- &(ft->clips));
+ sox_sw_write_buf(ao->buf, buf, len, ft->encoding.reverse_bytes);
if (ao_play(ao->device, (void *)ao->buf, aobuf_size) == 0)
return 0;
--- a/src/band.h
+++ b/src/band.h
@@ -40,7 +40,8 @@
p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate);
- if (p->filter_type == filter_BPF_SPK_N)
- p->b0 = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2));
- else
- p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2);
+ p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2);
+ if (p->filter_type == filter_BPF_SPK_N) {
+ mult = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)) / p->b0;
+ p->b0 *= mult;
+ }
--- a/src/bend.c
+++ b/src/bend.c
@@ -154,7 +154,7 @@
++p->in_pos;
/* As long as we have not yet collected enough data just read in */
- p->gInFIFO[p->gRover] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
+ p->gInFIFO[p->gRover] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i]);
obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(
p->gOutFIFO[p->gRover - inFifoLatency], effp->clips);
p->gRover++;
--- a/src/biquad.h
+++ b/src/biquad.h
@@ -18,6 +18,7 @@
#ifndef biquad_included
#define biquad_included
+#define LSX_EFF_ALIAS
#include "sox_i.h"
typedef enum {
@@ -73,8 +74,5 @@
int lsx_biquad_start(sox_effect_t * effp);
int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
size_t *isamp, size_t *osamp);
-
-#undef lsx_fail
-#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail
#endif
--- a/src/biquads.c
+++ b/src/biquads.c
@@ -164,7 +164,7 @@
priv_t * p = (priv_t *)effp->priv;
double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
double A = exp(p->gain / 40 * log(10.));
- double alpha = 0;
+ double alpha = 0, mult = dB_to_linear(max(p->gain, 0));
if (w0 > M_PI) {
lsx_fail("frequency must be less than half the sample-rate (Nyquist rate)");
@@ -362,8 +362,11 @@
{double g = dB_to_linear(19.9 - linear_to_dB(
(p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2)));
p->b0 *= g; p->b1 *= g; p->b2 *= g;}
+ mult = dB_to_linear(19.9);
break;
}
+ if (effp->in_signal.mult)
+ *effp->in_signal.mult /= mult;
return lsx_biquad_start(effp);
}
--- a/src/chorus.c
+++ b/src/chorus.c
@@ -333,7 +333,7 @@
static sox_effect_handler_t sox_chorus_effect = {
"chorus",
"gain-in gain-out delay decay speed depth [ -s | -t ]",
- SOX_EFF_LENGTH,
+ SOX_EFF_LENGTH | SOX_EFF_GAIN,
sox_chorus_getopts,
sox_chorus_start,
sox_chorus_flow,
--- a/src/compand.c
+++ b/src/compand.c
@@ -275,7 +275,7 @@
sox_effect_handler_t const * sox_compand_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "compand", compand_usage, SOX_EFF_MCHAN,
+ "compand", compand_usage, SOX_EFF_MCHAN | SOX_EFF_GAIN,
getopts, start, flow, drain, stop, kill, sizeof(priv_t)
};
return &handler;
--- a/src/coreaudio.c
+++ b/src/coreaudio.c
@@ -285,7 +285,7 @@
p = &ac->buffer[ac->buf_offset];
while (samp_left--)
- *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++, ft->clips);
+ *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++);
ac->buf_offset += len;
--- a/src/dat.c
+++ b/src/dat.c
@@ -104,6 +104,7 @@
/* Read a complete set of channels */
sscanf(inpstr," %*s%n", &inpPtr);
for (i=0; i<ft->signal.channels; i++) {
+ SOX_SAMPLE_LOCALS;
retc = sscanf(&inpstr[inpPtr]," %lg%n", &sampval, &inpPtrInc);
inpPtr += inpPtrInc;
if (retc != 1) {
@@ -110,8 +111,7 @@
lsx_fail_errno(ft,SOX_EOF,"Unable to read sample.");
return 0;
}
- sampval *= SOX_SAMPLE_MAX;
- *buf++ = SOX_ROUND_CLIP_COUNT(sampval, ft->clips);
+ *buf++ = SOX_FLOAT_64BIT_TO_SAMPLE(sampval, ft->clips);
done++;
}
}
@@ -135,8 +135,7 @@
sprintf(s," %15.8g ",dat->timevalue);
lsx_writes(ft, s);
for (i=0; i<ft->signal.channels; i++) {
- SOX_SAMPLE_LOCALS;
- sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++, ft->clips);
+ sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++);
sprintf(s," %15.8g", sampval);
lsx_writes(ft, s);
done++;
--- a/src/dcshift.c
+++ b/src/dcshift.c
@@ -173,7 +173,7 @@
"shift [ limitergain ]\n"
" The peak limiter has a gain much less than 1.0 (ie 0.05 or 0.02) which is only\n"
" used on peaks to prevent clipping. (default is no limiter)",
- SOX_EFF_MCHAN,
+ SOX_EFF_MCHAN | SOX_EFF_GAIN,
sox_dcshift_getopts,
sox_dcshift_start,
sox_dcshift_flow,
--- a/src/dft_filter.c
+++ b/src/dft_filter.c
@@ -79,7 +79,7 @@
p->samples_in += (int)*isamp;
for (i = *isamp; i; --i)
- *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
+ *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++);
filter(p);
}
else *isamp = 0;
@@ -122,7 +122,7 @@
sox_effect_handler_t const * sox_dft_filter_effect_fn(void)
{
static sox_effect_handler_t handler = {
- NULL, NULL, 0, NULL, start, flow, drain, stop, NULL, 0
+ NULL, NULL, SOX_EFF_GAIN, NULL, start, flow, drain, stop, NULL, 0
};
return &handler;
}
--- a/src/dither.c
+++ b/src/dither.c
@@ -24,10 +24,6 @@
#include <assert.h>
#define PREC effp->out_signal.precision
-#define SOX_ROUND_PREC_CLIP_COUNT(d, clips) \
- ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \
- : (d) >= SOX_SAMPLE_MAX - (1 << (31-PREC)) + 0.5? \
- ++(clips), SOX_SAMPLE_MAX - (1 << (31-PREC)): (d) + 0.5)
typedef enum {Pdf_rectangular, Pdf_triangular, Pdf_gaussian} pdf_type_t;
static lsx_enum_item const pdf_types[] = {
@@ -134,12 +130,12 @@
{48000, iir, 4, 21.0, ges48, Shape_gesemann},
{44100, iir, 4, 21.2, ges44, Shape_gesemann},
{48000, fir, 16, 28.8, shi48, Shape_shibata},
- {44100, fir, 20, 32.5, shi44, Shape_shibata},
+ {44100, fir, 20, 32.6, shi44, Shape_shibata},
{37800, fir, 16, 22.7, shi38, Shape_shibata},
{32000, fir, 16, 15.7, shi32, Shape_shibata},
{22050, fir, 15, 9.0, shi22, Shape_shibata},
{48000, fir, 16, 23.5, shl48, Shape_low_shibata},
- {44100, fir, 15, 23.0, shl44, Shape_low_shibata},
+ {44100, fir, 15, 23.1, shl44, Shape_low_shibata},
{44100, fir, 20, 37.5, shh44, Shape_high_shibata},
{ 0, fir, 0, 0.0, NULL, Shape_none},
};
@@ -154,6 +150,7 @@
double previous_outputs[MAX_N * 2];
size_t pos;
double const * coefs;
+ sox_sample_t offset;
int (*flow)(sox_effect_t *, const sox_sample_t *, sox_sample_t *, size_t *, size_t *);
} priv_t;
@@ -189,7 +186,7 @@
size_t len = *isamp = *osamp = min(*isamp, *osamp);
while (len--) {
- double d = *ibuf++ + floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1);
+ double d = *ibuf++ + p->offset + floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1);
SOX_SAMPLE_CLIP_COUNT(d, effp->clips);
*obuf++ = d;
}
@@ -227,36 +224,39 @@
if (PREC > 24)
return SOX_EFF_NULL; /* Dithering not needed at this resolution */
- if (!p->filter_name)
- p->flow = flow_no_shape;
- else {
+ p->flow = flow_no_shape;
+ if (p->filter_name) {
filter_t const * f;
for (f = filters; f->len && (f->name != p->filter_name || fabs(effp->in_signal.rate - f->rate) / f->rate > .05); ++f);
if (!f->len) {
- lsx_fail("no `%s' filter is available for rate %g", lsx_find_enum_value(p->filter_name, filter_names)->text, effp->in_signal.rate);
- return SOX_EOF;
+ lsx_warn("no `%s' filter is available for rate %g", lsx_find_enum_value(p->filter_name, filter_names)->text, effp->in_signal.rate);
}
- assert(f->len <= MAX_N);
- if (f->type == fir) switch(f->len) {
- case 5: p->flow = flow_fir_5 ; break;
- case 9: p->flow = flow_fir_9 ; break;
- case 15: p->flow = flow_fir_15; break;
- case 16: p->flow = flow_fir_16; break;
- case 20: p->flow = flow_fir_20; break;
- default: assert(sox_false);
- } else switch(f->len) {
- case 4: p->flow = flow_iir_4 ; break;
- default: assert(sox_false);
+ else {
+ assert(f->len <= MAX_N);
+ if (f->type == fir) switch(f->len) {
+ case 5: p->flow = flow_fir_5 ; break;
+ case 9: p->flow = flow_fir_9 ; break;
+ case 15: p->flow = flow_fir_15; break;
+ case 16: p->flow = flow_fir_16; break;
+ case 20: p->flow = flow_fir_20; break;
+ default: assert(sox_false);
+ } else switch(f->len) {
+ case 4: p->flow = flow_iir_4 ; break;
+ default: assert(sox_false);
+ }
+ p->coefs = f->coefs;
+ mult = dB_to_linear(f->gain);
}
- p->coefs = f->coefs;
- mult = dB_to_linear(f->gain);
}
p->am1 = p->depth / (1 << PREC);
p->am0 = (p->pdf == Pdf_triangular) * p->am1;
+ if (effp->out_encoding->half_bit && PREC < 32)
+ p->offset = 1 << (31 - PREC);
if (effp->flow == 0 && effp->in_signal.mult)
- *effp->in_signal.mult *= 1 - (p->am0 + p->am1) * mult;
+ *effp->in_signal.mult *=
+ 1 - (p->offset * (1./SOX_SAMPLE_MAX) + p->am0 + p->am1) * mult;
lsx_debug("pdf=%s filter=%s depth=%g", lsx_find_enum_value(p->pdf, pdf_types)->text, lsx_find_enum_value(p->filter_name, filter_names)->text, p->depth);
return SOX_SUCCESS;
--- a/src/dither_fir.h
+++ b/src/dither_fir.h
@@ -7,12 +7,12 @@
while (len--) {
double r = floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1);
- double error, d = *ibuf++;
+ double error, d = *ibuf++ + p->offset;
int j = 0;
CONVOLVE
assert(j == N);
- *obuf = SOX_ROUND_PREC_CLIP_COUNT(d + r, effp->clips);
- error = ((*obuf++ + (1 << (31-PREC))) & (-1 << (32-PREC))) - d;
+ *obuf = SOX_ROUND_CLIP_COUNT(d + r, effp->clips);
+ error = (*obuf++ & (-1 << (32-PREC))) + (1 << (31-PREC)) - d;
p->pos = p->pos? p->pos - 1 : p->pos - 1 + N;
p->previous_errors[p->pos + N] = p->previous_errors[p->pos] = error;
}
--- a/src/dither_iir.h
+++ b/src/dither_iir.h
@@ -12,9 +12,9 @@
int j = 0;
CONVOLVE
assert(j == N);
- d = *ibuf++ - output;
- *obuf = SOX_ROUND_PREC_CLIP_COUNT(d + r, effp->clips);
- error = ((*obuf++ + (1 << (31-PREC))) & (-1 << (32-PREC))) - d;
+ d = *ibuf++ + p->offset - output;
+ *obuf = SOX_ROUND_CLIP_COUNT(d + r, effp->clips);
+ error = (*obuf++ & (-1 << (32-PREC))) + (1 << (31-PREC)) - d;
p->pos = p->pos? p->pos - 1 : p->pos - 1 + N;
p->previous_errors[p->pos + N] = p->previous_errors[p->pos] = error;
p->previous_outputs[p->pos + N] = p->previous_outputs[p->pos] = output;
--- a/src/earwax.c
+++ b/src/earwax.c
@@ -62,6 +62,8 @@
return SOX_EOF;
}
memset(p->tap, 0, NUMTAPS * sizeof(*p->tap)); /* zero tap memory */
+ if (effp->in_signal.mult)
+ *effp->in_signal.mult *= dB_to_linear(-4.4);
return SOX_SUCCESS;
}
--- a/src/echo.c
+++ b/src/echo.c
@@ -248,7 +248,7 @@
static sox_effect_handler_t sox_echo_effect = {
"echo",
"gain-in gain-out delay decay [ delay decay ... ]",
- SOX_EFF_LENGTH,
+ SOX_EFF_LENGTH | SOX_EFF_GAIN,
sox_echo_getopts,
sox_echo_start,
sox_echo_flow,
--- a/src/echos.c
+++ b/src/echos.c
@@ -260,7 +260,7 @@
static sox_effect_handler_t sox_echos_effect = {
"echos",
"gain-in gain-out delay decay [ delay decay ... ]",
- SOX_EFF_LENGTH,
+ SOX_EFF_LENGTH | SOX_EFF_GAIN,
sox_echos_getopts,
sox_echos_start,
sox_echos_flow,
--- a/src/effects.c
+++ b/src/effects.c
@@ -15,6 +15,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define LSX_EFF_ALIAS
#include "sox_i.h"
#include "getopt.h"
#include <assert.h>
@@ -23,12 +24,6 @@
#include <strings.h>
#endif
-
-#undef lsx_fail
-#undef lsx_report
-#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail
-#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report
-
#define DEBUG_EFFECTS_CHAIN 0
/* FIXME: Not thread safe using globals */
@@ -99,7 +94,7 @@
/* Effects chain: */
sox_effects_chain_t * sox_create_effects_chain(
- sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)
+ sox_encodinginfo_t const * in_enc, sox_encodinginfo_t * out_enc)
{
sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
result->global_info = sox_effects_globals;
@@ -150,6 +145,8 @@
effp->out_signal.rate = in->rate;
if (!(effp->handler.flags & SOX_EFF_PREC))
effp->out_signal.precision = in->precision;
+ if (!(effp->handler.flags & SOX_EFF_GAIN))
+ effp->out_signal.mult = in->mult;
effp->flows =
(effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
@@ -167,6 +164,8 @@
free(eff0.priv);
return SOX_EOF;
}
+ if (in->mult)
+ lsx_debug("mult=%g", *in->mult);
*in = effp->out_signal;
--- a/src/effects_i.c
+++ b/src/effects_i.c
@@ -18,11 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define LSX_EFF_ALIAS
#include "sox_i.h"
#include <string.h>
-
-#undef lsx_fail
-#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail
int lsx_usage(sox_effect_t * effp)
{
--- a/src/example2.c
+++ b/src/example2.c
@@ -82,15 +82,14 @@
/* Read in and process blocks of audio for the selected period or until EOF: */
for (blocks = 0; sox_read(in, buf, block_size) == block_size && blocks * block_period < period; ++blocks) {
double left = 0, right = 0;
- size_t i, clips = 0;
+ size_t i;
static const char line[] = "===================================";
int l, r;
for (i = 0; i < block_size; ++i) {
- SOX_SAMPLE_LOCALS;
/* convert the sample from SoX's internal format to a `double' for
* processing in this application: */
- double sample = SOX_SAMPLE_TO_FLOAT_64BIT(buf[i], clips);
+ double sample = SOX_SAMPLE_TO_FLOAT_64BIT(buf[i]);
/* The samples for each channel are interleaved; in this example
* we allow only stereo audio, so the left channel audio can be found in
--- a/src/ffmpeg.c
+++ b/src/ffmpeg.c
@@ -406,9 +406,8 @@
do {
/* If output frame is not full, copy data into it */
if (ffmpeg->samples_index < ffmpeg->audio_input_frame_size) {
- SOX_SAMPLE_LOCALS;
for (; nread < len && ffmpeg->samples_index < ffmpeg->audio_input_frame_size; nread++)
- ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread], ft->clips);
+ ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread]);
}
/* If output frame full or no more data to read, write it out */
--- a/src/flac.c
+++ b/src/flac.c
@@ -441,22 +441,21 @@
unsigned i;
for (i = 0; i < len; ++i) {
- SOX_SAMPLE_LOCALS;
- long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips);
+ long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]);
p->decoded_samples[i] = pcm >> (32 - p->bits_per_sample);
switch (p->bits_per_sample) {
case 8: p->decoded_samples[i] =
- SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
+ SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i]);
break;
case 16: p->decoded_samples[i] =
- SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
+ SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i]);
break;
case 24: p->decoded_samples[i] = /* sign extension: */
- SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8;
+ SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i]) << 8;
p->decoded_samples[i] >>= 8;
break;
case 32: p->decoded_samples[i] =
- SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
+ SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]);
break;
}
}
--- a/src/formats.c
+++ b/src/formats.c
@@ -428,6 +428,7 @@
if (magic)
filetype = magic_file(magic, path);
if (filetype && (
+ lsx_strends(filetype, "/unknown") ||
!strcmp(filetype, "application/octet-stream") ||
!strncmp(filetype, "text/plain", (size_t)10) ))
filetype = NULL;
--- a/src/formats_i.c
+++ b/src/formats_i.c
@@ -90,14 +90,6 @@
return SOX_EOF;
}
-sox_sample_t lsx_sample_max(sox_encodinginfo_t const * encoding)
-{
- unsigned precision = encoding->encoding == SOX_ENCODING_FLOAT?
- SOX_SAMPLE_PRECISION : sox_precision(encoding->encoding, encoding->bits_per_sample);
- unsigned shift = SOX_SAMPLE_PRECISION - min(precision, SOX_SAMPLE_PRECISION);
- return (SOX_SAMPLE_MAX >> shift) << shift;
-}
-
/* Read in a buffer of data of length len bytes.
* Returns number of bytes read.
*/
--- /dev/null
+++ b/src/gain.c
@@ -1,0 +1,248 @@
+/* libSoX effect: gain/norm/etc. (c) 2008-9 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library 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 Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <ctype.h>
+#include <string.h>
+
+typedef struct {
+ sox_bool do_equalise, do_balance, do_balance_no_clip;
+ sox_bool do_restore, make_headroom, do_normalise, do_scan;
+ double fixed_gain; /* Valid only in channel 0 */
+
+ double mult;
+ double restore;
+ double rms;
+ off_t num_samples;
+ sox_sample_t min, max;
+ FILE * tmp_file;
+} priv_t;
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ char const * q;
+ for (--argc, ++argv; argc && **argv == '-' && !isdigit(argv[0][1]) &&
+ argv[0][1] != '.'; --argc, ++argv)
+ for (q = &argv[0][1]; *q; ++q) switch (*q) {
+ case 'n': p->do_scan = p->do_normalise = sox_true; break;
+ case 'e': p->do_scan = p->do_equalise = sox_true; break;
+ case 'B': p->do_scan = p->do_balance = sox_true; break;
+ case 'b': p->do_scan = p->do_balance_no_clip = sox_true; break;
+ case 'r': p->do_scan = p->do_restore = sox_true; break;
+ case 'h': p->make_headroom = sox_true; break;
+ default: lsx_fail("invalid option `-%c'", *q); return lsx_usage(effp);
+ }
+ if ((p->do_equalise + p->do_balance + p->do_balance_no_clip + p->do_restore)/ sox_true > 1) {
+ lsx_fail("Only one of -e, -B, -b, -r may be given");
+ return SOX_EOF;
+ }
+ if (p->do_normalise && p->do_restore) {
+ lsx_fail("Only one of -n, -r may be given");
+ return SOX_EOF;
+ }
+ do {NUMERIC_PARAMETER(fixed_gain, -HUGE_VAL, HUGE_VAL)} while (0);
+ p->fixed_gain = dB_to_linear(p->fixed_gain);
+ return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+static int start(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+
+ if (effp->flow == 0) {
+ if (p->do_restore) {
+ if (!effp->in_signal.mult || *effp->in_signal.mult >= 1) {
+ lsx_fail("can't restore level");
+ return SOX_EOF;
+ }
+ p->restore = 1 / *effp->in_signal.mult;
+ }
+ effp->out_signal.mult = p->make_headroom? &p->fixed_gain : NULL;
+ if (!p->do_equalise && !p->do_balance && !p->do_balance_no_clip)
+ effp->flows = 1;
+ }
+ p->mult = p->max = p->min = 0;
+ if (p->do_scan) {
+ p->tmp_file = lsx_tmpfile();
+ if (p->tmp_file == NULL) {
+ lsx_fail("can't create temporary file: %s", strerror(errno));
+ return SOX_EOF;
+ }
+ }
+ return SOX_SUCCESS;
+}
+
+static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
+ sox_sample_t * obuf, size_t * isamp, size_t * osamp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ size_t len;
+
+ if (p->do_scan) {
+ if (fwrite(ibuf, sizeof(*ibuf), *isamp, p->tmp_file) != *isamp) {
+ lsx_fail("error writing temporary file: %s", strerror(errno));
+ return SOX_EOF;
+ }
+ if (p->do_balance && !p->do_normalise)
+ for (len = *isamp; len; --len, ++ibuf) {
+ double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf);
+ p->rms += sqr(d);
+ ++p->num_samples;
+ }
+ else if (p->do_balance || p->do_balance_no_clip)
+ for (len = *isamp; len; --len, ++ibuf) {
+ double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf);
+ p->rms += sqr(d);
+ ++p->num_samples;
+ p->max = max(p->max, *ibuf);
+ p->min = min(p->min, *ibuf);
+ }
+ else for (len = *isamp; len; --len, ++ibuf) {
+ p->max = max(p->max, *ibuf);
+ p->min = min(p->min, *ibuf);
+ }
+ *osamp = 0; /* samples not output until drain */
+ }
+ else {
+ double mult = ((priv_t *)(effp - effp->flow)->priv)->fixed_gain;
+ len = *isamp = *osamp = min(*isamp, *osamp);
+ for (; len; --len, ++ibuf)
+ *obuf++ = SOX_ROUND_CLIP_COUNT(*ibuf * mult, effp->clips);
+ }
+ return SOX_SUCCESS;
+}
+
+static void start_drain(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ double max = SOX_SAMPLE_MAX, max_peak = 0, max_rms = 0;
+ size_t i;
+
+ if (p->do_balance || p->do_balance_no_clip) {
+ for (i = 0; i < effp->flows; ++i) {
+ priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
+ max_rms = max(max_rms, sqrt(q->rms / q->num_samples));
+ rewind(q->tmp_file);
+ }
+ for (i = 0; i < effp->flows; ++i) {
+ priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
+ double this_rms = sqrt(q->rms / q->num_samples);
+ double this_peak = max(q->max / max, q->min / (double)SOX_SAMPLE_MIN);
+ q->mult = this_rms != 0? max_rms / this_rms : 1;
+ max_peak = max(max_peak, q->mult * this_peak);
+ q->mult *= p->fixed_gain;
+ }
+ if (p->do_normalise || (p->do_balance_no_clip && max_peak > 1))
+ for (i = 0; i < effp->flows; ++i) {
+ priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
+ q->mult /= max_peak;
+ }
+ } else if (p->do_equalise && !p->do_normalise) {
+ for (i = 0; i < effp->flows; ++i) {
+ priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
+ double this_peak = max(q->max / max, q->min / (double)SOX_SAMPLE_MIN);
+ max_peak = max(max_peak, this_peak);
+ q->mult = p->fixed_gain / this_peak;
+ rewind(q->tmp_file);
+ }
+ for (i = 0; i < effp->flows; ++i) {
+ priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
+ q->mult *= max_peak;
+ }
+ } else {
+ p->mult = min(max / p->max, (double)SOX_SAMPLE_MIN / p->min);
+ if (p->do_restore) {
+ if (p->restore > p->mult)
+ lsx_debug("%.3gdB not restored", linear_to_dB(p->restore / p->mult));
+ else p->mult = p->restore;
+ }
+ p->mult *= p->fixed_gain;
+ rewind(p->tmp_file);
+ }
+}
+
+static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ size_t len;
+ int result = SOX_SUCCESS;
+
+ if (p->do_scan) {
+ if (!p->mult)
+ start_drain(effp);
+ len = fread(obuf, sizeof(*obuf), *osamp, p->tmp_file);
+ if (len != *osamp && !feof(p->tmp_file)) {
+ lsx_fail("error reading temporary file: %s", strerror(errno));
+ result = SOX_EOF;
+ }
+ if (p->mult > 1) for (*osamp = len; len; --len, ++obuf)
+ *obuf = SOX_ROUND_CLIP_COUNT(*obuf * p->mult, effp->clips);
+ else for (*osamp = len; len; --len, ++obuf)
+ *obuf = floor(*obuf * p->mult + .5);
+ }
+ else *osamp = 0;
+ return result;
+}
+
+static int stop(sox_effect_t * effp)
+{
+ priv_t * p = (priv_t *)effp->priv;
+ if (p->do_scan)
+ fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */
+ return SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * sox_gain_effect_fn(void)
+{
+ static sox_effect_handler_t handler = {
+ "gain", "[-e|-b|-B|-r] [-n] [-h] [gain-dB]", SOX_EFF_GAIN,
+ create, start, flow, drain, stop, NULL, sizeof(priv_t)};
+ return &handler;
+}
+
+/*------------------ emulation of the old `normalise' effect -----------------*/
+
+static int norm_getopts(sox_effect_t * effp, int argc, char * * argv)
+{
+ char * argv2[3];
+ int argc2 = 0;
+
+ argv2[argc2++] = argv[0], --argc, ++argv;
+ if (argc && !strcmp(*argv, "-i"))
+ argv2[argc2++] = "-en", --argc, ++argv;
+ else if (argc && !strcmp(*argv, "-b"))
+ argv2[argc2++] = "-B", --argc, ++argv;
+ if (argc2 > 1)
+ lsx_warn("this use is deprecated; use `gain %s' instead", argv2[1]);
+ else argv2[argc2++] = "-n";
+ if (argc)
+ argv2[argc2++] = *argv, --argc, ++argv;
+ return argc? lsx_usage(effp) :
+ sox_gain_effect_fn()->getopts(effp, argc2, argv2);
+}
+
+sox_effect_handler_t const * sox_norm_effect_fn(void)
+{
+ static sox_effect_handler_t handler;
+ handler = *sox_gain_effect_fn();
+ handler.name = "norm";
+ handler.usage = "[level]";
+ handler.getopts = norm_getopts;
+ return &handler;
+}
--- a/src/gsm.c
+++ b/src/gsm.c
@@ -195,10 +195,9 @@
while (done < samp)
{
- SOX_SAMPLE_LOCALS;
while ((p->samplePtr < p->sampleTop) && (done < samp))
*(p->samplePtr)++ =
- SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips);
+ SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]);
if (p->samplePtr == p->sampleTop)
{
--- a/src/hcom.c
+++ b/src/hcom.c
@@ -277,9 +277,8 @@
}
for (i = 0; i < len; i++) {
- SOX_SAMPLE_LOCALS;
datum = *buf++;
- p->data[p->pos++] = SOX_SAMPLE_TO_UNSIGNED_8BIT(datum, ft->clips);
+ p->data[p->pos++] = SOX_SAMPLE_TO_UNSIGNED_8BIT(datum);
}
return len;
--- a/src/ladspa.c
+++ b/src/ladspa.c
@@ -237,7 +237,7 @@
if (l_st->input_port != ULONG_MAX) {
/* Copy the input; FIXME: Assume LADSPA_Data == float! */
for (i = 0; i < len; i++)
- buf[i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
+ buf[i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i]);
/* Connect the input port */
l_st->desc->connect_port(l_st->handle, l_st->input_port, buf);
@@ -291,7 +291,7 @@
static sox_effect_handler_t sox_ladspa_effect = {
"ladspa",
"MODULE [PLUGIN] [ARGUMENT...]",
- 0,
+ SOX_EFF_GAIN,
sox_ladspa_getopts,
sox_ladspa_start,
sox_ladspa_flow,
--- a/src/lpc10.c
+++ b/src/lpc10.c
@@ -179,8 +179,7 @@
while (len > 0) {
while (len > 0 && lpc->samples < LPC10_SAMPLES_PER_FRAME) {
- SOX_SAMPLE_LOCALS;
- lpc->speech[lpc->samples++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf[nwritten++], ft->clips);
+ lpc->speech[lpc->samples++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf[nwritten++]);
len--;
}
--- a/src/mcompand.c
+++ b/src/mcompand.c
@@ -492,7 +492,7 @@
" attack1,decay1[,attack2,decay2...]\n"
" in-dB1,out-dB1[,in-dB2,out-dB2...]\n"
" [ gain [ initial-volume [ delay ] ] ]",
- SOX_EFF_MCHAN,
+ SOX_EFF_MCHAN | SOX_EFF_GAIN,
getopts, start, flow, drain, stop, kill, sizeof(priv_t)
};
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -485,6 +485,19 @@
}
}
+ if (effp->in_signal.mult) {
+ double max_sum = 0;
+
+ for (j = 0; j < (int)effp->out_signal.channels; ++j) {
+ double sum = 0;
+ for (i = 0; i < (int)effp->in_signal.channels; ++i)
+ sum += fabs(mixer->sources[mixer->mix == MIX_CENTER? 0 : i][j]);
+ max_sum = max(max_sum, sum);
+ }
+ if (max_sum > 1)
+ *effp->in_signal.mult /= max_sum;
+ }
+
if (effp->in_signal.channels != effp->out_signal.channels)
return SOX_SUCCESS;
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -406,7 +406,6 @@
int i,j;
ptrdiff_t done = 0;
size_t written;
- SOX_SAMPLE_LOCALS;
/* NOTE: This logic assumes that "short int" is 16-bits
* on all platforms. It happens to be for all that I know
@@ -435,8 +434,8 @@
j=0;
for (i=0; i<nsamples; i++)
{
- buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
- buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
+ buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]);
+ buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]);
}
}
else
@@ -443,7 +442,7 @@
{
j=0;
for (i=0; i<nsamples; i++)
- buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
+ buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]);
}
mp3buffer_size = 1.25 * nsamples + 7200;
--- a/src/noiseprof.c
+++ b/src/noiseprof.c
@@ -116,7 +116,7 @@
size_t *isamp, size_t *osamp)
{
priv_t * p = (priv_t *) effp->priv;
- size_t samp = min(*isamp, *osamp), dummy = 0; /* No need to clip count */
+ size_t samp = min(*isamp, *osamp);
size_t chans = effp->in_signal.channels;
size_t i, j, n = min(samp / chans, WINDOWSIZE - p->bufdata);
@@ -125,11 +125,10 @@
/* Collect data for every channel. */
for (i = 0; i < chans; i ++) {
- SOX_SAMPLE_LOCALS;
chandata_t * chan = &(p->chandata[i]);
for (j = 0; j < n; j ++)
chan->window[j + p->bufdata] =
- SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + j * chans], dummy);
+ SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + j * chans]);
if (n + p->bufdata == WINDOWSIZE)
collect_data(chan);
}
@@ -208,7 +207,7 @@
static sox_effect_handler_t sox_noiseprof_effect = {
"noiseprof",
"[profile-file]",
- SOX_EFF_MCHAN,
+ SOX_EFF_MCHAN | SOX_EFF_MODIFY,
sox_noiseprof_getopts,
sox_noiseprof_start,
sox_noiseprof_flow,
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -285,7 +285,6 @@
/* Reduce noise on every channel. */
for (i = 0; i < tracks; i ++) {
- SOX_SAMPLE_LOCALS;
chandata_t* chan = &(data->chandata[i]);
size_t j;
@@ -294,7 +293,7 @@
for (j = 0; j < ncopy; j ++)
chan->window[oldbuf + j] =
- SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + tracks * j], effp->clips);
+ SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + tracks * j]);
if (!whole_window)
continue;
--- a/src/normalise.c
+++ /dev/null
@@ -1,127 +1,0 @@
-/* libSoX effect: Normalise (c) 2008 robs@users.sourceforge.net
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library 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 Lesser
- * General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "sox_i.h"
-#include <string.h>
-
-typedef struct {
- sox_bool individual, balance;
- double norm0; /* Multiplier to take to 0dB FSD */
- double level; /* Multiplier to take to 'level' */
- double rms;
- off_t num_samples;
- sox_sample_t min, max;
- FILE * tmp_file;
-} priv_t;
-
-static int create(sox_effect_t * effp, int argc, char * * argv)
-{
- priv_t * p = (priv_t *)effp->priv;
- --argc, ++argv;
- if (argc && !strcmp(*argv, "-i")) p->individual = sox_true, ++argv, --argc;
- if (argc && !strcmp(*argv, "-b")) p->balance = sox_true, ++argv, --argc;
- do {NUMERIC_PARAMETER(level, -100, 0)} while (0);
- p->level = dB_to_linear(p->level);
- return argc? lsx_usage(effp) : SOX_SUCCESS;
-}
-
-static int start(sox_effect_t * effp)
-{
- priv_t * p = (priv_t *)effp->priv;
- if (!(p->individual || p->balance))
- effp->flows = 1;
- p->norm0 = p->max = p->min = 0;
- p->tmp_file = lsx_tmpfile();
- if (p->tmp_file == NULL) {
- lsx_fail("can't create temporary file: %s", strerror(errno));
- return SOX_EOF;
- }
- return SOX_SUCCESS;
-}
-
-static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
- sox_sample_t * obuf, size_t * isamp, size_t * osamp)
-{
- priv_t * p = (priv_t *)effp->priv;
- size_t len;
-
- if (fwrite(ibuf, sizeof(*ibuf), *isamp, p->tmp_file) != *isamp) {
- lsx_fail("error writing temporary file: %s", strerror(errno));
- return SOX_EOF;
- }
- if (p->balance) for (len = *isamp; len; --len, ++ibuf) {
- SOX_SAMPLE_LOCALS;
- size_t dummy = 0;
- double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf, dummy);
- p->rms += sqr(d);
- ++p->num_samples;
- }
- else for (len = *isamp; len; --len, ++ibuf) {
- p->max = max(p->max, *ibuf);
- p->min = min(p->min, *ibuf);
- }
- (void)obuf, *osamp = 0; /* samples not output until drain */
- return SOX_SUCCESS;
-}
-
-static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp)
-{
- priv_t * p = (priv_t *)effp->priv;
- size_t len, i;
- int result = SOX_SUCCESS;
-
- if (!p->norm0) {
- if (p->balance) {
- double max_rms = 0, this_rms = sqrt(p->rms / p->num_samples);
- sox_effect_t * effects = effp - effp->flow;
- for (i = 0; i < effp->flows; ++i) {
- priv_t * q = (priv_t *)(effects + i)->priv;
- max_rms = max(max_rms, sqrt(q->rms / q->num_samples));
- }
- p->norm0 = p->level * (this_rms != 0? max_rms / this_rms : 1);
- }
- else {
- double max = lsx_sample_max(effp->out_encoding);
- p->norm0 = p->level * min(max / p->max, (double)SOX_SAMPLE_MIN / p->min);
- }
- rewind(p->tmp_file);
- }
- len = fread(obuf, sizeof(*obuf), *osamp, p->tmp_file);
- if (len != *osamp && !feof(p->tmp_file)) {
- lsx_fail("error reading temporary file: %s", strerror(errno));
- result = SOX_EOF;
- }
- if (p->balance) for (*osamp = len; len; --len, ++obuf)
- *obuf = SOX_ROUND_CLIP_COUNT(*obuf * p->norm0, effp->clips);
- else for (*osamp = len; len; --len, ++obuf)
- *obuf = floor(*obuf * p->norm0 + .5);
- return result;
-}
-
-static int stop(sox_effect_t * effp)
-{
- priv_t * p = (priv_t *)effp->priv;
- fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */
- return SOX_SUCCESS;
-}
-
-sox_effect_handler_t const * sox_norm_effect_fn(void)
-{
- static sox_effect_handler_t handler = {"norm", "[-i|-b] [level]", 0,
- create, start, flow, drain, stop, NULL, sizeof(priv_t)};
- return &handler;
-}
--- a/src/overdrive.c
+++ b/src/overdrive.c
@@ -52,7 +52,7 @@
size_t dummy = 0, len = *isamp = *osamp = min(*isamp, *osamp);
while (len--) {
SOX_SAMPLE_LOCALS;
- double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, dummy), d0 = d;
+ double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++), d0 = d;
d *= p->gain;
d += p->colour;
d = d < -1? -2./3 : d > 1? 2./3 : d - d * d * d * (1./3);
@@ -66,6 +66,6 @@
sox_effect_handler_t const * sox_overdrive_effect_fn(void)
{
static sox_effect_handler_t handler = {"overdrive", "[gain [colour]]",
- 0, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)};
+ SOX_EFF_GAIN, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)};
return &handler;
}
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -139,7 +139,7 @@
{
static sox_effect_handler_t handler = {
"phaser", "gain-in gain-out delay decay speed [ -s | -t ]",
- SOX_EFF_LENGTH, getopts, start, flow, NULL, stop, NULL, sizeof(priv_t)
+ SOX_EFF_LENGTH | SOX_EFF_GAIN, getopts, start, flow, NULL, stop, NULL, sizeof(priv_t)
};
return &handler;
}
--- a/src/rate.c
+++ b/src/rate.c
@@ -494,7 +494,7 @@
if (effp->in_signal.rate == out_rate)
return SOX_EFF_NULL;
- if (effp->flow == 0 && effp->in_signal.mult)
+ if (effp->in_signal.mult)
*effp->in_signal.mult *= .705; /* 1/(2/sinc(pi/3)-1); see De Soras 4.1.2 */
effp->out_signal.channels = effp->in_signal.channels;
@@ -516,7 +516,7 @@
if (*isamp && odone < *osamp) {
sample_t * t = rate_input(&p->rate, NULL, *isamp);
- for (i = *isamp; i; --i) *t++ = FROM_SOX(*ibuf++, effp->clips);
+ for (i = *isamp; i; --i) *t++ = FROM_SOX(*ibuf++);
rate_process(&p->rate);
}
else *isamp = 0;
--- a/src/raw.c
+++ b/src/raw.c
@@ -14,8 +14,8 @@
typedef uint16_t uint13_t;
#define SOX_ULAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_ulaw2linear16(d),clips)
#define SOX_ALAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_alaw2linear16(d),clips)
-#define SOX_SAMPLE_TO_ULAW_BYTE(d,c) sox_14linear2ulaw(SOX_SAMPLE_TO_UNSIGNED(14,d,c) - 0x2000)
-#define SOX_SAMPLE_TO_ALAW_BYTE(d,c) sox_13linear2alaw(SOX_SAMPLE_TO_UNSIGNED(13,d,c) - 0x1000)
+#define SOX_SAMPLE_TO_ULAW_BYTE(d) sox_14linear2ulaw(SOX_SAMPLE_TO_UNSIGNED(14,d) - 0x2000)
+#define SOX_SAMPLE_TO_ALAW_BYTE(d) sox_13linear2alaw(SOX_SAMPLE_TO_UNSIGNED(13,d) - 0x1000)
int lsx_rawseek(sox_format_t * ft, uint64_t offset)
{
@@ -95,11 +95,10 @@
static size_t sox_write_ ## sign ## type ## _samples( \
sox_format_t * ft, sox_sample_t const * buf, size_t len) \
{ \
- SOX_SAMPLE_LOCALS; \
size_t n, nwritten; \
ctype *data = lsx_malloc(sizeof(ctype) * len); \
for (n = 0; n < len; n++) \
- data[n] = cast(buf[n], ft->clips); \
+ data[n] = cast(buf[n]); \
nwritten = lsx_write_ ## type ## _buf(ft, (uctype *)data, len); \
free(data); \
return nwritten; \
--- a/src/remix.c
+++ b/src/remix.c
@@ -95,6 +95,19 @@
p->out_specs[i].in_specs[j].multiplier = (p->mode == automatic || (p->mode == semi && !mul_spec)) ? mult : 1;
}
effp->out_signal.channels = p->num_out_channels;
+
+ if (effp->in_signal.mult) {
+ double max_sum = 0;
+
+ for (j = 0; j < effp->out_signal.channels; j++) {
+ double sum = 0;
+ for (i = 0; i < p->out_specs[j].num_in_channels; i++)
+ sum += fabs(p->out_specs[j].in_specs[i].multiplier);
+ max_sum = max(max_sum, sum);
+ }
+ if (max_sum > 1)
+ *effp->in_signal.mult /= max_sum;
+ }
return SOX_SUCCESS;
}
--- a/src/reverb.c
+++ b/src/reverb.c
@@ -212,6 +212,9 @@
&p->chan[i].reverb, effp->in_signal.rate, p->wet_gain_dB, p->room_scale,
p->reverberance, p->hf_damping, p->pre_delay_ms, p->stereo_depth,
effp->global_info->global_info->bufsiz / p->ochannels, p->chan[i].wet);
+
+ if (effp->in_signal.mult)
+ *effp->in_signal.mult /= !p->wet_only + 2 * dB_to_linear(max(0,p->wet_gain_dB));
return SOX_SUCCESS;
}
@@ -226,7 +229,7 @@
for (c = 0; c < p->ichannels; ++c)
p->chan[c].dry = fifo_write(&p->chan[c].reverb.input_fifo, len, 0);
for (i = 0; i < len; ++i) for (c = 0; c < p->ichannels; ++c)
- p->chan[c].dry[i] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
+ p->chan[c].dry[i] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++);
for (c = 0; c < p->ichannels; ++c)
reverb_process(&p->chan[c].reverb, len);
if (p->ichannels == 2) for (i = 0; i < len; ++i) for (w = 0; w < 2; ++w) {
--- a/src/silence.c
+++ b/src/silence.c
@@ -275,27 +275,25 @@
{
double ratio;
int rc;
- sox_sample_t dummy_clipped_count = 0;
/* When scaling low bit data, noise values got scaled way up */
/* Only consider the original bits when looking for silence */
switch(effp->in_signal.precision)
{
- SOX_SAMPLE_LOCALS;
case 8:
- value = SOX_SAMPLE_TO_SIGNED_8BIT(value, dummy_clipped_count);
+ value = SOX_SAMPLE_TO_SIGNED_8BIT(value);
ratio = (double)abs(value) / (double)SOX_INT8_MAX;
break;
case 16:
- value = SOX_SAMPLE_TO_SIGNED_16BIT(value, dummy_clipped_count);
+ value = SOX_SAMPLE_TO_SIGNED_16BIT(value);
ratio = (double)abs(value) / (double)SOX_INT16_MAX;
break;
case 24:
- value = SOX_SAMPLE_TO_SIGNED_24BIT(value, dummy_clipped_count);
+ value = SOX_SAMPLE_TO_SIGNED_24BIT(value);
ratio = (double)abs(value) / (double)SOX_INT24_MAX;
break;
case 32:
- value = SOX_SAMPLE_TO_SIGNED_32BIT(value,);
+ value = SOX_SAMPLE_TO_SIGNED_32BIT(value);
ratio = (double)abs(value) / (double)SOX_INT32_MAX;
break;
default:
--- a/src/skelform.c
+++ b/src/skelform.c
@@ -159,9 +159,8 @@
switch (ft->encoding.bits_per_sample) {
case 8:
switch (ft->encoding.encoding) {
- SOX_SAMPLE_LOCALS;
case SOX_ENCODING_UNSIGNED:
- while (done < len && lsx_writeb(ft, SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips)) == SOX_SUCCESS)
+ while (done < len && lsx_writeb(ft, SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++)) == SOX_SUCCESS)
++done;
break;
default:
--- a/src/smp.c
+++ b/src/smp.c
@@ -368,8 +368,7 @@
size_t done = 0;
while(done < len) {
- SOX_SAMPLE_LOCALS;
- datum = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
+ datum = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
lsx_writew(ft, (uint16_t)datum);
smp->NoOfSamps++;
done++;
--- a/src/sox.c
+++ b/src/sox.c
@@ -1,9 +1,9 @@
/* SoX - The Swiss Army Knife of Audio Manipulation.
*
- * This is the main function for the command line sox program.
+ * This is the main function for the SoX command line programs.
*
+ * Copyright 1998-2009 Chris Bagwell and SoX contributors
* Copyright 1991 Lance Norskog And Sundry Contributors
- * Copyright 1998-2008 Chris Bagwell and SoX contributors
*
* 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
@@ -133,6 +133,7 @@
sox_signalinfo_t signal;
sox_encodinginfo_t encoding;
double volume;
+ sox_sample_t offset;
double replay_gain;
sox_oob_t oob;
sox_bool no_glob;
@@ -197,9 +198,8 @@
static struct termios original_termios;
#endif
-static sox_bool stdin_is_a_tty, is_player;
+static sox_bool stdin_is_a_tty, is_player, is_guarded, do_guarded_norm;
-
/* Cleanup atexit() function, hence always called. */
static void cleanup(void)
{
@@ -214,7 +214,7 @@
}
if (file_count) {
- if (ofile->ft) {
+ if (ofile->ft) {
if (!success && ofile->ft->fp) { /* If we failed part way through */
struct stat st; /* writing a normal file, remove it. */
fstat(fileno(ofile->ft->fp), &st);
@@ -405,6 +405,8 @@
display_file_info(f->ft, f, sox_false);
if (f->volume == HUGE_VAL)
f->volume = 1;
+ if (f->encoding.half_bit && f->ft->signal.precision < 32)
+ f->offset = 1 << (31 - f->ft->signal.precision);
if (f->replay_gain != HUGE_VAL)
f->volume *= pow(10.0, f->replay_gain / 20);
f->ft->sox_errno = errno = 0;
@@ -411,7 +413,6 @@
}
/* Read up to max `wide' samples. A wide sample contains one sample per channel
- printf("effect %d obeg = %d oend = %d\n", e, effects_chain->effects[e]->obeg, effects_chain->effects[e]->oend);
* from the input audio. */
static size_t sox_read_wide(sox_format_t * ft, sox_sample_t * buf, size_t max)
{
@@ -427,11 +428,12 @@
{
size_t s = ws * f->ft->signal.channels;
- if (f->volume != 1)
- while (s--) {
- double d = f->volume * *buf;
- *buf++ = SOX_ROUND_CLIP_COUNT(d, f->volume_clips);
- }
+ if (f->volume == 1 && f->offset !=0 ) while (s--)
+ *buf++ -= f->offset;
+ else if (f->volume != 1 || f->offset !=0 ) while (s--) {
+ double d = f->volume * (*buf - f->offset);
+ *buf++ = SOX_ROUND_CLIP_COUNT(d, f->volume_clips);
+ }
}
/* The input combiner: contains one sample buffer per input file, but only
@@ -557,12 +559,24 @@
return &handler;
}
+static int ostart(sox_effect_t *effp)
+{
+ (void)effp;
+ if (effp->out_encoding->half_bit && effp->out_signal.precision < 32)
+ ofile->offset = 1 << (31 - ofile->ft->signal.precision);
+ return SOX_SUCCESS;
+}
+
static int output_flow(sox_effect_t *effp, sox_sample_t const * ibuf,
sox_sample_t * obuf, size_t * isamp, size_t * osamp)
{
+ sox_sample_t const * buf;
size_t len;
(void)effp, (void)obuf;
+ if (ofile->offset != 0 ) for (buf = ibuf, len = *isamp; len; --len, ++buf)
+ *(sox_sample_t *)buf = *buf >= SOX_SAMPLE_MAX - ofile->offset?
+ SOX_SAMPLE_MAX : *buf + ofile->offset;
if (show_progress) for (len = 0; len < *isamp; len += effp->in_signal.channels) {
omax[0] = max(omax[0], ibuf[len]);
omin[0] = min(omin[0], ibuf[len]);
@@ -591,26 +605,49 @@
static sox_effect_handler_t const * output_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "output", 0, SOX_EFF_MCHAN, NULL, NULL, output_flow, NULL, NULL, NULL, 0
+ "output", 0, SOX_EFF_MCHAN, NULL, ostart, output_flow, NULL, NULL, NULL, 0
};
return &handler;
}
-static void add_effect(sox_effects_chain_t *chain, char const *name,
- int argc, char *argv[], sox_signalinfo_t *signal)
+static void auto_effect(sox_effects_chain_t *, char const *, int, char **,
+ sox_signalinfo_t *, int *);
+
+static int add_effect(sox_effects_chain_t * chain, sox_effect_t * effp,
+ sox_signalinfo_t * in, sox_signalinfo_t const * out, int * guard) {
+ int no_guard = -1;
+ switch (*guard) {
+ case 0: if (!(effp->handler.flags & SOX_EFF_GAIN)) {
+ char * arg = "-h";
+ auto_effect(chain, "gain", 1, &arg, in, &no_guard);
+ ++*guard;
+ }
+ break;
+ case 1: if (effp->handler.flags & SOX_EFF_GAIN) {
+ char * arg = "-r";
+ auto_effect(chain, "gain", 1, &arg, in, &no_guard);
+ --*guard;
+ }
+ break;
+ case 2: if (!(effp->handler.flags & SOX_EFF_MODIFY)) {
+ lsx_fail("effects that modify audio must not follow dither");
+ exit(1);
+ }
+ }
+ return sox_add_effect(chain, effp, in, out);
+}
+
+static void auto_effect(sox_effects_chain_t *chain, char const *name, int argc,
+ char *argv[], sox_signalinfo_t *signal, int * guard)
{
sox_effect_t * effp;
effp = sox_create_effect(sox_find_effect(name)); /* Should always succeed. */
- if (effp->handler.flags & SOX_EFF_DEPRECATED)
- lsx_warn("effect `%s' is deprecated; see sox(1) for an alternative",
- effp->handler.name);
-
if (sox_effect_options(effp, argc, argv) == SOX_EOF)
exit(1); /* The failing effect should have displayed an error message */
-
- if (sox_add_effect(chain, effp, signal, &ofile->ft->signal) != SOX_SUCCESS)
+
+ if (add_effect(chain, effp, signal, &ofile->ft->signal, guard) != SOX_SUCCESS)
exit(2); /* The effects chain should have displayed an error message */
}
@@ -621,7 +658,7 @@
nuser_effects[0] = 0;
} /* init_eff_chains */
-/* add_eff_chain() - NOTE: this only adds memory for one
+/* add_eff_chain() - NOTE: this only adds memory for one
* additional effects chain beyond value of eff_chain_count. It
* does not unconditionally increase size of effects chain.
*/
@@ -639,9 +676,9 @@
unsigned j;
int i, k;
- for (i = 0; i < eff_chain_count; i++)
+ for (i = 0; i < eff_chain_count; i++)
{
- for (j = 0; j < nuser_effects[i]; j++)
+ for (j = 0; j < nuser_effects[i]; j++)
{
if (user_effargs[i][j].name)
free(user_effargs[i][j].name);
@@ -665,7 +702,7 @@
static sox_bool is_pseudo_effect(char *s)
{
- if (strcmp("newfile", s) == 0 ||
+ if (strcmp("newfile", s) == 0 ||
strcmp("restart", s) == 0 ||
strcmp(":", s) == 0)
return sox_true;
@@ -700,7 +737,7 @@
optind++;
continue;
}
-
+
if (strcmp(argv[optind], "newfile") == 0)
{
/* Start a new effect chain for newfile if user doesn't
@@ -739,7 +776,7 @@
optind += j; /* Skip past the effect arguments */
nuser_effects[eff_chain_count]++;
- if (newline_mode)
+ if (newline_mode)
{
output_method = sox_multiple;
eff_chain_count++;
@@ -865,9 +902,9 @@
/* Creates users effects and passes in user specified options.
* This is done without putting anything into the effects chain
* because an effect may set the effp->in_format and we may want
- * to copy that back into the input/combiner before opening and
- * inserting it.
- * Similarly, we may want to use effp->out_format to override the
+ * to copy that back into the input/combiner before opening and
+ * inserting it.
+ * Similarly, we may want to use effp->out_format to override the
* default values of output file before we open it.
* To keep things simple, we create all user effects. Later, when
* we add them, some may already be in the chain and we will need to free
@@ -882,11 +919,11 @@
effp = sox_create_effect(sox_find_effect(user_effargs[current_eff_chain][i].name));
if (effp->handler.flags & SOX_EFF_DEPRECATED)
- lsx_warn("effect `%s' is deprecated; see sox(1) for an alternative",
+ lsx_warn("effect `%s' is deprecated; see sox(1) for an alternative",
effp->handler.name);
/* The failing effect should have displayed an error message */
- if (sox_effect_options(effp, user_effargs[current_eff_chain][i].argc,
+ if (sox_effect_options(effp, user_effargs[current_eff_chain][i].argc,
user_effargs[current_eff_chain][i].argv) == SOX_EOF)
exit(1);
@@ -905,6 +942,7 @@
static void add_effects(sox_effects_chain_t *chain)
{
sox_signalinfo_t signal = combiner_signal;
+ int guard = is_guarded - 1;
unsigned i;
sox_effect_t * effp;
char * rate_arg =
@@ -911,32 +949,43 @@
is_player ? (rate_arg = getenv("PLAY_RATE_ARG")) ? rate_arg : "-l" : NULL;
/* 1st `effect' in the chain is the input combiner_signal.
- * add it only if its not there from a previous run.
- */
- if (chain->length == 0)
- {
+ * add it only if its not there from a previous run. */
+ if (chain->length == 0) {
effp = sox_create_effect(input_combiner_effect_fn());
sox_add_effect(chain, effp, &signal, &ofile->ft->signal);
}
- /* Add auto effects if appropriate; add user specified effects */
- for (i = 0; i < nuser_effects[current_eff_chain]; i++) {
- /* Effects chain should have displayed an error message */
- if (sox_add_effect(chain, user_efftab[i],
- &signal, &ofile->ft->signal) != SOX_SUCCESS)
- exit(2);
- }
+ /* Add user specified effects; stop before `dither' */
+ for (i = 0; i < nuser_effects[current_eff_chain] &&
+ strcmp(user_efftab[i]->handler.name, "dither"); i++)
+ if (add_effect(chain, user_efftab[i], &signal, &ofile->ft->signal,
+ &guard) != SOX_SUCCESS)
+ exit(2); /* Effects chain should have displayed an error message */
/* Add auto effects if still needed at this point */
+ if (signal.channels < ofile->ft->signal.channels &&
+ signal.rate != ofile->ft->signal.rate)
+ auto_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal, &guard);
+ if (signal.channels != ofile->ft->signal.channels)
+ auto_effect(chain, "mixer", 0, NULL, &signal, &guard);
if (signal.rate != ofile->ft->signal.rate)
- {
- add_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal); /* Must be up-sampling */
+ auto_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal, &guard);
+
+ if (is_guarded && (do_guarded_norm || !(signal.mult && *signal.mult == 1))) {
+ char * arg = do_guarded_norm? "-nh" : guard? "-rh" : "-h";
+ int no_guard = -1;
+ auto_effect(chain, "gain", 1, &arg, &signal, &no_guard);
+ guard = 1;
}
- if (signal.channels != ofile->ft->signal.channels)
- {
- add_effect(chain, "mixer", 0, NULL, &signal); /* Must be increasing channels */
+
+ /* Add user specified effects from `dither' onwards */
+ for (; i < nuser_effects[current_eff_chain]; i++, guard = 2) {
+ if (add_effect(chain, user_efftab[i], &signal, &ofile->ft->signal,
+ &guard) != SOX_SUCCESS)
+ exit(2); /* Effects chain should have displayed an error message */
+ chain->out_enc->half_bit = sox_false;
}
-
+
if (!save_output_eff)
{
/* Last `effect' in the chain is the output file */
@@ -981,15 +1030,15 @@
/* Effect chain stopped so advance to next effect chain but
* quite if no more chains exist.
*/
- else if (++current_eff_chain >= eff_chain_count)
+ else if (++current_eff_chain >= eff_chain_count)
return SOX_EOF;
- while (nuser_effects[current_eff_chain] == 1 &&
+ while (nuser_effects[current_eff_chain] == 1 &&
is_pseudo_effect(user_effargs[current_eff_chain][0].name))
{
if (strcmp("newfile", user_effargs[current_eff_chain][0].name) == 0)
{
- if (++current_eff_chain >= eff_chain_count)
+ if (++current_eff_chain >= eff_chain_count)
return SOX_EOF;
reuse_output = sox_false;
}
@@ -1167,7 +1216,7 @@
int ch = getchar();
#ifdef INTERACTIVE
- if (files[current_input]->ft->handler.seek &&
+ if (files[current_input]->ft->handler.seek &&
files[current_input]->ft->seekable)
{
if (ch == '>')
@@ -1408,7 +1457,7 @@
*/
for (i = 0; i < input_count; i++) {
unsigned j;
- for (j =0; j < nuser_effects[current_eff_chain] &&
+ for (j =0; j < nuser_effects[current_eff_chain] &&
!files[i]->ft->signal.channels; ++j)
files[i]->ft->signal.channels = user_efftab[j]->in_signal.channels;
/* For historical reasons, default to one channel if not specified. */
@@ -1520,7 +1569,7 @@
/* Determine the output file encoding attributes; set from user options
* if given: */
ofile->encoding = ofile_encoding_options;
-
+
/* Get unspecified output file encoding attributes from the input file and
* set the output file to the resultant encoding if this is supported by the
* output file type; if not, the output file handler should select an
@@ -1548,7 +1597,7 @@
open_output_file();
if (!effects_chain)
- effects_chain = sox_create_effects_chain(&combiner_encoding,
+ effects_chain = sox_create_effects_chain(&combiner_encoding,
&ofile->ft->encoding);
add_effects(effects_chain);
@@ -1564,7 +1613,7 @@
* effect chains.
* For case #2, something else must decide when to stop processing.
*/
- if ((input_eof && current_input < input_count) ||
+ if ((input_eof && current_input < input_count) ||
(!output_eof && current_eff_chain < eff_chain_count))
flow_status = SOX_SUCCESS;
@@ -1691,6 +1740,7 @@
"--combine concatenate Concatenate multiple input files (default for sox, rec)",
"--combine sequence Sequence multiple input files (default for play)",
"--effects-file FILENAME File containing effects and options",
+"-G, --guard Use temporary files to guard against clipping",
"-h, --help Display version number and usage information",
"--help-effect NAME Show usage of effect NAME, or NAME=all for all",
"--help-format NAME Show info on format NAME, or NAME=all for all",
@@ -1698,6 +1748,7 @@
"--interactive Prompt to overwrite output file",
"-m, --combine mix Mix multiple input files (instead of concatenating)",
"-M, --combine merge Merge multiple input files (instead of concatenating)",
+"--norm Guard (see --guard) & normalise",
"--plot gnuplot|octave Generate script to plot response of filter effect",
"-q, --no-show-progress Run in quiet mode; opposite of -S",
"--replay-gain track|album|off Default: off (sox, rec), track (play)",
@@ -1728,6 +1779,7 @@
"-X|--reverse-bits Encoded bit-order",
"--endian little|big|swap Encoded byte-order; swap means opposite to default",
"-L/-B/-x Short options for the above",
+"-0 PCM encoding is 0 biased (offset by half a bit)",
"-c|--channels CHANNELS Number of channels of audio data; e.g. 2 = stereo",
"-r|--rate RATE Sample rate of audio",
"-C|--compression FACTOR Compression factor for output format",
@@ -1885,7 +1937,7 @@
free(text);
}
-static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:LMNRSTUV::X12348";
+static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:GLMNRSTUV::X012348";
static struct option long_options[] =
{
@@ -1908,6 +1960,7 @@
{"temp" , required_argument, NULL, 0},
{"single-threaded" , no_argument, NULL, 0},
{"ignore-length" , no_argument, NULL, 0},
+ {"norm" , no_argument, NULL, 0},
{"bits" , required_argument, NULL, 'b'},
{"channels" , required_argument, NULL, 'c'},
@@ -1924,6 +1977,7 @@
{"show-progress" , no_argument, NULL, 'S'},
{"type" , required_argument, NULL, 't'},
{"volume" , required_argument, NULL, 'v'},
+ {"guard" , no_argument, NULL, 'G'},
{NULL, 0, NULL, 0}
};
@@ -2056,57 +2110,25 @@
sox_globals.input_bufsiz = i;
break;
- case 7:
- interactive = sox_true;
- break;
-
- case 8:
- usage_effect(optarg);
- break;
-
- case 9:
- usage_format(optarg);
- break;
-
- case 10:
- f->no_glob = sox_true;
- break;
-
+ case 7: interactive = sox_true; break;
+ case 8: usage_effect(optarg); break;
+ case 9: usage_format(optarg); break;
+ case 10: f->no_glob = sox_true; break;
case 11:
sox_effects_globals.plot = enum_option(option_index, plot_methods);
break;
-
- case 12:
- replay_gain_mode = enum_option(option_index, rg_modes);
- break;
-
- case 13:
- display_SoX_version(stdout);
- exit(0);
- break;
-
- case 14:
- break;
-
- case 15:
- effects_filename = strdup(optarg);
- break;
-
- case 16:
- sox_globals.tmp_path = strdup(optarg);
- break;
-
- case 17:
- single_threaded = sox_true;
- break;
-
- case 18:
- f->signal.length = SOX_IGNORE_LENGTH;
- break;
-
+ case 12: replay_gain_mode = enum_option(option_index, rg_modes); break;
+ case 13: display_SoX_version(stdout); exit(0); break;
+ case 14: break;
+ case 15: effects_filename = strdup(optarg); break;
+ case 16: sox_globals.tmp_path = strdup(optarg); break;
+ case 17: single_threaded = sox_true; break;
+ case 18: f->signal.length = SOX_IGNORE_LENGTH; break;
+ case 19: do_guarded_norm = is_guarded = sox_true; break;
}
break;
+ case 'G': is_guarded = sox_true; break;
case 'm': combine_method = sox_mix; break;
case 'M': combine_method = sox_merge; break;
case 'T': combine_method = sox_multiply; break;
@@ -2119,7 +2141,7 @@
return c;
break;
- case 'h':
+ case 'h':
usage(NULL);
break;
@@ -2144,6 +2166,8 @@
break;
}
+ case '0': f->encoding.half_bit = sox_true; break;
+
case 'v':
if (sscanf(optarg, "%lf %c", &f->volume, &dummy) != 1) {
lsx_fail("Volume value `%s' is not a number", optarg);
@@ -2444,7 +2468,7 @@
}
sox_globals.verbosity = (unsigned)i;
}
- }
+ }
else if (opt == 'T')
do_total = sox_true;
else type = 1 + (strchr(opts, opt) - opts);
@@ -2512,12 +2536,6 @@
return c1 && c2 && !strcasecmp(c1, c2);
}
-static int strends(char const * str, char const * end)
-{
- size_t str_len = strlen(str), end_len = strlen(end);
- return str_len >= end_len && !strcmp(str + str_len - end_len, end);
-}
-
#ifdef __CYGWIN__
static char * check_dir(char * name)
{
@@ -2534,11 +2552,11 @@
myname = argv[0];
sox_globals.output_message_handler = output_message;
- if (strends(myname, "play"))
+ if (lsx_strends(myname, "play"))
sox_mode = sox_play;
- else if (strends(myname, "rec"))
+ else if (lsx_strends(myname, "rec"))
sox_mode = sox_rec;
- else if (strends(myname, "soxi"))
+ else if (lsx_strends(myname, "soxi"))
sox_mode = sox_soxi;
if (sox_init() != SOX_SUCCESS)
@@ -2686,7 +2704,7 @@
}
/* Not the best way for users to do this; now deprecated in favour of soxi. */
- if (!show_progress && !nuser_effects[current_eff_chain] &&
+ if (!show_progress && !nuser_effects[current_eff_chain] &&
ofile->filetype && !strcmp(ofile->filetype, "null")) {
for (i = 0; i < input_count; i++)
report_file_info(files[i]);
@@ -2703,7 +2721,7 @@
/* If user specified an effects filename then use that file
* to load user effects. Free any previously specified options
- * from the command line.
+ * from the command line.
*/
if (effects_filename)
{
--- a/src/sox.h
+++ b/src/sox.h
@@ -1,6 +1,6 @@
/* libSoX Library Public Interface
*
- * Copyright 1999-2008 Chris Bagwell and SoX Contributors.
+ * Copyright 1999-2009 Chris Bagwell and SoX Contributors.
*
* This source code is freely redistributable and may be used for
* any purpose. This copyright notice must be maintained.
@@ -12,6 +12,7 @@
#define SOX_H
#include <limits.h>
+#include <math.h>
#include <stdarg.h>
#include <stddef.h> /* Ensure NULL etc. are available throughout SoX */
#include <stdio.h>
@@ -75,40 +76,32 @@
/* Conversions: Linear PCM <--> sox_sample_t
*
- * I/O I/O sox_sample_t Clips? I/O sox_sample_t Clips?
- * Format Minimum Minimum I O Maximum Maximum I O
- * ------ --------- ------------ -- -- -------- ------------ -- --
- * Float -1 -1.00000000047 y y 1 1 y n
- * Int8 -128 -128 n n 127 127.9999999 n y
- * Int16 -32768 -32768 n n 32767 32767.99998 n y
- * Int24 -8388608 -8388608 n n 8388607 8388607.996 n y
- * Int32 -2147483648 -2147483648 n n 2147483647 2147483647 n n
+ * I/O I/O sox_sample_t I/O sox_sample_t
+ * Format Minimum Minimum Maximum Maximum
+ * ------ --------- ------------ -------- ------------
+ * Float -1 -1 1 1 - 5e-10
+ * Int8 -128 -127.5 127 127.4999999
+ * Int16 -32768 -32767.5 32767 32767.49998
+ * Int24 -8388608 -8388607.5 8388607 8388607.496
+ * Int32 -2147483648 -2147483648 2147483647 2147483647
*
* Conversions are as accurate as possible (with rounding).
*
* Rounding: halves toward +inf, all others to nearest integer.
*
- * Clips? shows whether on not there is the possibility of a conversion
- * clipping to the minimum or maximum value when inputing from or outputing
- * to a given type.
+ * The only possibility of clipping on conversion is when inputting Float.
*
* Unsigned integers are converted to and from signed integers by flipping
* the upper-most bit then treating them as signed integers.
*/
-#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample UNUSED; \
- double sox_macro_temp_double UNUSED
+#define SOX_SAMPLE_LOCALS double sox_macro_temp_double UNUSED
#define SOX_SAMPLE_NEG SOX_INT_MIN(32)
-#define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \
- (uint##bits##_t)( \
- sox_macro_temp_sample=(d), \
- sox_macro_temp_sample>(sox_sample_t)(SOX_SAMPLE_MAX-(1U<<(31-bits)))? \
- ++(clips),SOX_UINT_MAX(bits): \
- ((uint32_t)(sox_macro_temp_sample^SOX_SAMPLE_NEG)+(1U<<(31-bits)))>>(32-bits))
-#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \
- (int##bits##_t)(SOX_SAMPLE_TO_UNSIGNED(bits,d,clips)^SOX_INT_MIN(bits))
-#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits))
+#define SOX_SAMPLE_TO_UNSIGNED(bits,d) \
+ (uint##bits##_t)(((uint32_t)((d)^SOX_SAMPLE_NEG))>>(32-bits))
+#define SOX_SAMPLE_TO_SIGNED(bits,d) (int##bits##_t)(((uint32_t)(d))>>(32-bits))
+#define SOX_SIGNED_TO_SAMPLE(bits,d)(((sox_sample_t)(d)<<(32-bits))+(1<<(31-bits)))
#define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG)
#define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d)
@@ -120,17 +113,17 @@
#define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG)
#define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d)
#define SOX_FLOAT_32BIT_TO_SAMPLE SOX_FLOAT_64BIT_TO_SAMPLE
-#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_macro_temp_double=(d),sox_macro_temp_double<-1?++(clips),(-SOX_SAMPLE_MAX):sox_macro_temp_double>1?++(clips),SOX_SAMPLE_MAX:(sox_sample_t)((uint32_t)((double)(sox_macro_temp_double)*SOX_SAMPLE_MAX+(SOX_SAMPLE_MAX+.5))-SOX_SAMPLE_MAX))
-#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips)
-#define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips)
-#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips)
-#define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips)
-#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips)
-#define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips)
-#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (uint32_t)((d)^SOX_SAMPLE_NEG)
-#define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (int32_t)(d)
+#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.)+.5,sox_macro_temp_double<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double>=SOX_SAMPLE_MAX+1.?sox_macro_temp_double>SOX_SAMPLE_MAX+1.5?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:(sox_sample_t)floor(sox_macro_temp_double))
+#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d) SOX_SAMPLE_TO_UNSIGNED(8,d)
+#define SOX_SAMPLE_TO_SIGNED_8BIT(d) SOX_SAMPLE_TO_SIGNED(8,d)
+#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d) SOX_SAMPLE_TO_UNSIGNED(16,d)
+#define SOX_SAMPLE_TO_SIGNED_16BIT(d) SOX_SAMPLE_TO_SIGNED(16,d)
+#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d) SOX_SAMPLE_TO_UNSIGNED(24,d)
+#define SOX_SAMPLE_TO_SIGNED_24BIT(d) SOX_SAMPLE_TO_SIGNED(24,d)
+#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d) (uint32_t)((d)^SOX_SAMPLE_NEG)
+#define SOX_SAMPLE_TO_SIGNED_32BIT(d) (int32_t)(d)
#define SOX_SAMPLE_TO_FLOAT_32BIT SOX_SAMPLE_TO_FLOAT_64BIT
-#define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) (sox_macro_temp_sample=(d),sox_macro_temp_sample==SOX_SAMPLE_MIN?++(clips),-1.0:((double)(sox_macro_temp_sample)*(1.0/SOX_SAMPLE_MAX)))
+#define SOX_SAMPLE_TO_FLOAT_64BIT(d) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
@@ -250,6 +243,7 @@
typedef struct { /* Encoding parameters */
sox_encoding_t encoding; /* format of sample numbers */
unsigned bits_per_sample; /* 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
+ sox_bool half_bit;
double compression; /* compression factor (where applicable) */
/* If these 3 variables are set to DEFAULT, then, during
@@ -452,6 +446,8 @@
#define SOX_EFF_MCHAN 16 /* Effect can handle multi-channel */
#define SOX_EFF_NULL 32 /* Effect does nothing */
#define SOX_EFF_DEPRECATED 64 /* Effect is living on borrowed time */
+#define SOX_EFF_GAIN 128 /* Effect does not support gain -r */
+#define SOX_EFF_MODIFY 256 /* Effect does not modify samples */
typedef enum {sox_plot_off, sox_plot_octave, sox_plot_gnuplot} sox_plot_t;
typedef struct sox_effect sox_effect_t;
@@ -508,11 +504,11 @@
sox_sample_t **ibufc, **obufc; /* Channel interleave buffers */
sox_effects_globals_t global_info;
sox_encodinginfo_t const * in_enc;
- sox_encodinginfo_t const * out_enc;
+ sox_encodinginfo_t * out_enc;
};
typedef struct sox_effects_chain sox_effects_chain_t;
sox_effects_chain_t * sox_create_effects_chain(
- sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc);
+ sox_encodinginfo_t const * in_enc, sox_encodinginfo_t * out_enc);
void sox_delete_effects_chain(sox_effects_chain_t *ecp);
int sox_add_effect( sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out);
int sox_flow_effects(sox_effects_chain_t *, int (* callback)(sox_bool all_done));
@@ -565,6 +561,7 @@
lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * lsx_enum_items);
lsx_enum_item const * lsx_find_enum_value(unsigned value, lsx_enum_item const * lsx_enum_items);
int lsx_enum_option(int c, lsx_enum_item const * items);
+sox_bool lsx_strends(char const * str, char const * end);
char const * lsx_find_file_extension(char const * pathname);
char const * lsx_sigfigs3(size_t number);
char const * lsx_sigfigs3p(double percentage);
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -19,6 +19,17 @@
#include <errno.h>
+#if defined(LSX_EFF_ALIAS)
+#undef lsx_debug
+#undef lsx_fail
+#undef lsx_report
+#undef lsx_warn
+#define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug
+#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail
+#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report
+#define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn
+#endif
+
#define RANQD1 ranqd1(sox_globals.ranqd1)
#define DRANQD1 dranqd1(sox_globals.ranqd1)
@@ -213,7 +224,6 @@
int lsx_check_read_params(sox_format_t * ft, unsigned channels,
sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
off_t num_samples, sox_bool check_length);
-sox_sample_t lsx_sample_max(sox_encodinginfo_t const * encoding);
#define SOX_FORMAT_HANDLER(name) \
sox_format_handler_t const * sox_##name##_format_fn(void); \
sox_format_handler_t const * sox_##name##_format_fn(void)
--- a/src/sox_sample_test.c
+++ /dev/null
@@ -1,18 +1,0 @@
-/* libSoX test code copyright (c) 2006 robs@users.sourceforge.net
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "sox_sample_test.h"
--- a/src/sox_sample_test.h
+++ /dev/null
@@ -1,207 +1,0 @@
-/* libSoX test code copyright (c) 2006 robs@users.sourceforge.net
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#define DEBUG
-#include <assert.h>
-#include "sox.h"
-
-#define TEST_UINT(bits) \
- uint##bits = 0; \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \
- assert(sample == SOX_SAMPLE_MIN); \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == 0 && clips == 0); \
- \
- uint##bits = 1; \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \
- assert(sample > SOX_SAMPLE_MIN && sample < 0); \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == 1 && clips == 0); \
- \
- uint##bits = SOX_INT_MAX(bits); \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \
- assert(sample * SOX_INT_MAX(bits) == SOX_UNSIGNED_TO_SAMPLE(bits,1)); \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == SOX_INT_MAX(bits) && clips == 0); \
- \
- sample =SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2; \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == 1 && clips == 0); \
- \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2-1; \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == 0 && clips == 0); \
- \
- uint##bits = (0^SOX_INT_MIN(bits)); \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \
- assert(sample == 0); \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == (0^SOX_INT_MIN(bits)) && clips == 0); \
- \
- uint##bits = ((0^SOX_INT_MIN(bits))+1); \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \
- assert(sample > 0 && sample < SOX_SAMPLE_MAX); \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == ((0^SOX_INT_MIN(bits))+1) && clips == 0); \
- \
- uint##bits = SOX_UINT_MAX(bits); \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \
- assert(sample == SOX_INT_MAX(bits) * SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))); \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == SOX_UINT_MAX(bits) && clips == 0); \
- \
- sample =SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2-1; \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == SOX_UINT_MAX(bits) && clips == 0); \
- \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2; \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == SOX_UINT_MAX(bits) && --clips == 0); \
- \
- sample = SOX_SAMPLE_MAX; \
- uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \
- assert(uint##bits == SOX_UINT_MAX(bits) && --clips == 0); \
-
-#define TEST_SINT(bits) \
- int##bits = SOX_INT_MIN(bits); \
- sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \
- assert(sample == SOX_SAMPLE_MIN); \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = SOX_INT_MIN(bits)+1; \
- sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \
- assert(sample > SOX_SAMPLE_MIN && sample < 0); \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = SOX_UINT_MAX(bits) /* i.e. -1 */; \
- sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \
- assert(sample * SOX_INT_MAX(bits) == SOX_SIGNED_TO_SAMPLE(bits,SOX_INT_MIN(bits)+1)); \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = SOX_INT_MIN(bits)+1; \
- sample =SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2; \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = SOX_INT_MIN(bits); \
- sample = SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2-1; \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = 0; \
- sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \
- assert(sample == 0); \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = 1; \
- sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \
- assert(sample > 0 && sample < SOX_SAMPLE_MAX); \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- int##bits = SOX_INT_MAX(bits); \
- sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \
- assert(sample == SOX_INT_MAX(bits) * SOX_SIGNED_TO_SAMPLE(bits,1)); \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- sample =SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2-1; \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && clips == 0); \
- \
- sample =SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2; \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && --clips == 0); \
- \
- sample = SOX_SAMPLE_MAX; \
- int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \
- assert(int##bits##_2 == int##bits && --clips == 0);
-
-#if defined __GNUC__
- #pragma GCC system_header
-#elif defined __SUNPRO_CC
- #pragma disable_warn
-#elif defined _MSC_VER
- #pragma warning(push, 1)
-#endif
-
-#define epsilon 1e-16
-
-int main()
-{
- int8_t int8;
- int16_t int16;
- int24_t int24;
-
- uint8_t uint8;
- uint16_t uint16;
- uint24_t uint24;
-
- int8_t int8_2;
- int16_t int16_2;
- int24_t int24_2;
-
- sox_sample_t sample;
- size_t clips = 0;
-
- double d;
- SOX_SAMPLE_LOCALS;
-
- TEST_UINT(8)
- TEST_UINT(16)
- TEST_UINT(24)
-
- TEST_SINT(8)
- TEST_SINT(16)
- TEST_SINT(24)
-
- d = -1.0000000001;
- sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips);
- assert(sample == -SOX_SAMPLE_MAX && --clips == 0);
-
- d = -1;
- sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips);
- assert(sample == -SOX_SAMPLE_MAX && clips == 0);
- d = SOX_SAMPLE_TO_FLOAT_64BIT(sample,clips);
- assert(fabs(d + 1) < epsilon && clips == 0);
-
- --sample;
- d = SOX_SAMPLE_TO_FLOAT_64BIT(sample,clips);
- assert(fabs(d + 1) < epsilon && --clips == 0);
-
- d = 1;
- sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips);
- assert(sample == SOX_SAMPLE_MAX && clips == 0);
- d = SOX_SAMPLE_TO_FLOAT_64BIT(sample,clips);
- assert(fabs(d - 1) < epsilon && clips == 0);
-
- d = 1.0000000001;
- sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips);
- assert(sample == SOX_SAMPLE_MAX && --clips == 0);
-
- return 0;
-}
-
-#if defined __SUNPRO_CC
- #pragma enable_warn
-#elif defined _MSC_VER
- #pragma warning(pop)
-#endif
--- a/src/spectrogram.c
+++ b/src/spectrogram.c
@@ -186,7 +186,7 @@
size_t * isamp, size_t * osamp)
{
priv_t * p = (priv_t *)effp->priv;
- size_t len = min(*isamp, *osamp), dummy = 0; /* No need to clip count */
+ size_t len = min(*isamp, *osamp);
int i;
memcpy(obuf, ibuf, len * sizeof(*obuf)); /* Pass on audio unaffected */
@@ -193,7 +193,6 @@
*isamp = *osamp = len;
while (sox_true) {
- SOX_SAMPLE_LOCALS;
if (p->read == p->step_size) {
memmove(p->buf, p->buf + p->step_size,
(p->dft_size - p->step_size) * sizeof(*p->buf));
@@ -200,7 +199,7 @@
p->read = 0;
}
for (; len && p->read < p->step_size; --len, ++p->read, --p->end)
- p->buf[p->dft_size - p->step_size + p->read] = FROM_SOX(*ibuf++, dummy);
+ p->buf[p->dft_size - p->step_size + p->read] = FROM_SOX(*ibuf++);
if (p->read != p->step_size)
break;
@@ -494,7 +493,7 @@
sox_effect_handler_t const * sox_spectrogram_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "spectrogram", 0, 0, getopts, start, flow, drain, stop, 0, sizeof(priv_t)};
+ "spectrogram", 0, SOX_EFF_MODIFY, getopts, start, flow, drain, stop, 0, sizeof(priv_t)};
static char const * lines[] = {
"[options]",
"\t-x num\tX-axis pixels/second, default 100",
--- a/src/splice.c
+++ b/src/splice.c
@@ -185,7 +185,7 @@
break;
}
for (c = 0; c < effp->in_signal.channels; ++c)
- p->buffer[p->buffer_pos++] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
+ p->buffer[p->buffer_pos++] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++);
}
break;
}
--- a/src/stat.c
+++ b/src/stat.c
@@ -141,8 +141,7 @@
if (stat->fft) {
for (x = 0; x < len; x++) {
- SOX_SAMPLE_LOCALS;
- stat->re_in[stat->fft_offset++] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[x], effp->clips);
+ stat->re_in[stat->fft_offset++] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[x]);
if (stat->fft_offset >= stat->fft_size) {
stat->fft_offset = 0;
@@ -321,7 +320,7 @@
static sox_effect_handler_t sox_stat_effect = {
"stat",
"[ -s N ] [ -rms ] [-freq] [ -v ] [ -d ]",
- SOX_EFF_MCHAN,
+ SOX_EFF_MCHAN | SOX_EFF_MODIFY,
sox_stat_getopts,
sox_stat_start,
sox_stat_flow,
--- a/src/synth.c
+++ b/src/synth.c
@@ -168,7 +168,6 @@
char * length_str;
channel_t * getopts_channels;
size_t getopts_nchannels;
- sox_sample_t max;
size_t samples_done;
size_t samples_to_do;
channel_t * channels;
@@ -378,7 +377,6 @@
priv_t * synth = (priv_t *) effp->priv;
size_t i, j;
- synth->max = lsx_sample_max(effp->out_encoding);
synth->samples_done = 0;
if (synth->length_str)
@@ -438,9 +436,6 @@
return SOX_SUCCESS;
}
-
-
-#define sign(d) ((d) < 0? -1. : 1.)
#define elapsed_time_s synth->samples_done / effp->in_signal.rate
static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, sox_sample_t * obuf,
@@ -607,11 +602,12 @@
synth_out = synth_out * (1 - fabs(chan->offset)) + chan->offset;
switch (chan->combine) {
- case synth_create: *obuf++ = synth_out * synth->max; break;
- case synth_mix : *obuf++ = (synth_out * synth->max + synth_input) * 0.5; break;
- case synth_amod : *obuf++ = (synth_out + 1) * synth_input * 0.5; break;
- case synth_fmod : *obuf++ = synth_out * synth_input; break;
+ case synth_create: synth_out *= SOX_SAMPLE_MAX; break;
+ case synth_mix : synth_out = (synth_out * SOX_SAMPLE_MAX + synth_input) * 0.5; break;
+ case synth_amod : synth_out = (synth_out + 1) * synth_input * 0.5; break;
+ case synth_fmod : synth_out *= synth_input; break;
}
+ *obuf++ = floor(synth_out + .5);
}
if (++synth->samples_done == synth->samples_to_do)
result = SOX_EOF;
@@ -649,7 +645,7 @@
{
static sox_effect_handler_t handler = {
"synth", "[len] {type [combine] [[%]freq[k][:|+|/|-[%]freq2[k]] [off [ph [p1 [p2 [p3]]]]]]}",
- SOX_EFF_MCHAN | SOX_EFF_PREC |SOX_EFF_LENGTH,
+ SOX_EFF_MCHAN | SOX_EFF_PREC |SOX_EFF_LENGTH | SOX_EFF_GAIN,
getopts, start, flow, 0, stop, kill, sizeof(priv_t)
};
return &handler;
--- a/src/tempo.c
+++ b/src/tempo.c
@@ -272,7 +272,7 @@
if (*isamp && odone < *osamp) {
float * t = tempo_input(p->tempo, NULL, *isamp / effp->in_signal.channels);
for (i = *isamp; i; --i)
- *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
+ *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++);
tempo_process(p->tempo);
}
else *isamp = 0;
--- a/src/tests.sh
+++ b/src/tests.sh
@@ -200,8 +200,6 @@
# Run tests
-${builddir}/sox_sample_test || exit 1
-
skip_check caf flac mat4 mat5 paf w64 wv
vectors=0
--- a/src/trim.c
+++ b/src/trim.c
@@ -172,7 +172,7 @@
const sox_effect_handler_t *sox_trim_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "trim", "start [length]", SOX_EFF_MCHAN|SOX_EFF_LENGTH,
+ "trim", "start [length]", SOX_EFF_MCHAN | SOX_EFF_LENGTH | SOX_EFF_MODIFY,
sox_trim_getopts, sox_trim_start, sox_trim_flow,
NULL, NULL, kill, sizeof(priv_t)
};
--- a/src/util.c
+++ b/src/util.c
@@ -37,6 +37,12 @@
}
#endif
+sox_bool lsx_strends(char const * str, char const * end)
+{
+ size_t str_len = strlen(str), end_len = strlen(end);
+ return str_len >= end_len && !strcmp(str + str_len - end_len, end);
+}
+
char const * lsx_find_file_extension(char const * pathname)
{
/* First, chop off any path portions of filename. This
--- a/src/util.h
+++ b/src/util.h
@@ -31,14 +31,22 @@
#ifdef _MSC_VER
#define __STDC__ 1
-#define S_IFMT _S_IFMT
-#define S_IFREG _S_IFREG
#define O_BINARY _O_BINARY
+#define O_CREAT _O_CREAT
+#define O_RDWR _O_RDWR
+#define O_TRUNC _O_TRUNC
+#define S_IFMT _S_IFMT
+#define S_IFREG _S_IFREG
+#define S_IREAD _S_IREAD
+#define S_IWRITE _S_IWRITE
+#define fdopen _fdopen
#define fstat _fstat
#define ftime _ftime
#define inline __inline
#define isatty _isatty
+#define mktemp _mktemp
#define off_t _off_t
+#define open _open
#define popen _popen
#define stat _stat
#define strdup _strdup
@@ -91,6 +99,8 @@
#ifndef M_SQRT2
#define M_SQRT2 sqrt(2.)
#endif
+
+#define sign(x) ((x) < 0? -1 : 1)
/* Numerical Recipes in C, p. 284 */
#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
binary files a/src/vectors/intermediate1_44100_-u_-1_wav_-N.s1 b/src/vectors/intermediate1_44100_-u_-1_wav_-N.s1 differ
binary files a/src/vectors/intermediate1_44100_-u_-1_wav_-X.s1 b/src/vectors/intermediate1_44100_-u_-1_wav_-X.s1 differ
binary files a/src/vectors/intermediate1_44100_-u_-1_wav_-X_-N.s1 b/src/vectors/intermediate1_44100_-u_-1_wav_-X_-N.s1 differ
binary files a/src/vectors/intermediate1_44100_-u_-1_wav_.s1 b/src/vectors/intermediate1_44100_-u_-1_wav_.s1 differ
--- a/src/voc.c
+++ b/src/voc.c
@@ -347,7 +347,6 @@
/* Read the data in the file */
if (v->size <= 4) {
if (!v->adpcm.setup.sign) {
- SOX_SAMPLE_LOCALS;
if (lsx_readb(ft, &uc) == SOX_EOF) {
lsx_warn("VOC input: short file");
v->block_remaining = 0;
@@ -354,7 +353,7 @@
return done;
}
*buf = SOX_UNSIGNED_8BIT_TO_SAMPLE(uc,);
- lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf, ft->clips));
+ lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf));
++buf;
--v->block_remaining;
++done;
@@ -490,12 +489,11 @@
}
v->samples += len;
while (done < len) {
- SOX_SAMPLE_LOCALS;
if (ft->encoding.bits_per_sample == 8) {
- uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips);
+ uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++);
lsx_writeb(ft, uc);
} else {
- sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
+ sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
lsx_writesw(ft, sw);
}
done++;
--- a/src/vol.c
+++ b/src/vol.c
@@ -178,28 +178,7 @@
sox_effect_handler_t const * sox_vol_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "vol", vol_usage, SOX_EFF_MCHAN, getopts, start, flow, 0, stop, 0, sizeof(priv_t)
+ "vol", vol_usage, SOX_EFF_MCHAN | SOX_EFF_GAIN, getopts, start, flow, 0, stop, 0, sizeof(priv_t)
};
- return &handler;
-}
-
-static int gain_getopts(sox_effect_t * effp, int argc, char * * argv)
-{
- char * args[] = {0, 0, "dB"};
-
- if (argc != 2)
- return lsx_usage(effp);
- args[0] = argv[0];
- args[1] = argv[1];
- return sox_vol_effect_fn()->getopts(effp, (int)array_length(args), args);
-}
-
-sox_effect_handler_t const * sox_gain_effect_fn(void)
-{
- static sox_effect_handler_t handler;
- handler = *sox_vol_effect_fn();
- handler.name = "gain";
- handler.usage = "dB-gain";
- handler.getopts = gain_getopts;
return &handler;
}
--- a/src/wav.c
+++ b/src/wav.c
@@ -331,10 +331,9 @@
ft->sox_errno = SOX_SUCCESS;
while (done < len) {
- SOX_SAMPLE_LOCALS;
while ((wav->gsmindex < 160*2) && (done < len))
wav->gsmsample[(wav->gsmindex)++] =
- SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips);
+ SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]);
if (wav->gsmindex < 160*2)
break;
--- a/src/wavpack.c
+++ b/src/wavpack.c
@@ -120,14 +120,13 @@
int result;
for (i = 0; i < len; ++i) switch (ft->encoding.bits_per_sample) {
- SOX_SAMPLE_LOCALS;
- case 8: obuf[i] = SOX_SAMPLE_TO_SIGNED_8BIT(buf[i], ft->clips); break;
- case 16: obuf[i] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[i], ft->clips); break;
- case 24: obuf[i] = SOX_SAMPLE_TO_SIGNED_24BIT(buf[i], ft->clips) << 8;
+ case 8: obuf[i] = SOX_SAMPLE_TO_SIGNED_8BIT(buf[i]); break;
+ case 16: obuf[i] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[i]); break;
+ case 24: obuf[i] = SOX_SAMPLE_TO_SIGNED_24BIT(buf[i]) << 8;
obuf[i] >>= 8; break;
case 32: obuf[i] = ft->encoding.encoding == SOX_ENCODING_WAVPACKF?
- SOX_SAMPLE_TO_SIGNED_24BIT(*(float *)&buf[i], ft->clips) :
- SOX_SAMPLE_TO_SIGNED_32BIT(buf[i], ft->clips);
+ SOX_SAMPLE_TO_SIGNED_24BIT(*(float *)&buf[i]) :
+ SOX_SAMPLE_TO_SIGNED_32BIT(buf[i]);
break;
}
result = WavpackPackSamples(p->codec, obuf, (uint32_t) len / ft->signal.channels);