1import audioop
2import sys
3import unittest
4
5def pack(width, data):
6    return b''.join(v.to_bytes(width, sys.byteorder, signed=True) for v in data)
7
8def unpack(width, data):
9    return [int.from_bytes(data[i: i + width], sys.byteorder, signed=True)
10            for i in range(0, len(data), width)]
11
12packs = {w: (lambda *data, width=w: pack(width, data)) for w in (1, 2, 3, 4)}
13maxvalues = {w: (1 << (8 * w - 1)) - 1 for w in (1, 2, 3, 4)}
14minvalues = {w: -1 << (8 * w - 1) for w in (1, 2, 3, 4)}
15
16datas = {
17    1: b'\x00\x12\x45\xbb\x7f\x80\xff',
18    2: packs[2](0, 0x1234, 0x4567, -0x4567, 0x7fff, -0x8000, -1),
19    3: packs[3](0, 0x123456, 0x456789, -0x456789, 0x7fffff, -0x800000, -1),
20    4: packs[4](0, 0x12345678, 0x456789ab, -0x456789ab,
21                0x7fffffff, -0x80000000, -1),
22}
23
24INVALID_DATA = [
25    (b'abc', 0),
26    (b'abc', 2),
27    (b'ab', 3),
28    (b'abc', 4),
29]
30
31
32class TestAudioop(unittest.TestCase):
33
34    def test_max(self):
35        for w in 1, 2, 3, 4:
36            self.assertEqual(audioop.max(b'', w), 0)
37            self.assertEqual(audioop.max(bytearray(), w), 0)
38            self.assertEqual(audioop.max(memoryview(b''), w), 0)
39            p = packs[w]
40            self.assertEqual(audioop.max(p(5), w), 5)
41            self.assertEqual(audioop.max(p(5, -8, -1), w), 8)
42            self.assertEqual(audioop.max(p(maxvalues[w]), w), maxvalues[w])
43            self.assertEqual(audioop.max(p(minvalues[w]), w), -minvalues[w])
44            self.assertEqual(audioop.max(datas[w], w), -minvalues[w])
45
46    def test_minmax(self):
47        for w in 1, 2, 3, 4:
48            self.assertEqual(audioop.minmax(b'', w),
49                             (0x7fffffff, -0x80000000))
50            self.assertEqual(audioop.minmax(bytearray(), w),
51                             (0x7fffffff, -0x80000000))
52            self.assertEqual(audioop.minmax(memoryview(b''), w),
53                             (0x7fffffff, -0x80000000))
54            p = packs[w]
55            self.assertEqual(audioop.minmax(p(5), w), (5, 5))
56            self.assertEqual(audioop.minmax(p(5, -8, -1), w), (-8, 5))
57            self.assertEqual(audioop.minmax(p(maxvalues[w]), w),
58                             (maxvalues[w], maxvalues[w]))
59            self.assertEqual(audioop.minmax(p(minvalues[w]), w),
60                             (minvalues[w], minvalues[w]))
61            self.assertEqual(audioop.minmax(datas[w], w),
62                             (minvalues[w], maxvalues[w]))
63
64    def test_maxpp(self):
65        for w in 1, 2, 3, 4:
66            self.assertEqual(audioop.maxpp(b'', w), 0)
67            self.assertEqual(audioop.maxpp(bytearray(), w), 0)
68            self.assertEqual(audioop.maxpp(memoryview(b''), w), 0)
69            self.assertEqual(audioop.maxpp(packs[w](*range(100)), w), 0)
70            self.assertEqual(audioop.maxpp(packs[w](9, 10, 5, 5, 0, 1), w), 10)
71            self.assertEqual(audioop.maxpp(datas[w], w),
72                             maxvalues[w] - minvalues[w])
73
74    def test_avg(self):
75        for w in 1, 2, 3, 4:
76            self.assertEqual(audioop.avg(b'', w), 0)
77            self.assertEqual(audioop.avg(bytearray(), w), 0)
78            self.assertEqual(audioop.avg(memoryview(b''), w), 0)
79            p = packs[w]
80            self.assertEqual(audioop.avg(p(5), w), 5)
81            self .assertEqual(audioop.avg(p(5, 8), w), 6)
82            self.assertEqual(audioop.avg(p(5, -8), w), -2)
83            self.assertEqual(audioop.avg(p(maxvalues[w], maxvalues[w]), w),
84                             maxvalues[w])
85            self.assertEqual(audioop.avg(p(minvalues[w], minvalues[w]), w),
86                             minvalues[w])
87        self.assertEqual(audioop.avg(packs[4](0x50000000, 0x70000000), 4),
88                         0x60000000)
89        self.assertEqual(audioop.avg(packs[4](-0x50000000, -0x70000000), 4),
90                         -0x60000000)
91
92    def test_avgpp(self):
93        for w in 1, 2, 3, 4:
94            self.assertEqual(audioop.avgpp(b'', w), 0)
95            self.assertEqual(audioop.avgpp(bytearray(), w), 0)
96            self.assertEqual(audioop.avgpp(memoryview(b''), w), 0)
97            self.assertEqual(audioop.avgpp(packs[w](*range(100)), w), 0)
98            self.assertEqual(audioop.avgpp(packs[w](9, 10, 5, 5, 0, 1), w), 10)
99        self.assertEqual(audioop.avgpp(datas[1], 1), 196)
100        self.assertEqual(audioop.avgpp(datas[2], 2), 50534)
101        self.assertEqual(audioop.avgpp(datas[3], 3), 12937096)
102        self.assertEqual(audioop.avgpp(datas[4], 4), 3311897002)
103
104    def test_rms(self):
105        for w in 1, 2, 3, 4:
106            self.assertEqual(audioop.rms(b'', w), 0)
107            self.assertEqual(audioop.rms(bytearray(), w), 0)
108            self.assertEqual(audioop.rms(memoryview(b''), w), 0)
109            p = packs[w]
110            self.assertEqual(audioop.rms(p(*range(100)), w), 57)
111            self.assertAlmostEqual(audioop.rms(p(maxvalues[w]) * 5, w),
112                                   maxvalues[w], delta=1)
113            self.assertAlmostEqual(audioop.rms(p(minvalues[w]) * 5, w),
114                                   -minvalues[w], delta=1)
115        self.assertEqual(audioop.rms(datas[1], 1), 77)
116        self.assertEqual(audioop.rms(datas[2], 2), 20001)
117        self.assertEqual(audioop.rms(datas[3], 3), 5120523)
118        self.assertEqual(audioop.rms(datas[4], 4), 1310854152)
119
120    def test_cross(self):
121        for w in 1, 2, 3, 4:
122            self.assertEqual(audioop.cross(b'', w), -1)
123            self.assertEqual(audioop.cross(bytearray(), w), -1)
124            self.assertEqual(audioop.cross(memoryview(b''), w), -1)
125            p = packs[w]
126            self.assertEqual(audioop.cross(p(0, 1, 2), w), 0)
127            self.assertEqual(audioop.cross(p(1, 2, -3, -4), w), 1)
128            self.assertEqual(audioop.cross(p(-1, -2, 3, 4), w), 1)
129            self.assertEqual(audioop.cross(p(0, minvalues[w]), w), 1)
130            self.assertEqual(audioop.cross(p(minvalues[w], maxvalues[w]), w), 1)
131
132    def test_add(self):
133        for w in 1, 2, 3, 4:
134            self.assertEqual(audioop.add(b'', b'', w), b'')
135            self.assertEqual(audioop.add(bytearray(), bytearray(), w), b'')
136            self.assertEqual(audioop.add(memoryview(b''), memoryview(b''), w), b'')
137            self.assertEqual(audioop.add(datas[w], b'\0' * len(datas[w]), w),
138                             datas[w])
139        self.assertEqual(audioop.add(datas[1], datas[1], 1),
140                         b'\x00\x24\x7f\x80\x7f\x80\xfe')
141        self.assertEqual(audioop.add(datas[2], datas[2], 2),
142                packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2))
143        self.assertEqual(audioop.add(datas[3], datas[3], 3),
144                packs[3](0, 0x2468ac, 0x7fffff, -0x800000,
145                       0x7fffff, -0x800000, -2))
146        self.assertEqual(audioop.add(datas[4], datas[4], 4),
147                packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000,
148                       0x7fffffff, -0x80000000, -2))
149
150    def test_bias(self):
151        for w in 1, 2, 3, 4:
152            for bias in 0, 1, -1, 127, -128, 0x7fffffff, -0x80000000:
153                self.assertEqual(audioop.bias(b'', w, bias), b'')
154                self.assertEqual(audioop.bias(bytearray(), w, bias), b'')
155                self.assertEqual(audioop.bias(memoryview(b''), w, bias), b'')
156        self.assertEqual(audioop.bias(datas[1], 1, 1),
157                         b'\x01\x13\x46\xbc\x80\x81\x00')
158        self.assertEqual(audioop.bias(datas[1], 1, -1),
159                         b'\xff\x11\x44\xba\x7e\x7f\xfe')
160        self.assertEqual(audioop.bias(datas[1], 1, 0x7fffffff),
161                         b'\xff\x11\x44\xba\x7e\x7f\xfe')
162        self.assertEqual(audioop.bias(datas[1], 1, -0x80000000),
163                         datas[1])
164        self.assertEqual(audioop.bias(datas[2], 2, 1),
165                packs[2](1, 0x1235, 0x4568, -0x4566, -0x8000, -0x7fff, 0))
166        self.assertEqual(audioop.bias(datas[2], 2, -1),
167                packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2))
168        self.assertEqual(audioop.bias(datas[2], 2, 0x7fffffff),
169                packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2))
170        self.assertEqual(audioop.bias(datas[2], 2, -0x80000000),
171                datas[2])
172        self.assertEqual(audioop.bias(datas[3], 3, 1),
173                packs[3](1, 0x123457, 0x45678a, -0x456788,
174                         -0x800000, -0x7fffff, 0))
175        self.assertEqual(audioop.bias(datas[3], 3, -1),
176                packs[3](-1, 0x123455, 0x456788, -0x45678a,
177                         0x7ffffe, 0x7fffff, -2))
178        self.assertEqual(audioop.bias(datas[3], 3, 0x7fffffff),
179                packs[3](-1, 0x123455, 0x456788, -0x45678a,
180                         0x7ffffe, 0x7fffff, -2))
181        self.assertEqual(audioop.bias(datas[3], 3, -0x80000000),
182                datas[3])
183        self.assertEqual(audioop.bias(datas[4], 4, 1),
184                packs[4](1, 0x12345679, 0x456789ac, -0x456789aa,
185                         -0x80000000, -0x7fffffff, 0))
186        self.assertEqual(audioop.bias(datas[4], 4, -1),
187                packs[4](-1, 0x12345677, 0x456789aa, -0x456789ac,
188                         0x7ffffffe, 0x7fffffff, -2))
189        self.assertEqual(audioop.bias(datas[4], 4, 0x7fffffff),
190                packs[4](0x7fffffff, -0x6dcba989, -0x3a987656, 0x3a987654,
191                         -2, -1, 0x7ffffffe))
192        self.assertEqual(audioop.bias(datas[4], 4, -0x80000000),
193                packs[4](-0x80000000, -0x6dcba988, -0x3a987655, 0x3a987655,
194                         -1, 0, 0x7fffffff))
195
196    def test_lin2lin(self):
197        for w in 1, 2, 3, 4:
198            self.assertEqual(audioop.lin2lin(datas[w], w, w), datas[w])
199            self.assertEqual(audioop.lin2lin(bytearray(datas[w]), w, w),
200                             datas[w])
201            self.assertEqual(audioop.lin2lin(memoryview(datas[w]), w, w),
202                             datas[w])
203
204        self.assertEqual(audioop.lin2lin(datas[1], 1, 2),
205            packs[2](0, 0x1200, 0x4500, -0x4500, 0x7f00, -0x8000, -0x100))
206        self.assertEqual(audioop.lin2lin(datas[1], 1, 3),
207            packs[3](0, 0x120000, 0x450000, -0x450000,
208                     0x7f0000, -0x800000, -0x10000))
209        self.assertEqual(audioop.lin2lin(datas[1], 1, 4),
210            packs[4](0, 0x12000000, 0x45000000, -0x45000000,
211                     0x7f000000, -0x80000000, -0x1000000))
212        self.assertEqual(audioop.lin2lin(datas[2], 2, 1),
213            b'\x00\x12\x45\xba\x7f\x80\xff')
214        self.assertEqual(audioop.lin2lin(datas[2], 2, 3),
215            packs[3](0, 0x123400, 0x456700, -0x456700,
216                     0x7fff00, -0x800000, -0x100))
217        self.assertEqual(audioop.lin2lin(datas[2], 2, 4),
218            packs[4](0, 0x12340000, 0x45670000, -0x45670000,
219                     0x7fff0000, -0x80000000, -0x10000))
220        self.assertEqual(audioop.lin2lin(datas[3], 3, 1),
221            b'\x00\x12\x45\xba\x7f\x80\xff')
222        self.assertEqual(audioop.lin2lin(datas[3], 3, 2),
223            packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1))
224        self.assertEqual(audioop.lin2lin(datas[3], 3, 4),
225            packs[4](0, 0x12345600, 0x45678900, -0x45678900,
226                     0x7fffff00, -0x80000000, -0x100))
227        self.assertEqual(audioop.lin2lin(datas[4], 4, 1),
228            b'\x00\x12\x45\xba\x7f\x80\xff')
229        self.assertEqual(audioop.lin2lin(datas[4], 4, 2),
230            packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1))
231        self.assertEqual(audioop.lin2lin(datas[4], 4, 3),
232            packs[3](0, 0x123456, 0x456789, -0x45678a,
233                     0x7fffff, -0x800000, -1))
234
235    def test_adpcm2lin(self):
236        self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 1, None),
237                         (b'\x00\x00\x00\xff\x00\xff', (-179, 40)))
238        self.assertEqual(audioop.adpcm2lin(bytearray(b'\x07\x7f\x7f'), 1, None),
239                         (b'\x00\x00\x00\xff\x00\xff', (-179, 40)))
240        self.assertEqual(audioop.adpcm2lin(memoryview(b'\x07\x7f\x7f'), 1, None),
241                         (b'\x00\x00\x00\xff\x00\xff', (-179, 40)))
242        self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 2, None),
243                         (packs[2](0, 0xb, 0x29, -0x16, 0x72, -0xb3), (-179, 40)))
244        self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 3, None),
245                         (packs[3](0, 0xb00, 0x2900, -0x1600, 0x7200,
246                                   -0xb300), (-179, 40)))
247        self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 4, None),
248                         (packs[4](0, 0xb0000, 0x290000, -0x160000, 0x720000,
249                                   -0xb30000), (-179, 40)))
250
251        # Very cursory test
252        for w in 1, 2, 3, 4:
253            self.assertEqual(audioop.adpcm2lin(b'\0' * 5, w, None),
254                             (b'\0' * w * 10, (0, 0)))
255
256    def test_lin2adpcm(self):
257        self.assertEqual(audioop.lin2adpcm(datas[1], 1, None),
258                         (b'\x07\x7f\x7f', (-221, 39)))
259        self.assertEqual(audioop.lin2adpcm(bytearray(datas[1]), 1, None),
260                         (b'\x07\x7f\x7f', (-221, 39)))
261        self.assertEqual(audioop.lin2adpcm(memoryview(datas[1]), 1, None),
262                         (b'\x07\x7f\x7f', (-221, 39)))
263        for w in 2, 3, 4:
264            self.assertEqual(audioop.lin2adpcm(datas[w], w, None),
265                             (b'\x07\x7f\x7f', (31, 39)))
266
267        # Very cursory test
268        for w in 1, 2, 3, 4:
269            self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None),
270                             (b'\0' * 5, (0, 0)))
271
272    def test_invalid_adpcm_state(self):
273        # state must be a tuple or None, not an integer
274        self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555)
275        self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555)
276        # Issues #24456, #24457: index out of range
277        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1))
278        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89))
279        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1))
280        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89))
281        # value out of range
282        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0))
283        self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0))
284        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0))
285        self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0))
286
287    def test_lin2alaw(self):
288        self.assertEqual(audioop.lin2alaw(datas[1], 1),
289                         b'\xd5\x87\xa4\x24\xaa\x2a\x5a')
290        self.assertEqual(audioop.lin2alaw(bytearray(datas[1]), 1),
291                         b'\xd5\x87\xa4\x24\xaa\x2a\x5a')
292        self.assertEqual(audioop.lin2alaw(memoryview(datas[1]), 1),
293                         b'\xd5\x87\xa4\x24\xaa\x2a\x5a')
294        for w in 2, 3, 4:
295            self.assertEqual(audioop.lin2alaw(datas[w], w),
296                             b'\xd5\x87\xa4\x24\xaa\x2a\x55')
297
298    def test_alaw2lin(self):
299        encoded = b'\x00\x03\x24\x2a\x51\x54\x55\x58\x6b\x71\x7f'\
300                  b'\x80\x83\xa4\xaa\xd1\xd4\xd5\xd8\xeb\xf1\xff'
301        src = [-688, -720, -2240, -4032, -9, -3, -1, -27, -244, -82, -106,
302               688, 720, 2240, 4032, 9, 3, 1, 27, 244, 82, 106]
303        for w in 1, 2, 3, 4:
304            decoded = packs[w](*(x << (w * 8) >> 13 for x in src))
305            self.assertEqual(audioop.alaw2lin(encoded, w), decoded)
306            self.assertEqual(audioop.alaw2lin(bytearray(encoded), w), decoded)
307            self.assertEqual(audioop.alaw2lin(memoryview(encoded), w), decoded)
308
309        encoded = bytes(range(256))
310        for w in 2, 3, 4:
311            decoded = audioop.alaw2lin(encoded, w)
312            self.assertEqual(audioop.lin2alaw(decoded, w), encoded)
313
314    def test_lin2ulaw(self):
315        self.assertEqual(audioop.lin2ulaw(datas[1], 1),
316                         b'\xff\xad\x8e\x0e\x80\x00\x67')
317        self.assertEqual(audioop.lin2ulaw(bytearray(datas[1]), 1),
318                         b'\xff\xad\x8e\x0e\x80\x00\x67')
319        self.assertEqual(audioop.lin2ulaw(memoryview(datas[1]), 1),
320                         b'\xff\xad\x8e\x0e\x80\x00\x67')
321        for w in 2, 3, 4:
322            self.assertEqual(audioop.lin2ulaw(datas[w], w),
323                             b'\xff\xad\x8e\x0e\x80\x00\x7e')
324
325    def test_ulaw2lin(self):
326        encoded = b'\x00\x0e\x28\x3f\x57\x6a\x76\x7c\x7e\x7f'\
327                  b'\x80\x8e\xa8\xbf\xd7\xea\xf6\xfc\xfe\xff'
328        src = [-8031, -4447, -1471, -495, -163, -53, -18, -6, -2, 0,
329               8031, 4447, 1471, 495, 163, 53, 18, 6, 2, 0]
330        for w in 1, 2, 3, 4:
331            decoded = packs[w](*(x << (w * 8) >> 14 for x in src))
332            self.assertEqual(audioop.ulaw2lin(encoded, w), decoded)
333            self.assertEqual(audioop.ulaw2lin(bytearray(encoded), w), decoded)
334            self.assertEqual(audioop.ulaw2lin(memoryview(encoded), w), decoded)
335
336        # Current u-law implementation has two codes fo 0: 0x7f and 0xff.
337        encoded = bytes(range(127)) + bytes(range(128, 256))
338        for w in 2, 3, 4:
339            decoded = audioop.ulaw2lin(encoded, w)
340            self.assertEqual(audioop.lin2ulaw(decoded, w), encoded)
341
342    def test_mul(self):
343        for w in 1, 2, 3, 4:
344            self.assertEqual(audioop.mul(b'', w, 2), b'')
345            self.assertEqual(audioop.mul(bytearray(), w, 2), b'')
346            self.assertEqual(audioop.mul(memoryview(b''), w, 2), b'')
347            self.assertEqual(audioop.mul(datas[w], w, 0),
348                             b'\0' * len(datas[w]))
349            self.assertEqual(audioop.mul(datas[w], w, 1),
350                             datas[w])
351        self.assertEqual(audioop.mul(datas[1], 1, 2),
352                         b'\x00\x24\x7f\x80\x7f\x80\xfe')
353        self.assertEqual(audioop.mul(datas[2], 2, 2),
354                packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2))
355        self.assertEqual(audioop.mul(datas[3], 3, 2),
356                packs[3](0, 0x2468ac, 0x7fffff, -0x800000,
357                         0x7fffff, -0x800000, -2))
358        self.assertEqual(audioop.mul(datas[4], 4, 2),
359                packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000,
360                         0x7fffffff, -0x80000000, -2))
361
362    def test_ratecv(self):
363        for w in 1, 2, 3, 4:
364            self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 8000, None),
365                             (b'', (-1, ((0, 0),))))
366            self.assertEqual(audioop.ratecv(bytearray(), w, 1, 8000, 8000, None),
367                             (b'', (-1, ((0, 0),))))
368            self.assertEqual(audioop.ratecv(memoryview(b''), w, 1, 8000, 8000, None),
369                             (b'', (-1, ((0, 0),))))
370            self.assertEqual(audioop.ratecv(b'', w, 5, 8000, 8000, None),
371                             (b'', (-1, ((0, 0),) * 5)))
372            self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 16000, None),
373                             (b'', (-2, ((0, 0),))))
374            self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None)[0],
375                             datas[w])
376            self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 1, 0)[0],
377                             datas[w])
378
379        state = None
380        d1, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state)
381        d2, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state)
382        self.assertEqual(d1 + d2, b'\000\000\001\001\002\001\000\000\001\001\002')
383
384        for w in 1, 2, 3, 4:
385            d0, state0 = audioop.ratecv(datas[w], w, 1, 8000, 16000, None)
386            d, state = b'', None
387            for i in range(0, len(datas[w]), w):
388                d1, state = audioop.ratecv(datas[w][i:i + w], w, 1,
389                                           8000, 16000, state)
390                d += d1
391            self.assertEqual(d, d0)
392            self.assertEqual(state, state0)
393
394        expected = {
395            1: packs[1](0, 0x0d, 0x37, -0x26, 0x55, -0x4b, -0x14),
396            2: packs[2](0, 0x0da7, 0x3777, -0x2630, 0x5673, -0x4a64, -0x129a),
397            3: packs[3](0, 0x0da740, 0x377776, -0x262fca,
398                        0x56740c, -0x4a62fd, -0x1298c0),
399            4: packs[4](0, 0x0da740da, 0x37777776, -0x262fc962,
400                        0x56740da6, -0x4a62fc96, -0x1298bf26),
401        }
402        for w in 1, 2, 3, 4:
403            self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 3, 1)[0],
404                             expected[w])
405            self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 30, 10)[0],
406                             expected[w])
407
408        self.assertRaises(TypeError, audioop.ratecv, b'', 1, 1, 8000, 8000, 42)
409        self.assertRaises(TypeError, audioop.ratecv,
410                          b'', 1, 1, 8000, 8000, (1, (42,)))
411
412    def test_reverse(self):
413        for w in 1, 2, 3, 4:
414            self.assertEqual(audioop.reverse(b'', w), b'')
415            self.assertEqual(audioop.reverse(bytearray(), w), b'')
416            self.assertEqual(audioop.reverse(memoryview(b''), w), b'')
417            self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w),
418                             packs[w](2, 1, 0))
419
420    def test_tomono(self):
421        for w in 1, 2, 3, 4:
422            data1 = datas[w]
423            data2 = bytearray(2 * len(data1))
424            for k in range(w):
425                data2[k::2*w] = data1[k::w]
426            self.assertEqual(audioop.tomono(data2, w, 1, 0), data1)
427            self.assertEqual(audioop.tomono(data2, w, 0, 1), b'\0' * len(data1))
428            for k in range(w):
429                data2[k+w::2*w] = data1[k::w]
430            self.assertEqual(audioop.tomono(data2, w, 0.5, 0.5), data1)
431            self.assertEqual(audioop.tomono(bytearray(data2), w, 0.5, 0.5),
432                             data1)
433            self.assertEqual(audioop.tomono(memoryview(data2), w, 0.5, 0.5),
434                             data1)
435
436    def test_tostereo(self):
437        for w in 1, 2, 3, 4:
438            data1 = datas[w]
439            data2 = bytearray(2 * len(data1))
440            for k in range(w):
441                data2[k::2*w] = data1[k::w]
442            self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2)
443            self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2))
444            for k in range(w):
445                data2[k+w::2*w] = data1[k::w]
446            self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2)
447            self.assertEqual(audioop.tostereo(bytearray(data1), w, 1, 1), data2)
448            self.assertEqual(audioop.tostereo(memoryview(data1), w, 1, 1),
449                             data2)
450
451    def test_findfactor(self):
452        self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0)
453        self.assertEqual(audioop.findfactor(bytearray(datas[2]),
454                                            bytearray(datas[2])), 1.0)
455        self.assertEqual(audioop.findfactor(memoryview(datas[2]),
456                                            memoryview(datas[2])), 1.0)
457        self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]),
458                         0.0)
459
460    def test_findfit(self):
461        self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0))
462        self.assertEqual(audioop.findfit(bytearray(datas[2]),
463                                         bytearray(datas[2])), (0, 1.0))
464        self.assertEqual(audioop.findfit(memoryview(datas[2]),
465                                         memoryview(datas[2])), (0, 1.0))
466        self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)),
467                         (1, 8038.8))
468        self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]),
469                         (30, 1.0))
470
471    def test_findmax(self):
472        self.assertEqual(audioop.findmax(datas[2], 1), 5)
473        self.assertEqual(audioop.findmax(bytearray(datas[2]), 1), 5)
474        self.assertEqual(audioop.findmax(memoryview(datas[2]), 1), 5)
475
476    def test_getsample(self):
477        for w in 1, 2, 3, 4:
478            data = packs[w](0, 1, -1, maxvalues[w], minvalues[w])
479            self.assertEqual(audioop.getsample(data, w, 0), 0)
480            self.assertEqual(audioop.getsample(bytearray(data), w, 0), 0)
481            self.assertEqual(audioop.getsample(memoryview(data), w, 0), 0)
482            self.assertEqual(audioop.getsample(data, w, 1), 1)
483            self.assertEqual(audioop.getsample(data, w, 2), -1)
484            self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w])
485            self.assertEqual(audioop.getsample(data, w, 4), minvalues[w])
486
487    def test_byteswap(self):
488        swapped_datas = {
489            1: datas[1],
490            2: packs[2](0, 0x3412, 0x6745, -0x6646, -0x81, 0x80, -1),
491            3: packs[3](0, 0x563412, -0x7698bb, 0x7798ba, -0x81, 0x80, -1),
492            4: packs[4](0, 0x78563412, -0x547698bb, 0x557698ba,
493                        -0x81, 0x80, -1),
494        }
495        for w in 1, 2, 3, 4:
496            self.assertEqual(audioop.byteswap(b'', w), b'')
497            self.assertEqual(audioop.byteswap(datas[w], w), swapped_datas[w])
498            self.assertEqual(audioop.byteswap(swapped_datas[w], w), datas[w])
499            self.assertEqual(audioop.byteswap(bytearray(datas[w]), w),
500                             swapped_datas[w])
501            self.assertEqual(audioop.byteswap(memoryview(datas[w]), w),
502                             swapped_datas[w])
503
504    def test_negativelen(self):
505        # from issue 3306, previously it segfaulted
506        self.assertRaises(audioop.error,
507            audioop.findmax, bytes(range(256)), -2392392)
508
509    def test_issue7673(self):
510        state = None
511        for data, size in INVALID_DATA:
512            size2 = size
513            self.assertRaises(audioop.error, audioop.getsample, data, size, 0)
514            self.assertRaises(audioop.error, audioop.max, data, size)
515            self.assertRaises(audioop.error, audioop.minmax, data, size)
516            self.assertRaises(audioop.error, audioop.avg, data, size)
517            self.assertRaises(audioop.error, audioop.rms, data, size)
518            self.assertRaises(audioop.error, audioop.avgpp, data, size)
519            self.assertRaises(audioop.error, audioop.maxpp, data, size)
520            self.assertRaises(audioop.error, audioop.cross, data, size)
521            self.assertRaises(audioop.error, audioop.mul, data, size, 1.0)
522            self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5)
523            self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5)
524            self.assertRaises(audioop.error, audioop.add, data, data, size)
525            self.assertRaises(audioop.error, audioop.bias, data, size, 0)
526            self.assertRaises(audioop.error, audioop.reverse, data, size)
527            self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2)
528            self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state)
529            self.assertRaises(audioop.error, audioop.lin2ulaw, data, size)
530            self.assertRaises(audioop.error, audioop.lin2alaw, data, size)
531            self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state)
532
533    def test_string(self):
534        data = 'abcd'
535        size = 2
536        self.assertRaises(TypeError, audioop.getsample, data, size, 0)
537        self.assertRaises(TypeError, audioop.max, data, size)
538        self.assertRaises(TypeError, audioop.minmax, data, size)
539        self.assertRaises(TypeError, audioop.avg, data, size)
540        self.assertRaises(TypeError, audioop.rms, data, size)
541        self.assertRaises(TypeError, audioop.avgpp, data, size)
542        self.assertRaises(TypeError, audioop.maxpp, data, size)
543        self.assertRaises(TypeError, audioop.cross, data, size)
544        self.assertRaises(TypeError, audioop.mul, data, size, 1.0)
545        self.assertRaises(TypeError, audioop.tomono, data, size, 0.5, 0.5)
546        self.assertRaises(TypeError, audioop.tostereo, data, size, 0.5, 0.5)
547        self.assertRaises(TypeError, audioop.add, data, data, size)
548        self.assertRaises(TypeError, audioop.bias, data, size, 0)
549        self.assertRaises(TypeError, audioop.reverse, data, size)
550        self.assertRaises(TypeError, audioop.lin2lin, data, size, size)
551        self.assertRaises(TypeError, audioop.ratecv, data, size, 1, 1, 1, None)
552        self.assertRaises(TypeError, audioop.lin2ulaw, data, size)
553        self.assertRaises(TypeError, audioop.lin2alaw, data, size)
554        self.assertRaises(TypeError, audioop.lin2adpcm, data, size, None)
555
556    def test_wrongsize(self):
557        data = b'abcdefgh'
558        state = None
559        for size in (-1, 0, 5, 1024):
560            self.assertRaises(audioop.error, audioop.ulaw2lin, data, size)
561            self.assertRaises(audioop.error, audioop.alaw2lin, data, size)
562            self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state)
563
564if __name__ == '__main__':
565    unittest.main()
566