ref: dee63f713a6c9ae5d37671ee7ff20b52d50f9232
parent: 69778917e402941035a4fdb9fdfb6b2bb71bac11
author: cbagwell <cbagwell>
date: Sun Feb 19 17:35:59 EST 2006
Convert to common set of CLIP routines.
--- a/Changelog
+++ b/Changelog
@@ -8,7 +8,7 @@
------------
o The "filter" effect could go into infinite drain mode. Now
- only drain 1 buffer.
+ only drain 1 buffer. noisered as well.
o SoX was ignoring user aborts (ctrl-c) if it occured during
effect drain operations. This was bad if effects had
bugs and stuck in infinite loop.
@@ -15,6 +15,8 @@
o Stop SoX from crashing when file type could not be auto
determined (bug 1417776).
o Output filenames with multiple '.' confused SoX. (Christian Hammers)
+ o Moved to a common set of CLIP routines. This fixed clipping
+ bugs in noisered and mcompand.
sox-12.17.9
-----------
--- a/src/avg.c
+++ b/src/avg.c
@@ -527,10 +527,7 @@
samp = 0.0;
for (i = 0; i < ichan; i++)
samp += ibuf[i] * avg->sources[i][j];
- if (samp < ST_SAMPLE_MIN)
- samp = ST_SAMPLE_MIN;
- else if (samp > ST_SAMPLE_MAX)
- samp = ST_SAMPLE_MAX;
+ ST_SAMPLE_CLIP(samp, NULL);
obuf[j] = samp;
}
}
--- a/src/btrworth.c
+++ b/src/btrworth.c
@@ -81,12 +81,7 @@
butterworth->y [1] = butterworth->y [0];
butterworth->y [0] = out;
- if (out < ST_SAMPLE_MIN) {
- out = ST_SAMPLE_MIN;
- }
- else if (out > ST_SAMPLE_MAX) {
- out = ST_SAMPLE_MAX;
- }
+ ST_SAMPLE_CLIP(out, NULL);
*obuf++ = out;
}
--- a/src/compand.c
+++ b/src/compand.c
@@ -325,12 +325,8 @@
if (l->delay_buf_size <= 0)
{
checkbuf = ibuf[chan]*(outv/v)*l->outgain;
- if(checkbuf > ST_SAMPLE_MAX)
- obuf[odone] = ST_SAMPLE_MAX;
- else if(checkbuf < ST_SAMPLE_MIN)
- obuf[odone] = ST_SAMPLE_MIN;
- else
- obuf[odone] = checkbuf;
+ ST_SAMPLE_CLIP(checkbuf, NULL);
+ obuf[odone] = checkbuf;
idone++;
odone++;
@@ -341,12 +337,8 @@
{
l->delay_buf_full=1; //delay buffer is now definetly full
checkbuf = l->delay_buf[l->delay_buf_ptr]*(outv/v)*l->outgain;
- if(checkbuf > ST_SAMPLE_MAX)
- obuf[odone] = ST_SAMPLE_MAX;
- else if(checkbuf < ST_SAMPLE_MIN)
- obuf[odone] = ST_SAMPLE_MIN;
- else
- obuf[odone] = checkbuf;
+ ST_SAMPLE_CLIP(checkbuf, NULL);
+ obuf[odone] = checkbuf;
odone++;
idone++;
--- a/src/dcshift.c
+++ b/src/dcshift.c
@@ -114,26 +114,6 @@
return ST_SUCCESS;
}
-/* conversion. clipping could be smoother at high ends?
- * this could be a function on its own, with clip count and report
- * handled by eff_t and caller.
- */
-static st_sample_t clip(dcs_t dcs, const DCSHIFT_FLOAT v)
-{
- if (v > ST_SAMPLE_MAX)
- {
- dcs->clipped++;
- return ST_SAMPLE_MAX;
- }
- else if (v < ST_SAMPLE_MIN)
- {
- dcs->clipped++;
- return ST_SAMPLE_MIN;
- }
- /* else */
- return (st_sample_t) v;
-}
-
#ifndef MIN
#define MIN(s1,s2) ((s1)<(s2)?(s1):(s2))
#endif
@@ -185,7 +165,8 @@
sample = dcshift * ST_SAMPLE_MAX + sample;
}
- *obuf++ = clip(dcs, sample);
+ ST_SAMPLE_CLIP(sample, &dcs->clipped);
+ *obuf++ = sample;
}
}
else
@@ -192,7 +173,13 @@
{
/* quite basic, with clipping */
for (;len>0; len--)
- *obuf++ = clip(dcs, dcshift * ST_SAMPLE_MAX + *ibuf++);
+ {
+ float f;
+
+ f = dcshift * ST_SAMPLE_MAX + *ibuf++;
+ ST_SAMPLE_CLIP(f, &dcs->clipped);
+ *obuf++ = f;
+ }
}
return ST_SUCCESS;
}
--- a/src/filter.c
+++ b/src/filter.c
@@ -266,6 +266,9 @@
/* fprintf(stderr,"DRAIN osamp %d\n", *osamp); */
if (isamp_res)
st_warn("drain overran obuf by %d\n", isamp_res); fflush(stderr);
+ /* This is very picky. osamp better be big enough to grab
+ * all remaining samples or they will be discarded.
+ */
return (ST_EOF);
}
--- a/src/highp.c
+++ b/src/highp.c
@@ -93,10 +93,7 @@
d = highp->A0 * l +
highp->A1 * highp->inm1 +
highp->B1 * highp->outm1;
- if (d < ST_SAMPLE_MIN)
- d = ST_SAMPLE_MIN;
- else if (d > ST_SAMPLE_MAX)
- d = ST_SAMPLE_MAX;
+ ST_SAMPLE_CLIP(d, NULL);
highp->inm1 = l;
highp->outm1 = d;
*obuf++ = d;
--- a/src/lowp.c
+++ b/src/lowp.c
@@ -87,10 +87,7 @@
for(done = 0; done < len; done++) {
l = *ibuf++;
d = lowp->A * l + lowp->B * lowp->outm1;
- if (d < ST_SAMPLE_MIN)
- d = ST_SAMPLE_MIN;
- else if (d > ST_SAMPLE_MAX)
- d = ST_SAMPLE_MAX;
+ ST_SAMPLE_CLIP(d, NULL);
lowp->outm1 = d;
*obuf++ = d;
}
--- a/src/mcompand.c
+++ b/src/mcompand.c
@@ -168,12 +168,7 @@
butterworth->xy_low[chan].y [1] = butterworth->xy_low[chan].y [0];
butterworth->xy_low[chan].y [0] = out;
- if (out < ST_SAMPLE_MIN) {
- out = ST_SAMPLE_MIN;
- }
- else if (out > ST_SAMPLE_MAX) {
- out = ST_SAMPLE_MAX;
- }
+ ST_SAMPLE_CLIP(out, NULL);
*lowbufptr = out;
@@ -190,12 +185,7 @@
butterworth->xy_high[chan].y [1] = butterworth->xy_high[chan].y [0];
butterworth->xy_high[chan].y [0] = out;
- if (out < ST_SAMPLE_MIN) {
- out = ST_SAMPLE_MIN;
- }
- else if (out > ST_SAMPLE_MAX) {
- out = ST_SAMPLE_MAX;
- }
+ ST_SAMPLE_CLIP(out, NULL);
/* don't forget polarity reversal of high pass! */
@@ -591,6 +581,7 @@
int len = ((*isamp > *osamp) ? *osamp : *isamp);
int band, i;
st_sample_t *abuf, *bbuf, *cbuf, *oldabuf;
+ double out;
if (c->band_buf_len < len) {
if ((! (c->band_buf1 = (st_sample_t *)realloc(c->band_buf1,len*sizeof(st_sample_t)))) ||
@@ -618,21 +609,16 @@
abuf = c->band_buf3;
(void)st_mcompand_flow_1(c,l,bbuf,abuf,len,effp->outinfo.channels);
for (i=0;i<len;++i)
- obuf[i] += abuf[i];
+ {
+ out = obuf[i] + abuf[i];
+ ST_SAMPLE_CLIP(out, NULL);
+ obuf[i] = out;
+ }
oldabuf = abuf;
abuf = cbuf;
cbuf = oldabuf;
}
- for (i=0;i<len;++i) {
- if (obuf[i] < ST_SAMPLE_MIN) {
- obuf[i] = ST_SAMPLE_MIN;
- }
- else if (obuf[i] > ST_SAMPLE_MAX) {
- obuf[i] = ST_SAMPLE_MAX;
- }
- }
-
*isamp = *osamp = len;
return ST_SUCCESS;
@@ -641,12 +627,15 @@
static int st_mcompand_drain_1(compand_t c, comp_band_t l, st_sample_t *obuf, int maxdrain, int band)
{
int done;
+ double out;
/*
* Drain out delay samples. Note that this loop does all channels.
*/
for (done = 0; done < maxdrain && l->delay_buf_cnt > 0; done++) {
- obuf[done] += l->delay_buf[l->delay_buf_ptr++];
+ out = obuf[done] + l->delay_buf[l->delay_buf_ptr++];
+ ST_SAMPLE_CLIP(out, NULL);
+ obuf[done] = out;
l->delay_buf_ptr %= c->delay_buf_size;
l->delay_buf_cnt--;
}
@@ -664,7 +653,6 @@
int band, drained, mostdrained = 0;
compand_t c = (compand_t)effp->priv;
comp_band_t l;
- int i;
memset(obuf,0,*osamp * sizeof *obuf);
for (band=0;band<c->nBands;++band) {
@@ -672,15 +660,6 @@
drained = st_mcompand_drain_1(c,l,obuf,*osamp,0);
if (drained > mostdrained)
mostdrained = drained;
- }
-
- for (i=0;i<mostdrained;++i) {
- if (obuf[i] < ST_SAMPLE_MIN) {
- obuf[i] = ST_SAMPLE_MIN;
- }
- else if (obuf[i] > ST_SAMPLE_MAX) {
- obuf[i] = ST_SAMPLE_MAX;
- }
}
*osamp = mostdrained;
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -210,9 +210,10 @@
st_sample_t *obuf, int len) {
int j;
float* nextwindow;
- int use = min(len, WINDOWSIZE)-(WINDOWSIZE/2);
+ 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,
@@ -223,15 +224,12 @@
if (!first) {
for (j = 0; j < use; j ++) {
float s = chan->window[j] + chan->lastwindow[WINDOWSIZE/2 + j];
- if (s < -1 || s > 1) {
- float news;
- if (s > 1)
- news = 1;
- else
- news = -1;
-
- st_warn("noisered: Output clipped from %f to %f.\n",
- s, news);
+ ST_NORMALIZED_CLIP(s, &clipped);
+ if (clipped)
+ {
+ /* Reset for future tests. */
+ clipped = 0;
+ st_warn("noisered: Output clipped to %f.\n", s);
}
obuf[chan_num + num_chans * j] =
ST_FLOAT_DWORD_TO_SAMPLE(s);
@@ -314,7 +312,10 @@
for (i = 0; i < tracks; i ++) {
*osamp = process_window(data, i, tracks, obuf, data->bufdata);
}
- return (ST_SUCCESS);
+ /* This is very picky. osamp needs to be big enough to get all
+ * remaining data or it will be discarded.
+ */
+ return (ST_EOF);
}
/*
--- a/src/pan.c
+++ b/src/pan.c
@@ -93,26 +93,6 @@
}
-/* clip value if necessary. see comments about such a function in vol.c
- * Okay, it might be quite slow to have such a function for so small
- * a task. Hopefully the function can be inlined by the compiler?
- */
-static st_sample_t clip(pan_t pan, PAN_FLOAT value)
-{
- if (value < ST_SAMPLE_MIN)
- {
- pan->clipped++;
- return ST_SAMPLE_MIN;
- }
- else if (value > ST_SAMPLE_MAX)
- {
- pan->clipped++;
- return ST_SAMPLE_MAX;
- } /* else */
-
- return (st_sample_t) value;
-}
-
#ifndef MIN
#define MIN(s1,s2) ((s1)<(s2)?(s1):(s2))
#endif
@@ -157,15 +137,24 @@
break;
case 2: /* average 2 */
for (done=0; done<len; done++)
- *obuf++ = clip(pan, HALF*ibuf[0] + HALF*ibuf[1]),
- ibuf += 2;
+ {
+ float f;
+ f = HALF*ibuf[0] + HALF*ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ *obuf++ = f;
+ ibuf += 2;
+ }
break;
case 4: /* average 4 */
for (done=0; done<len; done++)
- *obuf++ = clip(pan,
- QUARTER*ibuf[0] + QUARTER*ibuf[1] +
- QUARTER*ibuf[2] + QUARTER*ibuf[3]),
- ibuf += 4;
+ {
+ float f;
+ f = QUARTER*ibuf[0] + QUARTER*ibuf[1] +
+ QUARTER*ibuf[2] + QUARTER*ibuf[3];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ *obuf++ = f;
+ ibuf += 4;
+ }
break;
default:
UNEXPECTED_CHANNELS;
@@ -177,8 +166,14 @@
case 1: /* linear */
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, left * ibuf[0]);
- obuf[1] = clip(pan, right * ibuf[0]);
+ float f;
+
+ f = left * ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = right * ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
obuf += 2;
ibuf++;
}
@@ -197,8 +192,14 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cll * ibuf[0] + clr * ibuf[1]);
- obuf[1] = clip(pan, cr * ibuf[1]);
+ float f;
+
+ f = cll * ibuf[0] + clr * ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = cr * ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
obuf += 2;
ibuf += 2;
}
@@ -214,8 +215,14 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cl * ibuf[0]);
- obuf[1] = clip(pan, crl * ibuf[0] + crr * ibuf[1]);
+ float f;
+
+ f = cl * ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = crl * ibuf[0] + crr * ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
obuf += 2;
ibuf += 2;
}
@@ -233,7 +240,7 @@
for (done=0; done<len; done++)
{
- register PAN_FLOAT ibuf0, ibuf1;
+ register PAN_FLOAT ibuf0, ibuf1, f;
/* build stereo signal */
ibuf0 = HALF*ibuf[0] + HALF*ibuf[2];
@@ -240,8 +247,12 @@
ibuf1 = HALF*ibuf[1] + HALF*ibuf[3];
/* pan it */
- obuf[0] = clip(pan, cll * ibuf0 + clr * ibuf1);
- obuf[1] = clip(pan, cr * ibuf1);
+ f = cll * ibuf0 + clr * ibuf1;
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = cr * ibuf1;
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
obuf += 2;
ibuf += 4;
}
@@ -257,13 +268,17 @@
for (done=0; done<len; done++)
{
- register PAN_FLOAT ibuf0, ibuf1;
+ register PAN_FLOAT ibuf0, ibuf1, f;
ibuf0 = HALF*ibuf[0] + HALF*ibuf[2];
ibuf1 = HALF*ibuf[1] + HALF*ibuf[3];
- obuf[0] = clip(pan, cl * ibuf0);
- obuf[1] = clip(pan, crl * ibuf0 + crr * ibuf1);
+ f = cl * ibuf0;
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = crl * ibuf0 + crr * ibuf1;
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
obuf += 2;
ibuf += 4;
}
@@ -285,10 +300,14 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cl * ibuf[0]);
- obuf[2] = obuf[0];
- obuf[1] = clip(pan, cr * ibuf[0]);
- ibuf[3] = obuf[1];
+ float f;
+
+ f = cl * ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[2] = obuf[0] = f;
+ f = cr * ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ ibuf[3] = obuf[1] = f;
obuf += 4;
ibuf++;
}
@@ -306,10 +325,14 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cll * ibuf[0] + clr * ibuf[1]);
- obuf[2] = obuf[0];
- obuf[1] = clip(pan, cr * ibuf[1]);
- ibuf[3] = obuf[1];
+ float f;
+
+ f = cll * ibuf[0] + clr * ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[2] = obuf[0] = f;
+ f = cr * ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ ibuf[3] = obuf[1] = f;
obuf += 4;
ibuf += 2;
}
@@ -325,10 +348,14 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cl * ibuf[0]);
- obuf[2] = obuf[0];
- obuf[1] = clip(pan, crl * ibuf[0] + crr * ibuf[1]);
- ibuf[3] = obuf[1];
+ float f;
+
+ f = cl * ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[2] = obuf[0] =f ;
+ f = crl * ibuf[0] + crr * ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ ibuf[3] = obuf[1] = f;
obuf += 4;
ibuf += 2;
}
@@ -347,10 +374,20 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cown*ibuf[0] + cright*ibuf[1]);
- obuf[1] = clip(pan, cown*ibuf[1] + cright*ibuf[3]);
- obuf[2] = clip(pan, cown*ibuf[2] + cright*ibuf[0]);
- obuf[3] = clip(pan, cown*ibuf[3] + cright*ibuf[2]);
+ float f;
+
+ f = cown*ibuf[0] + cright*ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = cown*ibuf[1] + cright*ibuf[3];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
+ f = cown*ibuf[2] + cright*ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[2] = f;
+ f = cown*ibuf[3] + cright*ibuf[2];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[3] = f;
obuf += 4;
ibuf += 4;
}
@@ -364,10 +401,20 @@
for (done=0; done<len; done++)
{
- obuf[0] = clip(pan, cleft*ibuf[2] + cown*ibuf[0]);
- obuf[1] = clip(pan, cleft*ibuf[0] + cown*ibuf[1]);
- obuf[2] = clip(pan, cleft*ibuf[3] + cown*ibuf[2]);
- obuf[3] = clip(pan, cleft*ibuf[1] + cown*ibuf[3]);
+ float f;
+
+ f = cleft*ibuf[2] + cown*ibuf[0];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[0] = f;
+ f = cleft*ibuf[0] + cown*ibuf[1];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[1] = f;
+ f = cleft*ibuf[3] + cown*ibuf[2];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[2] = f;
+ f = cleft*ibuf[1] + cown*ibuf[3];
+ ST_SAMPLE_CLIP(f, &pan->clipped);
+ obuf[3] = f;
obuf += 4;
ibuf += 4;
}
--- a/src/pitch.c
+++ b/src/pitch.c
@@ -275,22 +275,6 @@
pitch->acc[i] += pitch->fade[pitch->step-i-1]*pitch->tmp[i];
}
-static st_sample_t clip(pitch_t pitch, PITCH_FLOAT v)
-{
- if (v < ST_SAMPLE_MIN)
- {
- pitch->clipped++;
- return ST_SAMPLE_MIN;
- }
- else if (v > ST_SAMPLE_MAX)
- {
- pitch->clipped++;
- return ST_SAMPLE_MAX;
- }
- else
- return (st_sample_t) v;
-}
-
/*
* Process options
*/
@@ -542,8 +526,14 @@
int toout = MIN(*osamp-oindex, pitch->step-pitch->iacc);
for (i=0; i<toout; i++)
- obuf[oindex++] = clip(pitch, pitch->acc[pitch->iacc++]);
+ {
+ float f;
+ f = pitch->acc[pitch->iacc++];
+ ST_SAMPLE_CLIP(f, &pitch->clipped);
+ obuf[oindex++] = f;
+ }
+
if (pitch->iacc == pitch->step)
{
pitch->state = pi_input;
@@ -589,7 +579,13 @@
/* (pitch->state == pi_output) */
for (i=0; i<*osamp && i<pitch->index-pitch->overlap;)
- obuf[i++] = clip(pitch, pitch->acc[pitch->iacc++]);
+ {
+ float f;
+
+ f = pitch->acc[pitch->iacc++];
+ ST_SAMPLE_CLIP(f, &pitch->clipped);
+ obuf[i++] = f;
+ }
/* report... */
*osamp = i;
--- a/src/polyphas.c
+++ b/src/polyphas.c
@@ -535,15 +535,6 @@
}
-static st_sample_t clipfloat(Float sample)
-{
- if (sample > ST_SAMPLE_MAX)
- return ST_SAMPLE_MAX;
- if (sample < ST_SAMPLE_MIN)
- return ST_SAMPLE_MIN;
- return sample;
-}
-
int st_poly_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
st_size_t *isamp, st_size_t *osamp)
{
@@ -621,7 +612,12 @@
if (out_size > oskip + *osamp) out_size = oskip + *osamp;
for(q=obuf, k=oskip; k < out_size; k++)
- *q++ = clipfloat(out_buf[k] * ISCALE); /* should clip-limit */
+ {
+ float f;
+ f = out_buf[k] * ISCALE; /* should clip-limit */
+ ST_SAMPLE_CLIP(f, NULL);
+ *q++ = f;
+ }
*osamp = q-obuf;
rate->inpipe -= *osamp;
--- a/src/resample.c
+++ b/src/resample.c
@@ -357,13 +357,8 @@
// orig: *obuf++ = r->Y[i] * ISCALE;
Float ftemp = r->Y[i] * ISCALE;
- if (ftemp > ST_SAMPLE_MAX)
- *obuf = ST_SAMPLE_MAX;
- else if (ftemp < ST_SAMPLE_MIN)
- *obuf = ST_SAMPLE_MIN;
- else
- *obuf = ftemp;
- obuf++;
+ ST_SAMPLE_CLIP(ftemp, NULL);
+ *obuf++ = ftemp;
}
*isamp = Nx;
--- a/src/sox.c
+++ b/src/sox.c
@@ -703,16 +703,7 @@
{
double sample;
sample = efftab[0].obuf[s] + ibuf[f][s];
- if (sample < ST_SAMPLE_MIN)
- {
- sample = ST_SAMPLE_MIN;
- clipped++;
- }
- else if (sample > ST_SAMPLE_MAX)
- {
- sample = ST_SAMPLE_MAX;
- clipped++;
- }
+ ST_SAMPLE_CLIP(sample, &clipped);
efftab[0].obuf[s] = sample;
}
}
@@ -1508,14 +1499,7 @@
top = buf+ct;
while (p < top) {
y = vol * *p;
- if (y < ST_SAMPLE_MIN) {
- y = ST_SAMPLE_MIN;
- clips++;
- }
- else if (y > ST_SAMPLE_MAX) {
- y = ST_SAMPLE_MAX;
- clips++;
- }
+ ST_SAMPLE_CLIP(y, &clips);
*p++ = y;
}
return clips;
--- a/src/speed.c
+++ b/src/speed.c
@@ -92,23 +92,6 @@
return ((a * x + b) * x + c) * x + d;
}
-/* clip if necessary, and report. */
-static st_sample_t clip(speed_t speed, SPEED_FLOAT v)
-{
- if (v < ST_SAMPLE_MIN)
- {
- speed->clipped++;
- return ST_SAMPLE_MIN;
- }
- else if (v > ST_SAMPLE_MAX)
- {
- speed->clipped++;
- return ST_SAMPLE_MAX;
- }
- else
- return (st_sample_t) v;
-}
-
/* get options. */
int st_speed_getopts(eff_t effp, int n, char **argv)
{
@@ -206,10 +189,15 @@
for(i = 0;
i<olen && speed->frac < ONE;
i++, speed->frac += speed->rate)
- obuf[i] = clip(speed,
- cub(speed->cbuf[0], speed->cbuf[1],
- speed->cbuf[2], speed->cbuf[3],
- speed->frac));
+ {
+ float f;
+
+ f = cub(speed->cbuf[0], speed->cbuf[1],
+ speed->cbuf[2], speed->cbuf[3],
+ speed->frac);
+ ST_SAMPLE_CLIP(f, &speed->clipped);
+ obuf[i] = f;
+ }
if (speed->frac >= ONE)
{
--- a/src/st.h
+++ b/src/st.h
@@ -56,6 +56,30 @@
#define ST_SAMPLE_TO_FLOAT_DWORD(d) ((float)(d/(ST_SAMPLE_FLOAT_SCALE)))
#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; optionally incrementing clips if its a
+ * non-NULL pointer of type st_size_t.
+ */
+#define ST_SAMPLE_CLIP(samp, clips) \
+ do { \
+ if (samp > ST_SAMPLE_MAX) \
+ { samp = ST_SAMPLE_MAX; if (clips) (*(st_size_t *)clips)++; } \
+ else if (samp < ST_SAMPLE_MIN) \
+ { samp = ST_SAMPLE_MIN; if (clips) (*(st_size_t *)clips)++; } \
+ } while (0)
+
+/* MACRO to clip a normalized floating point data between 1.0 and -1.0
+ * to those limits.; optionally incrementing clips if its a
+ * non-NULL pointer of type st_size_t.
+ */
+#define ST_NORMALIZED_CLIP(samp, clips) \
+ do { \
+ if (samp > 1) \
+ { samp = 1; if (clips) (*(st_size_t *)clips)++; } \
+ else if (samp < -1) \
+ { samp = -1; if (clips) (*(st_size_t *)clips)++; } \
+ } while (0)
+
/* Maximum value size type can hold. (Minimum is 0). */
#define ST_SIZE_MAX 0xffffffffL
--- a/src/stretch.c
+++ b/src/stretch.c
@@ -103,26 +103,6 @@
}
*/
-/* clip amplitudes and count number of clipped values.
- */
-static st_sample_t clip(stretch_t stretch, STRETCH_FLOAT v)
-{
- if (v < ST_SAMPLE_MIN)
- {
- stretch->clipped++;
- return ST_SAMPLE_MIN;
- }
- else if (v > ST_SAMPLE_MAX)
- {
- stretch->clipped++;
- return ST_SAMPLE_MAX;
- }
- else
- {
- return (st_sample_t) v;
- }
-}
-
/*
* Process options
*/
@@ -353,8 +333,12 @@
if (stretch->state == output_state)
{
while (stretch->oindex<stretch->oshift && oindex<*osamp)
- obuf[oindex++] =
- clip(stretch, stretch->obuf[stretch->oindex++]);
+ {
+ float f;
+ f = stretch->obuf[stretch->oindex++];
+ ST_SAMPLE_CLIP(f, &stretch->clipped);
+ obuf[oindex++] = f;
+ }
if (stretch->oindex >= stretch->oshift && oindex<*osamp)
{
@@ -405,7 +389,13 @@
if (stretch->state == output_state)
{
for (; oindex<*osamp && stretch->oindex<stretch->index;)
- obuf[oindex++] = clip(stretch, stretch->obuf[stretch->oindex++]);
+ {
+ float f;
+
+ f = stretch->obuf[stretch->oindex++];
+ ST_SAMPLE_CLIP(f, &stretch->clipped);
+ obuf[oindex++] = f;
+ }
}
*osamp = oindex;
--- a/src/vol.c
+++ b/src/vol.c
@@ -133,26 +133,6 @@
return ST_SUCCESS;
}
-/* conversion. clipping could be smoother at high ends?
- * this could be a function on its own, with clip count and report
- * handled by eff_t and caller.
- */
-static st_sample_t clip(vol_t vol, const VOL_FLOAT v)
-{
- if (v > ST_SAMPLE_MAX)
- {
- vol->clipped++;
- return ST_SAMPLE_MAX;
- }
- else if (v < ST_SAMPLE_MIN)
- {
- vol->clipped++;
- return ST_SAMPLE_MIN;
- }
- /* else */
- return (st_sample_t) v;
-}
-
#ifndef MIN
#define MIN(s1,s2) ((s1)<(s2)?(s1):(s2))
#endif
@@ -203,7 +183,8 @@
sample = gain * sample;
}
- *obuf++ = clip(vol, sample);
+ ST_SAMPLE_CLIP(sample, vol->clipped);
+ *obuf++ = sample;
}
}
else
@@ -210,7 +191,11 @@
{
/* quite basic, with clipping */
for (;len>0; len--)
- *obuf++ = clip(vol, gain * *ibuf++);
+ {
+ sample = gain * *ibuf++;
+ ST_SAMPLE_CLIP(sample, vol->clipped);
+ *obuf++ = sample;
+ }
}
return ST_SUCCESS;
}