[pypy-commit] pypy py3.5: audioop support size == 3
plan_rich
pypy.commits at gmail.com
Wed Feb 22 08:39:15 EST 2017
Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5
Changeset: r90292:a4c46e6650b2
Date: 2017-02-22 14:20 +0100
http://bitbucket.org/pypy/pypy/changeset/a4c46e6650b2/
Log: audioop support size == 3
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)) << 16;
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, val1);
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
@@ -47,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)
@@ -108,8 +140,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")
@@ -249,6 +290,7 @@
def avgpp(cp, size):
+ _check_bytes(cp)
_check_params(len(cp), size)
sample_count = _sample_count(cp, size)
if sample_count <= 2:
@@ -415,6 +457,7 @@
def lin2lin(cp, size, size2):
+ _check_bytes(cp)
_check_params(len(cp), size)
_check_size(size2)
@@ -504,6 +547,8 @@
yield sample << 8
elif size == 2:
yield sample
+ elif size == 3:
+ yield sample >> 8
elif size == 4:
yield sample >> 16
@@ -513,6 +558,8 @@
sample >>= 8
elif size == 2:
pass
+ elif size == 3:
+ sample <<= 8
elif size == 4:
sample <<= 16
_put_sample(result, size, i, sample)
More information about the pypy-commit
mailing list