|
|
@@ -8,24 +8,36 @@ from ctypes import * |
|
|
|
__all__ = [ 'FLACDec' ] |
|
|
|
|
|
|
|
# Find out if we need to endian swap the buffer |
|
|
|
t = array.array('H', '\x00\x01') |
|
|
|
if t[0] == 1: |
|
|
|
is_little_endian = False |
|
|
|
else: |
|
|
|
is_little_endian = True |
|
|
|
del t |
|
|
|
|
|
|
|
interleavelib = CDLL(os.path.join(os.path.dirname(__file__), '_interleave.so')) |
|
|
|
def _islittleendian(): |
|
|
|
'''Run a check to see if the box is little endian or not.''' |
|
|
|
|
|
|
|
t = array.array('H', '\x00\x01') |
|
|
|
if t[0] == 1: |
|
|
|
return False |
|
|
|
else: |
|
|
|
return True |
|
|
|
|
|
|
|
is_little_endian = _islittleendian() |
|
|
|
|
|
|
|
inter = {} |
|
|
|
|
|
|
|
for i in (16, ): |
|
|
|
f = getattr(interleavelib, 'interleave%d' % i) |
|
|
|
f.restype = None |
|
|
|
# bigendian, nchan, chanmap, chansamps, data, out |
|
|
|
outtype = locals()['c_int%d' % i] |
|
|
|
f.argtypes = [ c_int, POINTER(c_int), c_int, |
|
|
|
POINTER(POINTER(c_int32)), POINTER(outtype), ] |
|
|
|
inter[i] = outtype, f |
|
|
|
try: |
|
|
|
interleavelib = CDLL(os.path.join(os.path.dirname(__file__), '_interleave.so')) |
|
|
|
for i in (16, ): |
|
|
|
f = getattr(interleavelib, 'interleave%d' % i) |
|
|
|
f.restype = None |
|
|
|
# bigendian, nchan, chanmap, chansamps, data, out |
|
|
|
outtype = locals()['c_int%d' % i] |
|
|
|
f.argtypes = [ c_int, POINTER(c_int), c_int, |
|
|
|
POINTER(POINTER(c_int32)), POINTER(outtype), ] |
|
|
|
inter[i] = outtype, f |
|
|
|
except OSError: |
|
|
|
import warnings |
|
|
|
warnings.warn('Using slow interleaver, compile the _interleave.so module to improve performance.') |
|
|
|
|
|
|
|
inter[16] = None, lambda nchan, chanmap, blksize, inbuf, ignore: \ |
|
|
|
array.array('h', [ inbuf[chanmap[x % nchan]][x / nchan] for x in |
|
|
|
xrange(blksize * nchan)]) |
|
|
|
|
|
|
|
flaclib = CDLL('libFLAC.so') |
|
|
|
|
|
|
@@ -541,24 +553,22 @@ class FLACDec(object): |
|
|
|
#print 'sample number:', frame.header.number.sample_number |
|
|
|
self.cursamp = frame.header.number.sample_number |
|
|
|
self.curcnt = frame.header.blocksize |
|
|
|
if True: |
|
|
|
outtype, fun = inter[frame.header.bits_per_sample] |
|
|
|
outtype, fun = inter[frame.header.bits_per_sample] |
|
|
|
if outtype is None: |
|
|
|
outbuf = None |
|
|
|
else: |
|
|
|
outbuf = (outtype * (nchan * frame.header.blocksize))() |
|
|
|
# nchan, chanmap, chansamps, data, out |
|
|
|
assert nchan == 2 |
|
|
|
fun(nchan, (c_int * 2)(0, 1), |
|
|
|
frame.header.blocksize, buffer_pp, outbuf) |
|
|
|
self.curdata = array.array('h', outbuf) |
|
|
|
if is_little_endian: |
|
|
|
self.curdata.byteswap() |
|
|
|
elif frame.header.bits_per_sample == 16: |
|
|
|
self.curdata = array.array('h', |
|
|
|
[ buffer_pp[x % nchan][x / nchan] for x in |
|
|
|
xrange(frame.header.blocksize * nchan)]) |
|
|
|
if is_little_endian: |
|
|
|
self.curdata.byteswap() |
|
|
|
# nchan, chanmap, chansamps, data, out |
|
|
|
assert nchan == 2 |
|
|
|
r = fun(nchan, (c_int * 2)(0, 1), frame.header.blocksize, |
|
|
|
buffer_pp, outbuf) |
|
|
|
if outtype is None: |
|
|
|
self.curdata = r |
|
|
|
else: |
|
|
|
print 'ERROR!' |
|
|
|
self.curdata = array.array('h', outbuf) |
|
|
|
|
|
|
|
if is_little_endian: |
|
|
|
self.curdata.byteswap() |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|