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 def test_reverse(self): 329 for w in 1, 2, 4: 330 self.assertEqual(audioop.reverse(b'', w), b'') 331 self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w), 332 packs[w](2, 1, 0)) 333 334 def test_tomono(self): 335 for w in 1, 2, 4: 336 data1 = datas[w] 337 data2 = bytearray(2 * len(data1)) 338 for k in range(w): 339 data2[k::2*w] = data1[k::w] 340 self.assertEqual(audioop.tomono(str(data2), w, 1, 0), data1) 341 self.assertEqual(audioop.tomono(str(data2), w, 0, 1), b'\0' * len(data1)) 342 for k in range(w): 343 data2[k+w::2*w] = data1[k::w] 344 self.assertEqual(audioop.tomono(str(data2), w, 0.5, 0.5), data1) 345 346 def test_tostereo(self): 347 for w in 1, 2, 4: 348 data1 = datas[w] 349 data2 = bytearray(2 * len(data1)) 350 for k in range(w): 351 data2[k::2*w] = data1[k::w] 352 self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2) 353 self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2)) 354 for k in range(w): 355 data2[k+w::2*w] = data1[k::w] 356 self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2) 357 358 def test_findfactor(self): 359 self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0) 360 self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]), 361 0.0) 362 363 def test_findfit(self): 364 self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0)) 365 self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)), 366 (1, 8038.8)) 367 self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]), 368 (30, 1.0)) 369 370 def test_findmax(self): 371 self.assertEqual(audioop.findmax(datas[2], 1), 5) 372 373 def test_getsample(self): 374 for w in 1, 2, 4: 375 data = packs[w](0, 1, -1, maxvalues[w], minvalues[w]) 376 self.assertEqual(audioop.getsample(data, w, 0), 0) 377 self.assertEqual(audioop.getsample(data, w, 1), 1) 378 self.assertEqual(audioop.getsample(data, w, 2), -1) 379 self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w]) 380 self.assertEqual(audioop.getsample(data, w, 4), minvalues[w]) 381 382 def test_negativelen(self): 383 # from issue 3306, previously it segfaulted 384 self.assertRaises(audioop.error, 385 audioop.findmax, ''.join( chr(x) for x in xrange(256)), -2392392) 386 387 def test_issue7673(self): 388 state = None 389 for data, size in INVALID_DATA: 390 size2 = size 391 self.assertRaises(audioop.error, audioop.getsample, data, size, 0) 392 self.assertRaises(audioop.error, audioop.max, data, size) 393 self.assertRaises(audioop.error, audioop.minmax, data, size) 394 self.assertRaises(audioop.error, audioop.avg, data, size) 395 self.assertRaises(audioop.error, audioop.rms, data, size) 396 self.assertRaises(audioop.error, audioop.avgpp, data, size) 397 self.assertRaises(audioop.error, audioop.maxpp, data, size) 398 self.assertRaises(audioop.error, audioop.cross, data, size) 399 self.assertRaises(audioop.error, audioop.mul, data, size, 1.0) 400 self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5) 401 self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5) 402 self.assertRaises(audioop.error, audioop.add, data, data, size) 403 self.assertRaises(audioop.error, audioop.bias, data, size, 0) 404 self.assertRaises(audioop.error, audioop.reverse, data, size) 405 self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2) 406 self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state) 407 self.assertRaises(audioop.error, audioop.lin2ulaw, data, size) 408 self.assertRaises(audioop.error, audioop.lin2alaw, data, size) 409 self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) 410 411 def test_wrongsize(self): 412 data = b'abcdefgh' 413 state = None 414 for size in (-1, 0, 3, 5, 1024): 415 self.assertRaises(audioop.error, audioop.ulaw2lin, data, size) 416 self.assertRaises(audioop.error, audioop.alaw2lin, data, size) 417 self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state) 418 419def test_main(): 420 run_unittest(TestAudioop) 421 422if __name__ == '__main__': 423 test_main() 424