Author: Richard Plangger <planri...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit