audiotests.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. from test.test_support import findfile, TESTFN, unlink
  2. import unittest
  3. import array
  4. import io
  5. import pickle
  6. import sys
  7. import base64
  8. class UnseekableIO(file):
  9. def tell(self):
  10. raise io.UnsupportedOperation
  11. def seek(self, *args, **kwargs):
  12. raise io.UnsupportedOperation
  13. def fromhex(s):
  14. return base64.b16decode(s.replace(' ', ''))
  15. def byteswap2(data):
  16. a = array.array('h')
  17. a.fromstring(data)
  18. a.byteswap()
  19. return a.tostring()
  20. def byteswap3(data):
  21. ba = bytearray(data)
  22. ba[::3] = data[2::3]
  23. ba[2::3] = data[::3]
  24. return bytes(ba)
  25. def byteswap4(data):
  26. a = array.array('i')
  27. a.fromstring(data)
  28. a.byteswap()
  29. return a.tostring()
  30. class AudioTests:
  31. close_fd = False
  32. def setUp(self):
  33. self.f = self.fout = None
  34. def tearDown(self):
  35. if self.f is not None:
  36. self.f.close()
  37. if self.fout is not None:
  38. self.fout.close()
  39. unlink(TESTFN)
  40. def check_params(self, f, nchannels, sampwidth, framerate, nframes,
  41. comptype, compname):
  42. self.assertEqual(f.getnchannels(), nchannels)
  43. self.assertEqual(f.getsampwidth(), sampwidth)
  44. self.assertEqual(f.getframerate(), framerate)
  45. self.assertEqual(f.getnframes(), nframes)
  46. self.assertEqual(f.getcomptype(), comptype)
  47. self.assertEqual(f.getcompname(), compname)
  48. params = f.getparams()
  49. self.assertEqual(params,
  50. (nchannels, sampwidth, framerate, nframes, comptype, compname))
  51. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  52. dump = pickle.dumps(params, proto)
  53. self.assertEqual(pickle.loads(dump), params)
  54. class AudioWriteTests(AudioTests):
  55. def create_file(self, testfile):
  56. f = self.fout = self.module.open(testfile, 'wb')
  57. f.setnchannels(self.nchannels)
  58. f.setsampwidth(self.sampwidth)
  59. f.setframerate(self.framerate)
  60. f.setcomptype(self.comptype, self.compname)
  61. return f
  62. def check_file(self, testfile, nframes, frames):
  63. f = self.module.open(testfile, 'rb')
  64. try:
  65. self.assertEqual(f.getnchannels(), self.nchannels)
  66. self.assertEqual(f.getsampwidth(), self.sampwidth)
  67. self.assertEqual(f.getframerate(), self.framerate)
  68. self.assertEqual(f.getnframes(), nframes)
  69. self.assertEqual(f.readframes(nframes), frames)
  70. finally:
  71. f.close()
  72. def test_write_params(self):
  73. f = self.create_file(TESTFN)
  74. f.setnframes(self.nframes)
  75. f.writeframes(self.frames)
  76. self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
  77. self.nframes, self.comptype, self.compname)
  78. f.close()
  79. def test_write(self):
  80. f = self.create_file(TESTFN)
  81. f.setnframes(self.nframes)
  82. f.writeframes(self.frames)
  83. f.close()
  84. self.check_file(TESTFN, self.nframes, self.frames)
  85. def test_incompleted_write(self):
  86. with open(TESTFN, 'wb') as testfile:
  87. testfile.write(b'ababagalamaga')
  88. f = self.create_file(testfile)
  89. f.setnframes(self.nframes + 1)
  90. f.writeframes(self.frames)
  91. f.close()
  92. with open(TESTFN, 'rb') as testfile:
  93. self.assertEqual(testfile.read(13), b'ababagalamaga')
  94. self.check_file(testfile, self.nframes, self.frames)
  95. def test_multiple_writes(self):
  96. with open(TESTFN, 'wb') as testfile:
  97. testfile.write(b'ababagalamaga')
  98. f = self.create_file(testfile)
  99. f.setnframes(self.nframes)
  100. framesize = self.nchannels * self.sampwidth
  101. f.writeframes(self.frames[:-framesize])
  102. f.writeframes(self.frames[-framesize:])
  103. f.close()
  104. with open(TESTFN, 'rb') as testfile:
  105. self.assertEqual(testfile.read(13), b'ababagalamaga')
  106. self.check_file(testfile, self.nframes, self.frames)
  107. def test_overflowed_write(self):
  108. with open(TESTFN, 'wb') as testfile:
  109. testfile.write(b'ababagalamaga')
  110. f = self.create_file(testfile)
  111. f.setnframes(self.nframes - 1)
  112. f.writeframes(self.frames)
  113. f.close()
  114. with open(TESTFN, 'rb') as testfile:
  115. self.assertEqual(testfile.read(13), b'ababagalamaga')
  116. self.check_file(testfile, self.nframes, self.frames)
  117. def test_unseekable_read(self):
  118. f = self.create_file(TESTFN)
  119. f.setnframes(self.nframes)
  120. f.writeframes(self.frames)
  121. f.close()
  122. with UnseekableIO(TESTFN, 'rb') as testfile:
  123. self.check_file(testfile, self.nframes, self.frames)
  124. def test_unseekable_write(self):
  125. with UnseekableIO(TESTFN, 'wb') as testfile:
  126. f = self.create_file(testfile)
  127. f.setnframes(self.nframes)
  128. f.writeframes(self.frames)
  129. f.close()
  130. self.fout = None
  131. self.check_file(TESTFN, self.nframes, self.frames)
  132. def test_unseekable_incompleted_write(self):
  133. with UnseekableIO(TESTFN, 'wb') as testfile:
  134. testfile.write(b'ababagalamaga')
  135. f = self.create_file(testfile)
  136. f.setnframes(self.nframes + 1)
  137. try:
  138. f.writeframes(self.frames)
  139. except IOError:
  140. pass
  141. try:
  142. f.close()
  143. except IOError:
  144. pass
  145. with open(TESTFN, 'rb') as testfile:
  146. self.assertEqual(testfile.read(13), b'ababagalamaga')
  147. self.check_file(testfile, self.nframes + 1, self.frames)
  148. def test_unseekable_overflowed_write(self):
  149. with UnseekableIO(TESTFN, 'wb') as testfile:
  150. testfile.write(b'ababagalamaga')
  151. f = self.create_file(testfile)
  152. f.setnframes(self.nframes - 1)
  153. try:
  154. f.writeframes(self.frames)
  155. except IOError:
  156. pass
  157. try:
  158. f.close()
  159. except IOError:
  160. pass
  161. with open(TESTFN, 'rb') as testfile:
  162. self.assertEqual(testfile.read(13), b'ababagalamaga')
  163. framesize = self.nchannels * self.sampwidth
  164. self.check_file(testfile, self.nframes - 1, self.frames[:-framesize])
  165. class AudioTestsWithSourceFile(AudioTests):
  166. @classmethod
  167. def setUpClass(cls):
  168. cls.sndfilepath = findfile(cls.sndfilename, subdir='audiodata')
  169. def test_read_params(self):
  170. f = self.f = self.module.open(self.sndfilepath)
  171. #self.assertEqual(f.getfp().name, self.sndfilepath)
  172. self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
  173. self.sndfilenframes, self.comptype, self.compname)
  174. def test_close(self):
  175. with open(self.sndfilepath, 'rb') as testfile:
  176. f = self.f = self.module.open(testfile)
  177. self.assertFalse(testfile.closed)
  178. f.close()
  179. self.assertEqual(testfile.closed, self.close_fd)
  180. with open(TESTFN, 'wb') as testfile:
  181. fout = self.fout = self.module.open(testfile, 'wb')
  182. self.assertFalse(testfile.closed)
  183. with self.assertRaises(self.module.Error):
  184. fout.close()
  185. self.assertEqual(testfile.closed, self.close_fd)
  186. fout.close() # do nothing
  187. def test_read(self):
  188. framesize = self.nchannels * self.sampwidth
  189. chunk1 = self.frames[:2 * framesize]
  190. chunk2 = self.frames[2 * framesize: 4 * framesize]
  191. f = self.f = self.module.open(self.sndfilepath)
  192. self.assertEqual(f.readframes(0), b'')
  193. self.assertEqual(f.tell(), 0)
  194. self.assertEqual(f.readframes(2), chunk1)
  195. f.rewind()
  196. pos0 = f.tell()
  197. self.assertEqual(pos0, 0)
  198. self.assertEqual(f.readframes(2), chunk1)
  199. pos2 = f.tell()
  200. self.assertEqual(pos2, 2)
  201. self.assertEqual(f.readframes(2), chunk2)
  202. f.setpos(pos2)
  203. self.assertEqual(f.readframes(2), chunk2)
  204. f.setpos(pos0)
  205. self.assertEqual(f.readframes(2), chunk1)
  206. with self.assertRaises(self.module.Error):
  207. f.setpos(-1)
  208. with self.assertRaises(self.module.Error):
  209. f.setpos(f.getnframes() + 1)
  210. def test_copy(self):
  211. f = self.f = self.module.open(self.sndfilepath)
  212. fout = self.fout = self.module.open(TESTFN, 'wb')
  213. fout.setparams(f.getparams())
  214. i = 0
  215. n = f.getnframes()
  216. while n > 0:
  217. i += 1
  218. fout.writeframes(f.readframes(i))
  219. n -= i
  220. fout.close()
  221. fout = self.fout = self.module.open(TESTFN, 'rb')
  222. f.rewind()
  223. self.assertEqual(f.getparams(), fout.getparams())
  224. self.assertEqual(f.readframes(f.getnframes()),
  225. fout.readframes(fout.getnframes()))
  226. def test_read_not_from_start(self):
  227. with open(TESTFN, 'wb') as testfile:
  228. testfile.write(b'ababagalamaga')
  229. with open(self.sndfilepath, 'rb') as f:
  230. testfile.write(f.read())
  231. with open(TESTFN, 'rb') as testfile:
  232. self.assertEqual(testfile.read(13), b'ababagalamaga')
  233. f = self.module.open(testfile, 'rb')
  234. try:
  235. self.assertEqual(f.getnchannels(), self.nchannels)
  236. self.assertEqual(f.getsampwidth(), self.sampwidth)
  237. self.assertEqual(f.getframerate(), self.framerate)
  238. self.assertEqual(f.getnframes(), self.sndfilenframes)
  239. self.assertEqual(f.readframes(self.nframes), self.frames)
  240. finally:
  241. f.close()