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    def test_reverse(self):
409        for w in 1, 2, 3, 4:
410            self.assertEqual(audioop.reverse(b'', w), b'')
411            self.assertEqual(audioop.reverse(bytearray(), w), b'')
412            self.assertEqual(audioop.reverse(memoryview(b''), w), b'')
413            self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w),
414                             packs[w](2, 1, 0))
415
416    def test_tomono(self):
417        for w in 1, 2, 3, 4:
418            data1 = datas[w]
419            data2 = bytearray(2 * len(data1))
420            for k in range(w):
421                data2[k::2*w] = data1[k::w]
422            self.assertEqual(audioop.tomono(data2, w, 1, 0), data1)
423            self.assertEqual(audioop.tomono(data2, w, 0, 1), b'\0' * len(data1))
424            for k in range(w):
425                data2[k+w::2*w] = data1[k::w]
426            self.assertEqual(audioop.tomono(data2, w, 0.5, 0.5), data1)
427            self.assertEqual(audioop.tomono(bytearray(data2), w, 0.5, 0.5),
428                             data1)
429            self.assertEqual(audioop.tomono(memoryview(data2), w, 0.5, 0.5),
430                             data1)
431
432    def test_tostereo(self):
433        for w in 1, 2, 3, 4:
434            data1 = datas[w]
435            data2 = bytearray(2 * len(data1))
436            for k in range(w):
437                data2[k::2*w] = data1[k::w]
438            self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2)
439            self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2))
440            for k in range(w):
441                data2[k+w::2*w] = data1[k::w]
442            self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2)
443            self.assertEqual(audioop.tostereo(bytearray(data1), w, 1, 1), data2)
444            self.assertEqual(audioop.tostereo(memoryview(data1), w, 1, 1),
445                             data2)
446
447    def test_findfactor(self):
448        self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0)
449        self.assertEqual(audioop.findfactor(bytearray(datas[2]),
450                                            bytearray(datas[2])), 1.0)
451        self.assertEqual(audioop.findfactor(memoryview(datas[2]),
452                                            memoryview(datas[2])), 1.0)
453        self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]),
454                         0.0)
455
456    def test_findfit(self):
457        self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0))
458        self.assertEqual(audioop.findfit(bytearray(datas[2]),
459                                         bytearray(datas[2])), (0, 1.0))
460        self.assertEqual(audioop.findfit(memoryview(datas[2]),
461                                         memoryview(datas[2])), (0, 1.0))
462        self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)),
463                         (1, 8038.8))
464        self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]),
465                         (30, 1.0))
466
467    def test_findmax(self):
468        self.assertEqual(audioop.findmax(datas[2], 1), 5)
469        self.assertEqual(audioop.findmax(bytearray(datas[2]), 1), 5)
470        self.assertEqual(audioop.findmax(memoryview(datas[2]), 1), 5)
471
472    def test_getsample(self):
473        for w in 1, 2, 3, 4:
474            data = packs[w](0, 1, -1, maxvalues[w], minvalues[w])
475            self.assertEqual(audioop.getsample(data, w, 0), 0)
476            self.assertEqual(audioop.getsample(bytearray(data), w, 0), 0)
477            self.assertEqual(audioop.getsample(memoryview(data), w, 0), 0)
478            self.assertEqual(audioop.getsample(data, w, 1), 1)
479            self.assertEqual(audioop.getsample(data, w, 2), -1)
480            self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w])
481            self.assertEqual(audioop.getsample(data, w, 4), minvalues[w])
482
483    def test_byteswap(self):
484        swapped_datas = {
485            1: datas[1],
486            2: packs[2](0, 0x3412, 0x6745, -0x6646, -0x81, 0x80, -1),
487            3: packs[3](0, 0x563412, -0x7698bb, 0x7798ba, -0x81, 0x80, -1),
488            4: packs[4](0, 0x78563412, -0x547698bb, 0x557698ba,
489                        -0x81, 0x80, -1),
490        }
491        for w in 1, 2, 3, 4:
492            self.assertEqual(audioop.byteswap(b'', w), b'')
493            self.assertEqual(audioop.byteswap(datas[w], w), swapped_datas[w])
494            self.assertEqual(audioop.byteswap(swapped_datas[w], w), datas[w])
495            self.assertEqual(audioop.byteswap(bytearray(datas[w]), w),
496                             swapped_datas[w])
497            self.assertEqual(audioop.byteswap(memoryview(datas[w]), w),
498                             swapped_datas[w])
499
500    def test_negativelen(self):
501        # from issue 3306, previously it segfaulted
502        self.assertRaises(audioop.error,
503            audioop.findmax, bytes(range(256)), -2392392)
504
505    def test_issue7673(self):
506        state = None
507        for data, size in INVALID_DATA:
508            size2 = size
509            self.assertRaises(audioop.error, audioop.getsample, data, size, 0)
510            self.assertRaises(audioop.error, audioop.max, data, size)
511            self.assertRaises(audioop.error, audioop.minmax, data, size)
512            self.assertRaises(audioop.error, audioop.avg, data, size)
513            self.assertRaises(audioop.error, audioop.rms, data, size)
514            self.assertRaises(audioop.error, audioop.avgpp, data, size)
515            self.assertRaises(audioop.error, audioop.maxpp, data, size)
516            self.assertRaises(audioop.error, audioop.cross, data, size)
517            self.assertRaises(audioop.error, audioop.mul, data, size, 1.0)
518            self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5)
519            self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5)
520            self.assertRaises(audioop.error, audioop.add, data, data, size)
521            self.assertRaises(audioop.error, audioop.bias, data, size, 0)
522            self.assertRaises(audioop.error, audioop.reverse, data, size)
523            self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2)
524            self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state)
525            self.assertRaises(audioop.error, audioop.lin2ulaw, data, size)
526            self.assertRaises(audioop.error, audioop.lin2alaw, data, size)
527            self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state)
528
529    def test_string(self):
530        data = 'abcd'
531        size = 2
532        self.assertRaises(TypeError, audioop.getsample, data, size, 0)
533        self.assertRaises(TypeError, audioop.max, data, size)
534        self.assertRaises(TypeError, audioop.minmax, data, size)
535        self.assertRaises(TypeError, audioop.avg, data, size)
536        self.assertRaises(TypeError, audioop.rms, data, size)
537        self.assertRaises(TypeError, audioop.avgpp, data, size)
538        self.assertRaises(TypeError, audioop.maxpp, data, size)
539        self.assertRaises(TypeError, audioop.cross, data, size)
540        self.assertRaises(TypeError, audioop.mul, data, size, 1.0)
541        self.assertRaises(TypeError, audioop.tomono, data, size, 0.5, 0.5)
542        self.assertRaises(TypeError, audioop.tostereo, data, size, 0.5, 0.5)
543        self.assertRaises(TypeError, audioop.add, data, data, size)
544        self.assertRaises(TypeError, audioop.bias, data, size, 0)
545        self.assertRaises(TypeError, audioop.reverse, data, size)
546        self.assertRaises(TypeError, audioop.lin2lin, data, size, size)
547        self.assertRaises(TypeError, audioop.ratecv, data, size, 1, 1, 1, None)
548        self.assertRaises(TypeError, audioop.lin2ulaw, data, size)
549        self.assertRaises(TypeError, audioop.lin2alaw, data, size)
550        self.assertRaises(TypeError, audioop.lin2adpcm, data, size, None)
551
552    def test_wrongsize(self):
553        data = b'abcdefgh'
554        state = None
555        for size in (-1, 0, 5, 1024):
556            self.assertRaises(audioop.error, audioop.ulaw2lin, data, size)
557            self.assertRaises(audioop.error, audioop.alaw2lin, data, size)
558            self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state)
559
560if __name__ == '__main__':
561    unittest.main()
562