audiotests.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. from test.support import findfile
  2. from test.support.os_helper import TESTFN, unlink
  3. import array
  4. import io
  5. import pickle
  6. class UnseekableIO(io.FileIO):
  7. def tell(self):
  8. raise io.UnsupportedOperation
  9. def seek(self, *args, **kwargs):
  10. raise io.UnsupportedOperation
  11. class AudioTests:
  12. close_fd = False
  13. def setUp(self):
  14. self.f = self.fout = None
  15. def tearDown(self):
  16. if self.f is not None:
  17. self.f.close()
  18. if self.fout is not None:
  19. self.fout.close()
  20. unlink(TESTFN)
  21. def check_params(self, f, nchannels, sampwidth, framerate, nframes,
  22. comptype, compname):
  23. self.assertEqual(f.getnchannels(), nchannels)
  24. self.assertEqual(f.getsampwidth(), sampwidth)
  25. self.assertEqual(f.getframerate(), framerate)
  26. self.assertEqual(f.getnframes(), nframes)
  27. self.assertEqual(f.getcomptype(), comptype)
  28. self.assertEqual(f.getcompname(), compname)
  29. params = f.getparams()
  30. self.assertEqual(params,
  31. (nchannels, sampwidth, framerate, nframes, comptype, compname))
  32. self.assertEqual(params.nchannels, nchannels)
  33. self.assertEqual(params.sampwidth, sampwidth)
  34. self.assertEqual(params.framerate, framerate)
  35. self.assertEqual(params.nframes, nframes)
  36. self.assertEqual(params.comptype, comptype)
  37. self.assertEqual(params.compname, compname)
  38. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  39. dump = pickle.dumps(params, proto)
  40. self.assertEqual(pickle.loads(dump), params)
  41. class AudioWriteTests(AudioTests):
  42. def create_file(self, testfile):
  43. f = self.fout = self.module.open(testfile, 'wb')
  44. f.setnchannels(self.nchannels)
  45. f.setsampwidth(self.sampwidth)
  46. f.setframerate(self.framerate)
  47. f.setcomptype(self.comptype, self.compname)
  48. return f
  49. def check_file(self, testfile, nframes, frames):
  50. with self.module.open(testfile, 'rb') as f:
  51. self.assertEqual(f.getnchannels(), self.nchannels)
  52. self.assertEqual(f.getsampwidth(), self.sampwidth)
  53. self.assertEqual(f.getframerate(), self.framerate)
  54. self.assertEqual(f.getnframes(), nframes)
  55. self.assertEqual(f.readframes(nframes), frames)
  56. def test_write_params(self):
  57. f = self.create_file(TESTFN)
  58. f.setnframes(self.nframes)
  59. f.writeframes(self.frames)
  60. self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
  61. self.nframes, self.comptype, self.compname)
  62. f.close()
  63. def test_write_context_manager_calls_close(self):
  64. # Close checks for a minimum header and will raise an error
  65. # if it is not set, so this proves that close is called.
  66. with self.assertRaises(self.module.Error):
  67. with self.module.open(TESTFN, 'wb'):
  68. pass
  69. with self.assertRaises(self.module.Error):
  70. with open(TESTFN, 'wb') as testfile:
  71. with self.module.open(testfile):
  72. pass
  73. def test_context_manager_with_open_file(self):
  74. with open(TESTFN, 'wb') as testfile:
  75. with self.module.open(testfile) as f:
  76. f.setnchannels(self.nchannels)
  77. f.setsampwidth(self.sampwidth)
  78. f.setframerate(self.framerate)
  79. f.setcomptype(self.comptype, self.compname)
  80. self.assertEqual(testfile.closed, self.close_fd)
  81. with open(TESTFN, 'rb') as testfile:
  82. with self.module.open(testfile) as f:
  83. self.assertFalse(f.getfp().closed)
  84. params = f.getparams()
  85. self.assertEqual(params.nchannels, self.nchannels)
  86. self.assertEqual(params.sampwidth, self.sampwidth)
  87. self.assertEqual(params.framerate, self.framerate)
  88. if not self.close_fd:
  89. self.assertIsNone(f.getfp())
  90. self.assertEqual(testfile.closed, self.close_fd)
  91. def test_context_manager_with_filename(self):
  92. # If the file doesn't get closed, this test won't fail, but it will
  93. # produce a resource leak warning.
  94. with self.module.open(TESTFN, 'wb') as f:
  95. f.setnchannels(self.nchannels)
  96. f.setsampwidth(self.sampwidth)
  97. f.setframerate(self.framerate)
  98. f.setcomptype(self.comptype, self.compname)
  99. with self.module.open(TESTFN) as f:
  100. self.assertFalse(f.getfp().closed)
  101. params = f.getparams()
  102. self.assertEqual(params.nchannels, self.nchannels)
  103. self.assertEqual(params.sampwidth, self.sampwidth)
  104. self.assertEqual(params.framerate, self.framerate)
  105. if not self.close_fd:
  106. self.assertIsNone(f.getfp())
  107. def test_write(self):
  108. f = self.create_file(TESTFN)
  109. f.setnframes(self.nframes)
  110. f.writeframes(self.frames)
  111. f.close()
  112. self.check_file(TESTFN, self.nframes, self.frames)
  113. def test_write_bytearray(self):
  114. f = self.create_file(TESTFN)
  115. f.setnframes(self.nframes)
  116. f.writeframes(bytearray(self.frames))
  117. f.close()
  118. self.check_file(TESTFN, self.nframes, self.frames)
  119. def test_write_array(self):
  120. f = self.create_file(TESTFN)
  121. f.setnframes(self.nframes)
  122. f.writeframes(array.array('h', self.frames))
  123. f.close()
  124. self.check_file(TESTFN, self.nframes, self.frames)
  125. def test_write_memoryview(self):
  126. f = self.create_file(TESTFN)
  127. f.setnframes(self.nframes)
  128. f.writeframes(memoryview(self.frames))
  129. f.close()
  130. self.check_file(TESTFN, self.nframes, self.frames)
  131. def test_incompleted_write(self):
  132. with open(TESTFN, 'wb') as testfile:
  133. testfile.write(b'ababagalamaga')
  134. f = self.create_file(testfile)
  135. f.setnframes(self.nframes + 1)
  136. f.writeframes(self.frames)
  137. f.close()
  138. with open(TESTFN, 'rb') as testfile:
  139. self.assertEqual(testfile.read(13), b'ababagalamaga')
  140. self.check_file(testfile, self.nframes, self.frames)
  141. def test_multiple_writes(self):
  142. with open(TESTFN, 'wb') as testfile:
  143. testfile.write(b'ababagalamaga')
  144. f = self.create_file(testfile)
  145. f.setnframes(self.nframes)
  146. framesize = self.nchannels * self.sampwidth
  147. f.writeframes(self.frames[:-framesize])
  148. f.writeframes(self.frames[-framesize:])
  149. f.close()
  150. with open(TESTFN, 'rb') as testfile:
  151. self.assertEqual(testfile.read(13), b'ababagalamaga')
  152. self.check_file(testfile, self.nframes, self.frames)
  153. def test_overflowed_write(self):
  154. with open(TESTFN, 'wb') as testfile:
  155. testfile.write(b'ababagalamaga')
  156. f = self.create_file(testfile)
  157. f.setnframes(self.nframes - 1)
  158. f.writeframes(self.frames)
  159. f.close()
  160. with open(TESTFN, 'rb') as testfile:
  161. self.assertEqual(testfile.read(13), b'ababagalamaga')
  162. self.check_file(testfile, self.nframes, self.frames)
  163. def test_unseekable_read(self):
  164. with self.create_file(TESTFN) as f:
  165. f.setnframes(self.nframes)
  166. f.writeframes(self.frames)
  167. with UnseekableIO(TESTFN, 'rb') as testfile:
  168. self.check_file(testfile, self.nframes, self.frames)
  169. def test_unseekable_write(self):
  170. with UnseekableIO(TESTFN, 'wb') as testfile:
  171. with self.create_file(testfile) as f:
  172. f.setnframes(self.nframes)
  173. f.writeframes(self.frames)
  174. self.check_file(TESTFN, self.nframes, self.frames)
  175. def test_unseekable_incompleted_write(self):
  176. with UnseekableIO(TESTFN, 'wb') as testfile:
  177. testfile.write(b'ababagalamaga')
  178. f = self.create_file(testfile)
  179. f.setnframes(self.nframes + 1)
  180. try:
  181. f.writeframes(self.frames)
  182. except OSError:
  183. pass
  184. try:
  185. f.close()
  186. except OSError:
  187. pass
  188. with open(TESTFN, 'rb') as testfile:
  189. self.assertEqual(testfile.read(13), b'ababagalamaga')
  190. self.check_file(testfile, self.nframes + 1, self.frames)
  191. def test_unseekable_overflowed_write(self):
  192. with UnseekableIO(TESTFN, 'wb') as testfile:
  193. testfile.write(b'ababagalamaga')
  194. f = self.create_file(testfile)
  195. f.setnframes(self.nframes - 1)
  196. try:
  197. f.writeframes(self.frames)
  198. except OSError:
  199. pass
  200. try:
  201. f.close()
  202. except OSError:
  203. pass
  204. with open(TESTFN, 'rb') as testfile:
  205. self.assertEqual(testfile.read(13), b'ababagalamaga')
  206. framesize = self.nchannels * self.sampwidth
  207. self.check_file(testfile, self.nframes - 1, self.frames[:-framesize])
  208. class AudioTestsWithSourceFile(AudioTests):
  209. @classmethod
  210. def setUpClass(cls):
  211. cls.sndfilepath = findfile(cls.sndfilename, subdir='audiodata')
  212. def test_read_params(self):
  213. f = self.f = self.module.open(self.sndfilepath)
  214. #self.assertEqual(f.getfp().name, self.sndfilepath)
  215. self.check_params(f, self.nchannels, self.sampwidth, self.framerate,
  216. self.sndfilenframes, self.comptype, self.compname)
  217. def test_close(self):
  218. with open(self.sndfilepath, 'rb') as testfile:
  219. f = self.f = self.module.open(testfile)
  220. self.assertFalse(testfile.closed)
  221. f.close()
  222. self.assertEqual(testfile.closed, self.close_fd)
  223. with open(TESTFN, 'wb') as testfile:
  224. fout = self.fout = self.module.open(testfile, 'wb')
  225. self.assertFalse(testfile.closed)
  226. with self.assertRaises(self.module.Error):
  227. fout.close()
  228. self.assertEqual(testfile.closed, self.close_fd)
  229. fout.close() # do nothing
  230. def test_read(self):
  231. framesize = self.nchannels * self.sampwidth
  232. chunk1 = self.frames[:2 * framesize]
  233. chunk2 = self.frames[2 * framesize: 4 * framesize]
  234. f = self.f = self.module.open(self.sndfilepath)
  235. self.assertEqual(f.readframes(0), b'')
  236. self.assertEqual(f.tell(), 0)
  237. self.assertEqual(f.readframes(2), chunk1)
  238. f.rewind()
  239. pos0 = f.tell()
  240. self.assertEqual(pos0, 0)
  241. self.assertEqual(f.readframes(2), chunk1)
  242. pos2 = f.tell()
  243. self.assertEqual(pos2, 2)
  244. self.assertEqual(f.readframes(2), chunk2)
  245. f.setpos(pos2)
  246. self.assertEqual(f.readframes(2), chunk2)
  247. f.setpos(pos0)
  248. self.assertEqual(f.readframes(2), chunk1)
  249. with self.assertRaises(self.module.Error):
  250. f.setpos(-1)
  251. with self.assertRaises(self.module.Error):
  252. f.setpos(f.getnframes() + 1)
  253. def test_copy(self):
  254. f = self.f = self.module.open(self.sndfilepath)
  255. fout = self.fout = self.module.open(TESTFN, 'wb')
  256. fout.setparams(f.getparams())
  257. i = 0
  258. n = f.getnframes()
  259. while n > 0:
  260. i += 1
  261. fout.writeframes(f.readframes(i))
  262. n -= i
  263. fout.close()
  264. fout = self.fout = self.module.open(TESTFN, 'rb')
  265. f.rewind()
  266. self.assertEqual(f.getparams(), fout.getparams())
  267. self.assertEqual(f.readframes(f.getnframes()),
  268. fout.readframes(fout.getnframes()))
  269. def test_read_not_from_start(self):
  270. with open(TESTFN, 'wb') as testfile:
  271. testfile.write(b'ababagalamaga')
  272. with open(self.sndfilepath, 'rb') as f:
  273. testfile.write(f.read())
  274. with open(TESTFN, 'rb') as testfile:
  275. self.assertEqual(testfile.read(13), b'ababagalamaga')
  276. with self.module.open(testfile, 'rb') as f:
  277. self.assertEqual(f.getnchannels(), self.nchannels)
  278. self.assertEqual(f.getsampwidth(), self.sampwidth)
  279. self.assertEqual(f.getframerate(), self.framerate)
  280. self.assertEqual(f.getnframes(), self.sndfilenframes)
  281. self.assertEqual(f.readframes(self.nframes), self.frames)