1 import audioop 2 import sys 3 import unittest 4 import struct 5 from test.test_support import run_unittest 6 7 8 formats = { 9 1: 'b', 10 2: 'h', 11 4: 'i', 12 } 13 14 def pack(width, data): 15 return struct.pack('=%d%s' % (len(data), formats[width]), *data) 16 17 packs = { 18 1: lambda *data: pack(1, data), 19 2: lambda *data: pack(2, data), 20 4: lambda *data: pack(4, data), 21 } 22 maxvalues = {w: (1 << (8 * w - 1)) - 1 for w in (1, 2, 4)} 23 minvalues = {w: -1 << (8 * w - 1) for w in (1, 2, 4)} 24 25 datas = { 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 32 INVALID_DATA = [ 33 (b'abc', 0), 34 (b'abc', 2), 35 (b'abc', 4), 36 ] 37 38 39 class 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_lin2alaw(self): 214 self.assertEqual(audioop.lin2alaw(datas[1], 1), 215 b'\xd5\x87\xa4\x24\xaa\x2a\x5a') 216 self.assertEqual(audioop.lin2alaw(datas[2], 2), 217 b'\xd5\x87\xa4\x24\xaa\x2a\x55') 218 self.assertEqual(audioop.lin2alaw(datas[4], 4), 219 b'\xd5\x87\xa4\x24\xaa\x2a\x55') 220 221 def test_alaw2lin(self): 222 encoded = b'\x00\x03\x24\x2a\x51\x54\x55\x58\x6b\x71\x7f'\ 223 b'\x80\x83\xa4\xaa\xd1\xd4\xd5\xd8\xeb\xf1\xff' 224 src = [-688, -720, -2240, -4032, -9, -3, -1, -27, -244, -82, -106, 225 688, 720, 2240, 4032, 9, 3, 1, 27, 244, 82, 106] 226 for w in 1, 2, 4: 227 self.assertEqual(audioop.alaw2lin(encoded, w), 228 packs[w](*(x << (w * 8) >> 13 for x in src))) 229 230 encoded = ''.join(chr(x) for x in xrange(256)) 231 for w in 2, 4: 232 decoded = audioop.alaw2lin(encoded, w) 233 self.assertEqual(audioop.lin2alaw(decoded, w), encoded) 234 235 def test_lin2ulaw(self): 236 self.assertEqual(audioop.lin2ulaw(datas[1], 1), 237 b'\xff\xad\x8e\x0e\x80\x00\x67') 238 self.assertEqual(audioop.lin2ulaw(datas[2], 2), 239 b'\xff\xad\x8e\x0e\x80\x00\x7e') 240 self.assertEqual(audioop.lin2ulaw(datas[4], 4), 241 b'\xff\xad\x8e\x0e\x80\x00\x7e') 242 243 def test_ulaw2lin(self): 244 encoded = b'\x00\x0e\x28\x3f\x57\x6a\x76\x7c\x7e\x7f'\ 245 b'\x80\x8e\xa8\xbf\xd7\xea\xf6\xfc\xfe\xff' 246 src = [-8031, -4447, -1471, -495, -163, -53, -18, -6, -2, 0, 247 8031, 4447, 1471, 495, 163, 53, 18, 6, 2, 0] 248 for w in 1, 2, 4: 249 self.assertEqual(audioop.ulaw2lin(encoded, w), 250 packs[w](*(x << (w * 8) >> 14 for x in src))) 251 252 # Current u-law implementation has two codes fo 0: 0x7f and 0xff. 253 encoded = ''.join(chr(x) for x in range(127) + range(128, 256)) 254 for w in 2, 4: 255 decoded = audioop.ulaw2lin(encoded, w) 256 self.assertEqual(audioop.lin2ulaw(decoded, w), encoded) 257 258 def test_mul(self): 259 for w in 1, 2, 4: 260 self.assertEqual(audioop.mul(b'', w, 2), b'') 261 self.assertEqual(audioop.mul(datas[w], w, 0), 262 b'\0' * len(datas[w])) 263 self.assertEqual(audioop.mul(datas[w], w, 1), 264 datas[w]) 265 self.assertEqual(audioop.mul(datas[1], 1, 2), 266 b'\x00\x24\x7f\x80\x7f\x80\xfe') 267 self.assertEqual(audioop.mul(datas[2], 2, 2), 268 packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) 269 self.assertEqual(audioop.mul(datas[4], 4, 2), 270 packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, 271 0x7fffffff, -0x80000000, -2)) 272 273 def test_ratecv(self): 274 for w in 1, 2, 4: 275 self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 8000, None), 276 (b'', (-1, ((0, 0),)))) 277 self.assertEqual(audioop.ratecv(b'', w, 5, 8000, 8000, None), 278 (b'', (-1, ((0, 0),) * 5))) 279 self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 16000, None), 280 (b'', (-2, ((0, 0),)))) 281 self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None)[0], 282 datas[w]) 283 state = None 284 d1, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) 285 d2, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) 286 self.assertEqual(d1 + d2, b'\000\000\001\001\002\001\000\000\001\001\002') 287 288 for w in 1, 2, 4: 289 d0, state0 = audioop.ratecv(datas[w], w, 1, 8000, 16000, None) 290 d, state = b'', None 291 for i in range(0, len(datas[w]), w): 292 d1, state = audioop.ratecv(datas[w][i:i + w], w, 1, 293 8000, 16000, state) 294 d += d1 295 self.assertEqual(d, d0) 296 self.assertEqual(state, state0) 297 298 def test_reverse(self): 299 for w in 1, 2, 4: 300 self.assertEqual(audioop.reverse(b'', w), b'') 301 self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w), 302 packs[w](2, 1, 0)) 303 304 def test_tomono(self): 305 for w in 1, 2, 4: 306 data1 = datas[w] 307 data2 = bytearray(2 * len(data1)) 308 for k in range(w): 309 data2[k::2*w] = data1[k::w] 310 self.assertEqual(audioop.tomono(str(data2), w, 1, 0), data1) 311 self.assertEqual(audioop.tomono(str(data2), w, 0, 1), b'\0' * len(data1)) 312 for k in range(w): 313 data2[k+w::2*w] = data1[k::w] 314 self.assertEqual(audioop.tomono(str(data2), w, 0.5, 0.5), data1) 315 316 def test_tostereo(self): 317 for w in 1, 2, 4: 318 data1 = datas[w] 319 data2 = bytearray(2 * len(data1)) 320 for k in range(w): 321 data2[k::2*w] = data1[k::w] 322 self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2) 323 self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2)) 324 for k in range(w): 325 data2[k+w::2*w] = data1[k::w] 326 self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2) 327 328 def test_findfactor(self): 329 self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0) 330 self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]), 331 0.0) 332 333 def test_findfit(self): 334 self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0)) 335 self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)), 336 (1, 8038.8)) 337 self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]), 338 (30, 1.0)) 339 340 def test_findmax(self): 341 self.assertEqual(audioop.findmax(datas[2], 1), 5) 342 343 def test_getsample(self): 344 for w in 1, 2, 4: 345 data = packs[w](0, 1, -1, maxvalues[w], minvalues[w]) 346 self.assertEqual(audioop.getsample(data, w, 0), 0) 347 self.assertEqual(audioop.getsample(data, w, 1), 1) 348 self.assertEqual(audioop.getsample(data, w, 2), -1) 349 self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w]) 350 self.assertEqual(audioop.getsample(data, w, 4), minvalues[w]) 351 352 def test_negativelen(self): 353 # from issue 3306, previously it segfaulted 354 self.assertRaises(audioop.error, 355 audioop.findmax, ''.join( chr(x) for x in xrange(256)), -2392392) 356 357 def test_issue7673(self): 358 state = None 359 for data, size in INVALID_DATA: 360 size2 = size 361 self.assertRaises(audioop.error, audioop.getsample, data, size, 0) 362 self.assertRaises(audioop.error, audioop.max, data, size) 363 self.assertRaises(audioop.error, audioop.minmax, data, size) 364 self.assertRaises(audioop.error, audioop.avg, data, size) 365 self.assertRaises(audioop.error, audioop.rms, data, size) 366 self.assertRaises(audioop.error, audioop.avgpp, data, size) 367 self.assertRaises(audioop.error, audioop.maxpp, data, size) 368 self.assertRaises(audioop.error, audioop.cross, data, size) 369 self.assertRaises(audioop.error, audioop.mul, data, size, 1.0) 370 self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5) 371 self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5) 372 self.assertRaises(audioop.error, audioop.add, data, data, size) 373 self.assertRaises(audioop.error, audioop.bias, data, size, 0) 374 self.assertRaises(audioop.error, audioop.reverse, data, size) 375 self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2) 376 self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state) 377 self.assertRaises(audioop.error, audioop.lin2ulaw, data, size) 378 self.assertRaises(audioop.error, audioop.lin2alaw, data, size) 379 self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) 380 381 def test_wrongsize(self): 382 data = b'abcdefgh' 383 state = None 384 for size in (-1, 0, 3, 5, 1024): 385 self.assertRaises(audioop.error, audioop.ulaw2lin, data, size) 386 self.assertRaises(audioop.error, audioop.alaw2lin, data, size) 387 self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state) 388 389 def test_main(): 390 run_unittest(TestAudioop) 391 392 if __name__ == '__main__': 393 test_main() 394