diff -r 454b97887c5a Lib/aifc.py --- a/Lib/aifc.py Fri Dec 02 19:49:02 2011 +0200 +++ b/Lib/aifc.py Fri Dec 30 14:29:36 2011 +0400 @@ -274,7 +274,8 @@ # _ssnd_seek_needed -- 1 iff positioned correctly in audio # file for readframes() # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk - # _framesize -- size of one frame in the file + # _framesize -- size in bits of one frame in the file: G722 uses + # 4 bits per sample, which can result in single frame size < 1 byte def initfp(self, file): self._version = 0 @@ -384,13 +385,13 @@ if self._ssnd_seek_needed: self._ssnd_chunk.seek(0) dummy = self._ssnd_chunk.read(8) - pos = self._soundpos * self._framesize + pos = (self._soundpos * self._framesize) // 8 if pos: self._ssnd_chunk.seek(pos + 8) self._ssnd_seek_needed = 0 if nframes == 0: return b'' - data = self._ssnd_chunk.read(nframes * self._framesize) + data = self._ssnd_chunk.read((nframes * self._framesize) // 8) if self._convert and data: data = self._convert(data) self._soundpos = self._soundpos + len(data) // (self._nchannels @@ -422,7 +423,7 @@ self._nframes = _read_long(chunk) self._sampwidth = (_read_short(chunk) + 7) // 8 self._framerate = int(_read_float(chunk)) - self._framesize = self._nchannels * self._sampwidth + self._framesize = self._nchannels * self._sampwidth * 8 if self._aifc: #DEBUG: SGI's soundeditor produces a bad size :-( kludge = 0 diff -r 454b97887c5a Lib/test/test_aifc.py --- a/Lib/test/test_aifc.py Fri Dec 02 19:49:02 2011 +0200 +++ b/Lib/test/test_aifc.py Fri Dec 30 14:29:36 2011 +0400 @@ -109,6 +109,23 @@ f.close() self.assertEqual(testfile.closed, True) + def test_read_compressed_frames(self): + def check_frames(comptype, nframes, sampwidth): + fout = self.fout = aifc.open(TESTFN, 'wb') + fout.aifc() + fout.setparams((1, sampwidth, 1, nframes, comptype, b'')) + frames = b'\x00' * nframes * fout.getnchannels() * sampwidth + fout.writeframes(frames) + fout.close() + f = self.f = aifc.open(TESTFN, 'rb') + self.assertEqual(len(f.readframes(nframes)), len(frames)) + f.close() + for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw'): + for nframes in (1, 2): + check_frames(comptype, nframes, 2) + for nframes in (2, 4): + check_frames(b'G722', nframes, 2) + def test_main(): run_unittest(AIFCTest)