Commit 45e4efba authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-33781: audioop: enhance rounding double as int (GH-7447)

Move the floor() call into fbound() to call floor() on a double
rather than an int. The change should enhance the rounding.

Document also (int)double rounding mode.
parent 36c60fb2
...@@ -20,10 +20,17 @@ static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; ...@@ -20,10 +20,17 @@ static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
static int static int
fbound(double val, double minval, double maxval) fbound(double val, double minval, double maxval)
{ {
if (val > maxval) if (val > maxval) {
val = maxval; val = maxval;
else if (val < minval + 1) }
else if (val < minval + 1.0) {
val = minval; val = minval;
}
/* Round towards minus infinity (-inf) */
val = floor(val);
/* Cast double to integer: round towards zero */
return (int)val; return (int)val;
} }
...@@ -924,9 +931,8 @@ audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -924,9 +931,8 @@ audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
for (i = 0; i < fragment->len; i += width) { for (i = 0; i < fragment->len; i += width) {
double val = GETRAWSAMPLE(width, fragment->buf, i); double val = GETRAWSAMPLE(width, fragment->buf, i);
val *= factor; int ival = fbound(val * factor, minval, maxval);
val = floor(fbound(val, minval, maxval)); SETRAWSAMPLE(width, ncp, i, ival);
SETRAWSAMPLE(width, ncp, i, (int)val);
} }
return rv; return rv;
} }
...@@ -973,9 +979,9 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -973,9 +979,9 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
for (i = 0; i < len; i += width*2) { for (i = 0; i < len; i += width*2) {
double val1 = GETRAWSAMPLE(width, cp, i); double val1 = GETRAWSAMPLE(width, cp, i);
double val2 = GETRAWSAMPLE(width, cp, i + width); double val2 = GETRAWSAMPLE(width, cp, i + width);
double val = val1*lfactor + val2*rfactor; double val = val1 * lfactor + val2 * rfactor;
val = floor(fbound(val, minval, maxval)); int ival = fbound(val, minval, maxval);
SETRAWSAMPLE(width, ncp, i/2, val); SETRAWSAMPLE(width, ncp, i/2, ival);
} }
return rv; return rv;
} }
...@@ -1021,8 +1027,8 @@ audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1021,8 +1027,8 @@ audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
for (i = 0; i < fragment->len; i += width) { for (i = 0; i < fragment->len; i += width) {
double val = GETRAWSAMPLE(width, fragment->buf, i); double val = GETRAWSAMPLE(width, fragment->buf, i);
int val1 = (int)floor(fbound(val*lfactor, minval, maxval)); int val1 = fbound(val * lfactor, minval, maxval);
int val2 = (int)floor(fbound(val*rfactor, minval, maxval)); int val2 = fbound(val * rfactor, minval, maxval);
SETRAWSAMPLE(width, ncp, i*2, val1); SETRAWSAMPLE(width, ncp, i*2, val1);
SETRAWSAMPLE(width, ncp, i*2 + width, val2); SETRAWSAMPLE(width, ncp, i*2 + width, val2);
} }
...@@ -1080,7 +1086,7 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1, ...@@ -1080,7 +1086,7 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
else { else {
double fval = (double)val1 + (double)val2; double fval = (double)val1 + (double)val2;
/* truncate in case of overflow */ /* truncate in case of overflow */
newval = (int)floor(fbound(fval, minval, maxval)); newval = fbound(fval, minval, maxval);
} }
SETRAWSAMPLE(width, ncp, i, newval); SETRAWSAMPLE(width, ncp, i, newval);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment