Issue #16686: Fixed a lot of bugs in audioop module.

* avgpp() and maxpp() no more crash on empty and 1-samples input fragment. They now work when peak-peak values are greater INT_MAX.
* ratecv() no more crashes on empty input fragment.
* Fixed an integer overflow in ratecv().
* Fixed an integer overflow in add() and bias() for 32-bit samples.
* reverse(), lin2lin() and ratecv() no more lose precision for 32-bit samples.
* max() and rms() no more returns negative result for 32-bit sample -0x80000000.
* minmax() now returns correct max value for 32-bit sample -0x80000000.
* avg(), mul(), tomono() and tostereo() now round negative result down and can return 32-bit sample -0x80000000.
* add() now can return 32-bit sample -0x80000000.
diff --git a/Modules/audioop.c b/Modules/audioop.c
index 9ab4834..5c69258 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -26,6 +26,21 @@
 #endif
 #endif
 
+static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
+static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x80000000};
+static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
+
+static int
+fbound(double val, double minval, double maxval)
+{
+    if (val > maxval)
+        val = maxval;
+    else if (val < minval + 1)
+        val = minval;
+    return val;
+}
+
+
 /* Code shamelessly stolen from sox, 12.17.7, g711.c
 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
 
@@ -347,7 +362,7 @@
     signed char *cp;
     Py_ssize_t len, i;
     int size, val = 0;
-    int max = 0;
+    unsigned int absval, max = 0;
 
     if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
         return 0;
@@ -357,10 +372,11 @@
         if ( size == 1 )      val = (int)*CHARP(cp, i);
         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
         else if ( size == 4 ) val = (int)*LONGP(cp, i);
-        if ( val < 0 ) val = (-val);
-        if ( val > max ) max = val;
+        if (val < 0) absval = (-val);
+        else absval = val;
+        if (absval > max) max = absval;
     }
-    return PyLong_FromLong(max);
+    return PyLong_FromUnsignedLong(max);
 }
 
 static PyObject *
@@ -369,7 +385,7 @@
     signed char *cp;
     Py_ssize_t len, i;
     int size, val = 0;
-    int min = 0x7fffffff, max = -0x7fffffff;
+    int min = 0x7fffffff, max = -0x80000000;
 
     if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
         return NULL;
@@ -406,7 +422,7 @@
     if ( len == 0 )
         val = 0;
     else
-        val = (int)(avg / (double)(len/size));
+        val = (int)floor(avg / (double)(len/size));
     return PyLong_FromLong(val);
 }
 
@@ -416,6 +432,7 @@
     signed char *cp;
     Py_ssize_t len, i;
     int size, val = 0;
+    unsigned int res;
     double sum_squares = 0.0;
 
     if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
@@ -429,10 +446,10 @@
         sum_squares += (double)val*(double)val;
     }
     if ( len == 0 )
-        val = 0;
+        res = 0;
     else
-        val = (int)sqrt(sum_squares / (double)(len/size));
-    return PyLong_FromLong(val);
+        res = (unsigned int)sqrt(sum_squares / (double)(len/size));
+    return PyLong_FromUnsignedLong(res);
 }
 
 static double _sum2(short *a, short *b, Py_ssize_t len)
@@ -624,52 +641,46 @@
     Py_ssize_t len, i;
     int size, val = 0, prevval = 0, prevextremevalid = 0,
         prevextreme = 0;
-    double avg = 0.0;
-    int diff, prevdiff, extremediff, nextreme = 0;
+    double sum = 0.0;
+    unsigned int avg;
+    int diff, prevdiff, nextreme = 0;
 
     if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
         return 0;
     if (!audioop_check_parameters(len, size))
         return NULL;
-    /* Compute first delta value ahead. Also automatically makes us
-    ** skip the first extreme value
-    */
+    if (len <= size)
+        return PyLong_FromLong(0);
     if ( size == 1 )      prevval = (int)*CHARP(cp, 0);
     else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
     else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
-    if ( size == 1 )      val = (int)*CHARP(cp, size);
-    else if ( size == 2 ) val = (int)*SHORTP(cp, size);
-    else if ( size == 4 ) val = (int)*LONGP(cp, size);
-    prevdiff = val - prevval;
-
+    prevdiff = 17; /* Anything != 0, 1 */
     for ( i=size; i<len; i+= size) {
         if ( size == 1 )      val = (int)*CHARP(cp, i);
         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
         else if ( size == 4 ) val = (int)*LONGP(cp, i);
-        diff = val - prevval;
-        if ( diff*prevdiff < 0 ) {
-            /* Derivative changed sign. Compute difference to last
-            ** extreme value and remember.
-            */
-            if ( prevextremevalid ) {
-                extremediff = prevval - prevextreme;
-                if ( extremediff < 0 )
-                    extremediff = -extremediff;
-                avg += extremediff;
-                nextreme++;
+        if (val != prevval) {
+            diff = val < prevval;
+            if (prevdiff == !diff) {
+                /* Derivative changed sign. Compute difference to last
+                ** extreme value and remember.
+                */
+                if (prevextremevalid) {
+                    sum += fabs((double)prevval - (double)prevextreme);
+                    nextreme++;
+                }
+                prevextremevalid = 1;
+                prevextreme = prevval;
             }
-            prevextremevalid = 1;
-            prevextreme = prevval;
-        }
-        prevval = val;
-        if ( diff != 0 )
+            prevval = val;
             prevdiff = diff;
+        }
     }
     if ( nextreme == 0 )
-        val = 0;
+        avg = 0;
     else
-        val = (int)(avg / (double)nextreme);
-    return PyLong_FromLong(val);
+        avg = (unsigned int)(sum / (double)nextreme);
+    return PyLong_FromUnsignedLong(avg);
 }
 
 static PyObject *
@@ -679,48 +690,47 @@
     Py_ssize_t len, i;
     int size, val = 0, prevval = 0, prevextremevalid = 0,
         prevextreme = 0;
-    int max = 0;
-    int diff, prevdiff, extremediff;
+    unsigned int max = 0, extremediff;
+    int diff, prevdiff;
 
     if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
         return 0;
     if (!audioop_check_parameters(len, size))
         return NULL;
-    /* Compute first delta value ahead. Also automatically makes us
-    ** skip the first extreme value
-    */
+    if (len <= size)
+        return PyLong_FromLong(0);
     if ( size == 1 )      prevval = (int)*CHARP(cp, 0);
     else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
     else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
-    if ( size == 1 )      val = (int)*CHARP(cp, size);
-    else if ( size == 2 ) val = (int)*SHORTP(cp, size);
-    else if ( size == 4 ) val = (int)*LONGP(cp, size);
-    prevdiff = val - prevval;
-
+    prevdiff = 17; /* Anything != 0, 1 */
     for ( i=size; i<len; i+= size) {
         if ( size == 1 )      val = (int)*CHARP(cp, i);
         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
         else if ( size == 4 ) val = (int)*LONGP(cp, i);
-        diff = val - prevval;
-        if ( diff*prevdiff < 0 ) {
-            /* Derivative changed sign. Compute difference to
-            ** last extreme value and remember.
-            */
-            if ( prevextremevalid ) {
-                extremediff = prevval - prevextreme;
-                if ( extremediff < 0 )
-                    extremediff = -extremediff;
-                if ( extremediff > max )
-                    max = extremediff;
+        if (val != prevval) {
+            diff = val < prevval;
+            if (prevdiff == !diff) {
+                /* Derivative changed sign. Compute difference to
+                ** last extreme value and remember.
+                */
+                if (prevextremevalid) {
+                    if (prevval < prevextreme)
+                        extremediff = (unsigned int)prevextreme -
+                                      (unsigned int)prevval;
+                    else
+                        extremediff = (unsigned int)prevval -
+                                      (unsigned int)prevextreme;
+                    if ( extremediff > max )
+                        max = extremediff;
+                }
+                prevextremevalid = 1;
+                prevextreme = prevval;
             }
-            prevextremevalid = 1;
-            prevextreme = prevval;
-        }
-        prevval = val;
-        if ( diff != 0 )
+            prevval = val;
             prevdiff = diff;
+        }
     }
-    return PyLong_FromLong(max);
+    return PyLong_FromUnsignedLong(max);
 }
 
 static PyObject *
@@ -755,7 +765,7 @@
     signed char *cp, *ncp;
     Py_ssize_t len, i;
     int size, val = 0;
-    double factor, fval, maxval;
+    double factor, fval, maxval, minval;
     PyObject *rv;
 
     if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
@@ -763,13 +773,8 @@
     if (!audioop_check_parameters(len, size))
         return NULL;
 
-    if ( size == 1 ) maxval = (double) 0x7f;
-    else if ( size == 2 ) maxval = (double) 0x7fff;
-    else if ( size == 4 ) maxval = (double) 0x7fffffff;
-    else {
-        PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
-        return 0;
-    }
+    maxval = (double) maxvals[size];
+    minval = (double) minvals[size];
 
     rv = PyBytes_FromStringAndSize(NULL, len);
     if ( rv == 0 )
@@ -782,9 +787,7 @@
         else if ( size == 2 ) val = (int)*SHORTP(cp, i);
         else if ( size == 4 ) val = (int)*LONGP(cp, i);
         fval = (double)val*factor;
-        if ( fval > maxval ) fval = maxval;
-        else if ( fval < -maxval ) fval = -maxval;
-        val = (int)fval;
+        val = (int)floor(fbound(fval, minval, maxval));
         if ( size == 1 )      *CHARP(ncp, i) = (signed char)val;
         else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
@@ -799,7 +802,7 @@
     signed char *cp, *ncp;
     Py_ssize_t len, i;
     int size, val1 = 0, val2 = 0;
-    double fac1, fac2, fval, maxval;
+    double fac1, fac2, fval, maxval, minval;
     PyObject *rv;
 
     if ( !PyArg_ParseTuple(args, "s*idd:tomono",
@@ -817,14 +820,8 @@
         return NULL;
     }
 
-    if ( size == 1 ) maxval = (double) 0x7f;
-    else if ( size == 2 ) maxval = (double) 0x7fff;
-    else if ( size == 4 ) maxval = (double) 0x7fffffff;
-    else {
-        PyBuffer_Release(&pcp);
-        PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
-        return 0;
-    }
+    maxval = (double) maxvals[size];
+    minval = (double) minvals[size];
 
     rv = PyBytes_FromStringAndSize(NULL, len/2);
     if ( rv == 0 ) {
@@ -842,9 +839,7 @@
         else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
         else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
         fval = (double)val1*fac1 + (double)val2*fac2;
-        if ( fval > maxval ) fval = maxval;
-        else if ( fval < -maxval ) fval = -maxval;
-        val1 = (int)fval;
+        val1 = (int)floor(fbound(fval, minval, maxval));
         if ( size == 1 )      *CHARP(ncp, i/2) = (signed char)val1;
         else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
         else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
@@ -859,7 +854,7 @@
     signed char *cp, *ncp;
     Py_ssize_t len, i;
     int size, val1, val2, val = 0;
-    double fac1, fac2, fval, maxval;
+    double fac1, fac2, fval, maxval, minval;
     PyObject *rv;
 
     if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
@@ -868,13 +863,8 @@
     if (!audioop_check_parameters(len, size))
         return NULL;
 
-    if ( size == 1 ) maxval = (double) 0x7f;
-    else if ( size == 2 ) maxval = (double) 0x7fff;
-    else if ( size == 4 ) maxval = (double) 0x7fffffff;
-    else {
-        PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
-        return 0;
-    }
+    maxval = (double) maxvals[size];
+    minval = (double) minvals[size];
 
     if (len > PY_SSIZE_T_MAX/2) {
         PyErr_SetString(PyExc_MemoryError,
@@ -894,14 +884,10 @@
         else if ( size == 4 ) val = (int)*LONGP(cp, i);
 
         fval = (double)val*fac1;
-        if ( fval > maxval ) fval = maxval;
-        else if ( fval < -maxval ) fval = -maxval;
-        val1 = (int)fval;
+        val1 = (int)floor(fbound(fval, minval, maxval));
 
         fval = (double)val*fac2;
-        if ( fval > maxval ) fval = maxval;
-        else if ( fval < -maxval ) fval = -maxval;
-        val2 = (int)fval;
+        val2 = (int)floor(fbound(fval, minval, maxval));
 
         if ( size == 1 )      *CHARP(ncp, i*2) = (signed char)val1;
         else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
@@ -919,7 +905,7 @@
 {
     signed char *cp1, *cp2, *ncp;
     Py_ssize_t len1, len2, i;
-    int size, val1 = 0, val2 = 0, maxval, newval;
+    int size, val1 = 0, val2 = 0, minval, maxval, newval;
     PyObject *rv;
 
     if ( !PyArg_ParseTuple(args, "s#s#i:add",
@@ -932,13 +918,8 @@
         return 0;
     }
 
-    if ( size == 1 ) maxval = 0x7f;
-    else if ( size == 2 ) maxval = 0x7fff;
-    else if ( size == 4 ) maxval = 0x7fffffff;
-    else {
-        PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
-        return 0;
-    }
+    maxval = maxvals[size];
+    minval = minvals[size];
 
     rv = PyBytes_FromStringAndSize(NULL, len1);
     if ( rv == 0 )
@@ -954,12 +935,19 @@
         else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
         else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
 
-        newval = val1 + val2;
-        /* truncate in case of overflow */
-        if (newval > maxval) newval = maxval;
-        else if (newval < -maxval) newval = -maxval;
-        else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
-            newval = val1 > 0 ? maxval : - maxval;
+        if (size < 4) {
+            newval = val1 + val2;
+            /* truncate in case of overflow */
+            if (newval > maxval)
+                newval = maxval;
+            else if (newval < minval)
+                newval = minval;
+        }
+        else {
+            double fval = (double)val1 + (double)val2;
+            /* truncate in case of overflow */
+            newval = (int)floor(fbound(fval, minval, maxval));
+        }
 
         if ( size == 1 )      *CHARP(ncp, i) = (signed char)newval;
         else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
@@ -973,9 +961,9 @@
 {
     signed char *cp, *ncp;
     Py_ssize_t len, i;
-    int size, val = 0;
+    int size, bias;
+    unsigned int val = 0, mask;
     PyObject *rv;
-    int bias;
 
     if ( !PyArg_ParseTuple(args, "s#ii:bias",
                       &cp, &len, &size , &bias) )
@@ -989,15 +977,20 @@
         return 0;
     ncp = (signed char *)PyBytes_AsString(rv);
 
+    mask = masks[size];
 
     for ( i=0; i < len; i += size ) {
-        if ( size == 1 )      val = (int)*CHARP(cp, i);
-        else if ( size == 2 ) val = (int)*SHORTP(cp, i);
-        else if ( size == 4 ) val = (int)*LONGP(cp, i);
+        if ( size == 1 )      val = (unsigned int)(unsigned char)*CHARP(cp, i);
+        else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
+        else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
 
-        if ( size == 1 )      *CHARP(ncp, i) = (signed char)(val+bias);
-        else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
-        else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
+        val += (unsigned int)bias;
+        /* wrap around in case of overflow */
+        val &= mask;
+
+        if ( size == 1 )      *CHARP(ncp, i) = (signed char)(unsigned char)val;
+        else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
+        else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
     }
     return rv;
 }
@@ -1024,15 +1017,15 @@
     ncp = (unsigned char *)PyBytes_AsString(rv);
 
     for ( i=0; i < len; i += size ) {
-        if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
-        else if ( size == 2 ) val = (int)*SHORTP(cp, i);
-        else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+        if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 24;
+        else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
+        else if ( size == 4 ) val = (int)*LONGP(cp, i);
 
         j = len - i - size;
 
-        if ( size == 1 )      *CHARP(ncp, j) = (signed char)(val >> 8);
-        else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
-        else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
+        if ( size == 1 )      *CHARP(ncp, j) = (signed char)(val >> 24);
+        else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
+        else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
     }
     return rv;
 }
@@ -1066,13 +1059,13 @@
     ncp = (unsigned char *)PyBytes_AsString(rv);
 
     for ( i=0, j=0; i < len; i += size, j += size2 ) {
-        if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 8;
-        else if ( size == 2 ) val = (int)*SHORTP(cp, i);
-        else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+        if ( size == 1 )      val = ((int)*CHARP(cp, i)) << 24;
+        else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
+        else if ( size == 4 ) val = (int)*LONGP(cp, i);
 
-        if ( size2 == 1 )  *CHARP(ncp, j) = (signed char)(val >> 8);
-        else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
-        else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
+        if ( size2 == 1 )  *CHARP(ncp, j) = (signed char)(val >> 24);
+        else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
+        else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
     }
     return rv;
 }
@@ -1136,6 +1129,10 @@
     d = gcd(inrate, outrate);
     inrate /= d;
     outrate /= d;
+    /* divide weightA and weightB by their greatest common divisor */
+    d = gcd(weightA, weightB);
+    weightA /= d;
+    weightA /= d;
 
     if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
         PyErr_SetString(PyExc_MemoryError,
@@ -1175,7 +1172,9 @@
     }
 
     /* str <- Space for the output buffer. */
-    {
+    if (len == 0)
+        str = PyBytes_FromStringAndSize(NULL, 0);
+    else {
         /* There are len input frames, so we need (mathematically)
            ceiling(len*outrate/inrate) output frames, and each frame
            requires bytes_per_frame bytes.  Computing this
@@ -1190,12 +1189,11 @@
         else
             str = PyBytes_FromStringAndSize(NULL,
                                             q * outrate * bytes_per_frame);
-
-        if (str == NULL) {
-            PyErr_SetString(PyExc_MemoryError,
-                "not enough memory for output buffer");
-            goto exit;
-        }
+    }
+    if (str == NULL) {
+        PyErr_SetString(PyExc_MemoryError,
+            "not enough memory for output buffer");
+        goto exit;
     }
     ncp = PyBytes_AsString(str);
 
@@ -1229,32 +1227,32 @@
             for (chan = 0; chan < nchannels; chan++) {
                 prev_i[chan] = cur_i[chan];
                 if (size == 1)
-                    cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
+                    cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
                 else if (size == 2)
-                    cur_i[chan] = (int)*SHORTP(cp, 0);
+                    cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
                 else if (size == 4)
-                    cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
+                    cur_i[chan] = (int)*LONGP(cp, 0);
                 cp += size;
                 /* implements a simple digital filter */
-                cur_i[chan] =
-                    (weightA * cur_i[chan] +
-                     weightB * prev_i[chan]) /
-                    (weightA + weightB);
+                cur_i[chan] = (int)(
+                    ((double)weightA * (double)cur_i[chan] +
+                     (double)weightB * (double)prev_i[chan]) /
+                    ((double)weightA + (double)weightB));
             }
             len--;
             d += outrate;
         }
         while (d >= 0) {
             for (chan = 0; chan < nchannels; chan++) {
-                cur_o = (prev_i[chan] * d +
-                         cur_i[chan] * (outrate - d)) /
-                    outrate;
+                cur_o = (int)(((double)prev_i[chan] * (double)d +
+                         (double)cur_i[chan] * (double)(outrate - d)) /
+                    (double)outrate);
                 if (size == 1)
-                    *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
+                    *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
                 else if (size == 2)
-                    *SHORTP(ncp, 0) = (short)(cur_o);
+                    *SHORTP(ncp, 0) = (short)(cur_o >> 16);
                 else if (size == 4)
-                    *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
+                    *LONGP(ncp, 0) = (Py_Int32)(cur_o);
                 ncp += size;
             }
             d -= inrate;