summaryrefslogtreecommitdiff
path: root/Lib/wave.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/wave.py')
-rw-r--r--Lib/wave.py41
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