blob: ee4ad6b0a32d37b2ec3f83435ef5ba5d47aa2723 [file] [log] [blame]
Ezio Melotti85769532012-03-12 23:52:40 +02001from test.support import findfile, run_unittest, TESTFN, captured_stdout, 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)
115
Sandro Tosibdd53542012-01-01 18:04:37 +0100116 def test_write_header_comptype_sampwidth(self):
117 for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
Ezio Melotti85769532012-03-12 23:52:40 +0200118 fout = aifc.open(io.BytesIO(), 'wb')
Sandro Tosibdd53542012-01-01 18:04:37 +0100119 fout.setnchannels(1)
120 fout.setframerate(1)
121 fout.setcomptype(comptype, b'')
122 fout.close()
123 self.assertEqual(fout.getsampwidth(), 2)
124 fout.initfp(None)
125
Sandro Tosi70efbef2012-01-01 22:53:08 +0100126 def test_write_markers_values(self):
Ezio Melotti85769532012-03-12 23:52:40 +0200127 fout = aifc.open(io.BytesIO(), 'wb')
Sandro Tosi70efbef2012-01-01 22:53:08 +0100128 self.assertEqual(fout.getmarkers(), None)
129 fout.setmark(1, 0, b'foo1')
130 fout.setmark(1, 1, b'foo2')
131 self.assertEqual(fout.getmark(1), (1, 1, b'foo2'))
132 self.assertEqual(fout.getmarkers(), [(1, 1, b'foo2')])
133 fout.initfp(None)
134
135 def test_read_markers(self):
136 fout = self.fout = aifc.open(TESTFN, 'wb')
137 fout.aiff()
138 fout.setparams((1, 1, 1, 1, b'NONE', b''))
139 fout.setmark(1, 0, b'odd')
140 fout.setmark(2, 0, b'even')
141 fout.writeframes(b'\x00')
142 fout.close()
143 f = self.f = aifc.open(TESTFN, 'rb')
144 self.assertEqual(f.getmarkers(), [(1, 0, b'odd'), (2, 0, b'even')])
145 self.assertEqual(f.getmark(1), (1, 0, b'odd'))
146 self.assertEqual(f.getmark(2), (2, 0, b'even'))
147 self.assertRaises(aifc.Error, f.getmark, 3)
148
R. David Murrayb507d2e2009-04-29 15:34:32 +0000149
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100150class AIFCLowLevelTest(unittest.TestCase):
151
152 def test_read_written(self):
153 def read_written(self, what):
154 f = io.BytesIO()
155 getattr(aifc, '_write_' + what)(f, x)
156 f.seek(0)
157 return getattr(aifc, '_read_' + what)(f)
158 for x in (-1, 0, 0.1, 1):
159 self.assertEqual(read_written(x, 'float'), x)
160 for x in (float('NaN'), float('Inf')):
161 self.assertEqual(read_written(x, 'float'), aifc._HUGE_VAL)
162 for x in (b'', b'foo', b'a' * 255):
163 self.assertEqual(read_written(x, 'string'), x)
164 for x in (-0x7FFFFFFF, -1, 0, 1, 0x7FFFFFFF):
165 self.assertEqual(read_written(x, 'long'), x)
166 for x in (0, 1, 0xFFFFFFFF):
167 self.assertEqual(read_written(x, 'ulong'), x)
168 for x in (-0x7FFF, -1, 0, 1, 0x7FFF):
169 self.assertEqual(read_written(x, 'short'), x)
170 for x in (0, 1, 0xFFFF):
171 self.assertEqual(read_written(x, 'ushort'), x)
172
173 def test_read_raises(self):
174 f = io.BytesIO(b'\x00')
175 self.assertRaises(EOFError, aifc._read_ulong, f)
176 self.assertRaises(EOFError, aifc._read_long, f)
177 self.assertRaises(EOFError, aifc._read_ushort, f)
178 self.assertRaises(EOFError, aifc._read_short, f)
179
180 def test_write_long_string_raises(self):
181 f = io.BytesIO()
182 with self.assertRaises(ValueError):
183 aifc._write_string(f, b'too long' * 255)
184
Ezio Melotti85769532012-03-12 23:52:40 +0200185 def test_wrong_open_mode(self):
186 with self.assertRaises(aifc.Error):
187 aifc.open(TESTFN, 'wrong_mode')
188
189 def test_read_wrong_form(self):
190 b1 = io.BytesIO(b'WRNG' + struct.pack('>L', 0))
191 b2 = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'WRNG')
192 self.assertRaises(aifc.Error, aifc.open, b1)
193 self.assertRaises(aifc.Error, aifc.open, b2)
194
195 def test_read_no_comm_chunk(self):
196 b = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'AIFF')
197 self.assertRaises(aifc.Error, aifc.open, b)
198
199 def test_read_wrong_compression_type(self):
200 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
201 b += b'COMM' + struct.pack('>LhlhhLL', 23, 0, 0, 0, 0, 0, 0)
202 b += b'WRNG' + struct.pack('B', 0)
203 self.assertRaises(aifc.Error, aifc.open, io.BytesIO(b))
204
205 def test_read_wrong_marks(self):
206 b = b'FORM' + struct.pack('>L', 4) + b'AIFF'
207 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
208 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
209 b += b'MARK' + struct.pack('>LhB', 3, 1, 1)
210 with captured_stdout() as s:
211 f = aifc.open(io.BytesIO(b))
212 self.assertEqual(
213 s.getvalue(),
214 'Warning: MARK chunk contains only 0 markers instead of 1\n')
215 self.assertEqual(f.getmarkers(), None)
216
217 def test_read_comm_kludge_compname_even(self):
218 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
219 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
220 b += b'NONE' + struct.pack('B', 4) + b'even' + b'\x00'
221 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
222 with captured_stdout() as s:
223 f = aifc.open(io.BytesIO(b))
224 self.assertEqual(s.getvalue(), 'Warning: bad COMM chunk size\n')
225 self.assertEqual(f.getcompname(), b'even')
226
227 def test_read_comm_kludge_compname_odd(self):
228 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
229 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
230 b += b'NONE' + struct.pack('B', 3) + b'odd'
231 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
232 with captured_stdout() as s:
233 f = aifc.open(io.BytesIO(b))
234 self.assertEqual(s.getvalue(), 'Warning: bad COMM chunk size\n')
235 self.assertEqual(f.getcompname(), b'odd')
236
237 def test_write_params_raises(self):
238 fout = aifc.open(io.BytesIO(), 'wb')
239 wrong_params = (0, 0, 0, 0, b'WRNG', '')
240 self.assertRaises(aifc.Error, fout.setparams, wrong_params)
241 self.assertRaises(aifc.Error, fout.getparams)
242 self.assertRaises(aifc.Error, fout.setnchannels, 0)
243 self.assertRaises(aifc.Error, fout.getnchannels)
244 self.assertRaises(aifc.Error, fout.setsampwidth, 0)
245 self.assertRaises(aifc.Error, fout.getsampwidth)
246 self.assertRaises(aifc.Error, fout.setframerate, 0)
247 self.assertRaises(aifc.Error, fout.getframerate)
248 self.assertRaises(aifc.Error, fout.setcomptype, b'WRNG', '')
249 fout.aiff()
250 fout.setnchannels(1)
251 fout.setsampwidth(1)
252 fout.setframerate(1)
253 fout.setnframes(1)
254 fout.writeframes(b'\x00')
255 self.assertRaises(aifc.Error, fout.setparams, (1, 1, 1, 1, 1, 1))
256 self.assertRaises(aifc.Error, fout.setnchannels, 1)
257 self.assertRaises(aifc.Error, fout.setsampwidth, 1)
258 self.assertRaises(aifc.Error, fout.setframerate, 1)
259 self.assertRaises(aifc.Error, fout.setnframes, 1)
260 self.assertRaises(aifc.Error, fout.setcomptype, b'NONE', '')
261 self.assertRaises(aifc.Error, fout.aiff)
262 self.assertRaises(aifc.Error, fout.aifc)
263
264 def test_write_params_singles(self):
265 fout = aifc.open(io.BytesIO(), 'wb')
266 fout.aifc()
267 fout.setnchannels(1)
268 fout.setsampwidth(2)
269 fout.setframerate(3)
270 fout.setnframes(4)
271 fout.setcomptype(b'NONE', b'name')
272 self.assertEqual(fout.getnchannels(), 1)
273 self.assertEqual(fout.getsampwidth(), 2)
274 self.assertEqual(fout.getframerate(), 3)
275 self.assertEqual(fout.getnframes(), 0)
276 self.assertEqual(fout.tell(), 0)
277 self.assertEqual(fout.getcomptype(), b'NONE')
278 self.assertEqual(fout.getcompname(), b'name')
279 fout.writeframes(b'\x00' * 4 * fout.getsampwidth() * fout.getnchannels())
280 self.assertEqual(fout.getnframes(), 4)
281 self.assertEqual(fout.tell(), 4)
282
283 def test_write_params_bunch(self):
284 fout = aifc.open(io.BytesIO(), 'wb')
285 fout.aifc()
286 p = (1, 2, 3, 4, b'NONE', b'name')
287 fout.setparams(p)
288 self.assertEqual(fout.getparams(), p)
289 fout.initfp(None)
290
291 def test_write_header_raises(self):
292 fout = aifc.open(io.BytesIO(), 'wb')
293 self.assertRaises(aifc.Error, fout.close)
294 fout.setnchannels(1)
295 self.assertRaises(aifc.Error, fout.close)
296 fout.setsampwidth(1)
297 self.assertRaises(aifc.Error, fout.close)
298 fout.initfp(None)
299
300 def test_write_header_comptype_raises(self):
301 for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
302 fout = aifc.open(io.BytesIO(), 'wb')
303 fout.setsampwidth(1)
304 fout.setcomptype(comptype, b'')
305 self.assertRaises(aifc.Error, fout.close)
306 fout.initfp(None)
307
308 def test_write_markers_raises(self):
309 fout = aifc.open(io.BytesIO(), 'wb')
310 self.assertRaises(aifc.Error, fout.setmark, 0, 0, b'')
311 self.assertRaises(aifc.Error, fout.setmark, 1, -1, b'')
312 self.assertRaises(aifc.Error, fout.setmark, 1, 0, None)
313 self.assertRaises(aifc.Error, fout.getmark, 1)
314 fout.initfp(None)
315
316 def test_write_aiff_by_extension(self):
317 sampwidth = 2
318 fout = self.fout = aifc.open(TESTFN + '.aiff', 'wb')
319 fout.setparams((1, sampwidth, 1, 1, b'ULAW', b''))
320 frames = b'\x00' * fout.getnchannels() * sampwidth
321 fout.writeframes(frames)
322 fout.close()
323 f = self.f = aifc.open(TESTFN + '.aiff', 'rb')
324 self.assertEqual(f.getcomptype(), b'NONE')
325 f.close()
326
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100327
R. David Murrayb507d2e2009-04-29 15:34:32 +0000328def test_main():
329 run_unittest(AIFCTest)
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100330 run_unittest(AIFCLowLevelTest)
R. David Murrayb507d2e2009-04-29 15:34:32 +0000331
332
333if __name__ == "__main__":
334 unittest.main()