blob: ed1eca3c1d7a539e711420dcdbfff47e320cd970 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Mark Dickinson81fece22010-05-11 13:34:35 +00004#define PY_SSIZE_T_CLEAN
5
Roger E. Masseeaa6e111997-01-03 19:26:27 +00006#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00007
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008typedef short PyInt16;
9
Guido van Rossum7b1e9741994-08-29 10:46:42 +000010#if defined(__CHAR_UNSIGNED__)
11#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012/* This module currently does not work on systems where only unsigned
13 characters are available. Take it out of Setup. Sorry. */
14#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000015#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000016
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020017static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
Tim Goldenfa6ab0f2013-10-31 10:25:47 +000018/* -1 trick is needed on Windows to support -0x80000000 without a warning */
19static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020020static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
21
22static int
23fbound(double val, double minval, double maxval)
24{
25 if (val > maxval)
26 val = maxval;
27 else if (val < minval + 1)
28 val = minval;
Victor Stinnerf2b9a342013-05-07 23:49:15 +020029 return (int)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020030}
31
32
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000033/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000034** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
35
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000036/* From g711.c:
37 *
38 * December 30, 1994:
39 * Functions linear2alaw, linear2ulaw have been updated to correctly
40 * convert unquantized 16 bit values.
41 * Tables for direct u- to A-law and A- to u-law conversions have been
42 * corrected.
43 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
44 * bli@cpk.auc.dk
45 *
46 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000047#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
48#define CLIP 32635
Martin Panter4c359642016-05-08 13:53:41 +000049#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000050#define QUANT_MASK (0xf) /* Quantization field mask. */
51#define SEG_SHIFT (4) /* Left shift for segment number. */
52#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000053
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020054static const PyInt16 seg_aend[8] = {
55 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
56};
57static const PyInt16 seg_uend[8] = {
58 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF
59};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000060
61static PyInt16
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020062search(PyInt16 val, const PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 for (i = 0; i < size; i++) {
67 if (val <= *table++)
68 return (i);
69 }
70 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000071}
72#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
73#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000074
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020075static const PyInt16 _st_ulaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000076 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
77 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
78 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
79 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
80 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
81 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
82 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
83 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
84 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
85 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
86 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
87 -1052, -988, -924, -876, -844, -812, -780,
88 -748, -716, -684, -652, -620, -588, -556,
89 -524, -492, -460, -428, -396, -372, -356,
90 -340, -324, -308, -292, -276, -260, -244,
91 -228, -212, -196, -180, -164, -148, -132,
92 -120, -112, -104, -96, -88, -80, -72,
93 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000095 27004, 25980, 24956, 23932, 22908, 21884, 20860,
96 19836, 18812, 17788, 16764, 15996, 15484, 14972,
97 14460, 13948, 13436, 12924, 12412, 11900, 11388,
98 10876, 10364, 9852, 9340, 8828, 8316, 7932,
99 7676, 7420, 7164, 6908, 6652, 6396, 6140,
100 5884, 5628, 5372, 5116, 4860, 4604, 4348,
101 4092, 3900, 3772, 3644, 3516, 3388, 3260,
102 3132, 3004, 2876, 2748, 2620, 2492, 2364,
103 2236, 2108, 1980, 1884, 1820, 1756, 1692,
104 1628, 1564, 1500, 1436, 1372, 1308, 1244,
105 1180, 1116, 1052, 988, 924, 876, 844,
106 812, 780, 748, 716, 684, 652, 620,
107 588, 556, 524, 492, 460, 428, 396,
108 372, 356, 340, 324, 308, 292, 276,
109 260, 244, 228, 212, 196, 180, 164,
110 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 80, 72, 64, 56, 48, 40, 32,
112 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000113};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000114
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000115/*
116 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000117 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000118 * the data shifted such that it only contains information in the lower
119 * 14-bits.
120 *
121 * In order to simplify the encoding process, the original linear magnitude
122 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
123 * (33 - 8191). The result can be seen in the following encoding table:
124 *
125 * Biased Linear Input Code Compressed Code
126 * ------------------------ ---------------
127 * 00000001wxyza 000wxyz
128 * 0000001wxyzab 001wxyz
129 * 000001wxyzabc 010wxyz
130 * 00001wxyzabcd 011wxyz
131 * 0001wxyzabcde 100wxyz
132 * 001wxyzabcdef 101wxyz
133 * 01wxyzabcdefg 110wxyz
134 * 1wxyzabcdefgh 111wxyz
135 *
136 * Each biased linear code has a leading 1 which identifies the segment
137 * number. The value of the segment number is equal to 7 minus the number
138 * of leading 0's. The quantization interval is directly available as the
139 * four bits wxyz. * The trailing bits (a - h) are ignored.
140 *
141 * Ordinarily the complement of the resulting code word is used for
142 * transmission, and so the code word is complemented before it is returned.
143 *
144 * For further information see John C. Bellamy's Digital Telephony, 1982,
145 * John Wiley & Sons, pps 98-111 and 472-476.
146 */
147static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000149{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 PyInt16 mask;
151 PyInt16 seg;
152 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 /* u-law inverts all bits */
155 /* Get the sign and the magnitude of the value. */
156 if (pcm_val < 0) {
157 pcm_val = -pcm_val;
158 mask = 0x7F;
159 } else {
160 mask = 0xFF;
161 }
162 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
163 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 /* Convert the scaled magnitude to segment number. */
166 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 /*
169 * Combine the sign, segment, quantization bits;
170 * and complement the code word.
171 */
172 if (seg >= 8) /* out of range, return maximum value. */
173 return (unsigned char) (0x7F ^ mask);
174 else {
175 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
176 return (uval ^ mask);
177 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000178
179}
180
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200181static const PyInt16 _st_alaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000182 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
183 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
184 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
185 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
186 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
187 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
188 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
189 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
190 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
191 -13568, -344, -328, -376, -360, -280, -264,
192 -312, -296, -472, -456, -504, -488, -408,
193 -392, -440, -424, -88, -72, -120, -104,
194 -24, -8, -56, -40, -216, -200, -248,
195 -232, -152, -136, -184, -168, -1376, -1312,
196 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
197 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
198 -688, -656, -752, -720, -560, -528, -624,
199 -592, -944, -912, -1008, -976, -816, -784,
200 -880, -848, 5504, 5248, 6016, 5760, 4480,
201 4224, 4992, 4736, 7552, 7296, 8064, 7808,
202 6528, 6272, 7040, 6784, 2752, 2624, 3008,
203 2880, 2240, 2112, 2496, 2368, 3776, 3648,
204 4032, 3904, 3264, 3136, 3520, 3392, 22016,
205 20992, 24064, 23040, 17920, 16896, 19968, 18944,
206 30208, 29184, 32256, 31232, 26112, 25088, 28160,
207 27136, 11008, 10496, 12032, 11520, 8960, 8448,
208 9984, 9472, 15104, 14592, 16128, 15616, 13056,
209 12544, 14080, 13568, 344, 328, 376, 360,
210 280, 264, 312, 296, 472, 456, 504,
211 488, 408, 392, 440, 424, 88, 72,
212 120, 104, 24, 8, 56, 40, 216,
213 200, 248, 232, 152, 136, 184, 168,
214 1376, 1312, 1504, 1440, 1120, 1056, 1248,
215 1184, 1888, 1824, 2016, 1952, 1632, 1568,
216 1760, 1696, 688, 656, 752, 720, 560,
217 528, 624, 592, 944, 912, 1008, 976,
218 816, 784, 880, 848
219};
220
221/*
Martin Panter4c359642016-05-08 13:53:41 +0000222 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000223 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000224 * the data shifted such that it only contains information in the lower
225 * 13-bits.
226 *
227 * Linear Input Code Compressed Code
228 * ------------------------ ---------------
229 * 0000000wxyza 000wxyz
230 * 0000001wxyza 001wxyz
231 * 000001wxyzab 010wxyz
232 * 00001wxyzabc 011wxyz
233 * 0001wxyzabcd 100wxyz
234 * 001wxyzabcde 101wxyz
235 * 01wxyzabcdef 110wxyz
236 * 1wxyzabcdefg 111wxyz
237 *
238 * For further information see John C. Bellamy's Digital Telephony, 1982,
239 * John Wiley & Sons, pps 98-111 and 472-476.
240 */
241static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 PyInt16 mask;
245 short seg;
246 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 /* A-law using even bit inversion */
249 if (pcm_val >= 0) {
250 mask = 0xD5; /* sign (7th) bit = 1 */
251 } else {
252 mask = 0x55; /* sign bit = 0 */
253 pcm_val = -pcm_val - 1;
254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Convert the scaled magnitude to segment number. */
257 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (seg >= 8) /* out of range, return maximum value. */
262 return (unsigned char) (0x7F ^ mask);
263 else {
264 aval = (unsigned char) seg << SEG_SHIFT;
265 if (seg < 2)
266 aval |= (pcm_val >> 1) & QUANT_MASK;
267 else
268 aval |= (pcm_val >> seg) & QUANT_MASK;
269 return (aval ^ mask);
270 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000271}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000272/* End of code taken from sox */
273
Guido van Rossumb64e6351992-07-06 14:21:56 +0000274/* Intel ADPCM step variation table */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200275static const int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 -1, -1, -1, -1, 2, 4, 6, 8,
277 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000278};
279
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200280static const int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
282 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
283 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
284 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
285 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
286 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
287 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
288 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
289 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000290};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291
Serhiy Storchaka23a78272013-11-11 07:47:35 +0200292#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
293#define SETINTX(T, cp, i, val) do { \
294 *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300295 } while (0)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000296
297
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300298#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
299#define GETINT16(cp, i) GETINTX(short, (cp), (i))
300#define GETINT32(cp, i) GETINTX(PY_INT32_T, (cp), (i))
301
302#if WORDS_BIGENDIAN
303#define GETINT24(cp, i) ( \
304 ((unsigned char *)(cp) + (i))[2] + \
305 (((unsigned char *)(cp) + (i))[1] << 8) + \
306 (((signed char *)(cp) + (i))[0] << 16) )
307#else
308#define GETINT24(cp, i) ( \
309 ((unsigned char *)(cp) + (i))[0] + \
310 (((unsigned char *)(cp) + (i))[1] << 8) + \
311 (((signed char *)(cp) + (i))[2] << 16) )
312#endif
313
314
315#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
316#define SETINT16(cp, i, val) SETINTX(short, (cp), (i), (val))
317#define SETINT32(cp, i, val) SETINTX(PY_INT32_T, (cp), (i), (val))
318
319#if WORDS_BIGENDIAN
320#define SETINT24(cp, i, val) do { \
321 ((unsigned char *)(cp) + (i))[2] = (int)(val); \
322 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
323 ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
324 } while (0)
325#else
326#define SETINT24(cp, i, val) do { \
327 ((unsigned char *)(cp) + (i))[0] = (int)(val); \
328 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
329 ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
330 } while (0)
331#endif
332
333
334#define GETRAWSAMPLE(size, cp, i) ( \
335 (size == 1) ? (int)GETINT8((cp), (i)) : \
336 (size == 2) ? (int)GETINT16((cp), (i)) : \
337 (size == 3) ? (int)GETINT24((cp), (i)) : \
338 (int)GETINT32((cp), (i)))
339
340#define SETRAWSAMPLE(size, cp, i, val) do { \
341 if (size == 1) \
342 SETINT8((cp), (i), (val)); \
343 else if (size == 2) \
344 SETINT16((cp), (i), (val)); \
345 else if (size == 3) \
346 SETINT24((cp), (i), (val)); \
347 else \
348 SETINT32((cp), (i), (val)); \
349 } while(0)
350
351
352#define GETSAMPLE32(size, cp, i) ( \
353 (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
354 (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
355 (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \
356 (int)GETINT32((cp), (i)))
357
358#define SETSAMPLE32(size, cp, i, val) do { \
359 if (size == 1) \
360 SETINT8((cp), (i), (val) >> 24); \
361 else if (size == 2) \
362 SETINT16((cp), (i), (val) >> 16); \
363 else if (size == 3) \
364 SETINT24((cp), (i), (val) >> 8); \
365 else \
366 SETINT32((cp), (i), (val)); \
367 } while(0)
368
Guido van Rossumb66efa01992-06-01 16:01:24 +0000369
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000370static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000371
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000372static int
373audioop_check_size(int size)
374{
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300375 if (size < 1 || size > 4) {
376 PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000377 return 0;
378 }
379 else
380 return 1;
381}
382
383static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000384audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000385{
386 if (!audioop_check_size(size))
387 return 0;
388 if (len % size != 0) {
389 PyErr_SetString(AudioopError, "not a whole number of frames");
390 return 0;
391 }
392 return 1;
393}
394
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200395/*[clinic input]
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200396module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200397[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300398/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200399
400/*[clinic input]
401audioop.getsample
402
403 fragment: Py_buffer
404 width: int
405 index: Py_ssize_t
406 /
407
408Return the value of sample index from the fragment.
409[clinic start generated code]*/
410
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300412audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400413 Py_ssize_t index)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300414/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000415{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200416 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000417
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200418 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000419 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200420 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200422 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200424 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200425 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000426}
427
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200428/*[clinic input]
429audioop.max
430
431 fragment: Py_buffer
432 width: int
433 /
434
435Return the maximum of the absolute value of all samples in a fragment.
436[clinic start generated code]*/
437
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300439audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
440/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000441{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200442 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200443 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000444
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200445 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000446 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200447 for (i = 0; i < fragment->len; i += width) {
448 int val = GETRAWSAMPLE(width, fragment->buf, i);
Martin Panter6fb90902016-07-19 03:05:42 +0000449 /* Cast to unsigned before negating. Unsigned overflow is well-
450 defined, but signed overflow is not. */
451 if (val < 0) absval = -(unsigned int)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200452 else absval = val;
453 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200455 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000456}
457
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200458/*[clinic input]
459audioop.minmax
460
461 fragment: Py_buffer
462 width: int
463 /
464
465Return the minimum and maximum values of all samples in the sound fragment.
466[clinic start generated code]*/
467
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300469audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
470/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000471{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200472 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000473 /* -1 trick below is needed on Windows to support -0x80000000 without
474 a warning */
475 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000476
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200477 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200479 for (i = 0; i < fragment->len; i += width) {
480 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 if (val > max) max = val;
482 if (val < min) min = val;
483 }
484 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000485}
486
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200487/*[clinic input]
488audioop.avg
489
490 fragment: Py_buffer
491 width: int
492 /
493
494Return the average over all samples in the fragment.
495[clinic start generated code]*/
496
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300498audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
499/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000500{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200501 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200502 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300503 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000504
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200505 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000506 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200507 for (i = 0; i < fragment->len; i += width)
508 sum += GETRAWSAMPLE(width, fragment->buf, i);
509 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300510 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200512 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300513 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000514}
515
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200516/*[clinic input]
517audioop.rms
518
519 fragment: Py_buffer
520 width: int
521 /
522
523Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
524[clinic start generated code]*/
525
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300527audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
528/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000529{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200530 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200531 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000533
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200534 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000535 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200536 for (i = 0; i < fragment->len; i += width) {
537 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300538 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200540 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200541 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200543 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200544 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000545}
546
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200547static double _sum2(const short *a, const short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000548{
Mark Dickinson81fece22010-05-11 13:34:35 +0000549 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 for( i=0; i<len; i++) {
553 sum = sum + (double)a[i]*(double)b[i];
554 }
555 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000556}
557
558/*
559** Findfit tries to locate a sample within another sample. Its main use
560** is in echo-cancellation (to find the feedback of the output signal in
561** the input signal).
562** The method used is as follows:
563**
564** let R be the reference signal (length n) and A the input signal (length N)
565** with N > n, and let all sums be over i from 0 to n-1.
566**
567** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
568** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
569** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
570**
571** Next, we compute the relative distance between the original signal and
572** the modified signal and minimize that over j:
573** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
574** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
575**
576** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000577** cp1 A
578** cp2 R
579** len1 N
580** len2 n
581** aj_m1 A[j-1]
582** aj_lm1 A[j+n-1]
583** sum_ri_2 sum(R[i]^2)
584** sum_aij_2 sum(A[i+j]^2)
585** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000586**
587** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
588** is completely recalculated each step.
589*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200590/*[clinic input]
591audioop.findfit
592
593 fragment: Py_buffer
594 reference: Py_buffer
595 /
596
597Try to match reference as well as possible to a portion of fragment.
598[clinic start generated code]*/
599
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300601audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400602 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300603/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000604{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200605 const short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000606 Py_ssize_t len1, len2;
607 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 double aj_m1, aj_lm1;
609 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000610
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200611 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200613 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200615 cp1 = (const short *)fragment->buf;
616 len1 = fragment->len >> 1;
617 cp2 = (const short *)reference->buf;
618 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000619
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200620 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200622 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 }
624 sum_ri_2 = _sum2(cp2, cp2, len2);
625 sum_aij_2 = _sum2(cp1, cp1, len2);
626 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 best_result = result;
631 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 for ( j=1; j<=len1-len2; j++) {
634 aj_m1 = (double)cp1[j-1];
635 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
638 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
641 / sum_aij_2;
642
643 if ( result < best_result ) {
644 best_result = result;
645 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000646 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 }
649
650 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
651
Mark Dickinson81fece22010-05-11 13:34:35 +0000652 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000653}
654
655/*
656** findfactor finds a factor f so that the energy in A-fB is minimal.
657** See the comment for findfit for details.
658*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200659/*[clinic input]
660audioop.findfactor
661
662 fragment: Py_buffer
663 reference: Py_buffer
664 /
665
666Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
667[clinic start generated code]*/
668
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300670audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400671 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300672/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000673{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200674 const short *cp1, *cp2;
675 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000677
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200678 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200680 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200682 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200684 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200686 cp1 = (const short *)fragment->buf;
687 cp2 = (const short *)reference->buf;
688 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200689 sum_ri_2 = _sum2(cp2, cp2, len);
690 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000695}
696
697/*
698** findmax returns the index of the n-sized segment of the input sample
699** that contains the most energy.
700*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200701/*[clinic input]
702audioop.findmax
703
704 fragment: Py_buffer
705 length: Py_ssize_t
706 /
707
708Search fragment for a slice of specified number of samples with maximum energy.
709[clinic start generated code]*/
710
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300712audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400713 Py_ssize_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300714/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000715{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200716 const short *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200717 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000718 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 double aj_m1, aj_lm1;
720 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000721
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200722 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200724 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200726 cp1 = (const short *)fragment->buf;
727 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200729 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200731 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 }
733
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200734 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735
736 best_result = result;
737 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200739 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200741 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742
743 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
744
745 if ( result > best_result ) {
746 best_result = result;
747 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000748 }
Jack Jansena90805f1993-02-17 14:29:28 +0000749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000751
Mark Dickinson81fece22010-05-11 13:34:35 +0000752 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000753}
754
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200755/*[clinic input]
756audioop.avgpp
757
758 fragment: Py_buffer
759 width: int
760 /
761
762Return the average peak-peak value over all samples in the fragment.
763[clinic start generated code]*/
764
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300766audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
767/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000768{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200769 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200770 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200771 double sum = 0.0;
772 unsigned int avg;
773 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000774
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200775 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000776 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200777 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200778 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200779 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200780 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200781 for (i = width; i < fragment->len; i += width) {
782 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200783 if (val != prevval) {
784 diff = val < prevval;
785 if (prevdiff == !diff) {
786 /* Derivative changed sign. Compute difference to last
787 ** extreme value and remember.
788 */
789 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300790 if (prevval < prevextreme)
791 sum += (double)((unsigned int)prevextreme -
792 (unsigned int)prevval);
793 else
794 sum += (double)((unsigned int)prevval -
795 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200796 nextreme++;
797 }
798 prevextremevalid = 1;
799 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200801 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200803 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 }
805 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200806 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200808 avg = (unsigned int)(sum / (double)nextreme);
809 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000810}
811
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200812/*[clinic input]
813audioop.maxpp
814
815 fragment: Py_buffer
816 width: int
817 /
818
819Return the maximum peak-peak value in the sound fragment.
820[clinic start generated code]*/
821
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000822static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300823audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
824/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000825{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200826 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200827 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200828 unsigned int max = 0, extremediff;
829 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000830
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200831 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000832 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200833 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200834 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200835 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200836 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200837 for (i = width; i < fragment->len; i += width) {
838 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200839 if (val != prevval) {
840 diff = val < prevval;
841 if (prevdiff == !diff) {
842 /* Derivative changed sign. Compute difference to
843 ** last extreme value and remember.
844 */
845 if (prevextremevalid) {
846 if (prevval < prevextreme)
847 extremediff = (unsigned int)prevextreme -
848 (unsigned int)prevval;
849 else
850 extremediff = (unsigned int)prevval -
851 (unsigned int)prevextreme;
852 if ( extremediff > max )
853 max = extremediff;
854 }
855 prevextremevalid = 1;
856 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200858 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200860 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200862 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000863}
864
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200865/*[clinic input]
866audioop.cross
867
868 fragment: Py_buffer
869 width: int
870 /
871
872Return the number of zero crossings in the fragment passed as an argument.
873[clinic start generated code]*/
874
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000875static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300876audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
877/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000878{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200879 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000880 int prevval;
881 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000882
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200883 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000884 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 ncross = -1;
886 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200887 for (i = 0; i < fragment->len; i += width) {
888 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300889 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 prevval = val;
891 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000892 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893}
894
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200895/*[clinic input]
896audioop.mul
897
898 fragment: Py_buffer
899 width: int
900 factor: double
901 /
902
903Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
904[clinic start generated code]*/
905
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300907audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400908 double factor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300909/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000910{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200911 signed char *ncp;
912 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200913 double maxval, minval;
914 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000915
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200916 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000917 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200919 maxval = (double) maxvals[width];
920 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200922 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200923 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200924 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 ncp = (signed char *)PyBytes_AsString(rv);
926
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200927 for (i = 0; i < fragment->len; i += width) {
928 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300929 val *= factor;
930 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200931 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 }
933 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000934}
935
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200936/*[clinic input]
937audioop.tomono
938
939 fragment: Py_buffer
940 width: int
941 lfactor: double
942 rfactor: double
943 /
944
945Convert a stereo fragment to a mono fragment.
946[clinic start generated code]*/
947
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300949audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400950 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300951/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000954 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200955 double maxval, minval;
956 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000957
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200958 cp = fragment->buf;
959 len = fragment->len;
960 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200961 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200962 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000963 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200964 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000965 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200967 maxval = (double) maxvals[width];
968 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969
970 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200971 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200972 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 ncp = (signed char *)PyBytes_AsString(rv);
974
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200975 for (i = 0; i < len; i += width*2) {
976 double val1 = GETRAWSAMPLE(width, cp, i);
977 double val2 = GETRAWSAMPLE(width, cp, i + width);
978 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300979 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200980 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000983}
984
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200985/*[clinic input]
986audioop.tostereo
987
988 fragment: Py_buffer
989 width: int
990 lfactor: double
991 rfactor: double
992 /
993
994Generate a stereo fragment from a mono fragment.
995[clinic start generated code]*/
996
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300998audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400999 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001000/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001001{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001002 signed char *ncp;
1003 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001004 double maxval, minval;
1005 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001006
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001007 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001008 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001009
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001010 maxval = (double) maxvals[width];
1011 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001012
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001013 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 PyErr_SetString(PyExc_MemoryError,
1015 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001016 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001018
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001019 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001020 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001021 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001023
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001024 for (i = 0; i < fragment->len; i += width) {
1025 double val = GETRAWSAMPLE(width, fragment->buf, i);
1026 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1027 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1028 SETRAWSAMPLE(width, ncp, i*2, val1);
1029 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 }
1031 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001032}
1033
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001034/*[clinic input]
1035audioop.add
1036
1037 fragment1: Py_buffer
1038 fragment2: Py_buffer
1039 width: int
1040 /
1041
1042Return a fragment which is the addition of the two samples passed as parameters.
1043[clinic start generated code]*/
1044
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001046audioop_add_impl(PyObject *module, Py_buffer *fragment1,
Larry Hastings89964c42015-04-14 18:07:59 -04001047 Py_buffer *fragment2, int width)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001048/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001049{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001050 signed char *ncp;
1051 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001052 int minval, maxval, newval;
1053 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001054
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001055 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001056 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001057 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001059 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001061
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001062 maxval = maxvals[width];
1063 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001064
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001065 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001066 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001067 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001069
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001070 for (i = 0; i < fragment1->len; i += width) {
1071 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1072 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001074 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001075 newval = val1 + val2;
1076 /* truncate in case of overflow */
1077 if (newval > maxval)
1078 newval = maxval;
1079 else if (newval < minval)
1080 newval = minval;
1081 }
1082 else {
1083 double fval = (double)val1 + (double)val2;
1084 /* truncate in case of overflow */
1085 newval = (int)floor(fbound(fval, minval, maxval));
1086 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001088 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 }
1090 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001091}
1092
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001093/*[clinic input]
1094audioop.bias
1095
1096 fragment: Py_buffer
1097 width: int
1098 bias: int
1099 /
1100
1101Return a fragment that is the original fragment with a bias added to each sample.
1102[clinic start generated code]*/
1103
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001105audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
1106/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001107{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001108 signed char *ncp;
1109 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001110 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001111 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001112
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001113 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001114 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001116 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001117 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001118 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 ncp = (signed char *)PyBytes_AsString(rv);
1120
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001121 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001123 for (i = 0; i < fragment->len; i += width) {
1124 if (width == 1)
1125 val = GETINTX(unsigned char, fragment->buf, i);
1126 else if (width == 2)
1127 val = GETINTX(unsigned short, fragment->buf, i);
1128 else if (width == 3)
1129 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001130 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001131 assert(width == 4);
1132 val = GETINTX(PY_UINT32_T, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001133 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001135 val += (unsigned int)bias;
1136 /* wrap around in case of overflow */
1137 val &= mask;
1138
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001139 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001140 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001141 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001142 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001143 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001144 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001145 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001146 assert(width == 4);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001147 SETINTX(PY_UINT32_T, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001148 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 }
1150 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001151}
1152
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001153/*[clinic input]
1154audioop.reverse
1155
1156 fragment: Py_buffer
1157 width: int
1158 /
1159
1160Reverse the samples in a fragment and returns the modified fragment.
1161[clinic start generated code]*/
1162
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001163static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001164audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
1165/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001168 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001169 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001170
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001171 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001172 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001173
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001174 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001175 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001176 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 ncp = (unsigned char *)PyBytes_AsString(rv);
1178
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001179 for (i = 0; i < fragment->len; i += width) {
1180 int val = GETRAWSAMPLE(width, fragment->buf, i);
1181 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 }
1183 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001184}
1185
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001186/*[clinic input]
1187audioop.byteswap
1188
1189 fragment: Py_buffer
1190 width: int
1191 /
1192
1193Convert big-endian samples to little-endian and vice versa.
1194[clinic start generated code]*/
1195
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001197audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
1198/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001199{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001200 unsigned char *ncp;
1201 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001202 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001203
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001204 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001205 return NULL;
1206
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001207 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001208 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001209 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001210 ncp = (unsigned char *)PyBytes_AsString(rv);
1211
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001212 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001213 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001214 for (j = 0; j < width; j++)
1215 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001216 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001217 return rv;
1218}
1219
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001220/*[clinic input]
1221audioop.lin2lin
1222
1223 fragment: Py_buffer
1224 width: int
1225 newwidth: int
1226 /
1227
1228Convert samples between 1-, 2-, 3- and 4-byte formats.
1229[clinic start generated code]*/
1230
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001232audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001233 int newwidth)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001234/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001237 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001238 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001239
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001240 if (!audioop_check_parameters(fragment->len, width))
1241 return NULL;
1242 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001243 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001244
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001245 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 PyErr_SetString(PyExc_MemoryError,
1247 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001248 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001250 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001251 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001252 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 ncp = (unsigned char *)PyBytes_AsString(rv);
1254
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001255 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1256 int val = GETSAMPLE32(width, fragment->buf, i);
1257 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 }
1259 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001260}
1261
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001262static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001263gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 while (b > 0) {
1266 int tmp = a % b;
1267 a = b;
1268 b = tmp;
1269 }
1270 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001271}
1272
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001273/*[clinic input]
1274audioop.ratecv
1275
1276 fragment: Py_buffer
1277 width: int
1278 nchannels: int
1279 inrate: int
1280 outrate: int
1281 state: object
1282 weightA: int = 1
1283 weightB: int = 0
1284 /
1285
1286Convert the frame rate of the input fragment.
1287[clinic start generated code]*/
1288
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001289static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001290audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001291 int nchannels, int inrate, int outrate, PyObject *state,
1292 int weightA, int weightB)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001293/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001296 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001298 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001300
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001301 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 if (nchannels < 1) {
1304 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001305 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001307 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 /* This overflow test is rigorously correct because
1309 both multiplicands are >= 1. Use the argument names
1310 from the docs for the error msg. */
1311 PyErr_SetString(PyExc_OverflowError,
1312 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001313 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001315 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 if (weightA < 1 || weightB < 0) {
1317 PyErr_SetString(AudioopError,
1318 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001319 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001321 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001322 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001324 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 }
1326 if (inrate <= 0 || outrate <= 0) {
1327 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001328 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 }
1330 /* divide inrate and outrate by their greatest common divisor */
1331 d = gcd(inrate, outrate);
1332 inrate /= d;
1333 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001334 /* divide weightA and weightB by their greatest common divisor */
1335 d = gcd(weightA, weightB);
1336 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001337 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001338
Mark Dickinson85eacea2010-05-10 16:27:45 +00001339 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 PyErr_SetString(PyExc_MemoryError,
1341 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001342 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001344 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1345 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 if (prev_i == NULL || cur_i == NULL) {
1347 (void) PyErr_NoMemory();
1348 goto exit;
1349 }
1350
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001351 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352
1353 if (state == Py_None) {
1354 d = -outrate;
1355 for (chan = 0; chan < nchannels; chan++)
1356 prev_i[chan] = cur_i[chan] = 0;
1357 }
1358 else {
1359 if (!PyArg_ParseTuple(state,
1360 "iO!;audioop.ratecv: illegal state argument",
1361 &d, &PyTuple_Type, &samps))
1362 goto exit;
1363 if (PyTuple_Size(samps) != nchannels) {
1364 PyErr_SetString(AudioopError,
1365 "illegal state argument");
1366 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001367 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 for (chan = 0; chan < nchannels; chan++) {
1369 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1370 "ii:ratecv", &prev_i[chan],
1371 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001372 goto exit;
1373 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001377 if (len == 0)
1378 str = PyBytes_FromStringAndSize(NULL, 0);
1379 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 /* There are len input frames, so we need (mathematically)
1381 ceiling(len*outrate/inrate) output frames, and each frame
1382 requires bytes_per_frame bytes. Computing this
1383 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001384 settle for a reasonable upper bound, though, in this
1385 case ceiling(len/inrate) * outrate. */
1386
1387 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001388 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001389 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 str = NULL;
1391 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001392 str = PyBytes_FromStringAndSize(NULL,
1393 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001394 }
1395 if (str == NULL) {
1396 PyErr_SetString(PyExc_MemoryError,
1397 "not enough memory for output buffer");
1398 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 }
1400 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001401 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402
1403 for (;;) {
1404 while (d < 0) {
1405 if (len == 0) {
1406 samps = PyTuple_New(nchannels);
1407 if (samps == NULL)
1408 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001409 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 PyTuple_SetItem(samps, chan,
1411 Py_BuildValue("(ii)",
1412 prev_i[chan],
1413 cur_i[chan]));
1414 if (PyErr_Occurred())
1415 goto exit;
1416 /* We have checked before that the length
1417 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001418 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 rv = PyBytes_FromStringAndSize
1420 (PyBytes_AsString(str), len);
1421 Py_DECREF(str);
1422 str = rv;
1423 if (str == NULL)
1424 goto exit;
1425 rv = Py_BuildValue("(O(iO))", str, d, samps);
1426 Py_DECREF(samps);
1427 Py_DECREF(str);
1428 goto exit; /* return rv */
1429 }
1430 for (chan = 0; chan < nchannels; chan++) {
1431 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001432 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1433 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001435 cur_i[chan] = (int)(
1436 ((double)weightA * (double)cur_i[chan] +
1437 (double)weightB * (double)prev_i[chan]) /
1438 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 }
1440 len--;
1441 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001442 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 while (d >= 0) {
1444 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001445 cur_o = (int)(((double)prev_i[chan] * (double)d +
1446 (double)cur_i[chan] * (double)(outrate - d)) /
1447 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001448 SETSAMPLE32(width, ncp, 0, cur_o);
1449 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 }
1451 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001452 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001454 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001455 PyMem_Free(prev_i);
1456 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001458}
Guido van Rossum1851a671997-02-14 16:14:03 +00001459
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001460/*[clinic input]
1461audioop.lin2ulaw
1462
1463 fragment: Py_buffer
1464 width: int
1465 /
1466
1467Convert samples in the audio fragment to u-LAW encoding.
1468[clinic start generated code]*/
1469
Roger E. Massec905fff1997-01-17 18:12:04 +00001470static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001471audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1472/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001475 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001476 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001477
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001478 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001479 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001480
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001481 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001482 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001483 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 ncp = (unsigned char *)PyBytes_AsString(rv);
1485
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001486 for (i = 0; i < fragment->len; i += width) {
1487 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001488 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 }
1490 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001491}
1492
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001493/*[clinic input]
1494audioop.ulaw2lin
1495
1496 fragment: Py_buffer
1497 width: int
1498 /
1499
1500Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1501[clinic start generated code]*/
1502
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001504audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1505/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001509 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001510 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001511
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001512 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001513 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001515 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 PyErr_SetString(PyExc_MemoryError,
1517 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001518 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001520 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001521 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001522 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 ncp = (signed char *)PyBytes_AsString(rv);
1524
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001525 cp = fragment->buf;
1526 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001527 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001528 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 }
1530 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001531}
1532
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001533/*[clinic input]
1534audioop.lin2alaw
1535
1536 fragment: Py_buffer
1537 width: int
1538 /
1539
1540Convert samples in the audio fragment to a-LAW encoding.
1541[clinic start generated code]*/
1542
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001544audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1545/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001548 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001549 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001550
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001551 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001552 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001553
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001554 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001555 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001556 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 ncp = (unsigned char *)PyBytes_AsString(rv);
1558
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001559 for (i = 0; i < fragment->len; i += width) {
1560 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001561 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 }
1563 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001564}
1565
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001566/*[clinic input]
1567audioop.alaw2lin
1568
1569 fragment: Py_buffer
1570 width: int
1571 /
1572
1573Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1574[clinic start generated code]*/
1575
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001577audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1578/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001579{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001582 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001583 int val;
1584 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001585
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001586 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001587 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001589 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 PyErr_SetString(PyExc_MemoryError,
1591 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001592 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001594 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001595 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001596 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001598 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001600 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001601 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001602 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 }
1604 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001605}
1606
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001607/*[clinic input]
1608audioop.lin2adpcm
1609
1610 fragment: Py_buffer
1611 width: int
1612 state: object
1613 /
1614
1615Convert samples to 4 bit Intel/DVI ADPCM encoding.
1616[clinic start generated code]*/
1617
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001619audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001620 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001621/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001624 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001625 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001627 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001628 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001629
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001630 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001631 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 /* Decode state, should have (value, step) */
1634 if ( state == Py_None ) {
1635 /* First time, it seems. Set defaults */
1636 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001638 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001639 else if (!PyTuple_Check(state)) {
1640 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1641 return NULL;
1642 }
1643 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1644 return NULL;
1645 }
1646 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1647 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1648 PyErr_SetString(PyExc_ValueError, "bad state");
1649 return NULL;
1650 }
1651
1652 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1653 if (str == NULL)
1654 return NULL;
1655 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656
1657 step = stepsizeTable[index];
1658 bufferstep = 1;
1659
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001660 for (i = 0; i < fragment->len; i += width) {
1661 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662
1663 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001664 if (val < valpred) {
1665 diff = valpred - val;
1666 sign = 8;
1667 }
1668 else {
1669 diff = val - valpred;
1670 sign = 0;
1671 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672
1673 /* Step 2 - Divide and clamp */
1674 /* Note:
1675 ** This code *approximately* computes:
1676 ** delta = diff*4/step;
1677 ** vpdiff = (delta+0.5)*step/4;
1678 ** but in shift step bits are dropped. The net result of this
1679 ** is that even if you have fast mul/div hardware you cannot
1680 ** put it to good use since the fixup would be too expensive.
1681 */
1682 delta = 0;
1683 vpdiff = (step >> 3);
1684
1685 if ( diff >= step ) {
1686 delta = 4;
1687 diff -= step;
1688 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001689 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 step >>= 1;
1691 if ( diff >= step ) {
1692 delta |= 2;
1693 diff -= step;
1694 vpdiff += step;
1695 }
1696 step >>= 1;
1697 if ( diff >= step ) {
1698 delta |= 1;
1699 vpdiff += step;
1700 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 /* Step 3 - Update previous value */
1703 if ( sign )
1704 valpred -= vpdiff;
1705 else
1706 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 /* Step 4 - Clamp previous value to 16 bits */
1709 if ( valpred > 32767 )
1710 valpred = 32767;
1711 else if ( valpred < -32768 )
1712 valpred = -32768;
1713
1714 /* Step 5 - Assemble value, update index and step values */
1715 delta |= sign;
1716
1717 index += indexTable[delta];
1718 if ( index < 0 ) index = 0;
1719 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001720 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 /* Step 6 - Output value */
1723 if ( bufferstep ) {
1724 outputbuffer = (delta << 4) & 0xf0;
1725 } else {
1726 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001727 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 bufferstep = !bufferstep;
1729 }
1730 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001731 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001733}
1734
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001735/*[clinic input]
1736audioop.adpcm2lin
1737
1738 fragment: Py_buffer
1739 width: int
1740 state: object
1741 /
1742
1743Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1744[clinic start generated code]*/
1745
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001747audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001748 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001749/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 signed char *cp;
1752 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001753 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001754 int valpred, step, delta, index, sign, vpdiff;
1755 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001756 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001757
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001758 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001759 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 /* Decode state, should have (value, step) */
1762 if ( state == Py_None ) {
1763 /* First time, it seems. Set defaults */
1764 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001766 }
1767 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001768 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001769 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001770 }
1771 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001772 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001773 }
1774 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1775 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1776 PyErr_SetString(PyExc_ValueError, "bad state");
1777 return NULL;
1778 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001780 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 PyErr_SetString(PyExc_MemoryError,
1782 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001783 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001785 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001786 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001787 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001788 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001790 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791
1792 step = stepsizeTable[index];
1793 bufferstep = 0;
1794
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001795 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 /* Step 1 - get the delta value and compute next index */
1797 if ( bufferstep ) {
1798 delta = inputbuffer & 0xf;
1799 } else {
1800 inputbuffer = *cp++;
1801 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001802 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 bufferstep = !bufferstep;
1805
1806 /* Step 2 - Find new index value (for later) */
1807 index += indexTable[delta];
1808 if ( index < 0 ) index = 0;
1809 if ( index > 88 ) index = 88;
1810
1811 /* Step 3 - Separate sign and magnitude */
1812 sign = delta & 8;
1813 delta = delta & 7;
1814
1815 /* Step 4 - Compute difference and new predicted value */
1816 /*
1817 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1818 ** in adpcm_coder.
1819 */
1820 vpdiff = step >> 3;
1821 if ( delta & 4 ) vpdiff += step;
1822 if ( delta & 2 ) vpdiff += step>>1;
1823 if ( delta & 1 ) vpdiff += step>>2;
1824
1825 if ( sign )
1826 valpred -= vpdiff;
1827 else
1828 valpred += vpdiff;
1829
1830 /* Step 5 - clamp output value */
1831 if ( valpred > 32767 )
1832 valpred = 32767;
1833 else if ( valpred < -32768 )
1834 valpred = -32768;
1835
1836 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001837 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001840 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1844 Py_DECREF(str);
1845 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001846}
1847
Larry Hastingsf256c222014-01-25 21:30:37 -08001848#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001849
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001850static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001851 AUDIOOP_MAX_METHODDEF
1852 AUDIOOP_MINMAX_METHODDEF
1853 AUDIOOP_AVG_METHODDEF
1854 AUDIOOP_MAXPP_METHODDEF
1855 AUDIOOP_AVGPP_METHODDEF
1856 AUDIOOP_RMS_METHODDEF
1857 AUDIOOP_FINDFIT_METHODDEF
1858 AUDIOOP_FINDMAX_METHODDEF
1859 AUDIOOP_FINDFACTOR_METHODDEF
1860 AUDIOOP_CROSS_METHODDEF
1861 AUDIOOP_MUL_METHODDEF
1862 AUDIOOP_ADD_METHODDEF
1863 AUDIOOP_BIAS_METHODDEF
1864 AUDIOOP_ULAW2LIN_METHODDEF
1865 AUDIOOP_LIN2ULAW_METHODDEF
1866 AUDIOOP_ALAW2LIN_METHODDEF
1867 AUDIOOP_LIN2ALAW_METHODDEF
1868 AUDIOOP_LIN2LIN_METHODDEF
1869 AUDIOOP_ADPCM2LIN_METHODDEF
1870 AUDIOOP_LIN2ADPCM_METHODDEF
1871 AUDIOOP_TOMONO_METHODDEF
1872 AUDIOOP_TOSTEREO_METHODDEF
1873 AUDIOOP_GETSAMPLE_METHODDEF
1874 AUDIOOP_REVERSE_METHODDEF
1875 AUDIOOP_BYTESWAP_METHODDEF
1876 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001878};
1879
Martin v. Löwis1a214512008-06-11 05:26:20 +00001880
1881static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 PyModuleDef_HEAD_INIT,
1883 "audioop",
1884 NULL,
1885 -1,
1886 audioop_methods,
1887 NULL,
1888 NULL,
1889 NULL,
1890 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001891};
1892
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001893PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001894PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyObject *m, *d;
1897 m = PyModule_Create(&audioopmodule);
1898 if (m == NULL)
1899 return NULL;
1900 d = PyModule_GetDict(m);
1901 if (d == NULL)
1902 return NULL;
1903 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1904 if (AudioopError != NULL)
1905 PyDict_SetItemString(d,"error",AudioopError);
1906 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001907}