]> granicus.if.org Git - python/commitdiff
bpo-33781: audioop: enhance rounding double as int (GH-7447) (GH-7451)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 6 Jun 2018 15:18:27 +0000 (08:18 -0700)
committerVictor Stinner <vstinner@redhat.com>
Wed, 6 Jun 2018 15:18:27 +0000 (17:18 +0200)
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.
(cherry picked from commit 45e4efba7fa2abe61d25e4f8b5bf482e19ff1280)

Co-authored-by: Victor Stinner <vstinner@redhat.com>
Modules/audioop.c

index d58204251913a8664abb523864e61c625adabda9..4aad2e517e1dbb1290fd029888f6f169e0b9bab9 100644 (file)
@@ -20,10 +20,17 @@ static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
 static int
 fbound(double val, double minval, double maxval)
 {
-    if (val > maxval)
+    if (val > maxval) {
         val = maxval;
-    else if (val < minval + 1)
+    }
+    else if (val < minval + 1.0) {
         val = minval;
+    }
+
+    /* Round towards minus infinity (-inf) */
+    val = floor(val);
+
+    /* Cast double to integer: round towards zero */
     return (int)val;
 }
 
@@ -924,9 +931,8 @@ audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
 
     for (i = 0; i < fragment->len; i += width) {
         double val = GETRAWSAMPLE(width, fragment->buf, i);
-        val *= factor;
-        val = floor(fbound(val, minval, maxval));
-        SETRAWSAMPLE(width, ncp, i, (int)val);
+        int ival = fbound(val * factor, minval, maxval);
+        SETRAWSAMPLE(width, ncp, i, ival);
     }
     return rv;
 }
@@ -973,9 +979,9 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
     for (i = 0; i < len; i += width*2) {
         double val1 = GETRAWSAMPLE(width, cp, i);
         double val2 = GETRAWSAMPLE(width, cp, i + width);
-        double val = val1*lfactor + val2*rfactor;
-        val = floor(fbound(val, minval, maxval));
-        SETRAWSAMPLE(width, ncp, i/2, val);
+        double val = val1 * lfactor + val2 * rfactor;
+        int ival = fbound(val, minval, maxval);
+        SETRAWSAMPLE(width, ncp, i/2, ival);
     }
     return rv;
 }
@@ -1021,8 +1027,8 @@ audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
 
     for (i = 0; i < fragment->len; i += width) {
         double val = GETRAWSAMPLE(width, fragment->buf, i);
-        int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
-        int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
+        int val1 = fbound(val * lfactor, minval, maxval);
+        int val2 = fbound(val * rfactor, minval, maxval);
         SETRAWSAMPLE(width, ncp, i*2, val1);
         SETRAWSAMPLE(width, ncp, i*2 + width, val2);
     }
@@ -1080,7 +1086,7 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
         else {
             double fval = (double)val1 + (double)val2;
             /* truncate in case of overflow */
-            newval = (int)floor(fbound(fval, minval, maxval));
+            newval = fbound(fval, minval, maxval);
         }
 
         SETRAWSAMPLE(width, ncp, i, newval);