blob: ad6f6105ecde2ab65405e804f3441860595d2405 [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)
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)
Ezio Melotti48d578c2012-03-12 23:57:18 +0200210 with self.assertWarns(UserWarning):
Ezio Melotti85769532012-03-12 23:52:40 +0200211 f = aifc.open(io.BytesIO(b))
Ezio Melotti85769532012-03-12 23:52:40 +0200212 self.assertEqual(f.getmarkers(), None)
213
214 def test_read_comm_kludge_compname_even(self):
215 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
216 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
217 b += b'NONE' + struct.pack('B', 4) + b'even' + b'\x00'
218 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
Ezio Melotti48d578c2012-03-12 23:57:18 +0200219 with self.assertWarns(UserWarning):
Ezio Melotti85769532012-03-12 23:52:40 +0200220 f = aifc.open(io.BytesIO(b))
Ezio Melotti85769532012-03-12 23:52:40 +0200221 self.assertEqual(f.getcompname(), b'even')
222
223 def test_read_comm_kludge_compname_odd(self):
224 b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
225 b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
226 b += b'NONE' + struct.pack('B', 3) + b'odd'
227 b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
Ezio Melotti48d578c2012-03-12 23:57:18 +0200228 with self.assertWarns(UserWarning):
Ezio Melotti85769532012-03-12 23:52:40 +0200229 f = aifc.open(io.BytesIO(b))
Ezio Melotti85769532012-03-12 23:52:40 +0200230 self.assertEqual(f.getcompname(), b'odd')
231
232 def test_write_params_raises(self):
233 fout = aifc.open(io.BytesIO(), 'wb')
234 wrong_params = (0, 0, 0, 0, b'WRNG', '')
235 self.assertRaises(aifc.Error, fout.setparams, wrong_params)
236 self.assertRaises(aifc.Error, fout.getparams)
237 self.assertRaises(aifc.Error, fout.setnchannels, 0)
238 self.assertRaises(aifc.Error, fout.getnchannels)
239 self.assertRaises(aifc.Error, fout.setsampwidth, 0)
240 self.assertRaises(aifc.Error, fout.getsampwidth)
241 self.assertRaises(aifc.Error, fout.setframerate, 0)
242 self.assertRaises(aifc.Error, fout.getframerate)
243 self.assertRaises(aifc.Error, fout.setcomptype, b'WRNG', '')
244 fout.aiff()
245 fout.setnchannels(1)
246 fout.setsampwidth(1)
247 fout.setframerate(1)
248 fout.setnframes(1)
249 fout.writeframes(b'\x00')
250 self.assertRaises(aifc.Error, fout.setparams, (1, 1, 1, 1, 1, 1))
251 self.assertRaises(aifc.Error, fout.setnchannels, 1)
252 self.assertRaises(aifc.Error, fout.setsampwidth, 1)
253 self.assertRaises(aifc.Error, fout.setframerate, 1)
254 self.assertRaises(aifc.Error, fout.setnframes, 1)
255 self.assertRaises(aifc.Error, fout.setcomptype, b'NONE', '')
256 self.assertRaises(aifc.Error, fout.aiff)
257 self.assertRaises(aifc.Error, fout.aifc)
258
259 def test_write_params_singles(self):
260 fout = aifc.open(io.BytesIO(), 'wb')
261 fout.aifc()
262 fout.setnchannels(1)
263 fout.setsampwidth(2)
264 fout.setframerate(3)
265 fout.setnframes(4)
266 fout.setcomptype(b'NONE', b'name')
267 self.assertEqual(fout.getnchannels(), 1)
268 self.assertEqual(fout.getsampwidth(), 2)
269 self.assertEqual(fout.getframerate(), 3)
270 self.assertEqual(fout.getnframes(), 0)
271 self.assertEqual(fout.tell(), 0)
272 self.assertEqual(fout.getcomptype(), b'NONE')
273 self.assertEqual(fout.getcompname(), b'name')
274 fout.writeframes(b'\x00' * 4 * fout.getsampwidth() * fout.getnchannels())
275 self.assertEqual(fout.getnframes(), 4)
276 self.assertEqual(fout.tell(), 4)
277
278 def test_write_params_bunch(self):
279 fout = aifc.open(io.BytesIO(), 'wb')
280 fout.aifc()
281 p = (1, 2, 3, 4, b'NONE', b'name')
282 fout.setparams(p)
283 self.assertEqual(fout.getparams(), p)
284 fout.initfp(None)
285
286 def test_write_header_raises(self):
287 fout = aifc.open(io.BytesIO(), 'wb')
288 self.assertRaises(aifc.Error, fout.close)
289 fout.setnchannels(1)
290 self.assertRaises(aifc.Error, fout.close)
291 fout.setsampwidth(1)
292 self.assertRaises(aifc.Error, fout.close)
293 fout.initfp(None)
294
295 def test_write_header_comptype_raises(self):
296 for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
297 fout = aifc.open(io.BytesIO(), 'wb')
298 fout.setsampwidth(1)
299 fout.setcomptype(comptype, b'')
300 self.assertRaises(aifc.Error, fout.close)
301 fout.initfp(None)
302
303 def test_write_markers_raises(self):
304 fout = aifc.open(io.BytesIO(), 'wb')
305 self.assertRaises(aifc.Error, fout.setmark, 0, 0, b'')
306 self.assertRaises(aifc.Error, fout.setmark, 1, -1, b'')
307 self.assertRaises(aifc.Error, fout.setmark, 1, 0, None)
308 self.assertRaises(aifc.Error, fout.getmark, 1)
309 fout.initfp(None)
310
311 def test_write_aiff_by_extension(self):
312 sampwidth = 2
313 fout = self.fout = aifc.open(TESTFN + '.aiff', 'wb')
314 fout.setparams((1, sampwidth, 1, 1, b'ULAW', b''))
315 frames = b'\x00' * fout.getnchannels() * sampwidth
316 fout.writeframes(frames)
317 fout.close()
318 f = self.f = aifc.open(TESTFN + '.aiff', 'rb')
319 self.assertEqual(f.getcomptype(), b'NONE')
320 f.close()
321
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100322
R. David Murrayb507d2e2009-04-29 15:34:32 +0000323def test_main():
324 run_unittest(AIFCTest)
Antoine Pitrou03757ec2012-01-17 17:13:04 +0100325 run_unittest(AIFCLowLevelTest)
R. David Murrayb507d2e2009-04-29 15:34:32 +0000326
327
328if __name__ == "__main__":
329 unittest.main()