Home | History | Annotate | Download | only in test
      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