ref: 4f75a1592f4833e48c1b7905d454d61a18315f5b
parent: 1bb23d65553fef31d8b588d3518e045a68620b30
author: robs <robs>
date: Sat Mar 21 15:23:44 EDT 2009
dither enhancements; calibration still to come
--- a/src/dither.c
+++ b/src/dither.c
@@ -131,14 +131,13 @@
{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.3, shi44, Shape_shibata},
+ {44100, fir, 20, 32.7, shi44, Shape_shibata},
{37800, fir, 16, 22.7, shi38, Shape_shibata},
{32000, fir, 16, 15.7, shi32, Shape_shibata},
{22050, fir, 15, 9.0, shi22, Shape_shibata},
{48000, fir, 16, 23.5, shl48, Shape_low_shibata},
- {44100, fir, 15, 23.1, shl44, Shape_low_shibata},
+ {44100, fir, 15, 24.5, shl44, Shape_low_shibata},
{44100, fir, 20, 37.5, shh44, Shape_high_shibata},
- { 0, fir, 0, 0.0, NULL, Shape_none},
};
#define MAX_N 20
@@ -193,12 +192,15 @@
if (p->auto_detect) while (len--) {
p->history = ((p->history << 1) + !!(*ibuf & (-1u >> p->prec)));
if (p->history) {
- double d = *ibuf++ + (double)(RANQD1 >> p->prec) + (RANQD1 >> p->prec);
- d /= (1 << (32 - p->prec));
- d = (int)(d < 0? d - .5 : d + .5);
- *obuf = d < (-1 << (p->prec-1))? ++effp->clips, -1 << (p->prec-1) :
- d > SOX_INT_MAX(p->prec)? ++effp->clips, SOX_INT_MAX(p->prec) : d;
- *obuf++ <<= 32 - p->prec;
+ int32_t r1 = RANQD1 >> p->prec, r2 = RANQD1 >> p->prec;
+ double d = ((double)*ibuf++ + r1 + r2) / (1 << (32 - p->prec));
+ int i = d < 0? d - .5 : d + .5;
+ if (i < (-1 << (p->prec-1)))
+ ++effp->clips, *obuf = SOX_SAMPLE_MIN;
+ else if (i > (int)SOX_INT_MAX(p->prec))
+ ++effp->clips, *obuf = SOX_INT_MAX(p->prec) << (32 - p->prec);
+ else *obuf = i << (32 - p->prec);
+ ++obuf;
if (p->dither_off)
lsx_debug("flow %u: on @ %u", effp->flow, (unsigned)p->num_output);
p->dither_off = sox_false;
@@ -212,12 +214,15 @@
++p->num_output;
}
else while (len--) {
- double d = *ibuf++ + (double)(RANQD1 >> p->prec) + (RANQD1 >> p->prec);
- d /= (1 << (32 - p->prec));
- d = (int)(d < 0? d - .5 : d + .5);
- *obuf = d < (-1 << (p->prec-1))? ++effp->clips, -1 << (p->prec-1) :
- d > SOX_INT_MAX(p->prec)? ++effp->clips, SOX_INT_MAX(p->prec) : d;
- *obuf++ <<= 32 - p->prec;
+ int32_t r1 = RANQD1 >> p->prec, r2 = RANQD1 >> p->prec;
+ double d = ((double)*ibuf++ + r1 + r2) / (1 << (32 - p->prec));
+ int i = d < 0? d - .5 : d + .5;
+ if (i <= (-1 << (p->prec-1)))
+ ++effp->clips, *obuf = SOX_SAMPLE_MIN;
+ else if (i > (int)SOX_INT_MAX(p->prec))
+ ++effp->clips, *obuf = SOX_INT_MAX(p->prec) << (32 - p->prec);
+ else *obuf = i << (32 - p->prec);
+ ++obuf;
}
return SOX_SUCCESS;
}
@@ -280,8 +285,8 @@
}
p->ranqd1 = ranqd1(sox_globals.ranqd1);
if (effp->in_signal.mult)
- *effp->in_signal.mult -= *effp->in_signal.mult * SOX_INT_MAX(32 - p->prec)
- * 2 / (SOX_INT_MAX(p->prec) << (32 - p->prec)) * mult;
+ *effp->in_signal.mult *= (SOX_SAMPLE_MAX - (1 << (31 - p->prec)) *
+ (2 * mult + 1)) / (SOX_SAMPLE_MAX - (1 << (31 - p->prec)));
lsx_debug("filter=%s auto=%i", lsx_find_enum_value(p->filter_name, filter_names)->text, p->auto_detect);
return SOX_SUCCESS;
--- a/src/dither.h
+++ b/src/dither.h
@@ -12,13 +12,13 @@
while (len--) {
if (!p->auto_detect || (p->history = ((p->history << 1) + !!(*ibuf & (-1u >> p->prec))))) {
- double d1, r = (RANQD1 >> p->prec) + (RANQD1 >> p->prec);
+ int32_t r1 = RANQD1 >> p->prec, r2 = RANQD1 >> p->prec;
#ifdef IIR
- double d, output = 0;
+ double d1, d, output = 0;
#else
- double d = *ibuf++;
+ double d1, d = *ibuf++;
#endif
- int j = 0;
+ int i, j = 0;
CONVOLVE
assert(j == N);
p->pos = p->pos? p->pos - 1 : p->pos - 1 + N;
@@ -26,13 +26,16 @@
d = *ibuf++ - output;
p->previous_outputs[p->pos + N] = p->previous_outputs[p->pos] = output;
#endif
- d1 = (d + r) / (1 << (32 - p->prec));
- d1 = (int)(d1 < 0? d1 - .5 : d1 + .5);
+ d1 = (d + r1 + r2) / (1 << (32 - p->prec));
+ i = d1 < 0? d1 - .5 : d1 + .5;
p->previous_errors[p->pos + N] = p->previous_errors[p->pos] =
- d1 * (1 << (32 - p->prec)) - d;
- *obuf = d1 < (-1 << (p->prec-1))? ++effp->clips, -1 << (p->prec-1) :
- d1 > SOX_INT_MAX(p->prec)? ++effp->clips, SOX_INT_MAX(p->prec) : d1;
- *obuf++ <<= 32 - p->prec;
+ (double)i * (1 << (32 - p->prec)) - d;
+ if (i < (-1 << (p->prec-1)))
+ ++effp->clips, *obuf = SOX_SAMPLE_MIN;
+ else if (i > (int)SOX_INT_MAX(p->prec))
+ ++effp->clips, *obuf = SOX_INT_MAX(p->prec) << (32 - p->prec);
+ else *obuf = i << (32 - p->prec);
+ ++obuf;
if (p->dither_off)
lsx_debug("flow %u: on @ %u", effp->flow, (unsigned)p->num_output);