ref: 2bd648a7378ed4eba107c2ee60392575945ae3f1
parent: 1f70a30a0d51cfd6499c4d76be8a593a91fd5a3d
author: robs <robs>
date: Sat Jan 24 14:44:05 EST 2009
updates for --guard
--- a/ChangeLog
+++ b/ChangeLog
@@ -90,6 +90,7 @@
header (for simple encodings); instead, read to end of file. (robs)
o New `--temp DIRECTORY' option. (robs)
o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs)
+ o Automatically `dither'; new `--no-dither' option to disable this. (robs)
o New bitrate, time in seconds, & total options for soxi. (robs)
Other bug fixes:
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -1,4 +1,5 @@
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,6 +254,7 @@
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;
@@ -262,7 +263,7 @@
while(done < len) {
for (i = 0; i < ft->signal.channels; i++) {
- datum = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++);
+ datum = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++, ft->clips);
/* FIXME: Needs to pass ft struct and not FILE */
putc(datum, p->ch[i]);
}
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -62,6 +62,7 @@
)
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
+EXTRA_PROGRAMS = example0 example1 example2 sox_sample_test
lib_LTLIBRARIES = libsox.la
include_HEADERS = sox.h
nodist_include_HEADERS = soxstdint.h
@@ -37,6 +37,7 @@
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 #
@@ -399,7 +400,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 example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT)
+all: sox$(EXEEXT) play rec soxi sox_sample_test$(EXEEXT) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT)
play rec: sox$(EXEEXT)
if test "$(PLAYRECLINKS)" = "yes"; then \
@@ -429,6 +430,7 @@
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,7 +251,8 @@
short word;
while (count < length) {
- word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++);
+ SOX_SAMPLE_LOCALS;
+ word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++, ft->clips);
byte <<= 4;
byte |= lsx_adpcm_encode(word, &state->encoder) & 0x0F;
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -187,6 +187,7 @@
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);
@@ -193,38 +194,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++);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++, ft->clips);
break;
}
case SND_PCM_FORMAT_U8: {
uint8_t * buf1 = (uint8_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips);
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++));
+ *buf1++ = lsx_swapw(SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips));
else
- while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
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++));
+ *buf1++ = lsx_swapw(SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips));
else
- while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips);
break;
}
case SND_PCM_FORMAT_S24: {
int24_t * buf1 = (int24_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_24BIT(*buf++);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_24BIT(*buf++, ft->clips);
break;
}
case SND_PCM_FORMAT_U24: {
uint24_t * buf1 = (uint24_t *)p->buf;
- while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_24BIT(*buf++);
+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_24BIT(*buf++, ft->clips);
break;
}
}
--- a/src/amr.h
+++ b/src/amr.h
@@ -117,7 +117,8 @@
size_t done;
for (done = 0; done < len; ++done) {
- p->pcm[p->pcm_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
+ SOX_SAMPLE_LOCALS;
+ p->pcm[p->pcm_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
if (p->pcm_index == AMR_FRAME) {
p->pcm_index = 0;
if (!encode_1_frame(ft))
--- a/src/ao.c
+++ b/src/ao.c
@@ -74,11 +74,12 @@
return SOX_SUCCESS;
}
-static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, size_t len, sox_bool swap)
+static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, size_t len, sox_bool swap, size_t * clips)
{
while (len--)
{
- uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++);
+ SOX_SAMPLE_LOCALS;
+ uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++, *clips);
if (swap)
datum = lsx_swapw(datum);
*(uint16_t *)buf1 = datum;
@@ -96,7 +97,8 @@
aobuf_size = (ft->encoding.bits_per_sample >> 3) * len;
- sox_sw_write_buf(ao->buf, buf, len, ft->encoding.reverse_bytes);
+ sox_sw_write_buf(ao->buf, buf, len, ft->encoding.reverse_bytes,
+ &(ft->clips));
if (ao_play(ao->device, (void *)ao->buf, aobuf_size) == 0)
return 0;
--- 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]);
+ p->gInFIFO[p->gRover] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(
p->gOutFIFO[p->gRover - inFifoLatency], effp->clips);
p->gRover++;
--- 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++);
+ *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++, ft->clips);
ac->buf_offset += len;
--- a/src/dat.c
+++ b/src/dat.c
@@ -135,7 +135,8 @@
sprintf(s," %15.8g ",dat->timevalue);
lsx_writes(ft, s);
for (i=0; i<ft->signal.channels; i++) {
- sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++);
+ SOX_SAMPLE_LOCALS;
+ sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++, ft->clips);
sprintf(s," %15.8g", sampval);
lsx_writes(ft, s);
done++;
--- a/src/delay.c
+++ b/src/delay.c
@@ -119,7 +119,7 @@
sox_effect_handler_t const * sox_delay_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "delay", "{length}", SOX_EFF_LENGTH,
+ "delay", "{length}", SOX_EFF_LENGTH | SOX_EFF_MODIFY,
create, start, flow, drain, stop, kill, sizeof(priv_t)
};
return &handler;
--- 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++);
+ *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
filter(p);
}
else *isamp = 0;
--- a/src/dither.c
+++ b/src/dither.c
@@ -23,7 +23,12 @@
#include "getopt.h"
#include <assert.h>
-#define PREC effp->out_signal.precision
+#undef RANQD1
+#define RANQD1 ranqd1(p->ranqd1)
+#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-p->prec)) + 0.5? \
+ ++(clips), SOX_SAMPLE_MAX - (1 << (31-p->prec)): (d) + 0.5)
typedef enum {Pdf_rectangular, Pdf_triangular, Pdf_gaussian} pdf_type_t;
static lsx_enum_item const pdf_types[] = {
@@ -130,7 +135,7 @@
{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.6, shi44, Shape_shibata},
+ {44100, fir, 20, 32.3, 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},
@@ -145,12 +150,13 @@
typedef struct {
pdf_type_t pdf;
filter_name_t filter_name;
+ sox_bool reseed;
double am0, am1, depth;
double previous_errors[MAX_N * 2];
double previous_outputs[MAX_N * 2];
- size_t pos;
+ size_t pos, prec;
+ int32_t ranqd1;
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;
@@ -186,7 +192,7 @@
size_t len = *isamp = *osamp = min(*isamp, *osamp);
while (len--) {
- double d = *ibuf++ + p->offset + floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1);
+ double d = *ibuf++ + floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1);
SOX_SAMPLE_CLIP_COUNT(d, effp->clips);
*obuf++ = d;
}
@@ -199,7 +205,8 @@
int c;
p->pdf = Pdf_triangular;
- while ((c = getopt(argc, argv, "+rtsf:")) != -1) switch (c) {
+ while ((c = getopt(argc, argv, "+Rrtsf:")) != -1) switch (c) {
+ case 'R': p->reseed = sox_true; break;
case 'r': p->pdf = Pdf_rectangular; break;
case 't': p->pdf = Pdf_triangular ; break;
case 's': p->filter_name = Shape_shibata; break;
@@ -221,8 +228,10 @@
priv_t * p = (priv_t *)effp->priv;
double mult = 1;
- if (PREC > 24)
+ p->prec = effp->out_signal.precision;
+ if (effp->in_signal.precision <= p->prec || p->prec > 24)
return SOX_EFF_NULL; /* Dithering not needed at this resolution */
+ effp->out_signal.precision = effp->in_signal.precision;
p->flow = flow_no_shape;
if (p->filter_name) {
@@ -249,14 +258,12 @@
mult = dB_to_linear(f->gain);
}
}
- p->am1 = p->depth / (1 << PREC);
+ p->ranqd1 = p->reseed? ranqd1(sox_globals.ranqd1) : 0;
+ p->am1 = p->depth / (1 << p->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->offset * (1./SOX_SAMPLE_MAX) + p->am0 + p->am1) * mult;
+ if (effp->in_signal.mult)
+ *effp->in_signal.mult *= 1 - (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;
@@ -273,6 +280,7 @@
{
static sox_effect_handler_t handler = {
"dither", "[-r|-t] [-s|-f filter] [depth]"
+ "\n -R Re-seed PRNG"
"\n -r Rectangular PDF"
"\n -t Triangular PDF (default)"
"\n -s Shape noise (with shibata filter)"
--- 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++ + p->offset;
+ double error, d = *ibuf++;
int j = 0;
CONVOLVE
assert(j == N);
- *obuf = SOX_ROUND_CLIP_COUNT(d + r, effp->clips);
- error = (*obuf++ & (-1 << (32-PREC))) + (1 << (31-PREC)) - d;
+ *obuf = SOX_ROUND_PREC_CLIP_COUNT(d + r, effp->clips);
+ error = ((*obuf++ + (1 << (31-p->prec))) & (-1 << (32-p->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++ + p->offset - output;
- *obuf = SOX_ROUND_CLIP_COUNT(d + r, effp->clips);
- error = (*obuf++ & (-1 << (32-PREC))) + (1 << (31-PREC)) - d;
+ d = *ibuf++ - output;
+ *obuf = SOX_ROUND_PREC_CLIP_COUNT(d + r, effp->clips);
+ error = ((*obuf++ + (1 << (31-p->prec))) & (-1 << (32-p->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/effects.c
+++ b/src/effects.c
@@ -94,7 +94,7 @@
/* Effects chain: */
sox_effects_chain_t * sox_create_effects_chain(
- sox_encodinginfo_t const * in_enc, sox_encodinginfo_t * out_enc)
+ sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)
{
sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
result->global_info = sox_effects_globals;
@@ -144,7 +144,8 @@
if (!(effp->handler.flags & SOX_EFF_RATE))
effp->out_signal.rate = in->rate;
if (!(effp->handler.flags & SOX_EFF_PREC))
- effp->out_signal.precision = in->precision;
+ effp->out_signal.precision = (effp->handler.flags & SOX_EFF_MODIFY)?
+ in->precision : SOX_SAMPLE_PRECISION;
if (!(effp->handler.flags & SOX_EFF_GAIN))
effp->out_signal.mult = in->mult;
@@ -152,8 +153,8 @@
(effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
effp->clips = 0;
effp->imin = 0;
- eff0 = *effp;
- eff0.priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+ eff0 = *effp, eff0.priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+ eff0.in_signal.mult = NULL; /* Only used in channel 0 */
ret = start(effp);
if (ret == SOX_EFF_NULL) {
lsx_report("has no effect in this configuration");
--- a/src/example2.c
+++ b/src/example2.c
@@ -87,9 +87,10 @@
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]);
+ 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,8 +406,9 @@
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]);
+ ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread], ft->clips);
}
/* If output frame full or no more data to read, write it out */
--- a/src/flac.c
+++ b/src/flac.c
@@ -441,21 +441,22 @@
unsigned i;
for (i = 0; i < len; ++i) {
- long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]);
+ SOX_SAMPLE_LOCALS;
+ long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips);
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]);
+ SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
break;
case 16: p->decoded_samples[i] =
- SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i]);
+ SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
break;
case 24: p->decoded_samples[i] = /* sign extension: */
- SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i]) << 8;
+ SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8;
p->decoded_samples[i] >>= 8;
break;
case 32: p->decoded_samples[i] =
- SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]);
+ SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
break;
}
}
--- a/src/formats_i.c
+++ b/src/formats_i.c
@@ -175,6 +175,7 @@
void lsx_clearerr(sox_format_t * ft)
{
clearerr(ft->fp);
+ ft->sox_errno = 0;
}
int lsx_unreadb(sox_format_t * ft, unsigned b)
--- a/src/gain.c
+++ b/src/gain.c
@@ -21,13 +21,11 @@
#include <string.h>
typedef struct {
- sox_bool do_equalise, do_balance, do_balance_no_clip;
+ sox_bool do_equalise, do_balance, do_balance_no_clip, do_limiter;
sox_bool do_restore, make_headroom, do_normalise, do_scan;
double fixed_gain; /* Valid only in channel 0 */
- double mult;
- double restore;
- double rms;
+ double mult, restore, rms, limiter;
off_t num_samples;
sox_sample_t min, max;
FILE * tmp_file;
@@ -46,6 +44,7 @@
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;
+ case 'l': p->do_limiter = 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) {
@@ -56,6 +55,10 @@
lsx_fail("Only one of -n, -r may be given");
return SOX_EOF;
}
+ if (p->do_limiter && p->make_headroom) {
+ lsx_fail("Only one of -l, -h 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;
@@ -85,6 +88,10 @@
return SOX_EOF;
}
}
+ if (p->do_limiter)
+ p->limiter = (1 - 1 / p->fixed_gain) * (1. / SOX_SAMPLE_MAX);
+ else if (p->fixed_gain == floor(p->fixed_gain) && !p->do_scan)
+ effp->out_signal.precision = effp->in_signal.precision;
return SOX_SUCCESS;
}
@@ -92,6 +99,7 @@
sox_sample_t * obuf, size_t * isamp, size_t * osamp)
{
priv_t * p = (priv_t *)effp->priv;
+ SOX_SAMPLE_LOCALS;
size_t len;
if (p->do_scan) {
@@ -101,13 +109,13 @@
}
if (p->do_balance && !p->do_normalise)
for (len = *isamp; len; --len, ++ibuf) {
- double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf);
+ double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf, effp->clips);
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);
+ double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf, effp->clips);
p->rms += sqr(d);
++p->num_samples;
p->max = max(p->max, *ibuf);
@@ -122,8 +130,13 @@
else {
double mult = ((priv_t *)(effp - effp->flow)->priv)->fixed_gain;
len = *isamp = *osamp = min(*isamp, *osamp);
- for (; len; --len, ++ibuf)
+ if (!p->do_limiter) for (; len; --len, ++ibuf)
*obuf++ = SOX_ROUND_CLIP_COUNT(*ibuf * mult, effp->clips);
+ else for (; len; --len, ++ibuf) {
+ double d = *ibuf * mult;
+ *obuf++ = d < 0 ? 1 / (1 / d - p->limiter) - .5 :
+ d > 0 ? 1 / (1 / d + p->limiter) + .5 : 0;
+ }
}
return SOX_SUCCESS;
}
@@ -191,10 +204,13 @@
lsx_fail("error reading temporary file: %s", strerror(errno));
result = SOX_EOF;
}
- if (p->mult > 1) for (*osamp = len; len; --len, ++obuf)
+ if (!p->do_limiter) 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 for (*osamp = len; len; --len) {
+ double d = *obuf * p->mult;
+ *obuf++ = d < 0 ? 1 / (1 / d - p->limiter) - .5 :
+ d > 0 ? 1 / (1 / d + p->limiter) + .5 : 0;
+ }
}
else *osamp = 0;
return result;
@@ -211,7 +227,7 @@
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,
+ "gain", "[-e|-b|-B|-r] [-n] [-l|-h] [gain-dB]", SOX_EFF_GAIN,
create, start, flow, drain, stop, NULL, sizeof(priv_t)};
return &handler;
}
--- a/src/gsm.c
+++ b/src/gsm.c
@@ -195,9 +195,10 @@
while (done < samp)
{
+ SOX_SAMPLE_LOCALS;
while ((p->samplePtr < p->sampleTop) && (done < samp))
*(p->samplePtr)++ =
- SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]);
+ SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips);
if (p->samplePtr == p->sampleTop)
{
--- a/src/hcom.c
+++ b/src/hcom.c
@@ -277,8 +277,9 @@
}
for (i = 0; i < len; i++) {
+ SOX_SAMPLE_LOCALS;
datum = *buf++;
- p->data[p->pos++] = SOX_SAMPLE_TO_UNSIGNED_8BIT(datum);
+ p->data[p->pos++] = SOX_SAMPLE_TO_UNSIGNED_8BIT(datum, ft->clips);
}
return len;
--- a/src/lpc10.c
+++ b/src/lpc10.c
@@ -179,7 +179,8 @@
while (len > 0) {
while (len > 0 && lpc->samples < LPC10_SAMPLES_PER_FRAME) {
- lpc->speech[lpc->samples++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf[nwritten++]);
+ SOX_SAMPLE_LOCALS;
+ lpc->speech[lpc->samples++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf[nwritten++], ft->clips);
len--;
}
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -546,11 +546,13 @@
static sox_effect_handler_t handler = {
"mixer",
"[ -l | -r | -f | -b | -1 | -2 | -3 | -4 | n,n,n...,n ]",
- SOX_EFF_MCHAN | SOX_EFF_CHAN,
+ SOX_EFF_MCHAN | SOX_EFF_CHAN | SOX_EFF_GAIN,
getopts, start, flow, 0, 0, 0, sizeof(priv_t)
};
return &handler;
}
+
+/*------------------------------- oops effect --------------------------------*/
static int oops_getopts(sox_effect_t * effp, int argc, char * * argv)
{
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -406,6 +406,7 @@
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
@@ -434,8 +435,8 @@
j=0;
for (i=0; i<nsamples; i++)
{
- buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]);
- buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]);
+ buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
+ buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
}
}
else
@@ -442,7 +443,7 @@
{
j=0;
for (i=0; i<nsamples; i++)
- buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]);
+ buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
}
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);
+ size_t samp = min(*isamp, *osamp), dummy = 0; /* No need to clip count */
size_t chans = effp->in_signal.channels;
size_t i, j, n = min(samp / chans, WINDOWSIZE - p->bufdata);
@@ -125,10 +125,11 @@
/* 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]);
+ SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + j * chans], dummy);
if (n + p->bufdata == WINDOWSIZE)
collect_data(chan);
}
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -285,6 +285,7 @@
/* Reduce noise on every channel. */
for (i = 0; i < tracks; i ++) {
+ SOX_SAMPLE_LOCALS;
chandata_t* chan = &(data->chandata[i]);
size_t j;
@@ -293,7 +294,7 @@
for (j = 0; j < ncopy; j ++)
chan->window[oldbuf + j] =
- SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + tracks * j]);
+ SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + tracks * j], effp->clips);
if (!whole_window)
continue;
--- 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++), d0 = d;
+ double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, dummy), d0 = d;
d *= p->gain;
d += p->colour;
d = d < -1? -2./3 : d > 1? 2./3 : d - d * d * d * (1./3);
--- a/src/pad.c
+++ b/src/pad.c
@@ -135,7 +135,7 @@
sox_effect_handler_t const * sox_pad_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "pad", "{length[@position]}", SOX_EFF_MCHAN|SOX_EFF_LENGTH,
+ "pad", "{length[@position]}", SOX_EFF_MCHAN|SOX_EFF_LENGTH|SOX_EFF_MODIFY,
create, start, flow, drain, stop, kill, sizeof(priv_t)
};
return &handler;
--- a/src/rate.c
+++ b/src/rate.c
@@ -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++);
+ for (i = *isamp; i; --i) *t++ = FROM_SOX(*ibuf++,);
rate_process(&p->rate);
}
else *isamp = 0;
--- a/src/raw.c
+++ b/src/raw.c
@@ -12,10 +12,12 @@
typedef uint16_t uint14_t;
typedef uint16_t uint13_t;
+typedef int16_t int14_t;
+typedef int16_t int13_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) 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)
+#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)
int lsx_rawseek(sox_format_t * ft, uint64_t offset)
{
@@ -95,10 +97,11 @@
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]); \
+ data[n] = cast(buf[n], ft->clips); \
nwritten = lsx_write_ ## type ## _buf(ft, (uctype *)data, len); \
free(data); \
return nwritten; \
--- a/src/remix.c
+++ b/src/remix.c
@@ -95,19 +95,6 @@
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;
}
@@ -125,11 +112,29 @@
static int start(sox_effect_t * effp)
{
priv_t * p = (priv_t *)effp->priv;
+ double max_sum = 0;
+ unsigned i, j;
+ int non_integer = 0;
+
parse(effp, NULL, effp->in_signal.channels);
if (effp->in_signal.channels < p->min_in_channels) {
lsx_fail("too few input channels");
return SOX_EOF;
}
+
+ for (j = 0; j < effp->out_signal.channels; j++) {
+ double sum = 0;
+ for (i = 0; i < p->out_specs[j].num_in_channels; i++) {
+ double mult = p->out_specs[j].in_specs[i].multiplier;
+ sum += fabs(mult);
+ non_integer += floor(mult) != mult;
+ }
+ max_sum = max(max_sum, sum);
+ }
+ if (effp->in_signal.mult && max_sum > 1)
+ *effp->in_signal.mult /= max_sum;
+ if (!non_integer)
+ effp->out_signal.precision = effp->in_signal.precision;
return SOX_SUCCESS;
}
@@ -167,7 +172,7 @@
{
static sox_effect_handler_t handler = {
"remix", "[-m|-a] [-p] <0|in-chan[v|d|i volume]{,in-chan[v|d|i volume]}>",
- SOX_EFF_MCHAN | SOX_EFF_CHAN, create, start, flow, NULL, NULL, kill, sizeof(priv_t)
+ SOX_EFF_MCHAN | SOX_EFF_CHAN | SOX_EFF_GAIN, create, start, flow, NULL, NULL, kill, sizeof(priv_t)
};
return &handler;
}
--- a/src/repeat.c
+++ b/src/repeat.c
@@ -93,7 +93,8 @@
sox_effect_handler_t const * sox_repeat_effect_fn(void)
{
- static sox_effect_handler_t effect = {"repeat", "[count]", SOX_EFF_MCHAN |
- SOX_EFF_LENGTH, create, start, flow, drain, stop, NULL, sizeof(priv_t)};
+ static sox_effect_handler_t effect = {"repeat", "[count]",
+ SOX_EFF_MCHAN | SOX_EFF_LENGTH | SOX_EFF_MODIFY,
+ create, start, flow, drain, stop, NULL, sizeof(priv_t)};
return &effect;
}
--- a/src/reverb.c
+++ b/src/reverb.c
@@ -229,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++);
+ p->chan[c].dry[i] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
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/reverse.c
+++ b/src/reverse.c
@@ -80,7 +80,7 @@
sox_effect_handler_t const * sox_reverse_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "reverse", NULL, 0, NULL, start, flow, drain, stop, NULL, sizeof(priv_t)
+ "reverse", NULL, SOX_EFF_MODIFY, NULL, start, flow, drain, stop, NULL, sizeof(priv_t)
};
return &handler;
}
--- a/src/silence.c
+++ b/src/silence.c
@@ -275,25 +275,27 @@
{
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);
+ value = SOX_SAMPLE_TO_SIGNED_8BIT(value, dummy_clipped_count);
ratio = (double)abs(value) / (double)SOX_INT8_MAX;
break;
case 16:
- value = SOX_SAMPLE_TO_SIGNED_16BIT(value);
+ value = SOX_SAMPLE_TO_SIGNED_16BIT(value, dummy_clipped_count);
ratio = (double)abs(value) / (double)SOX_INT16_MAX;
break;
case 24:
- value = SOX_SAMPLE_TO_SIGNED_24BIT(value);
+ value = SOX_SAMPLE_TO_SIGNED_24BIT(value, dummy_clipped_count);
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:
@@ -686,7 +688,7 @@
static sox_effect_handler_t sox_silence_effect = {
"silence",
"[ -l ] above_periods [ duration thershold[d|%%] ] [ below_periods duration threshold[d|%%]]",
- SOX_EFF_MCHAN,
+ SOX_EFF_MCHAN | SOX_EFF_MODIFY,
sox_silence_getopts,
sox_silence_start,
sox_silence_flow,
--- a/src/skelform.c
+++ b/src/skelform.c
@@ -159,8 +159,9 @@
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++)) == SOX_SUCCESS)
+ while (done < len && lsx_writeb(ft, SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips)) == SOX_SUCCESS)
++done;
break;
default:
--- a/src/smp.c
+++ b/src/smp.c
@@ -368,7 +368,8 @@
size_t done = 0;
while(done < len) {
- datum = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
+ SOX_SAMPLE_LOCALS;
+ datum = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
lsx_writew(ft, (uint16_t)datum);
smp->NoOfSamps++;
done++;
--- a/src/sox.c
+++ b/src/sox.c
@@ -133,7 +133,6 @@
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;
@@ -198,7 +197,7 @@
static struct termios original_termios;
#endif
-static sox_bool stdin_is_a_tty, is_player, is_guarded, do_guarded_norm;
+static sox_bool stdin_is_a_tty, is_player, is_guarded, do_guarded_norm, no_dither;
/* Cleanup atexit() function, hence always called. */
static void cleanup(void)
@@ -405,8 +404,6 @@
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;
@@ -428,10 +425,8 @@
{
size_t s = ws * f->ft->signal.channels;
- 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);
+ if (f->volume != 1) while (s--) {
+ double d = f->volume * *buf;
*buf++ = SOX_ROUND_CLIP_COUNT(d, f->volume_clips);
}
}
@@ -552,8 +547,8 @@
static sox_effect_handler_t const * input_combiner_effect_fn(void)
{
- static sox_effect_handler_t handler = {
- "input", 0, SOX_EFF_MCHAN, 0, combiner_start, 0, combiner_drain,
+ static sox_effect_handler_t handler = { "input", 0, SOX_EFF_MCHAN |
+ SOX_EFF_MODIFY, 0, combiner_start, 0, combiner_drain,
combiner_stop, 0, sizeof(input_combiner_t)
};
return &handler;
@@ -561,9 +556,9 @@
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);
+ unsigned prec = effp->out_signal.precision;
+ if (effp->in_signal.mult && effp->in_signal.precision > prec)
+ *effp->in_signal.mult *= 1 - (1 << (31 - prec)) * (1. / SOX_SAMPLE_MAX);
return SOX_SUCCESS;
}
@@ -570,13 +565,9 @@
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]);
@@ -604,8 +595,8 @@
static sox_effect_handler_t const * output_effect_fn(void)
{
- static sox_effect_handler_t handler = {
- "output", 0, SOX_EFF_MCHAN, NULL, ostart, output_flow, NULL, NULL, NULL, 0
+ static sox_effect_handler_t handler = {"output", 0, SOX_EFF_MCHAN |
+ SOX_EFF_MODIFY | SOX_EFF_PREC, NULL, ostart, output_flow, NULL, NULL, NULL, 0
};
return &handler;
}
@@ -978,13 +969,15 @@
guard = 1;
}
+ if (i == nuser_effects[current_eff_chain] && !no_dither && signal.precision >
+ ofile->ft->signal.precision && ofile->ft->signal.precision <= 24)
+ auto_effect(chain, "dither", 0, NULL, &signal, &guard);
+
/* Add user specified effects from `dither' onwards */
- for (; i < nuser_effects[current_eff_chain]; i++, guard = 2) {
+ 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)
{
@@ -1740,6 +1733,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",
+"-D, --no-dither Don't dither automatically",
"-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",
@@ -1779,7 +1773,6 @@
"-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",
@@ -1937,7 +1930,7 @@
free(text);
}
-static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:GLMNRSTUV::X012348";
+static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:DGLMNRSTUV::X12348";
static struct option long_options[] =
{
@@ -1966,6 +1959,7 @@
{"channels" , required_argument, NULL, 'c'},
{"compression" , required_argument, NULL, 'C'},
{"default-device" , no_argument, NULL, 'd'},
+ {"no-dither" , no_argument, NULL, 'D'},
{"encoding" , required_argument, NULL, 'e'},
{"help" , no_argument, NULL, 'h'},
{"null" , no_argument, NULL, 'n'},
@@ -2166,8 +2160,6 @@
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);
@@ -2259,6 +2251,7 @@
case 'S': show_progress = SOX_OPTION_YES; break;
case 'q': show_progress = SOX_OPTION_NO; break;
+ case 'D': no_dither = sox_true; break;
case 'V':
if (optarg == NULL)
--- a/src/sox.h
+++ b/src/sox.h
@@ -12,7 +12,6 @@
#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>
@@ -76,32 +75,36 @@
/* Conversions: Linear PCM <--> sox_sample_t
*
- * 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
+ * I/O Input sox_sample_t Clips? Input sox_sample_t Clips?
+ * Format Minimum Minimum I O Maximum Maximum I O
+ * ------ --------- ------------ -- -- -------- ------------ -- --
+ * Float -inf -1 y n inf 1 - 5e-10 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
*
* Conversions are as accurate as possible (with rounding).
*
* Rounding: halves toward +inf, all others to nearest integer.
*
- * The only possibility of clipping on conversion is when inputting Float.
+ * 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.
*
* 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 double sox_macro_temp_double UNUSED
+#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample UNUSED; \
+ double sox_macro_temp_double UNUSED
#define SOX_SAMPLE_NEG SOX_INT_MIN(32)
-#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_SAMPLE_TO_UNSIGNED(bits,d,clips) \
+ (uint##bits##_t)(SOX_SAMPLE_TO_SIGNED(bits,d,clips)^SOX_INT_MIN(bits))
+#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \
+ (int##bits##_t)(sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-(1<<(31-bits))?++(clips),SOX_INT_MAX(bits):((uint32_t)(sox_macro_temp_sample+(1<<(31-bits))))>>(32-bits))
+#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-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)
@@ -112,18 +115,18 @@
#define SOX_SIGNED_24BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(24,d)
#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_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) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
+#define SOX_FLOAT_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),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.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double)
+#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_sample_t)(sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<0?sox_macro_temp_double<=SOX_SAMPLE_MIN-.5?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double-.5:sox_macro_temp_double>=SOX_SAMPLE_MAX+.5?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double+.5)
+#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_SAMPLE_TO_FLOAT_32BIT(d,clips) (sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-128?++(clips),1:(((sox_macro_temp_sample+128)&~255)*(1./(SOX_SAMPLE_MAX+1.))))
+#define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
@@ -243,7 +246,6 @@
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
@@ -504,11 +506,11 @@
sox_sample_t **ibufc, **obufc; /* Channel interleave buffers */
sox_effects_globals_t global_info;
sox_encodinginfo_t const * in_enc;
- sox_encodinginfo_t * out_enc;
+ sox_encodinginfo_t const * 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 * out_enc);
+ sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * 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));
--- a/src/spectrogram.c
+++ b/src/spectrogram.c
@@ -193,6 +193,7 @@
*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));
@@ -199,7 +200,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++);
+ p->buf[p->dft_size - p->step_size + p->read] = FROM_SOX(*ibuf++,);
if (p->read != p->step_size)
break;
--- 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++);
+ p->buffer[p->buffer_pos++] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
}
break;
}
--- a/src/stat.c
+++ b/src/stat.c
@@ -141,7 +141,8 @@
if (stat->fft) {
for (x = 0; x < len; x++) {
- stat->re_in[stat->fft_offset++] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[x]);
+ SOX_SAMPLE_LOCALS;
+ stat->re_in[stat->fft_offset++] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[x], effp->clips);
if (stat->fft_offset >= stat->fft_size) {
stat->fft_offset = 0;
--- a/src/swap.c
+++ b/src/swap.c
@@ -181,7 +181,7 @@
const sox_effect_handler_t *sox_swap_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "swap", "[1 2 | 1 2 3 4]", SOX_EFF_MCHAN,
+ "swap", "[1 2 | 1 2 3 4]", SOX_EFF_MCHAN | SOX_EFF_MODIFY,
sox_swap_getopts, sox_swap_start, sox_swap_flow,
NULL, NULL, NULL, sizeof(priv_t)
};
--- a/src/synth.c
+++ b/src/synth.c
@@ -1,7 +1,7 @@
/* libSoX synth - Synthesizer Effect.
*
+ * Copyright (c) 2001-2009 SoX contributors
* Copyright (c) Jan 2001 Carsten Borchardt
- * Copyright (c) 2001-2008 SoX contributors
*
* This source code is freely redistributable and may be used for any purpose.
* This copyright notice must be maintained. The authors are not responsible
@@ -166,12 +166,14 @@
/* Private data for the synthesizer */
typedef struct {
char * length_str;
- channel_t * getopts_channels;
- size_t getopts_nchannels;
- size_t samples_done;
- size_t samples_to_do;
- channel_t * channels;
- size_t number_of_channels;
+ channel_t * getopts_channels;
+ size_t getopts_nchannels;
+ size_t samples_done;
+ size_t samples_to_do;
+ channel_t * channels;
+ size_t number_of_channels;
+ sox_bool no_headroom;
+ double gain;
} priv_t;
@@ -263,17 +265,19 @@
static int getopts(sox_effect_t * effp, int argc, char **argv)
{
- priv_t * synth = (priv_t *) effp->priv;
+ priv_t * p = (priv_t *) effp->priv;
channel_t master, * chan = &master;
int argn = 0;
--argc, ++argv;
+ if (argc && !strcmp(*argv, "-n")) p->no_headroom = sox_true, ++argv, --argc;
+
/* Get duration if given (if first arg starts with digit) */
if (argc && (isdigit((int)argv[argn][0]) || argv[argn][0] == '.')) {
- synth->length_str = lsx_malloc(strlen(argv[argn]) + 1);
- strcpy(synth->length_str, argv[argn]);
+ p->length_str = lsx_malloc(strlen(argv[argn]) + 1);
+ strcpy(p->length_str, argv[argn]);
/* Do a dummy parse of to see if it will fail */
- if (lsx_parsesamples(0., synth->length_str, &synth->samples_to_do, 't') == NULL)
+ if (lsx_parsesamples(0., p->length_str, &p->samples_to_do, 't') == NULL)
return lsx_usage(effp);
argn++;
}
@@ -291,23 +295,23 @@
while (argn < argc) { /* type [combine] [f1[-f2] [off [ph [p1 [p2 [p3]]]]]] */
char * end_ptr;
- lsx_enum_item const *p = lsx_find_enum_text(argv[argn], synth_type);
+ lsx_enum_item const *enum_p = lsx_find_enum_text(argv[argn], synth_type);
- if (p == NULL) {
+ if (enum_p == NULL) {
lsx_fail("no type given");
return SOX_EOF;
}
- synth->getopts_channels = lsx_realloc(synth->getopts_channels, sizeof(*synth->getopts_channels) * (synth->getopts_nchannels + 1));
- chan = &synth->getopts_channels[synth->getopts_nchannels++];
+ p->getopts_channels = lsx_realloc(p->getopts_channels, sizeof(*p->getopts_channels) * (p->getopts_nchannels + 1));
+ chan = &p->getopts_channels[p->getopts_nchannels++];
memcpy(chan, &master, sizeof(*chan));
- chan->type = p->value;
+ chan->type = enum_p->value;
if (++argn == argc)
break;
/* maybe there is a combine-type in next arg */
- p = lsx_find_enum_text(argv[argn], combine_type);
- if (p != NULL) {
- chan->combine = p->value;
+ enum_p = lsx_find_enum_text(argv[argn], combine_type);
+ if (enum_p != NULL) {
+ chan->combine = enum_p->value;
if (++argn == argc)
break;
}
@@ -329,7 +333,7 @@
lsx_fail("invalid freq2");
return SOX_EOF;
}
- if (synth->length_str == NULL) {
+ if (p->length_str == NULL) {
lsx_fail("duration must be given when using freq2");
return SOX_EOF;
}
@@ -358,14 +362,14 @@
}
/* If no channel parameters were given, create one default channel: */
- if (!synth->getopts_nchannels) {
- synth->getopts_channels = lsx_malloc(sizeof(*synth->getopts_channels));
- memcpy(&synth->getopts_channels[0], &master, sizeof(channel_t));
- ++synth->getopts_nchannels;
+ if (!p->getopts_nchannels) {
+ p->getopts_channels = lsx_malloc(sizeof(*p->getopts_channels));
+ memcpy(&p->getopts_channels[0], &master, sizeof(channel_t));
+ ++p->getopts_nchannels;
}
if (!effp->in_signal.channels)
- effp->in_signal.channels = synth->getopts_nchannels;
+ effp->in_signal.channels = p->getopts_nchannels;
return SOX_SUCCESS;
}
@@ -374,20 +378,20 @@
static int start(sox_effect_t * effp)
{
- priv_t * synth = (priv_t *) effp->priv;
+ priv_t * p = (priv_t *)effp->priv;
size_t i, j;
- synth->samples_done = 0;
+ p->samples_done = 0;
- if (synth->length_str)
- if (lsx_parsesamples(effp->in_signal.rate, synth->length_str, &synth->samples_to_do, 't') == NULL)
+ if (p->length_str)
+ if (lsx_parsesamples(effp->in_signal.rate, p->length_str, &p->samples_to_do, 't') == NULL)
return lsx_usage(effp);
- synth->number_of_channels = effp->in_signal.channels;
- synth->channels = lsx_calloc(synth->number_of_channels, sizeof(*synth->channels));
- for (i = 0; i < synth->number_of_channels; ++i) {
- channel_t * chan = &synth->channels[i];
- *chan = synth->getopts_channels[i % synth->getopts_nchannels];
+ p->number_of_channels = effp->in_signal.channels;
+ p->channels = lsx_calloc(p->number_of_channels, sizeof(*p->channels));
+ for (i = 0; i < p->number_of_channels; ++i) {
+ channel_t * chan = &p->channels[i];
+ *chan = p->getopts_channels[i % p->getopts_nchannels];
set_default_parameters(chan, i);
if (chan->type == synth_pluck) {
int32_t r = 0;
@@ -410,20 +414,20 @@
lsx_debug("a=%g colour=%g", a, 1/colour);
}
switch (chan->sweep) {
- case Linear: chan->mult = synth->samples_to_do?
- (chan->freq2 - chan->freq) / synth->samples_to_do / 2 : 0;
+ case Linear: chan->mult = p->samples_to_do?
+ (chan->freq2 - chan->freq) / p->samples_to_do / 2 : 0;
break;
- case Square: chan->mult = synth->samples_to_do?
- sqrt(fabs(chan->freq2 - chan->freq)) / synth->samples_to_do / sqrt(3.) : 0;
+ case Square: chan->mult = p->samples_to_do?
+ sqrt(fabs(chan->freq2 - chan->freq)) / p->samples_to_do / sqrt(3.) : 0;
if (chan->freq > chan->freq2)
chan->mult = -chan->mult;
break;
- case Exp: chan->mult = synth->samples_to_do?
- log(chan->freq2 / chan->freq) / synth->samples_to_do * effp->in_signal.rate : 1;
+ case Exp: chan->mult = p->samples_to_do?
+ log(chan->freq2 / chan->freq) / p->samples_to_do * effp->in_signal.rate : 1;
chan->freq /= chan->mult;
break;
- case Exp_cycle: chan->mult = synth->samples_to_do?
- (log(chan->freq2) - log(chan->freq)) / synth->samples_to_do : 1;
+ case Exp_cycle: chan->mult = p->samples_to_do?
+ (log(chan->freq2) - log(chan->freq)) / p->samples_to_do : 1;
break;
}
lsx_debug("type=%s, combine=%s, samples_to_do=%lu, f1=%g, f2=%g, "
@@ -430,18 +434,20 @@
"offset=%g, phase=%g, p1=%g, p2=%g, p3=%g mult=%g",
lsx_find_enum_value(chan->type, synth_type)->text,
lsx_find_enum_value(chan->combine, combine_type)->text,
- (unsigned long)synth->samples_to_do, chan->freq, chan->freq2,
+ (unsigned long)p->samples_to_do, chan->freq, chan->freq2,
chan->offset, chan->phase, chan->p1, chan->p2, chan->p3, chan->mult);
}
+ p->gain = 1;
+ effp->out_signal.mult = p->no_headroom? NULL : &p->gain;
return SOX_SUCCESS;
}
-#define elapsed_time_s synth->samples_done / effp->in_signal.rate
+#define elapsed_time_s p->samples_done / effp->in_signal.rate
static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, sox_sample_t * obuf,
size_t * isamp, size_t * osamp)
{
- priv_t * synth = (priv_t *) effp->priv;
+ priv_t * p = (priv_t *) effp->priv;
unsigned len = min(*isamp, *osamp) / effp->in_signal.channels;
unsigned c, done;
int result = SOX_SUCCESS;
@@ -449,7 +455,7 @@
for (done = 0; done < len && result == SOX_SUCCESS; ++done) {
for (c = 0; c < effp->in_signal.channels; c++) {
sox_sample_t synth_input = *ibuf++;
- channel_t * chan = &synth->channels[c];
+ channel_t * chan = &p->channels[c];
double synth_out; /* [-1, 1] */
if (chan->type < synth_noise) { /* Need to calculate phase: */
@@ -456,18 +462,18 @@
double phase; /* [0, 1) */
switch (chan->sweep) {
case Linear:
- phase = (chan->freq + synth->samples_done * chan->mult) *
+ phase = (chan->freq + p->samples_done * chan->mult) *
elapsed_time_s;
break;
case Square:
phase = (chan->freq + sign(chan->mult) *
- sqr(synth->samples_done * chan->mult)) * elapsed_time_s;
+ sqr(p->samples_done * chan->mult)) * elapsed_time_s;
break;
case Exp:
phase = chan->freq * exp(chan->mult * elapsed_time_s);
break;
case Exp_cycle: default: {
- double f = chan->freq * exp(synth->samples_done * chan->mult);
+ double f = chan->freq * exp(p->samples_done * chan->mult);
double cycle_elapsed_time_s = elapsed_time_s - chan->cycle_start_time_s;
if (f * cycle_elapsed_time_s >= 1) { /* move to next cycle */
chan->cycle_start_time_s += 1 / f;
@@ -603,13 +609,13 @@
switch (chan->combine) {
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_mix : synth_out = (synth_out * SOX_SAMPLE_MAX + synth_input) * .5; break;
+ case synth_amod : synth_out = (synth_out + 1) * synth_input * .5; break;
case synth_fmod : synth_out *= synth_input; break;
}
- *obuf++ = floor(synth_out + .5);
+ *obuf++ = synth_out < 0? synth_out * p->gain - .5 : synth_out * p->gain + .5;
}
- if (++synth->samples_done == synth->samples_to_do)
+ if (++p->samples_done == p->samples_to_do)
result = SOX_EOF;
}
*isamp = *osamp = done * effp->in_signal.channels;
@@ -620,12 +626,12 @@
static int stop(sox_effect_t * effp)
{
- priv_t * synth = (priv_t *) effp->priv;
+ priv_t * p = (priv_t *) effp->priv;
size_t i;
- for (i = 0; i < synth->number_of_channels; ++i)
- free(synth->channels[i].buffer);
- free(synth->channels);
+ for (i = 0; i < p->number_of_channels; ++i)
+ free(p->channels[i].buffer);
+ free(p->channels);
return SOX_SUCCESS;
}
@@ -633,9 +639,9 @@
static int kill(sox_effect_t * effp)
{
- priv_t * synth = (priv_t *) effp->priv;
- free(synth->getopts_channels);
- free(synth->length_str);
+ priv_t * p = (priv_t *) effp->priv;
+ free(p->getopts_channels);
+ free(p->length_str);
return SOX_SUCCESS;
}
@@ -644,8 +650,8 @@
const sox_effect_handler_t *sox_synth_effect_fn(void)
{
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_GAIN,
+ "synth", "[-n] [len] {type [combine] [[%]freq[k][:|+|/|-[%]freq2[k]] [off [ph [p1 [p2 [p3]]]]]]}",
+ SOX_EFF_MCHAN | 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++);
+ *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
tempo_process(p->tempo);
}
else *isamp = 0;
--- a/src/tests.sh
+++ b/src/tests.sh
@@ -89,7 +89,7 @@
getFormat $1; format2Ext=$formatExt; format2Text=$formatText; format2Flags=$formatFlags
execute ${bindir}/sox $verbose -R -r $rate -c $channels -n $format1Flags input.$format1Ext synth $samples's' sin 300-3300 noise trapezium
execute ${bindir}/sox $verbose -R -r $rate -c $channels $format1Flags input.$format1Ext $format2Flags intermediate.$format2Ext
- execute ${bindir}/sox $verbose -R -r $rate -c $channels $format2Flags intermediate.$format2Ext $format1Flags output.$format1Ext
+ execute ${bindir}/sox $verbose -RD -r $rate -c $channels $format2Flags intermediate.$format2Ext $format1Flags output.$format1Ext
intermediateReference=vectors/intermediate`echo "$channels $rate $format1Flags $format1Ext $format2Flags"|tr " " "_"`.$format2Ext
# Uncomment to generate new reference files
@@ -172,21 +172,20 @@
# Reading and writing performance test
timeIO () {
+ ${bindir}/sox -c $channels -r $rate -n tmp.sox synth $samples's' saw 0:`expr $rate / 2` noise brown vol .9
while [ $# != 0 ]; do
- if [ "${skip}x" != "x" ] ; then
- from_skip=`echo ${skip} | grep ${1}`
- fi
- if [ "${from_skip}x" = "x" ] ; then
- getFormat $1;
- echo ${bindir}/sox -c $channels -r $rate -n $formatFlags input.$1 synth $samples's' sin 300-3300 noise trapezium
- echo time ${bindir}/sox $verbose -r $rate -c $channels $formatFlags input.$1 $formatFlags output.$1
- ${bindir}/sox -c $channels -r $rate -n $formatFlags input.$1 synth $samples's' sin 300-3300 noise trapezium
- time ${bindir}/sox $verbose -r $rate -c $channels $formatFlags input.$1 $formatFlags output.$1
-
- rm -f input.$1 output.$1
- fi
- shift
+ if [ "${skip}x" != "x" ] ; then
+ from_skip=`echo ${skip} | grep ${1}`
+ fi
+ if [ "${from_skip}x" = "x" ] ; then
+ getFormat $1;
+ echo "TIME \"$formatText\" channels=$channels samples=$samples write, read:"
+ time ${bindir}/sox $verbose -D tmp.sox $formatFlags -t $1 - | \
+ time ${bindir}/sox $verbose -t $1 -c $channels -r $rate - -t sox /dev/null
+ fi
+ shift
done
+ rm tmp.sox
}
# Don't try to test un-built formats
@@ -200,6 +199,8 @@
# Run tests
+${builddir}/sox_sample_test || exit 1
+
skip_check caf flac mat4 mat5 paf w64 wv
vectors=0
@@ -246,8 +247,8 @@
echo "Checked $vectors vectors"
channels=2
-samples=10000000
-timeIO s1 u1 s2 u2 s3 u3 s4 u4 f4 f8 au wav aiff aifc caf sph # FIXME?: flac dat
+samples=1e7
+timeIO s1 u1 s2 u2 s3 u3 s4 u4 f4 f8 au wav aiff aifc sph # FIXME?: caf flac dat
test -n "$skip" && echo "Skipped: $skip"
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,6 +347,7 @@
/* 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;
@@ -353,7 +354,7 @@
return done;
}
*buf = SOX_UNSIGNED_8BIT_TO_SAMPLE(uc,);
- lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf));
+ lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf, ft->clips));
++buf;
--v->block_remaining;
++done;
@@ -489,11 +490,12 @@
}
v->samples += len;
while (done < len) {
+ SOX_SAMPLE_LOCALS;
if (ft->encoding.bits_per_sample == 8) {
- uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++);
+ uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips);
lsx_writeb(ft, uc);
} else {
- sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
+ sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
lsx_writesw(ft, sw);
}
done++;
--- a/src/wav.c
+++ b/src/wav.c
@@ -331,9 +331,10 @@
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++]);
+ SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips);
if (wav->gsmindex < 160*2)
break;
--- a/src/wavpack.c
+++ b/src/wavpack.c
@@ -120,13 +120,14 @@
int result;
for (i = 0; i < len; ++i) switch (ft->encoding.bits_per_sample) {
- 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;
+ 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;
obuf[i] >>= 8; break;
case 32: obuf[i] = ft->encoding.encoding == SOX_ENCODING_WAVPACKF?
- SOX_SAMPLE_TO_SIGNED_24BIT(*(float *)&buf[i]) :
- SOX_SAMPLE_TO_SIGNED_32BIT(buf[i]);
+ SOX_SAMPLE_TO_SIGNED_24BIT(*(float *)&buf[i], ft->clips) :
+ SOX_SAMPLE_TO_SIGNED_32BIT(buf[i], ft->clips);
break;
}
result = WavpackPackSamples(p->codec, obuf, (uint32_t) len / ft->signal.channels);