ref: d1d432ebe0152dd93f6b083b60e5f717e60a9685
parent: 537a028ea85b2f587a4e556b4520244e26128f8b
author: robs <robs>
date: Sat Nov 25 03:01:53 EST 2006
Improvements to clipping detection and reporting.
--- a/Changelog
+++ b/Changelog
@@ -45,6 +45,8 @@
o Remove old, optional rate change and alaw/ulaw conversion code.
(Reuben Thomas)
o Make sox and soxmix a single binary. (Reuben Thomas)
+ o Consistent (and hopefully complete) clipping detection and
+ reporting. (robs)
sox-12.18.2
-----------
--- a/TODO
+++ b/TODO
@@ -2,9 +2,6 @@
patches to cbagwell@users.sourceforge.net, or post them on the patches
tracker at http://sf.net/projects/sox/.
- o Change all calls to ST_SAMPLE_CLIP to use counters and report
- clipping to user.
-
o Update all read routines to be like WAV handler and only
return data in multiples of sample_size*channels. This
will prevent corrupt files from causing sox to go into
--- /dev/null
+++ b/src/README
@@ -1,0 +1,58 @@
+Clipping Counting & Reporting Implementation Status
+
+As of 24th Nov '06, this aspect of the implementation is
+believed to be complete.
+
+1st column: effect/format name
+2nd column: could clip (in theory)
+3rd column: CLIP_COUNT reporting implemented: yes, no, or (yes) custom
+
+avg y y
+band n n
+bass y y
+bandpass n y
+bandreject see bandpass
+chorus y y
+compand y y
+copy n n
+dcshift y c
+deemph n n
+earwax ? n
+echo y y
+echos y y
+equalizer y y
+fade n n
+filter n n
+flanger y y
+highp n y
+highpass see bandpass
+lowp n y
+lowpass see bandpass
+mask n n
+mcompand y y
+noiseprof n n
+noisered n y
+pan n y
+phaser y y
+pick see avg
+pitch y y
+polyphase y y
+rate n n
+repeat n n
+resample y y
+reverb y y
+reverse n n
+silence n n
+speed y y
+stat n n
+stretch y y
+swap n n
+synth n n
+treble see bass
+trim n n
+vibro n n
+vol y c
+
+-v y c
+
+dat y y
--- a/src/avg.c
+++ b/src/avg.c
@@ -527,7 +527,7 @@
samp = 0.0;
for (i = 0; i < ichan; i++)
samp += ibuf[i] * avg->sources[i][j];
- ST_SAMPLE_CLIP(samp);
+ ST_EFF_SAMPLE_CLIP_COUNT(samp);
obuf[j] = samp;
}
}
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -14,19 +14,7 @@
double o0 = *ibuf*p->b0 +p->i1*p->b1 +p->i2*p->b2 -p->o1*p->a1 -p->o2*p->a2;
p->i2 = p->i1, p->i1 = *ibuf++;
p->o2 = p->o1, p->o1 = o0;
- *obuf++ = ST_ROUND_CLIP_COUNT(o0, p->clippedCount);
- }
- return ST_SUCCESS;
-}
-
-
-
-int st_biquad_stop(eff_t effp) /* Stop processing, warn if overflows */
-{
- biquad_t p = (biquad_t) effp->priv;
- if (p->clippedCount != 0)
- {
- st_warn("%s: %d samples clipped", effp->name, p->clippedCount);
+ *obuf++ = ST_EFF_ROUND_CLIP_COUNT(o0);
}
return ST_SUCCESS;
}
--- a/src/biquad.h
+++ b/src/biquad.h
@@ -17,14 +17,10 @@
st_sample_t i1, i2; /* Filter memory */
double o1, o2; /* Filter memory */
-
- unsigned clippedCount;
} * biquad_t;
int st_biquad_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
st_size_t *isamp, st_size_t *osamp);
-
-int st_biquad_stop(eff_t effp);
assert_static(sizeof(struct biquad) <= ST_MAX_EFFECT_PRIVSIZE,
/* else */ biquad_PRIVSIZE_too_big);
--- a/src/btrworth.c
+++ b/src/btrworth.c
@@ -111,7 +111,7 @@
butterworth->y [1] = butterworth->y [0];
butterworth->y [0] = out;
- ST_SAMPLE_CLIP(out);
+ ST_EFF_SAMPLE_CLIP_COUNT(out);
*obuf++ = out;
}
--- a/src/chorus.c
+++ b/src/chorus.c
@@ -276,7 +276,7 @@
chorus->maxsamples] * chorus->decay[i];
/* Adjust the output volume and size to 24 bit */
d_out = d_out * chorus->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delay and input */
chorus->chorusbuf[chorus->counter] = d_in;
@@ -313,7 +313,7 @@
chorus->maxsamples] * chorus->decay[i];
/* Adjust the output volume and size to 24 bit */
d_out = d_out * chorus->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delay and input */
chorus->chorusbuf[chorus->counter] = d_in;
--- a/src/compand.c
+++ b/src/compand.c
@@ -320,7 +320,7 @@
if (l->delay_buf_size <= 0)
{
checkbuf = ibuf[chan]*(outv/v)*l->outgain;
- ST_SAMPLE_CLIP(checkbuf);
+ ST_EFF_SAMPLE_CLIP_COUNT(checkbuf);
obuf[odone] = checkbuf;
idone++;
@@ -332,7 +332,7 @@
{
l->delay_buf_full=1; //delay buffer is now definetly full
checkbuf = l->delay_buf[l->delay_buf_ptr]*(outv/v)*l->outgain;
- ST_SAMPLE_CLIP(checkbuf);
+ ST_EFF_SAMPLE_CLIP_COUNT(checkbuf);
obuf[odone] = checkbuf;
odone++;
--- a/src/dat.c
+++ b/src/dat.c
@@ -37,13 +37,6 @@
char prevline[LINEWIDTH];
} *dat_t;
-/* FIXME: Move this to misc.c */
-static st_sample_t roundoff(double x)
-{
- if (x < 0.0) return(x - 0.5);
- else return(x + 0.5);
-}
-
int st_datstartread(ft_t ft)
{
char inpstr[LINEWIDTH];
@@ -136,9 +129,8 @@
st_fail_errno(ft,ST_EOF,"Unable to read sample.");
return (ST_EOF);
}
- sampval = roundoff(sampval * FLOATTOLONG);
- ST_SAMPLE_CLIP(sampval);
- *buf++ = sampval;
+ sampval *= FLOATTOLONG;
+ *buf++ = ST_ROUND_CLIP_COUNT(sampval, ft->clippedCount);
done++;
}
}
--- a/src/echo.c
+++ b/src/echo.c
@@ -208,7 +208,7 @@
}
/* Adjust the output volume and size to 24 bit */
d_out = d_out * echo->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Store input in delay buffer */
echo->delay_buf[echo->counter] = d_in;
@@ -242,7 +242,7 @@
}
/* Adjust the output volume and size to 24 bit */
d_out = d_out * echo->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Store input in delay buffer */
echo->delay_buf[echo->counter] = d_in;
--- a/src/echos.c
+++ b/src/echos.c
@@ -198,7 +198,7 @@
}
/* Adjust the output volume and size to 24 bit */
d_out = d_out * echos->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delays and input */
for ( j = 0; j < echos->num_delays; j++ ) {
@@ -238,7 +238,7 @@
}
/* Adjust the output volume and size to 24 bit */
d_out = d_out * echos->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delays and input */
for ( j = 0; j < echos->num_delays; j++ ) {
--- a/src/equalizer.c
+++ b/src/equalizer.c
@@ -173,13 +173,7 @@
);
eq->y[0] = out;
- if (out < ST_SAMPLE_MIN) {
- out = ST_SAMPLE_MIN;
- }
- else if (out > ST_SAMPLE_MAX) {
- out = ST_SAMPLE_MAX;
- }
-
+ ST_EFF_SAMPLE_CLIP_COUNT(out);
*obuf++ = out;
}
--- a/src/flanger.c
+++ b/src/flanger.c
@@ -227,7 +227,7 @@
flanger->maxsamples] * flanger->decay;
/* Adjust the output volume and size to 24 bit */
d_out = d_out * flanger->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delay and input */
flanger->flangerbuf[flanger->counter] = d_in;
@@ -260,7 +260,7 @@
flanger->maxsamples] * flanger->decay;
/* Adjust the output volume and size to 24 bit */
d_out = d_out * flanger->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delay and input */
flanger->flangerbuf[flanger->counter] = d_in;
--- a/src/highp.c
+++ b/src/highp.c
@@ -115,7 +115,7 @@
d = highp->A0 * l +
highp->A1 * highp->inm1 +
highp->B1 * highp->outm1;
- ST_SAMPLE_CLIP(d);
+ ST_EFF_SAMPLE_CLIP_COUNT(d);
highp->inm1 = l;
highp->outm1 = d;
*obuf++ = d;
--- a/src/lowp.c
+++ b/src/lowp.c
@@ -109,7 +109,7 @@
for(done = 0; done < len; done++) {
l = *ibuf++;
d = lowp->A * l + lowp->B * lowp->outm1;
- ST_SAMPLE_CLIP(d);
+ ST_EFF_SAMPLE_CLIP_COUNT(d);
lowp->outm1 = d;
*obuf++ = d;
}
--- a/src/mcompand.c
+++ b/src/mcompand.c
@@ -132,7 +132,7 @@
return (ST_SUCCESS);
}
-static int lowpass_flow(butterworth_crossover_t butterworth, int nChan, st_sample_t *ibuf, st_sample_t *lowbuf, st_sample_t *highbuf,
+static int lowpass_flow(eff_t effp, butterworth_crossover_t butterworth, int nChan, st_sample_t *ibuf, st_sample_t *lowbuf, st_sample_t *highbuf,
int len) {
int chan;
double in, out;
@@ -168,7 +168,7 @@
butterworth->xy_low[chan].y [1] = butterworth->xy_low[chan].y [0];
butterworth->xy_low[chan].y [0] = out;
- ST_SAMPLE_CLIP(out);
+ ST_EFF_SAMPLE_CLIP_COUNT(out);
*lowbufptr = out;
@@ -185,7 +185,7 @@
butterworth->xy_high[chan].y [1] = butterworth->xy_high[chan].y [0];
butterworth->xy_high[chan].y [0] = out;
- ST_SAMPLE_CLIP(out);
+ ST_EFF_SAMPLE_CLIP_COUNT(out);
/* don't forget polarity reversal of high pass! */
@@ -600,7 +600,7 @@
l = &c->bands[band];
if (l->topfreq)
- lowpass_flow(&l->filter, effp->outinfo.channels, abuf, bbuf, cbuf, len);
+ lowpass_flow(effp, &l->filter, effp->outinfo.channels, abuf, bbuf, cbuf, len);
else {
bbuf = abuf;
abuf = cbuf;
@@ -611,7 +611,7 @@
for (i=0;i<len;++i)
{
out = obuf[i] + abuf[i];
- ST_SAMPLE_CLIP(out);
+ ST_EFF_SAMPLE_CLIP_COUNT(out);
obuf[i] = out;
}
oldabuf = abuf;
@@ -624,7 +624,7 @@
return ST_SUCCESS;
}
-static int st_mcompand_drain_1(compand_t c, comp_band_t l, st_sample_t *obuf, int maxdrain, int band)
+static int st_mcompand_drain_1(eff_t effp, compand_t c, comp_band_t l, st_sample_t *obuf, int maxdrain, int band)
{
int done;
double out;
@@ -634,7 +634,7 @@
*/
for (done = 0; done < maxdrain && l->delay_buf_cnt > 0; done++) {
out = obuf[done] + l->delay_buf[l->delay_buf_ptr++];
- ST_SAMPLE_CLIP(out);
+ ST_EFF_SAMPLE_CLIP_COUNT(out);
obuf[done] = out;
l->delay_buf_ptr %= c->delay_buf_size;
l->delay_buf_cnt--;
@@ -657,7 +657,7 @@
memset(obuf,0,*osamp * sizeof *obuf);
for (band=0;band<c->nBands;++band) {
l = &c->bands[band];
- drained = st_mcompand_drain_1(c,l,obuf,*osamp,0);
+ drained = st_mcompand_drain_1(effp, c,l,obuf,*osamp,0);
if (drained > mostdrained)
mostdrained = drained;
}
--- a/src/misc.c
+++ b/src/misc.c
@@ -436,16 +436,6 @@
srand(t);
}
-st_sample_t st_clip24(st_sample_t l)
-{
- if (l >= ((st_sample_t)1 << 23))
- return ((st_sample_t)1 << 23) - 1;
- else if (l <= -((st_sample_t)1 << 23))
- return -((st_sample_t)1 << 23) + 1;
- else
- return l;
-}
-
/* This was very painful. We need a sine library. */
void st_sine(int *buf, st_ssize_t len, int max, int depth)
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -208,7 +208,7 @@
/* Do window management once we have a complete window, including mangling
* the current window. */
-static int process_window(reddata_t data, int chan_num, int num_chans,
+static int process_window(eff_t effp, reddata_t data, int chan_num, int num_chans,
st_sample_t *obuf, int len) {
int j;
float* nextwindow;
@@ -215,7 +215,6 @@
int use = min(len, WINDOWSIZE)-min(len,(WINDOWSIZE/2));
chandata_t *chan = &(data->chandata[chan_num]);
int first = (chan->lastwindow == NULL);
- int clipped = 0;
nextwindow = (float*)calloc(WINDOWSIZE, sizeof(float));
memcpy(nextwindow, chan->window+WINDOWSIZE/2,
@@ -226,13 +225,7 @@
if (!first) {
for (j = 0; j < use; j ++) {
float s = chan->window[j] + chan->lastwindow[WINDOWSIZE/2 + j];
- ST_NORMALIZED_CLIP_COUNT(s, clipped);
- if (clipped)
- {
- /* Reset for future tests. */
- clipped = 0;
- st_warn("noisered: Output clipped to %f.\n", s);
- }
+ ST_EFF_NORMALIZED_CLIP_COUNT(s);
obuf[chan_num + num_chans * j] =
ST_FLOAT_DWORD_TO_SAMPLE(s);
}
@@ -288,7 +281,7 @@
if (!whole_window)
continue;
else {
- process_window(data, i, tracks, obuf, oldbuf + ncopy);
+ process_window(effp, data, i, tracks, obuf, oldbuf + ncopy);
}
}
@@ -312,7 +305,7 @@
int i;
int tracks = effp->ininfo.channels;
for (i = 0; i < tracks; i ++) {
- *osamp = process_window(data, i, tracks, obuf, data->bufdata);
+ *osamp = process_window(effp, data, i, tracks, obuf, data->bufdata);
}
/* FIXME: This is very picky. osamp needs to be big enough to get all
* remaining data or it will be discarded.
--- a/src/pan.c
+++ b/src/pan.c
@@ -49,7 +49,6 @@
/* local data
*/
- int clipped; /* number of clipped values */
} * pan_t;
/*
@@ -60,7 +59,6 @@
pan_t pan = (pan_t) effp->priv;
pan->dir = ZERO; /* default is no change */
- pan->clipped = 0;
if (n && (!sscanf(argv[0], PAN_FLOAT_SCAN, &pan->dir) ||
pan->dir < MONE || pan->dir > ONE))
@@ -134,7 +132,7 @@
{
float f;
f = HALF*ibuf[0] + HALF*ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
*obuf++ = f;
ibuf += 2;
}
@@ -145,7 +143,7 @@
float f;
f = QUARTER*ibuf[0] + QUARTER*ibuf[1] +
QUARTER*ibuf[2] + QUARTER*ibuf[3];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
*obuf++ = f;
ibuf += 4;
}
@@ -163,10 +161,10 @@
float f;
f = left * ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = right * ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
obuf += 2;
ibuf++;
@@ -189,10 +187,10 @@
float f;
f = cll * ibuf[0] + clr * ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = cr * ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
obuf += 2;
ibuf += 2;
@@ -212,10 +210,10 @@
float f;
f = cl * ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = crl * ibuf[0] + crr * ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
obuf += 2;
ibuf += 2;
@@ -242,10 +240,10 @@
/* pan it */
f = cll * ibuf0 + clr * ibuf1;
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = cr * ibuf1;
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
obuf += 2;
ibuf += 4;
@@ -268,10 +266,10 @@
ibuf1 = HALF*ibuf[1] + HALF*ibuf[3];
f = cl * ibuf0;
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = crl * ibuf0 + crr * ibuf1;
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
obuf += 2;
ibuf += 4;
@@ -297,10 +295,10 @@
float f;
f = cl * ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[2] = obuf[0] = f;
f = cr * ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
ibuf[3] = obuf[1] = f;
obuf += 4;
ibuf++;
@@ -322,10 +320,10 @@
float f;
f = cll * ibuf[0] + clr * ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[2] = obuf[0] = f;
f = cr * ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
ibuf[3] = obuf[1] = f;
obuf += 4;
ibuf += 2;
@@ -345,10 +343,10 @@
float f;
f = cl * ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[2] = obuf[0] =f ;
f = crl * ibuf[0] + crr * ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
ibuf[3] = obuf[1] = f;
obuf += 4;
ibuf += 2;
@@ -371,16 +369,16 @@
float f;
f = cown*ibuf[0] + cright*ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = cown*ibuf[1] + cright*ibuf[3];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
f = cown*ibuf[2] + cright*ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[2] = f;
f = cown*ibuf[3] + cright*ibuf[2];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[3] = f;
obuf += 4;
ibuf += 4;
@@ -398,16 +396,16 @@
float f;
f = cleft*ibuf[2] + cown*ibuf[0];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[0] = f;
f = cleft*ibuf[0] + cown*ibuf[1];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[1] = f;
f = cleft*ibuf[3] + cown*ibuf[2];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[2] = f;
f = cleft*ibuf[1] + cown*ibuf[3];
- ST_SAMPLE_CLIP_COUNT(f, pan->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[3] = f;
obuf += 4;
ibuf += 4;
@@ -435,11 +433,6 @@
*/
int st_pan_stop(eff_t effp)
{
- pan_t pan = (pan_t) effp->priv;
- if (pan->clipped) {
- st_warn("PAN clipped %d values, maybe adjust volume?",
- pan->clipped);
- }
return ST_SUCCESS;
}
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -214,7 +214,7 @@
phaser->maxsamples] * phaser->decay * -1.0;
/* Adjust the output volume and size to 24 bit */
d_out = d_in * phaser->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delay and input */
phaser->phaserbuf[phaser->counter] = d_in;
@@ -247,7 +247,7 @@
phaser->maxsamples] * phaser->decay * -1.0;
/* Adjust the output volume and size to 24 bit */
d_out = d_in * phaser->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
/* Mix decay of delay and input */
phaser->phaserbuf[phaser->counter] = d_in;
--- a/src/pitch.c
+++ b/src/pitch.c
@@ -130,8 +130,6 @@
pitch_state_t state; /* buffer management status. */
- int clipped; /* number of clipped values (i.e. overflows) */
-
} * pitch_t;
/* // debug functions
@@ -348,8 +346,6 @@
return ST_EOF;
}
- pitch->clipped = 0;
-
return ST_SUCCESS;
}
@@ -467,8 +463,6 @@
return ST_EOF;
}
- pitch->clipped = 0;
-
return ST_SUCCESS;
}
@@ -525,7 +519,7 @@
float f;
f = pitch->acc[pitch->iacc++];
- ST_SAMPLE_CLIP_COUNT(f, pitch->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[oindex++] = f;
}
@@ -578,7 +572,7 @@
float f;
f = pitch->acc[pitch->iacc++];
- ST_SAMPLE_CLIP_COUNT(f, pitch->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[i++] = f;
}
@@ -603,10 +597,6 @@
free(pitch->tmp);
free(pitch->acc);
free(pitch->buf);
-
- if (pitch->clipped)
- st_warn("PITCH clipped %d values... adjust volume with -v option maybe?",
- pitch->clipped);
return ST_SUCCESS;
}
--- a/src/polyphas.c
+++ b/src/polyphas.c
@@ -615,7 +615,7 @@
{
float f;
f = out_buf[k] * ISCALE; /* should clip-limit */
- ST_SAMPLE_CLIP(f);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
*q++ = f;
}
--- a/src/resample.c
+++ b/src/resample.c
@@ -359,7 +359,7 @@
// orig: *obuf++ = r->Y[i] * ISCALE;
Float ftemp = r->Y[i] * ISCALE;
- ST_SAMPLE_CLIP(ftemp);
+ ST_EFF_SAMPLE_CLIP_COUNT(ftemp);
*obuf++ = ftemp;
}
--- a/src/reverb.c
+++ b/src/reverb.c
@@ -229,7 +229,7 @@
d_in +=
reverb->reverbbuf[(i + reverb->maxsamples - reverb->samples[j]) % reverb->maxsamples] * reverb->decay[j];
d_out = d_in * reverb->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
*obuf++ = out * 256;
reverb->reverbbuf[i] = d_in;
i++; /* XXX need a % maxsamples here ? */
@@ -261,10 +261,10 @@
d_in +=
reverb->reverbbuf[(i + reverb->maxsamples - reverb->samples[j]) % reverb->maxsamples] * reverb->decay[j];
d_out = d_in * reverb->out_gain;
- out = st_clip24((st_sample_t) d_out);
+ out = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_out);
obuf[done++] = out * 256;
reverb->reverbbuf[i] = d_in;
- l = st_clip24((st_sample_t) d_in);
+ l = ST_EFF_24BIT_CLIP_COUNT((st_sample_t) d_in);
reverb->pppl = reverb->ppl;
reverb->ppl = reverb->pl;
reverb->pl = l;
--- a/src/sox.c
+++ b/src/sox.c
@@ -848,6 +848,11 @@
for (f = 0; f < input_count; f++)
{
+ if (file_desc[f]->clippedCount != 0)
+ {
+ st_warn("%s: %u values clipped on input", file_desc[f]->filename, file_desc[f]->clippedCount);
+ }
+
/* If problems closing input file, just warn user since
* we are exiting anyways.
*/
@@ -1130,11 +1135,15 @@
int e, ret = ST_SUCCESS;
for(e = 1; e < neffects; e++) {
+ efftab[e].clippedCount = 0;
if ((ret = (*efftab[e].h->start)(&efftab[e])) == ST_EOF)
break;
if (efftabR[e].name)
+ {
+ efftabR[e].clippedCount = 0;
if ((ret = (*efftabR[e].h->start)(&efftabR[e])) == ST_EOF)
break;
+ }
}
return ret;
@@ -1563,9 +1572,18 @@
int e;
for (e = 1; e < neffects; e++) {
+ st_size_t clippedCount;
(*efftab[e].h->stop)(&efftab[e]);
+ clippedCount = efftab[e].clippedCount;
if (efftabR[e].name)
+ {
(* efftabR[e].h->stop)(&efftabR[e]);
+ clippedCount += efftab[e].clippedCount;
+ }
+ if (clippedCount != 0)
+ {
+ st_warn("%s: %u values clipped, maybe adjust volume?", efftab[e].name, clippedCount);
+ }
}
}
--- a/src/speed.c
+++ b/src/speed.c
@@ -47,8 +47,6 @@
/* internals.
*/
- int clipped; /* number of clipped values to report */
-
SPEED_FLOAT rate; /* rate of buffer sweep */
int compression; /* integer compression of the signal. */
@@ -126,7 +124,6 @@
int st_speed_start(eff_t effp)
{
speed_t speed = (speed_t) effp->priv;
- speed->clipped = 0;
if (speed->factor >= ONE)
{
@@ -178,7 +175,7 @@
/* interpolate values
*/
-static st_size_t compute(speed_t speed, st_sample_t *obuf, st_size_t olen)
+static st_size_t compute(eff_t effp, speed_t speed, st_sample_t *obuf, st_size_t olen)
{
st_size_t i;
@@ -191,7 +188,7 @@
f = cub(speed->cbuf[0], speed->cbuf[1],
speed->cbuf[2], speed->cbuf[3],
speed->frac);
- ST_SAMPLE_CLIP_COUNT(f, speed->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[i] = f;
}
@@ -238,7 +235,7 @@
/* compute interpolation. */
if (speed->state==sp_compute)
- oindex += compute(speed, obuf+oindex, len-oindex);
+ oindex += compute(effp, speed, obuf+oindex, len-oindex);
}
*isamp = iindex;
@@ -273,7 +270,7 @@
/* compute interpolation. */
if (speed->state==sp_compute)
- oindex += compute(speed, obuf+oindex, *osamp-oindex);
+ oindex += compute(effp, speed, obuf+oindex, *osamp-oindex);
}
*osamp = oindex; /* report how much was generated. */
@@ -289,9 +286,6 @@
int st_speed_stop(eff_t effp)
{
speed_t speed = (speed_t) effp->priv;
-
- if (speed->clipped)
- st_report("SPEED: %d values clipped...", speed->clipped);
free(speed->ibuf);
--- a/src/st.h
+++ b/src/st.h
@@ -83,17 +83,6 @@
#define ST_SAMPLE_TO_FLOAT_DDWORD(d) ((double)((double)d/(ST_SAMPLE_FLOAT_SCALE)))
/* MACRO to clip a data type that is greater then st_sample_t to
- * st_sample_t's limits.
- */
-#define ST_SAMPLE_CLIP(samp) \
- do { \
- if (samp > ST_SAMPLE_MAX) \
- { samp = ST_SAMPLE_MAX; } \
- else if (samp < ST_SAMPLE_MIN) \
- { samp = ST_SAMPLE_MIN; } \
- } while (0)
-
-/* MACRO to clip a data type that is greater then st_sample_t to
* st_sample_t's limits and increment a counter if clipping occurs..
*/
#define ST_SAMPLE_CLIP_COUNT(samp, clips) \
@@ -108,9 +97,16 @@
* and increment a counter if clipping occurs.
*/
#define ST_ROUND_CLIP_COUNT(d, clips) \
- (d < 0? d <= ST_SAMPLE_MIN - 0.5? ++clips, ST_SAMPLE_MIN: d - 0.5 \
- : d >= ST_SAMPLE_MAX + 0.5? ++clips, ST_SAMPLE_MAX: d + 0.5)
+ ((d) < 0? (d) <= ST_SAMPLE_MIN - 0.5? ++(clips), ST_SAMPLE_MIN: (d) - 0.5 \
+ : (d) >= ST_SAMPLE_MAX + 0.5? ++(clips), ST_SAMPLE_MAX: (d) + 0.5)
+/* Rvalue MACRO to clip a st_sample_t to 24 bits,
+ * and increment a counter if clipping occurs.
+ */
+#define ST_24BIT_CLIP_COUNT(l, clips) \
+ ((l) >= ((st_sample_t)1 << 23)? ++(clips), ((st_sample_t)1 << 23) - 1 : \
+ (l) <=-((st_sample_t)1 << 23)? ++(clips),-((st_sample_t)1 << 23) + 1 : (l))
+
/* MACRO to clip a normalized floating point data between 1.0 and -1.0
* to those limits and increment a counter when clipping occurs.
*/
@@ -122,6 +118,12 @@
{ samp = -1; clips++; } \
} while (0)
+/* MACROs for effects where standard clip counting and reporting is used. */
+#define ST_EFF_SAMPLE_CLIP_COUNT(s) ST_SAMPLE_CLIP_COUNT(s, effp->clippedCount)
+#define ST_EFF_24BIT_CLIP_COUNT(s) ST_24BIT_CLIP_COUNT(s, effp->clippedCount)
+#define ST_EFF_ROUND_CLIP_COUNT(s) ST_ROUND_CLIP_COUNT(s, effp->clippedCount)
+#define ST_EFF_NORMALIZED_CLIP_COUNT(s) ST_NORMALIZED_CLIP_COUNT(s, effp->clippedCount)
+
/* Maximum value size type can hold. (Minimum is 0). */
#define ST_SIZE_MAX 0xffffffffL
@@ -227,6 +229,7 @@
char mode; /* read or write mode */
/* Total samples per channel of file. Zero if unknown. */
st_size_t length;
+ st_size_t clippedCount; /* increment if clipping occurs */
char *filename; /* file name */
char *filetype; /* type of file */
char *comment; /* comment string */
@@ -319,6 +322,7 @@
const st_effect_t *h; /* effects driver */
st_sample_t *obuf; /* output buffer */
st_size_t odone, olen; /* consumed, total length */
+ st_size_t clippedCount; /* increment if clipping occurs */
/* The following is a portable trick to align this variable on
* an 8-byte bounder. Once this is done, the buffer alloced
* after it should be align on an 8-byte boundery as well.
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -38,7 +38,6 @@
#endif
/* declared in misc.c */
-st_sample_t st_clip24(st_sample_t) REGPARM(1);
void st_sine(int *buf, st_ssize_t len, int max, int depth);
void st_triangle(int *buf, st_ssize_t len, int max, int depth);
--- a/src/stretch.c
+++ b/src/stretch.c
@@ -68,7 +68,6 @@
/* internal stuff
*/
stretch_status_t state; /* automaton status */
- int clipped; /* number of clipped values. */
int size; /* buffer size */
int index; /* next available element */
@@ -206,7 +205,6 @@
}
stretch->state = input_state;
- stretch->clipped = 0;
stretch->size = (int)(effp->outinfo.rate * ONETHOUSANDS * stretch->window);
/* start in the middle of an input to avoid initial fading... */
@@ -337,7 +335,7 @@
{
float f;
f = stretch->obuf[stretch->oindex++];
- ST_SAMPLE_CLIP_COUNT(f, stretch->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[oindex++] = f;
}
@@ -392,7 +390,7 @@
float f;
f = stretch->obuf[stretch->oindex++];
- ST_SAMPLE_CLIP_COUNT(f, stretch->clipped);
+ ST_EFF_SAMPLE_CLIP_COUNT(f);
obuf[oindex++] = f;
}
@@ -416,9 +414,6 @@
free(stretch->ibuf);
free(stretch->obuf);
free(stretch->fbuf);
-
- if (stretch->clipped)
- st_warn("STRETCH clipped %d values...", stretch->clipped);
return ST_SUCCESS;
}
--- a/src/tone.c
+++ b/src/tone.c
@@ -156,7 +156,7 @@
st_biquad_shelf_start,
st_biquad_flow,
st_effect_nothing_drain,
- st_biquad_stop
+ st_effect_nothing
};
@@ -176,7 +176,7 @@
st_biquad_shelf_start,
st_biquad_flow,
st_effect_nothing_drain,
- st_biquad_stop
+ st_effect_nothing
};