Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r90296:d15adb9f2806
Date: 2017-02-22 14:57 +0100
http://bitbucket.org/pypy/pypy/changeset/d15adb9f2806/

Log:    merge heads

diff --git a/lib_pypy/_audioop_build.py b/lib_pypy/_audioop_build.py
--- a/lib_pypy/_audioop_build.py
+++ b/lib_pypy/_audioop_build.py
@@ -301,6 +301,32 @@
 #define CHARP(cp, i) ((signed char *)(cp+i))
 #define SHORTP(cp, i) ((short *)(cp+i))
 #define LONGP(cp, i) ((Py_Int32 *)(cp+i))
+
+#if WORDS_BIGENDIAN
+#define GETINT24(cp, i)  (                              \
+        ((unsigned char *)(cp) + (i))[2] +              \
+        (((unsigned char *)(cp) + (i))[1] << 8) +       \
+        (((signed char *)(cp) + (i))[0] << 16) )
+#else
+#define GETINT24(cp, i)  (                              \
+        ((unsigned char *)(cp) + (i))[0] +              \
+        (((unsigned char *)(cp) + (i))[1] << 8) +       \
+        (((signed char *)(cp) + (i))[2] << 16) )
+#endif
+
+#if WORDS_BIGENDIAN
+#define SETINT24(cp, i, val)  do {                              \
+        ((unsigned char *)(cp) + (i))[2] = (int)(val);          \
+        ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8;     \
+        ((signed char *)(cp) + (i))[0] = (int)(val) >> 16;      \
+    } while (0)
+#else
+#define SETINT24(cp, i, val)  do {                              \
+        ((unsigned char *)(cp) + (i))[0] = (int)(val);          \
+        ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8;     \
+        ((signed char *)(cp) + (i))[2] = (int)(val) >> 16;      \
+    } while (0)
+#endif
 """
 
 C_SOURCE = _AUDIOOP_C_MODULE + r"""
@@ -362,6 +388,8 @@
                     cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
                 else if (size == 2)
                     cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
+                else if (size == 3)
+                    cur_i[chan] = ((int)GETINT24(cp, 0)) << 8;
                 else if (size == 4)
                     cur_i[chan] = (int)*LONGP(cp, 0);
                 cp += size;
@@ -384,6 +412,8 @@
                     *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
                 else if (size == 2)
                     *SHORTP(ncp, 0) = (short)(cur_o >> 16);
+                else if (size == 3)
+                    SETINT24(ncp, 0, cur_o >> 8);
                 else if (size == 4)
                     *LONGP(ncp, 0) = (Py_Int32)(cur_o);
                 ncp += size;
@@ -407,6 +437,7 @@
     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 == 3 ) val = (int)GETINT24(cp, i);
         else if ( size == 4 ) val = (int)*LONGP(cp, i);
 
         fval = (double)val*fac1;
@@ -417,10 +448,12 @@
 
         if ( size == 1 )      *CHARP(ncp, i*2) = (signed char)val1;
         else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
+        else if ( size == 3 ) SETINT24(ncp, i*2, val1);
         else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
 
         if ( size == 1 )      *CHARP(ncp, i*2+1) = (signed char)val2;
         else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
+        else if ( size == 3 ) SETINT24(ncp, i*2+3, val2);
         else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
     }
 }
@@ -437,10 +470,12 @@
     for ( i=0; i < len1; i += size ) {
         if ( size == 1 )      val1 = (int)*CHARP(cp1, i);
         else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
+        else if ( size == 3 ) val1 = (int)GETINT24(cp1, i);
         else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
 
         if ( size == 1 )      val2 = (int)*CHARP(cp2, i);
         else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
+        else if ( size == 3 ) val2 = (int)GETINT24(cp2, i);
         else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
 
         if (size < 4) {
@@ -459,6 +494,7 @@
 
         if ( size == 1 )      *CHARP(ncp, i) = (signed char)newval;
         else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
+        else if ( size == 3 ) SETINT24(ncp, i, newval);
         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
     }
 }
@@ -479,6 +515,7 @@
     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 == 3 ) val = ((int)GETINT24(cp, i)) >> 8;
         else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
 
         /* Step 1 - compute difference with previous value */
@@ -608,6 +645,7 @@
         /* Step 6 - Output value */
         if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
         else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
+        else if ( size == 3 ) SETINT24(ncp, i, valpred << 8);
         else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
     }
     state[0] = valpred;
diff --git a/lib_pypy/audioop.py b/lib_pypy/audioop.py
--- a/lib_pypy/audioop.py
+++ b/lib_pypy/audioop.py
@@ -1,10 +1,11 @@
+import sys
 import builtins
 import math
 import struct
-from fractions import gcd
+from math import gcd
 from _audioop_cffi import ffi, lib
 
-
+BIG_ENDIAN = sys.byteorder != 'little'
 _buffer = memoryview
 
 
@@ -13,9 +14,8 @@
 
 
 def _check_size(size):
-    if size != 1 and size != 2 and size != 4:
-        raise error("Size should be 1, 2 or 4")
-
+    if size < 1 or size > 4:
+        raise error("Size should be 1, 2, 3 or 4")
 
 def _check_params(length, size):
     _check_size(size)
@@ -48,18 +48,49 @@
         return "b" if signed else "B"
     elif size == 2:
         return "h" if signed else "H"
+    elif size == 3:
+        raise NotImplementedError
     elif size == 4:
         return "i" if signed else "I"
 
+def _unpack_int24(buf):
+    if BIG_ENDIAN:
+        val = (buf[2] & 0xff) | \
+               ((buf[1] & 0xff) << 8) | \
+               ((buf[0] & 0xff) << 16)
+    else:
+        val = (buf[0] & 0xff) | \
+               ((buf[1] & 0xff) << 8) | \
+               ((buf[2] & 0xff) << 16)
+    if val & 0x800000:
+        val = val - 0x1000000
+    return val
+
+def _pack_int24(into, off, val):
+    buf = _buffer(into)
+    if BIG_ENDIAN:
+        buf[off+2] = val & 0xff
+        buf[off+1] = (val >> 8) & 0xff
+        buf[off+0] = (val >> 16) & 0xff
+    else:
+        buf[off+0] = val & 0xff
+        buf[off+1] = (val >> 8) & 0xff
+        buf[off+2] = (val >> 16) & 0xff
 
 def _get_sample(cp, size, i, signed=True):
-    fmt = _struct_format(size, signed)
     start = i * size
     end = start + size
-    return struct.unpack_from(fmt, _buffer(cp)[start:end])[0]
+    chars = _buffer(cp)[start:end]
+    if size == 3:
+        return _unpack_int24(chars)
+    fmt = _struct_format(size, signed)
+    return struct.unpack_from(fmt, chars)[0]
 
 
 def _put_sample(cp, size, i, val, signed=True):
+    if size == 3:
+        _pack_int24(cp, i*size, val)
+        return
     fmt = _struct_format(size, signed)
     struct.pack_into(fmt, cp, i * size, val)
 
@@ -73,6 +104,10 @@
         return 0x7fff
     elif size == 2:
         return 0xffff
+    elif signed and size == 3:
+        return 0x7fffff
+    elif size == 3:
+        return 0xffffff
     elif signed and size == 4:
         return 0x7fffffff
     elif size == 4:
@@ -86,6 +121,8 @@
         return -0x80
     elif size == 2:
         return -0x8000
+    elif size == 3:
+        return -0x800000
     elif size == 4:
         return -0x80000000
 
@@ -109,8 +146,17 @@
     else:
         return val % (2**bits)
 
+def _check_bytes(cp):
+    # we have no argument clinic
+    try:
+        memoryview(cp)
+    except TypeError:
+        raise TypeError("a bytes-like object is required, not '%s'" % \
+                str(type(cp)))
+
 
 def getsample(cp, size, i):
+    # _check_bytes checked in _get_sample
     _check_params(len(cp), size)
     if not (0 <= i < len(cp) // size):
         raise error("Index out of range")
@@ -250,6 +296,7 @@
 
 
 def avgpp(cp, size):
+    _check_bytes(cp)
     _check_params(len(cp), size)
     sample_count = _sample_count(cp, size)
     if sample_count <= 2:
@@ -416,6 +463,7 @@
 
 
 def lin2lin(cp, size, size2):
+    _check_bytes(cp)
     _check_params(len(cp), size)
     _check_size(size2)
 
@@ -432,10 +480,14 @@
             sample <<= 24
         elif size == 2:
             sample <<= 16
+        elif size == 3:
+            sample <<= 8
         if size2 == 1:
             sample >>= 24
         elif size2 == 2:
             sample >>= 16
+        elif size2 == 3:
+            sample >>= 8
         sample = _overflow(sample, size2)
         _put_sample(result, size2, i, sample)
 
@@ -489,7 +541,8 @@
     nbytes = ceiling * bytes_per_frame
 
     rv = ffi.new("char[]", nbytes)
-    trim_index = lib.ratecv(rv, cp, frame_count, size,
+    cpbuf = ffi.from_buffer(cp)
+    trim_index = lib.ratecv(rv, cpbuf, frame_count, size,
                             nchannels, inrate, outrate,
                             state_d, prev_i, cur_i,
                             weightA, weightB)
@@ -505,6 +558,8 @@
             yield sample << 8
         elif size == 2:
             yield sample
+        elif size == 3:
+            yield sample >> 8
         elif size == 4:
             yield sample >> 16
 
@@ -514,6 +569,8 @@
         sample >>= 8
     elif size == 2:
         pass
+    elif size == 3:
+        sample <<= 8
     elif size == 4:
         sample <<= 16
     _put_sample(result, size, i, sample)
@@ -560,7 +617,8 @@
     state = _check_state(state)
     rv = ffi.new("unsigned char[]", len(cp) // size // 2)
     state_ptr = ffi.new("int[]", state)
-    lib.lin2adcpm(rv, cp, len(cp), size, state_ptr)
+    cpbuf = ffi.cast("unsigned char*", ffi.from_buffer(cp))
+    lib.lin2adcpm(rv, cpbuf, len(cp), size, state_ptr)
     return ffi.buffer(rv)[:], tuple(state_ptr)
 
 
@@ -569,7 +627,8 @@
     state = _check_state(state)
     rv = ffi.new("unsigned char[]", len(cp) * size * 2)
     state_ptr = ffi.new("int[]", state)
-    lib.adcpm2lin(rv, ffi.from_buffer(cp), len(cp), size, state_ptr)
+    cpbuf = ffi.cast("unsigned char*", ffi.from_buffer(cp))
+    lib.adcpm2lin(rv, cpbuf, len(cp), size, state_ptr)
     return ffi.buffer(rv)[:], tuple(state_ptr)
 
 def byteswap(cp, size):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to