changeset: 87026:1ee45eb6aab9 parent: 87023:2834e410d1ae parent: 87025:79b8b7c5fe8a user: Serhiy Storchaka date: Sat Nov 09 23:15:52 2013 +0200 files: Lib/test/test_wave.py Lib/wave.py Misc/NEWS description: Issue #1575020: Fixed support of 24-bit wave files on big-endian platforms. diff -r 2834e410d1ae -r 1ee45eb6aab9 Lib/test/test_wave.py --- a/Lib/test/test_wave.py Sat Nov 09 21:17:37 2013 +0200 +++ b/Lib/test/test_wave.py Sat Nov 09 23:15:52 2013 +0200 @@ -49,9 +49,6 @@ frames = audiotests.byteswap2(frames) -@unittest.skipIf(sys.byteorder == 'big', - '24-bit wave files are supported only on little-endian ' - 'platforms') class WavePCM24Test(audiotests.AudioWriteTests, audiotests.AudioTestsWithSourceFile, unittest.TestCase): diff -r 2834e410d1ae -r 1ee45eb6aab9 Lib/wave.py --- a/Lib/wave.py Sat Nov 09 21:17:37 2013 +0200 +++ b/Lib/wave.py Sat Nov 09 23:15:52 2013 +0200 @@ -87,6 +87,12 @@ from chunk import Chunk from collections import namedtuple +def _byteswap3(data): + ba = bytearray(data) + ba[::3] = data[2::3] + ba[2::3] = data[::3] + return bytes(ba) + _wave_params = namedtuple('_wave_params', 'nchannels sampwidth framerate nframes comptype compname') @@ -237,7 +243,7 @@ self._data_seek_needed = 0 if nframes == 0: return b'' - if self._sampwidth > 1 and sys.byteorder == 'big': + 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 @@ -258,6 +264,8 @@ 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) @@ -431,7 +439,7 @@ nframes = len(data) // (self._sampwidth * self._nchannels) if self._convert: data = self._convert(data) - if self._sampwidth > 1 and sys.byteorder == 'big': + if self._sampwidth in (2, 4) and sys.byteorder == 'big': import array data = array.array(_array_fmts[self._sampwidth], data) assert data.itemsize == self._sampwidth @@ -439,6 +447,8 @@ 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 diff -r 2834e410d1ae -r 1ee45eb6aab9 Misc/NEWS --- a/Misc/NEWS Sat Nov 09 21:17:37 2013 +0200 +++ b/Misc/NEWS Sat Nov 09 23:15:52 2013 +0200 @@ -34,6 +34,8 @@ Library ------- +- Issue #1575020: Fixed support of 24-bit wave files on big-endian platforms. + - Issue #19378: Fixed a number of cases in the dis module where the new "file" parameter was not being honoured correctly