Issue #18950: Fix miscellaneous bugs in the sunau module.

Au_read.readframes() now updates current file position and reads correct
number of frames from multichannel stream.  Au_write.writeframesraw() now
correctly updates current file position.  Au_read.getnframes() now returns an
integer (as in Python 2).  Au_read and Au_write now correctly works with file
object if start file position is not a zero.
This commit is contained in:
Serhiy Storchaka 2013-09-28 21:21:39 +03:00
parent d2c07a58af
commit 0300a8db49
2 changed files with 28 additions and 6 deletions

View File

@ -205,6 +205,10 @@ def initfp(self, file):
break break
else: else:
self._info = '' self._info = ''
try:
self._data_pos = file.tell()
except (AttributeError, OSError):
self._data_pos = None
def getfp(self): def getfp(self):
return self._file return self._file
@ -222,7 +226,7 @@ def getnframes(self):
if self._data_size == AUDIO_UNKNOWN_SIZE: if self._data_size == AUDIO_UNKNOWN_SIZE:
return AUDIO_UNKNOWN_SIZE return AUDIO_UNKNOWN_SIZE
if self._encoding in _simple_encodings: if self._encoding in _simple_encodings:
return self._data_size / self._framesize return self._data_size // self._framesize
return 0 # XXX--must do some arithmetic here return 0 # XXX--must do some arithmetic here
def getcomptype(self): def getcomptype(self):
@ -257,7 +261,8 @@ def readframes(self, nframes):
if nframes == AUDIO_UNKNOWN_SIZE: if nframes == AUDIO_UNKNOWN_SIZE:
data = self._file.read() data = self._file.read()
else: else:
data = self._file.read(nframes * self._framesize * self._nchannels) data = self._file.read(nframes * self._framesize)
self._soundpos += len(data) // self._framesize
if self._encoding == AUDIO_FILE_ENCODING_MULAW_8: if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
import audioop import audioop
data = audioop.ulaw2lin(data, self._sampwidth) data = audioop.ulaw2lin(data, self._sampwidth)
@ -265,8 +270,10 @@ def readframes(self, nframes):
return None # XXX--not implemented yet return None # XXX--not implemented yet
def rewind(self): def rewind(self):
if self._data_pos is None:
raise OSError('cannot seek')
self._file.seek(self._data_pos)
self._soundpos = 0 self._soundpos = 0
self._file.seek(self._hdr_size)
def tell(self): def tell(self):
return self._soundpos return self._soundpos
@ -274,7 +281,9 @@ def tell(self):
def setpos(self, pos): def setpos(self, pos):
if pos < 0 or pos > self.getnframes(): if pos < 0 or pos > self.getnframes():
raise Error('position not in range') raise Error('position not in range')
self._file.seek(pos * self._framesize + self._hdr_size) if self._data_pos is None:
raise OSError('cannot seek')
self._file.seek(self._data_pos + pos * self._framesize)
self._soundpos = pos self._soundpos = pos
def close(self): def close(self):
@ -390,10 +399,10 @@ def tell(self):
def writeframesraw(self, data): def writeframesraw(self, data):
self._ensure_header_written() self._ensure_header_written()
nframes = len(data) / self._framesize
if self._comptype == 'ULAW': if self._comptype == 'ULAW':
import audioop import audioop
data = audioop.lin2ulaw(data, self._sampwidth) data = audioop.lin2ulaw(data, self._sampwidth)
nframes = len(data) // self._framesize
self._file.write(data) self._file.write(data)
self._nframeswritten = self._nframeswritten + nframes self._nframeswritten = self._nframeswritten + nframes
self._datawritten = self._datawritten + len(data) self._datawritten = self._datawritten + len(data)
@ -455,6 +464,10 @@ def _write_header(self):
length = AUDIO_UNKNOWN_SIZE length = AUDIO_UNKNOWN_SIZE
else: else:
length = self._nframes * self._framesize length = self._nframes * self._framesize
try:
self._form_length_pos = self._file.tell()
except (AttributeError, OSError):
self._form_length_pos = None
_write_u32(self._file, length) _write_u32(self._file, length)
self._datalength = length self._datalength = length
_write_u32(self._file, encoding) _write_u32(self._file, encoding)
@ -464,7 +477,9 @@ def _write_header(self):
self._file.write(b'\0'*(header_size - len(self._info) - 24)) self._file.write(b'\0'*(header_size - len(self._info) - 24))
def _patchheader(self): def _patchheader(self):
self._file.seek(8) if self._form_length_pos is None:
raise OSError('cannot seek')
self._file.seek(self._form_length_pos)
_write_u32(self._file, self._datawritten) _write_u32(self._file, self._datawritten)
self._datalength = self._datawritten self._datalength = self._datawritten
self._file.seek(0, 2) self._file.seek(0, 2)

View File

@ -71,6 +71,13 @@ Core and Builtins
Library Library
------- -------
- Issue #18950: Fix miscellaneous bugs in the sunau module.
Au_read.readframes() now updates current file position and reads correct
number of frames from multichannel stream. Au_write.writeframesraw() now
correctly updates current file position. Au_read.getnframes() now returns an
integer (as in Python 2). Au_read and Au_write now correctly works with file
object if start file position is not a zero.
- Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty - Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
bytes until end of data. bytes until end of data.