1import audioop 2import sys 3import unittest 4import struct 5from test.test_support import run_unittest 6 7 8formats = { 9 1: 'b', 10 2: 'h', 11 4: 'i', 12} 13 14def pack(width, data): 15 return struct.pack('=%d%s' % (len(data), formats[width]), *data) 16 17packs = { 18 1: lambda *data: pack(1, data), 19 2: lambda *data: pack(2, data), 20 4: lambda *data: pack(4, data), 21} 22maxvalues = {w: (1 << (8 * w - 1)) - 1 for w in (1, 2, 4)} 23minvalues = {w: -1 << (8 * w - 1) for w in (1, 2, 4)} 24 25datas = { 26 1: b'\x00\x12\x45\xbb\x7f\x80\xff', 27 2: packs[2](0, 0x1234, 0x4567, -0x4567, 0x7fff, -0x8000, -1), 28 4: packs[4](0, 0x12345678, 0x456789ab, -0x456789ab, 29 0x7fffffff, -0x80000000, -1), 30} 31 32INVALID_DATA = [ 33 (b'abc', 0), 34 (b'abc', 2), 35 (b'abc', 4), 36] 37 38 39class TestAudioop(unittest.TestCase): 40 41 def test_max(self): 42 for w in 1, 2, 4: 43 self.assertEqual(audioop.max(b'', w), 0) 44 p = packs[w] 45 self.assertEqual(audioop.max(p(5), w), 5) 46 self.assertEqual(audioop.max(p(5, -8, -1), w), 8) 47 self.assertEqual(audioop.max(p(maxvalues[w]), w), maxvalues[w]) 48 self.assertEqual(audioop.max(p(minvalues[w]), w), -minvalues[w]) 49 self.assertEqual(audioop.max(datas[w], w), -minvalues[w]) 50 51 def test_minmax(self): 52 for w in 1, 2, 4: 53 self.assertEqual(audioop.minmax(b'', w), 54 (0x7fffffff, -0x80000000)) 55 p = packs[w] 56 self.assertEqual(audioop.minmax(p(5), w), (5, 5)) 57 self.assertEqual(audioop.minmax(p(5, -8, -1), w), (-8, 5)) 58 self.assertEqual(audioop.minmax(p(maxvalues[w]), w), 59 (maxvalues[w], maxvalues[w])) 60 self.assertEqual(audioop.minmax(p(minvalues[w]), w), 61 (minvalues[w], minvalues[w])) 62 self.assertEqual(audioop.minmax(datas[w], w), 63 (minvalues[w], maxvalues[w])) 64 65 def test_maxpp(self): 66 for w in 1, 2, 4: 67 self.assertEqual(audioop.maxpp(b'', w), 0) 68 self.assertEqual(audioop.maxpp(packs[w](*range(100)), w), 0) 69 self.assertEqual(audioop.maxpp(packs[w](9, 10, 5, 5, 0, 1), w), 10) 70 self.assertEqual(audioop.maxpp(datas[w], w), 71 maxvalues[w] - minvalues[w]) 72 73 def test_avg(self): 74 for w in 1, 2, 4: 75 self.assertEqual(audioop.avg(b'', w), 0) 76 p = packs[w] 77 self.assertEqual(audioop.avg(p(5), w), 5) 78 self .assertEqual(audioop.avg(p(5, 8), w), 6) 79 self.assertEqual(audioop.avg(p(5, -8), w), -2) 80 self.assertEqual(audioop.avg(p(maxvalues[w], maxvalues[w]), w), 81 maxvalues[w]) 82 self.assertEqual(audioop.avg(p(minvalues[w], minvalues[w]), w), 83 minvalues[w]) 84 self.assertEqual(audioop.avg(packs[4](0x50000000, 0x70000000), 4), 85 0x60000000) 86 self.assertEqual(audioop.avg(packs[4](-0x50000000, -0x70000000), 4), 87 -0x60000000) 88 89 def test_avgpp(self): 90 for w in 1, 2, 4: 91 self.assertEqual(audioop.avgpp(b'', w), 0) 92 self.assertEqual(audioop.avgpp(packs[w](*range(100)), w), 0) 93 self.assertEqual(audioop.avgpp(packs[w](9, 10, 5, 5, 0, 1), w), 10) 94 self.assertEqual(audioop.avgpp(datas[1], 1), 196) 95 self.assertEqual(audioop.avgpp(datas[2], 2), 50534) 96 self.assertEqual(audioop.avgpp(datas[4], 4), 3311897002) 97 98 def test_rms(self): 99 for w in 1, 2, 4: 100 self.assertEqual(audioop.rms(b'', w), 0) 101 p = packs[w] 102 self.assertEqual(audioop.rms(p(*range(100)), w), 57) 103 self.assertAlmostEqual(audioop.rms(p(maxvalues[w]) * 5, w), 104 maxvalues[w], delta=1) 105 self.assertAlmostEqual(audioop.rms(p(minvalues[w]) * 5, w), 106 -minvalues[w], delta=1) 107 self.assertEqual(audioop.rms(datas[1], 1), 77) 108 self.assertEqual(audioop.rms(datas[2], 2), 20001) 109 self.assertEqual(audioop.rms(datas[4], 4), 1310854152) 110 111 def test_cross(self): 112 for w in 1, 2, 4: 113 self.assertEqual(audioop.cross(b'', w), -1) 114 p = packs[w] 115 self.assertEqual(audioop.cross(p(0, 1, 2), w), 0) 116 self.assertEqual(audioop.cross(p(1, 2, -3, -4), w), 1) 117 self.assertEqual(audioop.cross(p(-1, -2, 3, 4), w), 1) 118 self.assertEqual(audioop.cross(p(0, minvalues[w]), w), 1) 119 self.assertEqual(audioop.cross(p(minvalues[w], maxvalues[w]), w), 1) 120 121 def test_add(self): 122 for w in 1, 2, 4: 123 self.assertEqual(audioop.add(b'', b'', w), b'') 124 self.assertEqual(audioop.add(datas[w], b'\0' * len(datas[w]), w), 125 datas[w]) 126 self.assertEqual(audioop.add(datas[1], datas[1], 1), 127 b'\x00\x24\x7f\x80\x7f\x80\xfe') 128 self.assertEqual(audioop.add(datas[2], datas[2], 2), 129 packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) 130 self.assertEqual(audioop.add(datas[4], datas[4], 4), 131 packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, 132 0x7fffffff, -0x80000000, -2)) 133 134 def test_bias(self): 135 for w in 1, 2, 4: 136 for bias in 0, 1, -1, 127, -128, 0x7fffffff, -0x80000000: 137 self.assertEqual(audioop.bias(b'', w, bias), b'') 138 self.assertEqual(audioop.bias(datas[1], 1, 1), 139 b'\x01\x13\x46\xbc\x80\x81\x00') 140 self.assertEqual(audioop.bias(datas[1], 1, -1), 141 b'\xff\x11\x44\xba\x7e\x7f\xfe') 142 self.assertEqual(audioop.bias(datas[1], 1, 0x7fffffff), 143 b'\xff\x11\x44\xba\x7e\x7f\xfe') 144 self.assertEqual(audioop.bias(datas[1], 1, -0x80000000), 145 datas[1]) 146 self.assertEqual(audioop.bias(datas[2], 2, 1), 147 packs[2](1, 0x1235, 0x4568, -0x4566, -0x8000, -0x7fff, 0)) 148 self.assertEqual(audioop.bias(datas[2], 2, -1), 149 packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2)) 150 self.assertEqual(audioop.bias(datas[2], 2, 0x7fffffff), 151 packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2)) 152 self.assertEqual(audioop.bias(datas[2], 2, -0x80000000), 153 datas[2]) 154 self.assertEqual(audioop.bias(datas[4], 4, 1), 155 packs[4](1, 0x12345679, 0x456789ac, -0x456789aa, 156 -0x80000000, -0x7fffffff, 0)) 157 self.assertEqual(audioop.bias(datas[4], 4, -1), 158 packs[4](-1, 0x12345677, 0x456789aa, -0x456789ac, 159 0x7ffffffe, 0x7fffffff, -2)) 160 self.assertEqual(audioop.bias(datas[4], 4, 0x7fffffff), 161 packs[4](0x7fffffff, -0x6dcba989, -0x3a987656, 0x3a987654, 162 -2, -1, 0x7ffffffe)) 163 self.assertEqual(audioop.bias(datas[4], 4, -0x80000000), 164 packs[4](-0x80000000, -0x6dcba988, -0x3a987655, 0x3a987655, 165 -1, 0, 0x7fffffff)) 166 167 def test_lin2lin(self): 168 for w in 1, 2, 4: 169 self.assertEqual(audioop.lin2lin(datas[w], w, w), datas[w]) 170 171 self.assertEqual(audioop.lin2lin(datas[1], 1, 2), 172 packs[2](0, 0x1200, 0x4500, -0x4500, 0x7f00, -0x8000, -0x100)) 173 self.assertEqual(audioop.lin2lin(datas[1], 1, 4), 174 packs[4](0, 0x12000000, 0x45000000, -0x45000000, 175 0x7f000000, -0x80000000, -0x1000000)) 176 self.assertEqual(audioop.lin2lin(datas[2], 2, 1), 177 b'\x00\x12\x45\xba\x7f\x80\xff') 178 self.assertEqual(audioop.lin2lin(datas[2], 2, 4), 179 packs[4](0, 0x12340000, 0x45670000, -0x45670000, 180 0x7fff0000, -0x80000000, -0x10000)) 181 self.assertEqual(audioop.lin2lin(datas[4], 4, 1), 182 b'\x00\x12\x45\xba\x7f\x80\xff') 183 self.assertEqual(audioop.lin2lin(datas[4], 4, 2), 184 packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1)) 185 186 def test_adpcm2lin(self): 187 self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 1, None), 188 (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) 189 self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 2, None), 190 (packs[2](0, 0xb, 0x29, -0x16, 0x72, -0xb3), (-179, 40))) 191 self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 4, None), 192 (packs[4](0, 0xb0000, 0x290000, -0x160000, 0x720000, 193 -0xb30000), (-179, 40))) 194 195 # Very cursory test 196 for w in 1, 2, 4: 197 self.assertEqual(audioop.adpcm2lin(b'\0' * 5, w, None), 198 (b'\0' * w * 10, (0, 0))) 199 200 def test_lin2adpcm(self): 201 self.assertEqual(audioop.lin2adpcm(datas[1], 1, None), 202 (b'\x07\x7f\x7f', (-221, 39))) 203 self.assertEqual(audioop.lin2adpcm(datas[2], 2, None), 204 (b'\x07\x7f\x7f', (31, 39))) 205 self.assertEqual(audioop.lin2adpcm(datas[4], 4, None), 206 (b'\x07\x7f\x7f', (31, 39))) 207 208 # Very cursory test 209 for w in 1, 2, 4: 210 self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None), 211 (b'\0' * 5, (0, 0))) 212 213 def test_invalid_adpcm_state(self): 214 # state must be a tuple or None, not an integer 215 self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555) 216 self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555) 217 # Issues #24456, #24457: index out of range 218 self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1)) 219 self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89)) 220 self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1)) 221 self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89)) 222 # value out of range 223 self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0)) 224 self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0)) 225 self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0)) 226 self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0)) 227 228 def test_lin2alaw(self): 229 self.assertEqual(audioop.lin2alaw(datas[1], 1), 230 b'\xd5\x87\xa4\x24\xaa\x2a\x5a') 231 self.assertEqual(audioop.lin2alaw(datas[2], 2), 232 b'\xd5\x87\xa4\x24\xaa\x2a\x55') 233 self.assertEqual(audioop.lin2alaw(datas[4], 4), 234 b'\xd5\x87\xa4\x24\xaa\x2a\x55') 235 236 def test_alaw2lin(self): 237 encoded = b'\x00\x03\x24\x2a\x51\x54\x55\x58\x6b\x71\x7f'\ 238 b'\x80\x83\xa4\xaa\xd1\xd4\xd5\xd8\xeb\xf1\xff' 239 src = [-688, -720, -2240, -4032, -9, -3, -1, -27, -244, -82, -106, 240 688, 720, 2240, 4032, 9, 3, 1, 27, 244, 82, 106] 241 for w in 1, 2, 4: 242 self.assertEqual(audioop.alaw2lin(encoded, w), 243 packs[w](*(x << (w * 8) >> 13 for x in src))) 244 245 encoded = ''.join(chr(x) for x in xrange(256)) 246 for w in 2, 4: 247 decoded = audioop.alaw2lin(encoded, w) 248 self.assertEqual(audioop.lin2alaw(decoded, w), encoded) 249 250 def test_lin2ulaw(self): 251 self.assertEqual(audioop.lin2ulaw(datas[1], 1), 252 b'\xff\xad\x8e\x0e\x80\x00\x67') 253 self.assertEqual(audioop.lin2ulaw(datas[2], 2), 254 b'\xff\xad\x8e\x0e\x80\x00\x7e') 255 self.assertEqual(audioop.lin2ulaw(datas[4], 4), 256 b'\xff\xad\x8e\x0e\x80\x00\x7e') 257 258 def test_ulaw2lin(self): 259 encoded = b'\x00\x0e\x28\x3f\x57\x6a\x76\x7c\x7e\x7f'\ 260 b'\x80\x8e\xa8\xbf\xd7\xea\xf6\xfc\xfe\xff' 261 src = [-8031, -4447, -1471, -495, -163, -53, -18, -6, -2, 0, 262 8031, 4447, 1471, 495, 163, 53, 18, 6, 2, 0] 263 for w in 1, 2, 4: 264 self.assertEqual(audioop.ulaw2lin(encoded, w), 265 packs[w](*(x << (w * 8) >> 14 for x in src))) 266 267 # Current u-law implementation has two codes fo 0: 0x7f and 0xff. 268 encoded = ''.join(chr(x) for x in range(127) + range(128, 256)) 269 for w in 2, 4: 270 decoded = audioop.ulaw2lin(encoded, w) 271 self.assertEqual(audioop.lin2ulaw(decoded, w), encoded) 272 273 def test_mul(self): 274 for w in 1, 2, 4: 275 self.assertEqual(audioop.mul(b'', w, 2), b'') 276 self.assertEqual(audioop.mul(datas[w], w, 0), 277 b'\0' * len(datas[w])) 278 self.assertEqual(audioop.mul(datas[w], w, 1), 279 datas[w]) 280 self.assertEqual(audioop.mul(datas[1], 1, 2), 281 b'\x00\x24\x7f\x80\x7f\x80\xfe') 282 self.assertEqual(audioop.mul(datas[2], 2, 2), 283 packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) 284 self.assertEqual(audioop.mul(datas[4], 4, 2), 285 packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, 286 0x7fffffff, -0x80000000, -2)) 287 288 def test_ratecv(self): 289 for w in 1, 2, 4: 290 self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 8000, None), 291 (b'', (-1, ((0, 0),)))) 292 self.assertEqual(audioop.ratecv(b'', w, 5, 8000, 8000, None), 293 (b'', (-1, ((0, 0),) * 5))) 294 self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 16000, None), 295 (b'', (-2, ((0, 0),)))) 296 self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None)[0], 297 datas[w]) 298 self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 1, 0)[0], 299 datas[w]) 300 301 state = None 302 d1, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) 303 d2, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) 304 self.assertEqual(d1 + d2, b'\000\000\001\001\002\001\000\000\001\001\002') 305 306 for w in 1, 2, 4: 307 d0, state0 = audioop.ratecv(datas[w], w, 1, 8000, 16000, None) 308 d, state = b'', None 309 for i in range(0, len(datas[w]), w): 310 d1, state = audioop.ratecv(datas[w][i:i + w], w, 1, 311 8000, 16000, state) 312 d += d1 313 self.assertEqual(d, d0) 314 self.assertEqual(state, state0) 315 316 expected = { 317 1: packs[1](0, 0x0d, 0x37, -0x26, 0x55, -0x4b, -0x14), 318 2: packs[2](0, 0x0da7, 0x3777, -0x2630, 0x5673, -0x4a64, -0x129a), 319 4: packs[4](0, 0x0da740da, 0x37777776, -0x262fc962, 320 0x56740da6, -0x4a62fc96, -0x1298bf26), 321 } 322 for w in 1, 2, 4: 323 self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 3, 1)[0], 324 expected[w]) 325 self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 30, 10)[0], 326 expected[w]) 327 328 self.assertRaises(TypeError, audioop.ratecv, b'', 1, 1, 8000, 8000, 42) 329 self.assertRaises(TypeError, audioop.ratecv, 330 b'', 1, 1, 8000, 8000, (1, (42,))) 331 332 def test_reverse(self): 333 for w in 1, 2, 4: 334 self.assertEqual(audioop.reverse(b'', w), b'') 335 self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w), 336 packs[w](2, 1, 0)) 337 338 def test_tomono(self): 339 for w in 1, 2, 4: 340 data1 = datas[w] 341 data2 = bytearray(2 * len(data1)) 342 for k in range(w): 343 data2[k::2*w] = data1[k::w] 344 self.assertEqual(audioop.tomono(str(data2), w, 1, 0), data1) 345 self.assertEqual(audioop.tomono(str(data2), w, 0, 1), b'\0' * len(data1)) 346 for k in range(w): 347 data2[k+w::2*w] = data1[k::w] 348 self.assertEqual(audioop.tomono(str(data2), w, 0.5, 0.5), data1) 349 350 def test_tostereo(self): 351 for w in 1, 2, 4: 352 data1 = datas[w] 353 data2 = bytearray(2 * len(data1)) 354 for k in range(w): 355 data2[k::2*w] = data1[k::w] 356 self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2) 357 self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2)) 358 for k in range(w): 359 data2[k+w::2*w] = data1[k::w] 360 self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2) 361 362 def test_findfactor(self): 363 self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0) 364 self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]), 365 0.0) 366 367 def test_findfit(self): 368 self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0)) 369 self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)), 370 (1, 8038.8)) 371 self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]), 372 (30, 1.0)) 373 374 def test_findmax(self): 375 self.assertEqual(audioop.findmax(datas[2], 1), 5) 376 377 def test_getsample(self): 378 for w in 1, 2, 4: 379 data = packs[w](0, 1, -1, maxvalues[w], minvalues[w]) 380 self.assertEqual(audioop.getsample(data, w, 0), 0) 381 self.assertEqual(audioop.getsample(data, w, 1), 1) 382 self.assertEqual(audioop.getsample(data, w, 2), -1) 383 self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w]) 384 self.assertEqual(audioop.getsample(data, w, 4), minvalues[w]) 385 386 def test_negativelen(self): 387 # from issue 3306, previously it segfaulted 388 self.assertRaises(audioop.error, 389 audioop.findmax, ''.join( chr(x) for x in xrange(256)), -2392392) 390 391 def test_issue7673(self): 392 state = None 393 for data, size in INVALID_DATA: 394 size2 = size 395 self.assertRaises(audioop.error, audioop.getsample, data, size, 0) 396 self.assertRaises(audioop.error, audioop.max, data, size) 397 self.assertRaises(audioop.error, audioop.minmax, data, size) 398 self.assertRaises(audioop.error, audioop.avg, data, size) 399 self.assertRaises(audioop.error, audioop.rms, data, size) 400 self.assertRaises(audioop.error, audioop.avgpp, data, size) 401 self.assertRaises(audioop.error, audioop.maxpp, data, size) 402 self.assertRaises(audioop.error, audioop.cross, data, size) 403 self.assertRaises(audioop.error, audioop.mul, data, size, 1.0) 404 self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5) 405 self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5) 406 self.assertRaises(audioop.error, audioop.add, data, data, size) 407 self.assertRaises(audioop.error, audioop.bias, data, size, 0) 408 self.assertRaises(audioop.error, audioop.reverse, data, size) 409 self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2) 410 self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state) 411 self.assertRaises(audioop.error, audioop.lin2ulaw, data, size) 412 self.assertRaises(audioop.error, audioop.lin2alaw, data, size) 413 self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) 414 415 def test_wrongsize(self): 416 data = b'abcdefgh' 417 state = None 418 for size in (-1, 0, 3, 5, 1024): 419 self.assertRaises(audioop.error, audioop.ulaw2lin, data, size) 420 self.assertRaises(audioop.error, audioop.alaw2lin, data, size) 421 self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state) 422 423def test_main(): 424 run_unittest(TestAudioop) 425 426if __name__ == '__main__': 427 test_main() 428