blob: 9c0e7b96ce98ebb9b4c669b7e06cda44bdac4ba9 [file] [log] [blame]
Ezio Melotti48d578c2012-03-12 23:57:18 +02001from test.support import findfile, run_unittest, TESTFN, unlink
R. David Murrayb507d2e2009-04-29 15:34:32 +00002import unittest
R. David Murrayeb01a6c2009-04-29 20:40:42 +00003import os
Sandro Tosibdd53542012-01-01 18:04:37 +01004import io
Ezio Melotti85769532012-03-12 23:52:40 +02005import struct
R. David Murrayb507d2e2009-04-29 15:34:32 +00006
7import aifc
8
9
10class AIFCTest(unittest.TestCase):
11
12 def setUp(self):
R. David Murrayeb01a6c2009-04-29 20:40:42 +000013 self.f = self.fout = None
R. David Murrayb507d2e2009-04-29 15:34:32 +000014 self.sndfilepath = findfile('Sine-1000Hz-300ms.aif')
15
R. David Murrayeb01a6c2009-04-29 20:40:42 +000016 def tearDown(self):
17 if self.f is not None:
18 self.f.close()
19 if self.fout is not None:
20 try:
21 self.fout.close()
22 except (aifc.Error, AttributeError):
23 pass
Ezio Melotti85769532012-03-12 23:52:40 +020024 unlink(TESTFN)
25 unlink(TESTFN + '.aiff')
R. David Murrayeb01a6c2009-04-29 20:40:42 +000026
R. David Murrayb507d2e2009-04-29 15:34:32 +000027 def test_skipunknown(self):
28 #Issue 2245
29 #This file contains chunk types aifc doesn't recognize.
Benjamin Peterson25c95f12009-05-08 20:42:26 +000030 self.f = aifc.open(self.sndfilepath)
R. David Murrayb507d2e2009-04-29 15:34:32 +000031
32 def test_params(self):
R. David Murrayeb01a6c2009-04-29 20:40:42 +000033 f = self.f = aifc.open(self.sndfilepath)
Ezio Melotti85769532012-03-12 23:52:40 +020034 self.assertEqual(f.getfp().name, self.sndfilepath)
R. David Murrayb507d2e2009-04-29 15:34:32 +000035 self.assertEqual(f.getnchannels(), 2)
36 self.assertEqual(f.getsampwidth(), 2)
37 self.assertEqual(f.getframerate(), 48000)
38 self.assertEqual(f.getnframes(), 14400)
R. David Murrayb507d2e2009-04-29 15:34:32 +000039 self.assertEqual(f.getcomptype(), b'NONE')
40 self.assertEqual(f.getcompname(), b'not compressed')
41 self.assertEqual(
42 f.getparams(),
43 (2, 2, 48000, 14400, b'NONE', b'not compressed'),
44 )
R. David Murrayb507d2e2009-04-29 15:34:32 +000045
46 def test_read(self):
R. David Murrayeb01a6c2009-04-29 20:40:42 +000047 f = self.f = aifc.open(self.sndfilepath)
Ezio Melotti85769532012-03-12 23:52:40 +020048 self.assertEqual(f.readframes(0), b'')
R. David Murrayb507d2e2009-04-29 15:34:32 +000049 self.assertEqual(f.tell(), 0)
50 self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4')
51 f.rewind()
52 pos0 = f.tell()
53 self.assertEqual(pos0, 0)
54 self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4')
55 pos2 = f.tell()
56 self.assertEqual(pos2, 2)
57 self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad')
58 f.setpos(pos2)
59 self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad')
60 f.setpos(pos0)
61 self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4')
Ezio Melotti85769532012-03-12 23:52:40 +020062 with self.assertRaises(aifc.Error):
63 f.setpos(-1)
64 with self.assertRaises(aifc.Error):
65 f.setpos(f.getnframes() + 1)
R. David Murrayb507d2e2009-04-29 15:34:32 +000066
R. David Murrayeb01a6c2009-04-29 20:40:42 +000067 def test_write(self):
68 f = self.f = aifc.open(self.sndfilepath)
69 fout = self.fout = aifc.open(TESTFN, 'wb')
70 fout.aifc()
71 fout.setparams(f.getparams())
72 for frame in range(f.getnframes()):
73 fout.writeframes(f.readframes(1))
74 fout.close()
75 fout = self.fout = aifc.open(TESTFN, 'rb')
76 f.rewind()
77 self.assertEqual(f.getparams(), fout.getparams())
78 self.assertEqual(f.readframes(5), fout.readframes(5))
79
80 def test_compress(self):
81 f = self.f = aifc.open(self.sndfilepath)
82 fout = self.fout = aifc.open(TESTFN, 'wb')
83 fout.aifc()
84 fout.setnchannels(f.getnchannels())
85 fout.setsampwidth(f.getsampwidth())
86 fout.setframerate(f.getframerate())
87 fout.setcomptype(b'ULAW', b'foo')
88 for frame in range(f.getnframes()):
89 fout.writeframes(f.readframes(1))
90 fout.close()
91 self.assertLess(
92 os.stat(TESTFN).st_size,
93 os.stat(self.sndfilepath).st_size*0.75,
94 )
95 fout = self.fout = aifc.open(TESTFN, 'rb')
96 f.rewind()
97 self.assertEqual(f.getparams()[0:3], fout.getparams()[0:3])
98 self.assertEqual(fout.getcomptype(), b'ULAW')
99 self.assertEqual(fout.getcompname(), b'foo')
R. David Murrayb507d2e2009-04-29 15:34:32 +0000100
R. David Murray99352742009-05-07 18:24:38 +0000101 def test_close(self):
102 class Wrapfile(object):
103 def __init__(self, file):
104 self.file = open(file, 'rb')
105 self.closed = False
106 def close(self):
107 self.file.close()
108 self.closed = True
109 def __getattr__(self, attr): return getattr(self.file, attr)
110 testfile = Wrapfile(self.sndfilepath)
111 f = self.f = aifc.open(testfile)
112 self.assertEqual(testfile.closed, False)
113 f.close()
114 self.assertEqual(testfile.closed, True)
Serhiy Storchaka051722d2012-12-29 22:30:56 +0200115 testfile = open(TESTFN, 'wb')
116 fout = aifc.open(testfile, 'wb')
117 self.assertFalse(testfile.closed)
118 with self.assertRaises(aifc.Error):
119 fout.close()
120 self.assertTrue(testfile.closed)
121 fout.close() # do nothing
R. David Murray99352742009-05-07 18:24:38 +0000122
Sandro Tosibdd53542012-01-01 18:04:37 +0100123 def test_write_header_comptype_sampwidth(self):
124 for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
Ezio Melotti85769532012-03-12 23:52:40 +0200125 fout = aifc.open(io.BytesIO(), 'wb')
Sandro Tosibdd53542012-01-01 18:04:37 +0100126 fout.setnchannels(1)
127 fout.setframerate(1)
128 fout.setcomptype(comptype, b'')
129 fout.close()
130 self.assertEqual(fout.getsampwidth(), 2)
131 fout.initfp(None)
132
Sandro Tosi70efbef2012-01-01 22:53:08 +0100133 def test_write_markers_values(self):
Ezio Melotti85769532012-03-12 23:52:40 +0200134 fout = aifc.open(io.BytesIO(), 'wb')
Sandro Tosi70efbef2012-01-01 22:53:08 +0100135 self.assertEqual(fout.getmarkers(), None)
136 fout.setmark(1, 0, b'foo1')
137 fout.setmark(1, 1, b'foo2')
138 self.assertEqual(fout.getmark(1), (1, 1, b'foo2'))
139 self.assertEqual(fout.getmarkers(), [(1, 1, b'foo2')])
140 fout.initfp(None)
141
142 def test_read_markers(self):
143 fout = self.fout = aifc.open(TESTFN, 'wb')
144 fout.aiff()
145 fout.setparams((1, 1, 1, 1, b'NONE', b''))
146 fout.setmark(1, 0, b'odd')
147 fout.setmark(2, 0, b'even')
148 fout.writeframes(b'\x00')
149 fout.close()
150 f = self.f = aifc.open(TESTFN, 'rb')
151 self.assertEqual(f.getmarkers(), [(1, 0, b'odd'), (2, 0, b'even')])
152 self.assertEqual(f.getmark(1), (1, 0, b'odd'))
153 self.assertEqual(f.getmark(2), (2, 0, b'even'))
154 self.assertRaises(aifc.Error, f.getmark, 3)
155
R. David Murrayb507d2e2009-04-29 15:34:32 +0000156
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100157class AIFCLowLevelTest(unittest.TestCase):
158
159 def test_read_written(self):
160 def read_written(self, what):
161 f = io.BytesIO()
162 getattr(aifc, '_write_' + what)(f, x)
163 f.seek(0)
164 return getattr(aifc, '_read_' + what)(f)
165 for x in (-1, 0, 0.1, 1):
166 self.assertEqual(read_written(x, 'float'), x)
167 for x in (float('NaN'), float('Inf')):
168 self.assertEqual(read_written(x, 'float'), aifc._HUGE_VAL)
169 for x in (b'', b'foo', b'a' * 255):
170 self.assertEqual(read_written(x, 'string'), x)
171 for x in (-0x7FFFFFFF, -1, 0, 1, 0x7FFFFFFF):
172 self.assertEqual(read_written(x, 'long'), x)
173 for x in (0, 1, 0xFFFFFFFF):
174 self.assertEqual(read_written(x, 'ulong'), x)
175 for x in (-0x7FFF, -1, 0, 1, 0x7FFF):
176 self.assertEqual(read_written(x, 'short'), x)
177 for x in (0, 1, 0xFFFF):
178 self.assertEqual(read_written(x, 'ushort'), x)
179
180 def test_read_raises(self):
181 f = io.BytesIO(b'\x00')
182 self.assertRaises(EOFError, aifc._read_ulong, f)
183 self.assertRaises(EOFError, aifc._read_long, f)
184 self.assertRaises(EOFError, aifc._read_ushort, f)
185 self.assertRaises(EOFError, aifc._read_short, f)
186
187 def test_write_long_string_raises(self):
188 f = io.BytesIO()
189 with self.assertRaises(ValueError):
190 aifc._write_string(f, b'too long' * 255)
191
Ezio Melotti85769532012-03-12 23:52:40 +0200192 def test_wrong_open_mode(self):
193 with self.assertRaises(aifc.Error):
194 aifc.open(TESTFN, 'wrong_mode')
195
196 def test_read_wrong_form(self):
197 b1 = io.BytesIO(b'WRNG' + struct.pack('>L', 0))
198 b2 = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'WRNG')
199 self.assertRaises(aifc.Error, aifc.open, b1)
200 self.assertRaises(aifc.Error, aifc.open, b2)
201
202 def test_read_no_comm_chunk(self):
203 b = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'AIFF')
204 self.assertRaises(aifc.Error, aifc.open, b)
205
206 def test_read_wrong_compression_type(self):
207 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
208 b += b'COMM' + struct.pack('>LhlhhLL', 23, 0, 0, 0, 0, 0, 0)
209 b += b'WRNG' + struct.pack('B', 0)
210 self.assertRaises(aifc.Error, aifc.open, io.BytesIO(b))
211
212 def test_read_wrong_marks(self):
213 b = b'FORM' + struct.pack('>L', 4) + b'AIFF'
214 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
215 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
216 b += b'MARK' + struct.pack('>LhB', 3, 1, 1)
Ezio Melotti48d578c2012-03-12 23:57:18 +0200217 with self.assertWarns(UserWarning):
Ezio Melotti85769532012-03-12 23:52:40 +0200218 f = aifc.open(io.BytesIO(b))
Ezio Melotti85769532012-03-12 23:52:40 +0200219 self.assertEqual(f.getmarkers(), None)
220
221 def test_read_comm_kludge_compname_even(self):
222 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
223 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
224 b += b'NONE' + struct.pack('B', 4) + b'even' + b'\x00'
225 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
Ezio Melotti48d578c2012-03-12 23:57:18 +0200226 with self.assertWarns(UserWarning):
Ezio Melotti85769532012-03-12 23:52:40 +0200227 f = aifc.open(io.BytesIO(b))
Ezio Melotti85769532012-03-12 23:52:40 +0200228 self.assertEqual(f.getcompname(), b'even')
229
230 def test_read_comm_kludge_compname_odd(self):
231 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
232 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
233 b += b'NONE' + struct.pack('B', 3) + b'odd'
234 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
Ezio Melotti48d578c2012-03-12 23:57:18 +0200235 with self.assertWarns(UserWarning):
Ezio Melotti85769532012-03-12 23:52:40 +0200236 f = aifc.open(io.BytesIO(b))
Ezio Melotti85769532012-03-12 23:52:40 +0200237 self.assertEqual(f.getcompname(), b'odd')
238
239 def test_write_params_raises(self):
240 fout = aifc.open(io.BytesIO(), 'wb')
241 wrong_params = (0, 0, 0, 0, b'WRNG', '')
242 self.assertRaises(aifc.Error, fout.setparams, wrong_params)
243 self.assertRaises(aifc.Error, fout.getparams)
244 self.assertRaises(aifc.Error, fout.setnchannels, 0)
245 self.assertRaises(aifc.Error, fout.getnchannels)
246 self.assertRaises(aifc.Error, fout.setsampwidth, 0)
247 self.assertRaises(aifc.Error, fout.getsampwidth)
248 self.assertRaises(aifc.Error, fout.setframerate, 0)
249 self.assertRaises(aifc.Error, fout.getframerate)
250 self.assertRaises(aifc.Error, fout.setcomptype, b'WRNG', '')
251 fout.aiff()
252 fout.setnchannels(1)
253 fout.setsampwidth(1)
254 fout.setframerate(1)
255 fout.setnframes(1)
256 fout.writeframes(b'\x00')
257 self.assertRaises(aifc.Error, fout.setparams, (1, 1, 1, 1, 1, 1))
258 self.assertRaises(aifc.Error, fout.setnchannels, 1)
259 self.assertRaises(aifc.Error, fout.setsampwidth, 1)
260 self.assertRaises(aifc.Error, fout.setframerate, 1)
261 self.assertRaises(aifc.Error, fout.setnframes, 1)
262 self.assertRaises(aifc.Error, fout.setcomptype, b'NONE', '')
263 self.assertRaises(aifc.Error, fout.aiff)
264 self.assertRaises(aifc.Error, fout.aifc)
265
266 def test_write_params_singles(self):
267 fout = aifc.open(io.BytesIO(), 'wb')
268 fout.aifc()
269 fout.setnchannels(1)
270 fout.setsampwidth(2)
271 fout.setframerate(3)
272 fout.setnframes(4)
273 fout.setcomptype(b'NONE', b'name')
274 self.assertEqual(fout.getnchannels(), 1)
275 self.assertEqual(fout.getsampwidth(), 2)
276 self.assertEqual(fout.getframerate(), 3)
277 self.assertEqual(fout.getnframes(), 0)
278 self.assertEqual(fout.tell(), 0)
279 self.assertEqual(fout.getcomptype(), b'NONE')
280 self.assertEqual(fout.getcompname(), b'name')
281 fout.writeframes(b'\x00' * 4 * fout.getsampwidth() * fout.getnchannels())
282 self.assertEqual(fout.getnframes(), 4)
283 self.assertEqual(fout.tell(), 4)
284
285 def test_write_params_bunch(self):
286 fout = aifc.open(io.BytesIO(), 'wb')
287 fout.aifc()
288 p = (1, 2, 3, 4, b'NONE', b'name')
289 fout.setparams(p)
290 self.assertEqual(fout.getparams(), p)
291 fout.initfp(None)
292
293 def test_write_header_raises(self):
294 fout = aifc.open(io.BytesIO(), 'wb')
295 self.assertRaises(aifc.Error, fout.close)
Serhiy Storchaka051722d2012-12-29 22:30:56 +0200296 fout = aifc.open(io.BytesIO(), 'wb')
Ezio Melotti85769532012-03-12 23:52:40 +0200297 fout.setnchannels(1)
298 self.assertRaises(aifc.Error, fout.close)
Serhiy Storchaka051722d2012-12-29 22:30:56 +0200299 fout = aifc.open(io.BytesIO(), 'wb')
300 fout.setnchannels(1)
Ezio Melotti85769532012-03-12 23:52:40 +0200301 fout.setsampwidth(1)
302 self.assertRaises(aifc.Error, fout.close)
Ezio Melotti85769532012-03-12 23:52:40 +0200303
304 def test_write_header_comptype_raises(self):
305 for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
306 fout = aifc.open(io.BytesIO(), 'wb')
307 fout.setsampwidth(1)
308 fout.setcomptype(comptype, b'')
309 self.assertRaises(aifc.Error, fout.close)
310 fout.initfp(None)
311
312 def test_write_markers_raises(self):
313 fout = aifc.open(io.BytesIO(), 'wb')
314 self.assertRaises(aifc.Error, fout.setmark, 0, 0, b'')
315 self.assertRaises(aifc.Error, fout.setmark, 1, -1, b'')
316 self.assertRaises(aifc.Error, fout.setmark, 1, 0, None)
317 self.assertRaises(aifc.Error, fout.getmark, 1)
318 fout.initfp(None)
319
320 def test_write_aiff_by_extension(self):
321 sampwidth = 2
322 fout = self.fout = aifc.open(TESTFN + '.aiff', 'wb')
323 fout.setparams((1, sampwidth, 1, 1, b'ULAW', b''))
324 frames = b'\x00' * fout.getnchannels() * sampwidth
325 fout.writeframes(frames)
326 fout.close()
327 f = self.f = aifc.open(TESTFN + '.aiff', 'rb')
328 self.assertEqual(f.getcomptype(), b'NONE')
329 f.close()
330
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100331
R. David Murrayb507d2e2009-04-29 15:34:32 +0000332def test_main():
333 run_unittest(AIFCTest)
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100334 run_unittest(AIFCLowLevelTest)
R. David Murrayb507d2e2009-04-29 15:34:32 +0000335
336
337if __name__ == "__main__":
338 unittest.main()