diff options
Diffstat (limited to 'Lib/wave.py')
-rw-r--r-- | Lib/wave.py | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/Lib/wave.py b/Lib/wave.py index 54f030267a..4a223451bf 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -80,17 +80,18 @@ class Error(Exception): WAVE_FORMAT_PCM = 0x0001 -_array_fmts = None, 'b', 'h', None, 'l' +_array_fmts = None, 'b', 'h', None, 'i' -# Determine endian-ness import struct -if struct.pack("h", 1) == b"\000\001": - big_endian = 1 -else: - big_endian = 0 - +import sys from chunk import Chunk +def _byteswap3(data): + ba = bytearray(data) + ba[::3] = data[2::3] + ba[2::3] = data[::3] + return bytes(ba) + class Wave_read: """Variables used in this class: @@ -231,13 +232,14 @@ class Wave_read: self._data_seek_needed = 0 if nframes == 0: return b'' - if self._sampwidth > 1 and big_endian: + if self._sampwidth in (2, 4) and sys.byteorder == 'big': # unfortunately the fromfile() method does not take # something that only looks like a file object, so # we have to reach into the innards of the chunk object import array chunk = self._data_chunk data = array.array(_array_fmts[self._sampwidth]) + assert data.itemsize == self._sampwidth nitems = nframes * self._nchannels if nitems * self._sampwidth > chunk.chunksize - chunk.size_read: nitems = (chunk.chunksize - chunk.size_read) // self._sampwidth @@ -251,6 +253,8 @@ class Wave_read: data = data.tobytes() else: data = self._data_chunk.read(nframes * self._framesize) + if self._sampwidth == 3 and sys.byteorder == 'big': + data = _byteswap3(data) if self._convert and data: data = self._convert(data) self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth) @@ -418,13 +422,18 @@ class Wave_write: nframes = len(data) // (self._sampwidth * self._nchannels) if self._convert: data = self._convert(data) - if self._sampwidth > 1 and big_endian: + if self._sampwidth in (2, 4) and sys.byteorder == 'big': import array - data = array.array(_array_fmts[self._sampwidth], data) + a = array.array(_array_fmts[self._sampwidth]) + a.frombytes(data) + data = a + assert data.itemsize == self._sampwidth data.byteswap() data.tofile(self._file) self._datawritten = self._datawritten + len(data) * self._sampwidth else: + if self._sampwidth == 3 and sys.byteorder == 'big': + data = _byteswap3(data) self._file.write(data) self._datawritten = self._datawritten + len(data) self._nframeswritten = self._nframeswritten + nframes @@ -436,11 +445,13 @@ class Wave_write: def close(self): if self._file: - self._ensure_header_written(0) - if self._datalength != self._datawritten: - self._patchheader() - self._file.flush() - self._file = None + try: + self._ensure_header_written(0) + if self._datalength != self._datawritten: + self._patchheader() + self._file.flush() + finally: + self._file = None if self._i_opened_the_file: self._i_opened_the_file.close() self._i_opened_the_file = None |