blob: 1e131d247695bca09942696dd395195ccd7c45d3 [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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000054static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
55 0x1FF, 0x3FF, 0x7FF, 0xFFF};
56static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
57 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
58
59static PyInt16
60search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 for (i = 0; i < size; i++) {
65 if (val <= *table++)
66 return (i);
67 }
68 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069}
70#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
71#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000072
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000073static PyInt16 _st_ulaw2linear16[256] = {
74 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
75 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
76 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
77 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
78 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
79 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
80 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
81 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
82 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
83 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
84 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
85 -1052, -988, -924, -876, -844, -812, -780,
86 -748, -716, -684, -652, -620, -588, -556,
87 -524, -492, -460, -428, -396, -372, -356,
88 -340, -324, -308, -292, -276, -260, -244,
89 -228, -212, -196, -180, -164, -148, -132,
90 -120, -112, -104, -96, -88, -80, -72,
91 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000093 27004, 25980, 24956, 23932, 22908, 21884, 20860,
94 19836, 18812, 17788, 16764, 15996, 15484, 14972,
95 14460, 13948, 13436, 12924, 12412, 11900, 11388,
96 10876, 10364, 9852, 9340, 8828, 8316, 7932,
97 7676, 7420, 7164, 6908, 6652, 6396, 6140,
98 5884, 5628, 5372, 5116, 4860, 4604, 4348,
99 4092, 3900, 3772, 3644, 3516, 3388, 3260,
100 3132, 3004, 2876, 2748, 2620, 2492, 2364,
101 2236, 2108, 1980, 1884, 1820, 1756, 1692,
102 1628, 1564, 1500, 1436, 1372, 1308, 1244,
103 1180, 1116, 1052, 988, 924, 876, 844,
104 812, 780, 748, 716, 684, 652, 620,
105 588, 556, 524, 492, 460, 428, 396,
106 372, 356, 340, 324, 308, 292, 276,
107 260, 244, 228, 212, 196, 180, 164,
108 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 80, 72, 64, 56, 48, 40, 32,
110 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000111};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000112
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000113/*
114 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000115 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000116 * the data shifted such that it only contains information in the lower
117 * 14-bits.
118 *
119 * In order to simplify the encoding process, the original linear magnitude
120 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
121 * (33 - 8191). The result can be seen in the following encoding table:
122 *
123 * Biased Linear Input Code Compressed Code
124 * ------------------------ ---------------
125 * 00000001wxyza 000wxyz
126 * 0000001wxyzab 001wxyz
127 * 000001wxyzabc 010wxyz
128 * 00001wxyzabcd 011wxyz
129 * 0001wxyzabcde 100wxyz
130 * 001wxyzabcdef 101wxyz
131 * 01wxyzabcdefg 110wxyz
132 * 1wxyzabcdefgh 111wxyz
133 *
134 * Each biased linear code has a leading 1 which identifies the segment
135 * number. The value of the segment number is equal to 7 minus the number
136 * of leading 0's. The quantization interval is directly available as the
137 * four bits wxyz. * The trailing bits (a - h) are ignored.
138 *
139 * Ordinarily the complement of the resulting code word is used for
140 * transmission, and so the code word is complemented before it is returned.
141 *
142 * For further information see John C. Bellamy's Digital Telephony, 1982,
143 * John Wiley & Sons, pps 98-111 and 472-476.
144 */
145static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 PyInt16 mask;
149 PyInt16 seg;
150 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 /* u-law inverts all bits */
153 /* Get the sign and the magnitude of the value. */
154 if (pcm_val < 0) {
155 pcm_val = -pcm_val;
156 mask = 0x7F;
157 } else {
158 mask = 0xFF;
159 }
160 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
161 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 /* Convert the scaled magnitude to segment number. */
164 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 /*
167 * Combine the sign, segment, quantization bits;
168 * and complement the code word.
169 */
170 if (seg >= 8) /* out of range, return maximum value. */
171 return (unsigned char) (0x7F ^ mask);
172 else {
173 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
174 return (uval ^ mask);
175 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000176
177}
178
179static PyInt16 _st_alaw2linear16[256] = {
180 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
181 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
182 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
183 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
184 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
185 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
186 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
187 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
188 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
189 -13568, -344, -328, -376, -360, -280, -264,
190 -312, -296, -472, -456, -504, -488, -408,
191 -392, -440, -424, -88, -72, -120, -104,
192 -24, -8, -56, -40, -216, -200, -248,
193 -232, -152, -136, -184, -168, -1376, -1312,
194 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
195 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
196 -688, -656, -752, -720, -560, -528, -624,
197 -592, -944, -912, -1008, -976, -816, -784,
198 -880, -848, 5504, 5248, 6016, 5760, 4480,
199 4224, 4992, 4736, 7552, 7296, 8064, 7808,
200 6528, 6272, 7040, 6784, 2752, 2624, 3008,
201 2880, 2240, 2112, 2496, 2368, 3776, 3648,
202 4032, 3904, 3264, 3136, 3520, 3392, 22016,
203 20992, 24064, 23040, 17920, 16896, 19968, 18944,
204 30208, 29184, 32256, 31232, 26112, 25088, 28160,
205 27136, 11008, 10496, 12032, 11520, 8960, 8448,
206 9984, 9472, 15104, 14592, 16128, 15616, 13056,
207 12544, 14080, 13568, 344, 328, 376, 360,
208 280, 264, 312, 296, 472, 456, 504,
209 488, 408, 392, 440, 424, 88, 72,
210 120, 104, 24, 8, 56, 40, 216,
211 200, 248, 232, 152, 136, 184, 168,
212 1376, 1312, 1504, 1440, 1120, 1056, 1248,
213 1184, 1888, 1824, 2016, 1952, 1632, 1568,
214 1760, 1696, 688, 656, 752, 720, 560,
215 528, 624, 592, 944, 912, 1008, 976,
216 816, 784, 880, 848
217};
218
219/*
Martin Panter4c359642016-05-08 13:53:41 +0000220 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000221 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000222 * the data shifted such that it only contains information in the lower
223 * 13-bits.
224 *
225 * Linear Input Code Compressed Code
226 * ------------------------ ---------------
227 * 0000000wxyza 000wxyz
228 * 0000001wxyza 001wxyz
229 * 000001wxyzab 010wxyz
230 * 00001wxyzabc 011wxyz
231 * 0001wxyzabcd 100wxyz
232 * 001wxyzabcde 101wxyz
233 * 01wxyzabcdef 110wxyz
234 * 1wxyzabcdefg 111wxyz
235 *
236 * For further information see John C. Bellamy's Digital Telephony, 1982,
237 * John Wiley & Sons, pps 98-111 and 472-476.
238 */
239static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 PyInt16 mask;
243 short seg;
244 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
252 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
273static int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
278static int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289
Serhiy Storchaka23a78272013-11-11 07:47:35 +0200290#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
291#define SETINTX(T, cp, i, val) do { \
292 *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300293 } while (0)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000294
295
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300296#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
297#define GETINT16(cp, i) GETINTX(short, (cp), (i))
298#define GETINT32(cp, i) GETINTX(PY_INT32_T, (cp), (i))
299
300#if WORDS_BIGENDIAN
301#define GETINT24(cp, i) ( \
302 ((unsigned char *)(cp) + (i))[2] + \
303 (((unsigned char *)(cp) + (i))[1] << 8) + \
304 (((signed char *)(cp) + (i))[0] << 16) )
305#else
306#define GETINT24(cp, i) ( \
307 ((unsigned char *)(cp) + (i))[0] + \
308 (((unsigned char *)(cp) + (i))[1] << 8) + \
309 (((signed char *)(cp) + (i))[2] << 16) )
310#endif
311
312
313#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
314#define SETINT16(cp, i, val) SETINTX(short, (cp), (i), (val))
315#define SETINT32(cp, i, val) SETINTX(PY_INT32_T, (cp), (i), (val))
316
317#if WORDS_BIGENDIAN
318#define SETINT24(cp, i, val) do { \
319 ((unsigned char *)(cp) + (i))[2] = (int)(val); \
320 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
321 ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
322 } while (0)
323#else
324#define SETINT24(cp, i, val) do { \
325 ((unsigned char *)(cp) + (i))[0] = (int)(val); \
326 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
327 ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
328 } while (0)
329#endif
330
331
332#define GETRAWSAMPLE(size, cp, i) ( \
333 (size == 1) ? (int)GETINT8((cp), (i)) : \
334 (size == 2) ? (int)GETINT16((cp), (i)) : \
335 (size == 3) ? (int)GETINT24((cp), (i)) : \
336 (int)GETINT32((cp), (i)))
337
338#define SETRAWSAMPLE(size, cp, i, val) do { \
339 if (size == 1) \
340 SETINT8((cp), (i), (val)); \
341 else if (size == 2) \
342 SETINT16((cp), (i), (val)); \
343 else if (size == 3) \
344 SETINT24((cp), (i), (val)); \
345 else \
346 SETINT32((cp), (i), (val)); \
347 } while(0)
348
349
350#define GETSAMPLE32(size, cp, i) ( \
351 (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
352 (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
353 (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \
354 (int)GETINT32((cp), (i)))
355
356#define SETSAMPLE32(size, cp, i, val) do { \
357 if (size == 1) \
358 SETINT8((cp), (i), (val) >> 24); \
359 else if (size == 2) \
360 SETINT16((cp), (i), (val) >> 16); \
361 else if (size == 3) \
362 SETINT24((cp), (i), (val) >> 8); \
363 else \
364 SETINT32((cp), (i), (val)); \
365 } while(0)
366
Guido van Rossumb66efa01992-06-01 16:01:24 +0000367
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000368static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000369
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000370static int
371audioop_check_size(int size)
372{
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300373 if (size < 1 || size > 4) {
374 PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000375 return 0;
376 }
377 else
378 return 1;
379}
380
381static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000382audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000383{
384 if (!audioop_check_size(size))
385 return 0;
386 if (len % size != 0) {
387 PyErr_SetString(AudioopError, "not a whole number of frames");
388 return 0;
389 }
390 return 1;
391}
392
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200393/*[clinic input]
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200394module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200395[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300396/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200397
398/*[clinic input]
399audioop.getsample
400
401 fragment: Py_buffer
402 width: int
403 index: Py_ssize_t
404 /
405
406Return the value of sample index from the fragment.
407[clinic start generated code]*/
408
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300410audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400411 Py_ssize_t index)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300412/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000413{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200414 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000415
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200416 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000417 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200418 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200420 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200422 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200423 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000424}
425
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200426/*[clinic input]
427audioop.max
428
429 fragment: Py_buffer
430 width: int
431 /
432
433Return the maximum of the absolute value of all samples in a fragment.
434[clinic start generated code]*/
435
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300437audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
438/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000439{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200440 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200441 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000442
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200443 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000444 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200445 for (i = 0; i < fragment->len; i += width) {
446 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200447 if (val < 0) absval = (-val);
448 else absval = val;
449 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200451 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000452}
453
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200454/*[clinic input]
455audioop.minmax
456
457 fragment: Py_buffer
458 width: int
459 /
460
461Return the minimum and maximum values of all samples in the sound fragment.
462[clinic start generated code]*/
463
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300465audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
466/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000467{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200468 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000469 /* -1 trick below is needed on Windows to support -0x80000000 without
470 a warning */
471 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000472
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200473 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200475 for (i = 0; i < fragment->len; i += width) {
476 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 if (val > max) max = val;
478 if (val < min) min = val;
479 }
480 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000481}
482
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200483/*[clinic input]
484audioop.avg
485
486 fragment: Py_buffer
487 width: int
488 /
489
490Return the average over all samples in the fragment.
491[clinic start generated code]*/
492
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300494audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
495/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000496{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200497 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200498 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300499 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000500
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200501 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000502 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200503 for (i = 0; i < fragment->len; i += width)
504 sum += GETRAWSAMPLE(width, fragment->buf, i);
505 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300506 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200508 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300509 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000510}
511
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200512/*[clinic input]
513audioop.rms
514
515 fragment: Py_buffer
516 width: int
517 /
518
519Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
520[clinic start generated code]*/
521
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300523audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
524/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000525{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200526 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200527 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000529
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200530 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000531 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200532 for (i = 0; i < fragment->len; i += width) {
533 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300534 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200536 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200537 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200539 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200540 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000541}
542
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200543static double _sum2(const short *a, const short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000544{
Mark Dickinson81fece22010-05-11 13:34:35 +0000545 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 for( i=0; i<len; i++) {
549 sum = sum + (double)a[i]*(double)b[i];
550 }
551 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000552}
553
554/*
555** Findfit tries to locate a sample within another sample. Its main use
556** is in echo-cancellation (to find the feedback of the output signal in
557** the input signal).
558** The method used is as follows:
559**
560** let R be the reference signal (length n) and A the input signal (length N)
561** with N > n, and let all sums be over i from 0 to n-1.
562**
563** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
564** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
565** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
566**
567** Next, we compute the relative distance between the original signal and
568** the modified signal and minimize that over j:
569** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
570** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
571**
572** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000573** cp1 A
574** cp2 R
575** len1 N
576** len2 n
577** aj_m1 A[j-1]
578** aj_lm1 A[j+n-1]
579** sum_ri_2 sum(R[i]^2)
580** sum_aij_2 sum(A[i+j]^2)
581** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000582**
583** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
584** is completely recalculated each step.
585*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200586/*[clinic input]
587audioop.findfit
588
589 fragment: Py_buffer
590 reference: Py_buffer
591 /
592
593Try to match reference as well as possible to a portion of fragment.
594[clinic start generated code]*/
595
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300597audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400598 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300599/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000600{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200601 const short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000602 Py_ssize_t len1, len2;
603 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 double aj_m1, aj_lm1;
605 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000606
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200607 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200609 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200611 cp1 = (const short *)fragment->buf;
612 len1 = fragment->len >> 1;
613 cp2 = (const short *)reference->buf;
614 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000615
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200616 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200618 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 }
620 sum_ri_2 = _sum2(cp2, cp2, len2);
621 sum_aij_2 = _sum2(cp1, cp1, len2);
622 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 best_result = result;
627 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 for ( j=1; j<=len1-len2; j++) {
630 aj_m1 = (double)cp1[j-1];
631 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
634 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
637 / sum_aij_2;
638
639 if ( result < best_result ) {
640 best_result = result;
641 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000642 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 }
645
646 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
647
Mark Dickinson81fece22010-05-11 13:34:35 +0000648 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000649}
650
651/*
652** findfactor finds a factor f so that the energy in A-fB is minimal.
653** See the comment for findfit for details.
654*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200655/*[clinic input]
656audioop.findfactor
657
658 fragment: Py_buffer
659 reference: Py_buffer
660 /
661
662Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
663[clinic start generated code]*/
664
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300666audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400667 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300668/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000669{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200670 const short *cp1, *cp2;
671 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000673
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200674 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200676 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200678 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 PyErr_SetString(AudioopError, "Samples should be same size");
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 cp1 = (const short *)fragment->buf;
683 cp2 = (const short *)reference->buf;
684 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200685 sum_ri_2 = _sum2(cp2, cp2, len);
686 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000691}
692
693/*
694** findmax returns the index of the n-sized segment of the input sample
695** that contains the most energy.
696*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200697/*[clinic input]
698audioop.findmax
699
700 fragment: Py_buffer
701 length: Py_ssize_t
702 /
703
704Search fragment for a slice of specified number of samples with maximum energy.
705[clinic start generated code]*/
706
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300708audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400709 Py_ssize_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300710/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000711{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200712 const short *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200713 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000714 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 double aj_m1, aj_lm1;
716 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000717
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200718 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200720 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200722 cp1 = (const short *)fragment->buf;
723 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200725 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200727 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 }
729
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200730 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731
732 best_result = result;
733 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200735 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200737 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738
739 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
740
741 if ( result > best_result ) {
742 best_result = result;
743 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744 }
Jack Jansena90805f1993-02-17 14:29:28 +0000745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000747
Mark Dickinson81fece22010-05-11 13:34:35 +0000748 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000749}
750
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200751/*[clinic input]
752audioop.avgpp
753
754 fragment: Py_buffer
755 width: int
756 /
757
758Return the average peak-peak value over all samples in the fragment.
759[clinic start generated code]*/
760
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000761static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300762audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
763/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000764{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200765 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200766 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200767 double sum = 0.0;
768 unsigned int avg;
769 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000770
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200771 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000772 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200773 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200774 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200775 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200776 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200777 for (i = width; i < fragment->len; i += width) {
778 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200779 if (val != prevval) {
780 diff = val < prevval;
781 if (prevdiff == !diff) {
782 /* Derivative changed sign. Compute difference to last
783 ** extreme value and remember.
784 */
785 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300786 if (prevval < prevextreme)
787 sum += (double)((unsigned int)prevextreme -
788 (unsigned int)prevval);
789 else
790 sum += (double)((unsigned int)prevval -
791 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200792 nextreme++;
793 }
794 prevextremevalid = 1;
795 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200797 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200799 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 }
801 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200802 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200804 avg = (unsigned int)(sum / (double)nextreme);
805 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000806}
807
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200808/*[clinic input]
809audioop.maxpp
810
811 fragment: Py_buffer
812 width: int
813 /
814
815Return the maximum peak-peak value in the sound fragment.
816[clinic start generated code]*/
817
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000818static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300819audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
820/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000821{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200822 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200823 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200824 unsigned int max = 0, extremediff;
825 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000826
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200827 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000828 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200829 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200830 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200831 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200832 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200833 for (i = width; i < fragment->len; i += width) {
834 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200835 if (val != prevval) {
836 diff = val < prevval;
837 if (prevdiff == !diff) {
838 /* Derivative changed sign. Compute difference to
839 ** last extreme value and remember.
840 */
841 if (prevextremevalid) {
842 if (prevval < prevextreme)
843 extremediff = (unsigned int)prevextreme -
844 (unsigned int)prevval;
845 else
846 extremediff = (unsigned int)prevval -
847 (unsigned int)prevextreme;
848 if ( extremediff > max )
849 max = extremediff;
850 }
851 prevextremevalid = 1;
852 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200854 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200856 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200858 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000859}
860
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200861/*[clinic input]
862audioop.cross
863
864 fragment: Py_buffer
865 width: int
866 /
867
868Return the number of zero crossings in the fragment passed as an argument.
869[clinic start generated code]*/
870
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300872audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
873/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000874{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200875 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000876 int prevval;
877 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000878
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200879 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000880 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 ncross = -1;
882 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200883 for (i = 0; i < fragment->len; i += width) {
884 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300885 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 prevval = val;
887 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000888 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000889}
890
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200891/*[clinic input]
892audioop.mul
893
894 fragment: Py_buffer
895 width: int
896 factor: double
897 /
898
899Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
900[clinic start generated code]*/
901
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300903audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400904 double factor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300905/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200907 signed char *ncp;
908 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200909 double maxval, minval;
910 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000911
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200912 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000913 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200915 maxval = (double) maxvals[width];
916 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200918 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200919 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200920 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 ncp = (signed char *)PyBytes_AsString(rv);
922
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200923 for (i = 0; i < fragment->len; i += width) {
924 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300925 val *= factor;
926 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200927 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 }
929 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000930}
931
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200932/*[clinic input]
933audioop.tomono
934
935 fragment: Py_buffer
936 width: int
937 lfactor: double
938 rfactor: double
939 /
940
941Convert a stereo fragment to a mono fragment.
942[clinic start generated code]*/
943
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300945audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400946 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300947/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000950 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200951 double maxval, minval;
952 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000953
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200954 cp = fragment->buf;
955 len = fragment->len;
956 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200957 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200958 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000959 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200960 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000961 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200963 maxval = (double) maxvals[width];
964 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965
966 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200967 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200968 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 ncp = (signed char *)PyBytes_AsString(rv);
970
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200971 for (i = 0; i < len; i += width*2) {
972 double val1 = GETRAWSAMPLE(width, cp, i);
973 double val2 = GETRAWSAMPLE(width, cp, i + width);
974 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300975 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200976 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000979}
980
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200981/*[clinic input]
982audioop.tostereo
983
984 fragment: Py_buffer
985 width: int
986 lfactor: double
987 rfactor: double
988 /
989
990Generate a stereo fragment from a mono fragment.
991[clinic start generated code]*/
992
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300994audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400995 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300996/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000997{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200998 signed char *ncp;
999 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001000 double maxval, minval;
1001 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001002
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001003 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001004 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001005
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001006 maxval = (double) maxvals[width];
1007 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001008
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001009 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 PyErr_SetString(PyExc_MemoryError,
1011 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001012 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001014
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001015 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001016 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001017 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001019
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001020 for (i = 0; i < fragment->len; i += width) {
1021 double val = GETRAWSAMPLE(width, fragment->buf, i);
1022 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1023 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1024 SETRAWSAMPLE(width, ncp, i*2, val1);
1025 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 }
1027 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001028}
1029
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001030/*[clinic input]
1031audioop.add
1032
1033 fragment1: Py_buffer
1034 fragment2: Py_buffer
1035 width: int
1036 /
1037
1038Return a fragment which is the addition of the two samples passed as parameters.
1039[clinic start generated code]*/
1040
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001042audioop_add_impl(PyObject *module, Py_buffer *fragment1,
Larry Hastings89964c42015-04-14 18:07:59 -04001043 Py_buffer *fragment2, int width)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001044/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001045{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001046 signed char *ncp;
1047 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001048 int minval, maxval, newval;
1049 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001050
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001051 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001052 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001053 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001055 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001057
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001058 maxval = maxvals[width];
1059 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001060
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001061 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001062 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001063 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001065
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001066 for (i = 0; i < fragment1->len; i += width) {
1067 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1068 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001070 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001071 newval = val1 + val2;
1072 /* truncate in case of overflow */
1073 if (newval > maxval)
1074 newval = maxval;
1075 else if (newval < minval)
1076 newval = minval;
1077 }
1078 else {
1079 double fval = (double)val1 + (double)val2;
1080 /* truncate in case of overflow */
1081 newval = (int)floor(fbound(fval, minval, maxval));
1082 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001084 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 }
1086 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001087}
1088
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001089/*[clinic input]
1090audioop.bias
1091
1092 fragment: Py_buffer
1093 width: int
1094 bias: int
1095 /
1096
1097Return a fragment that is the original fragment with a bias added to each sample.
1098[clinic start generated code]*/
1099
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001100static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001101audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
1102/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001103{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001104 signed char *ncp;
1105 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001106 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001107 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001108
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001109 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001110 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001112 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001113 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001114 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 ncp = (signed char *)PyBytes_AsString(rv);
1116
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001117 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001119 for (i = 0; i < fragment->len; i += width) {
1120 if (width == 1)
1121 val = GETINTX(unsigned char, fragment->buf, i);
1122 else if (width == 2)
1123 val = GETINTX(unsigned short, fragment->buf, i);
1124 else if (width == 3)
1125 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001126 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001127 assert(width == 4);
1128 val = GETINTX(PY_UINT32_T, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001129 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001131 val += (unsigned int)bias;
1132 /* wrap around in case of overflow */
1133 val &= mask;
1134
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001135 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001136 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001137 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001138 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001139 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001140 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001141 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001142 assert(width == 4);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001143 SETINTX(PY_UINT32_T, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001144 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 }
1146 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001147}
1148
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001149/*[clinic input]
1150audioop.reverse
1151
1152 fragment: Py_buffer
1153 width: int
1154 /
1155
1156Reverse the samples in a fragment and returns the modified fragment.
1157[clinic start generated code]*/
1158
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001160audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
1161/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001164 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001165 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001166
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001167 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001168 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001169
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001170 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001171 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001172 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 ncp = (unsigned char *)PyBytes_AsString(rv);
1174
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001175 for (i = 0; i < fragment->len; i += width) {
1176 int val = GETRAWSAMPLE(width, fragment->buf, i);
1177 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 }
1179 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001180}
1181
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001182/*[clinic input]
1183audioop.byteswap
1184
1185 fragment: Py_buffer
1186 width: int
1187 /
1188
1189Convert big-endian samples to little-endian and vice versa.
1190[clinic start generated code]*/
1191
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001193audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
1194/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001195{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001196 unsigned char *ncp;
1197 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001198 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001199
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001200 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001201 return NULL;
1202
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001203 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001204 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001205 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001206 ncp = (unsigned char *)PyBytes_AsString(rv);
1207
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001208 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001209 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001210 for (j = 0; j < width; j++)
1211 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001212 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001213 return rv;
1214}
1215
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001216/*[clinic input]
1217audioop.lin2lin
1218
1219 fragment: Py_buffer
1220 width: int
1221 newwidth: int
1222 /
1223
1224Convert samples between 1-, 2-, 3- and 4-byte formats.
1225[clinic start generated code]*/
1226
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001228audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001229 int newwidth)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001230/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001233 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001234 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001235
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001236 if (!audioop_check_parameters(fragment->len, width))
1237 return NULL;
1238 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001239 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001240
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001241 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 PyErr_SetString(PyExc_MemoryError,
1243 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001244 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001246 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001247 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001248 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 ncp = (unsigned char *)PyBytes_AsString(rv);
1250
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001251 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1252 int val = GETSAMPLE32(width, fragment->buf, i);
1253 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 }
1255 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001256}
1257
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001258static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001259gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 while (b > 0) {
1262 int tmp = a % b;
1263 a = b;
1264 b = tmp;
1265 }
1266 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001267}
1268
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001269/*[clinic input]
1270audioop.ratecv
1271
1272 fragment: Py_buffer
1273 width: int
1274 nchannels: int
1275 inrate: int
1276 outrate: int
1277 state: object
1278 weightA: int = 1
1279 weightB: int = 0
1280 /
1281
1282Convert the frame rate of the input fragment.
1283[clinic start generated code]*/
1284
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001286audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001287 int nchannels, int inrate, int outrate, PyObject *state,
1288 int weightA, int weightB)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001289/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001292 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001294 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001296
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001297 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 if (nchannels < 1) {
1300 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001301 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001303 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 /* This overflow test is rigorously correct because
1305 both multiplicands are >= 1. Use the argument names
1306 from the docs for the error msg. */
1307 PyErr_SetString(PyExc_OverflowError,
1308 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001309 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001311 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (weightA < 1 || weightB < 0) {
1313 PyErr_SetString(AudioopError,
1314 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001315 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001317 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001318 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001320 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 }
1322 if (inrate <= 0 || outrate <= 0) {
1323 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001324 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 }
1326 /* divide inrate and outrate by their greatest common divisor */
1327 d = gcd(inrate, outrate);
1328 inrate /= d;
1329 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001330 /* divide weightA and weightB by their greatest common divisor */
1331 d = gcd(weightA, weightB);
1332 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001333 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001334
Mark Dickinson85eacea2010-05-10 16:27:45 +00001335 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 PyErr_SetString(PyExc_MemoryError,
1337 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001338 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001340 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1341 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 if (prev_i == NULL || cur_i == NULL) {
1343 (void) PyErr_NoMemory();
1344 goto exit;
1345 }
1346
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001347 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348
1349 if (state == Py_None) {
1350 d = -outrate;
1351 for (chan = 0; chan < nchannels; chan++)
1352 prev_i[chan] = cur_i[chan] = 0;
1353 }
1354 else {
1355 if (!PyArg_ParseTuple(state,
1356 "iO!;audioop.ratecv: illegal state argument",
1357 &d, &PyTuple_Type, &samps))
1358 goto exit;
1359 if (PyTuple_Size(samps) != nchannels) {
1360 PyErr_SetString(AudioopError,
1361 "illegal state argument");
1362 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001363 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 for (chan = 0; chan < nchannels; chan++) {
1365 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1366 "ii:ratecv", &prev_i[chan],
1367 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001368 goto exit;
1369 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001373 if (len == 0)
1374 str = PyBytes_FromStringAndSize(NULL, 0);
1375 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 /* There are len input frames, so we need (mathematically)
1377 ceiling(len*outrate/inrate) output frames, and each frame
1378 requires bytes_per_frame bytes. Computing this
1379 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001380 settle for a reasonable upper bound, though, in this
1381 case ceiling(len/inrate) * outrate. */
1382
1383 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001384 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001385 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 str = NULL;
1387 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001388 str = PyBytes_FromStringAndSize(NULL,
1389 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001390 }
1391 if (str == NULL) {
1392 PyErr_SetString(PyExc_MemoryError,
1393 "not enough memory for output buffer");
1394 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 }
1396 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001397 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398
1399 for (;;) {
1400 while (d < 0) {
1401 if (len == 0) {
1402 samps = PyTuple_New(nchannels);
1403 if (samps == NULL)
1404 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001405 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 PyTuple_SetItem(samps, chan,
1407 Py_BuildValue("(ii)",
1408 prev_i[chan],
1409 cur_i[chan]));
1410 if (PyErr_Occurred())
1411 goto exit;
1412 /* We have checked before that the length
1413 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001414 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 rv = PyBytes_FromStringAndSize
1416 (PyBytes_AsString(str), len);
1417 Py_DECREF(str);
1418 str = rv;
1419 if (str == NULL)
1420 goto exit;
1421 rv = Py_BuildValue("(O(iO))", str, d, samps);
1422 Py_DECREF(samps);
1423 Py_DECREF(str);
1424 goto exit; /* return rv */
1425 }
1426 for (chan = 0; chan < nchannels; chan++) {
1427 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001428 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1429 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001431 cur_i[chan] = (int)(
1432 ((double)weightA * (double)cur_i[chan] +
1433 (double)weightB * (double)prev_i[chan]) /
1434 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 }
1436 len--;
1437 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001438 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 while (d >= 0) {
1440 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001441 cur_o = (int)(((double)prev_i[chan] * (double)d +
1442 (double)cur_i[chan] * (double)(outrate - d)) /
1443 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001444 SETSAMPLE32(width, ncp, 0, cur_o);
1445 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 }
1447 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001448 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001450 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001451 PyMem_Free(prev_i);
1452 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001454}
Guido van Rossum1851a671997-02-14 16:14:03 +00001455
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001456/*[clinic input]
1457audioop.lin2ulaw
1458
1459 fragment: Py_buffer
1460 width: int
1461 /
1462
1463Convert samples in the audio fragment to u-LAW encoding.
1464[clinic start generated code]*/
1465
Roger E. Massec905fff1997-01-17 18:12:04 +00001466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001467audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1468/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001471 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001472 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001473
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001474 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001475 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001476
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001477 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001478 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001479 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 ncp = (unsigned char *)PyBytes_AsString(rv);
1481
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001482 for (i = 0; i < fragment->len; i += width) {
1483 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001484 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 }
1486 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001487}
1488
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001489/*[clinic input]
1490audioop.ulaw2lin
1491
1492 fragment: Py_buffer
1493 width: int
1494 /
1495
1496Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1497[clinic start generated code]*/
1498
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001500audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1501/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001505 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001506 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001507
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001508 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001509 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001511 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 PyErr_SetString(PyExc_MemoryError,
1513 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001514 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001516 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001517 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001518 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 ncp = (signed char *)PyBytes_AsString(rv);
1520
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001521 cp = fragment->buf;
1522 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001523 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001524 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 }
1526 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001527}
1528
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001529/*[clinic input]
1530audioop.lin2alaw
1531
1532 fragment: Py_buffer
1533 width: int
1534 /
1535
1536Convert samples in the audio fragment to a-LAW encoding.
1537[clinic start generated code]*/
1538
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001539static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001540audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1541/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001544 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001545 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001546
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001547 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001548 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001549
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001550 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001551 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001552 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 ncp = (unsigned char *)PyBytes_AsString(rv);
1554
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001555 for (i = 0; i < fragment->len; i += width) {
1556 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001557 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 }
1559 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001560}
1561
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001562/*[clinic input]
1563audioop.alaw2lin
1564
1565 fragment: Py_buffer
1566 width: int
1567 /
1568
1569Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1570[clinic start generated code]*/
1571
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001572static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001573audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1574/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001578 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001579 int val;
1580 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001581
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001582 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001583 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001585 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 PyErr_SetString(PyExc_MemoryError,
1587 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001588 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001590 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001591 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001592 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001594 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001596 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001597 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001598 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 }
1600 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001601}
1602
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001603/*[clinic input]
1604audioop.lin2adpcm
1605
1606 fragment: Py_buffer
1607 width: int
1608 state: object
1609 /
1610
1611Convert samples to 4 bit Intel/DVI ADPCM encoding.
1612[clinic start generated code]*/
1613
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001615audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001616 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001617/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001620 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001621 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001623 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001624 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001625
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001626 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001627 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 /* Decode state, should have (value, step) */
1630 if ( state == Py_None ) {
1631 /* First time, it seems. Set defaults */
1632 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001634 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001635 else if (!PyTuple_Check(state)) {
1636 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1637 return NULL;
1638 }
1639 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1640 return NULL;
1641 }
1642 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1643 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1644 PyErr_SetString(PyExc_ValueError, "bad state");
1645 return NULL;
1646 }
1647
1648 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1649 if (str == NULL)
1650 return NULL;
1651 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652
1653 step = stepsizeTable[index];
1654 bufferstep = 1;
1655
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001656 for (i = 0; i < fragment->len; i += width) {
1657 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658
1659 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001660 if (val < valpred) {
1661 diff = valpred - val;
1662 sign = 8;
1663 }
1664 else {
1665 diff = val - valpred;
1666 sign = 0;
1667 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668
1669 /* Step 2 - Divide and clamp */
1670 /* Note:
1671 ** This code *approximately* computes:
1672 ** delta = diff*4/step;
1673 ** vpdiff = (delta+0.5)*step/4;
1674 ** but in shift step bits are dropped. The net result of this
1675 ** is that even if you have fast mul/div hardware you cannot
1676 ** put it to good use since the fixup would be too expensive.
1677 */
1678 delta = 0;
1679 vpdiff = (step >> 3);
1680
1681 if ( diff >= step ) {
1682 delta = 4;
1683 diff -= step;
1684 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001685 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 step >>= 1;
1687 if ( diff >= step ) {
1688 delta |= 2;
1689 diff -= step;
1690 vpdiff += step;
1691 }
1692 step >>= 1;
1693 if ( diff >= step ) {
1694 delta |= 1;
1695 vpdiff += step;
1696 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 /* Step 3 - Update previous value */
1699 if ( sign )
1700 valpred -= vpdiff;
1701 else
1702 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 /* Step 4 - Clamp previous value to 16 bits */
1705 if ( valpred > 32767 )
1706 valpred = 32767;
1707 else if ( valpred < -32768 )
1708 valpred = -32768;
1709
1710 /* Step 5 - Assemble value, update index and step values */
1711 delta |= sign;
1712
1713 index += indexTable[delta];
1714 if ( index < 0 ) index = 0;
1715 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001716 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 /* Step 6 - Output value */
1719 if ( bufferstep ) {
1720 outputbuffer = (delta << 4) & 0xf0;
1721 } else {
1722 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001723 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 bufferstep = !bufferstep;
1725 }
1726 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001727 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001729}
1730
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001731/*[clinic input]
1732audioop.adpcm2lin
1733
1734 fragment: Py_buffer
1735 width: int
1736 state: object
1737 /
1738
1739Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1740[clinic start generated code]*/
1741
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001742static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001743audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001744 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001745/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 signed char *cp;
1748 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001749 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001750 int valpred, step, delta, index, sign, vpdiff;
1751 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001752 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001753
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001754 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001755 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 /* Decode state, should have (value, step) */
1758 if ( state == Py_None ) {
1759 /* First time, it seems. Set defaults */
1760 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001762 }
1763 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001764 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001765 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001766 }
1767 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001768 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001769 }
1770 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1771 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1772 PyErr_SetString(PyExc_ValueError, "bad state");
1773 return NULL;
1774 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001776 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 PyErr_SetString(PyExc_MemoryError,
1778 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001779 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001781 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001782 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001783 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001784 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001786 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787
1788 step = stepsizeTable[index];
1789 bufferstep = 0;
1790
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001791 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 /* Step 1 - get the delta value and compute next index */
1793 if ( bufferstep ) {
1794 delta = inputbuffer & 0xf;
1795 } else {
1796 inputbuffer = *cp++;
1797 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001798 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 bufferstep = !bufferstep;
1801
1802 /* Step 2 - Find new index value (for later) */
1803 index += indexTable[delta];
1804 if ( index < 0 ) index = 0;
1805 if ( index > 88 ) index = 88;
1806
1807 /* Step 3 - Separate sign and magnitude */
1808 sign = delta & 8;
1809 delta = delta & 7;
1810
1811 /* Step 4 - Compute difference and new predicted value */
1812 /*
1813 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1814 ** in adpcm_coder.
1815 */
1816 vpdiff = step >> 3;
1817 if ( delta & 4 ) vpdiff += step;
1818 if ( delta & 2 ) vpdiff += step>>1;
1819 if ( delta & 1 ) vpdiff += step>>2;
1820
1821 if ( sign )
1822 valpred -= vpdiff;
1823 else
1824 valpred += vpdiff;
1825
1826 /* Step 5 - clamp output value */
1827 if ( valpred > 32767 )
1828 valpred = 32767;
1829 else if ( valpred < -32768 )
1830 valpred = -32768;
1831
1832 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001833 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001836 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1840 Py_DECREF(str);
1841 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001842}
1843
Larry Hastingsf256c222014-01-25 21:30:37 -08001844#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001845
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001846static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001847 AUDIOOP_MAX_METHODDEF
1848 AUDIOOP_MINMAX_METHODDEF
1849 AUDIOOP_AVG_METHODDEF
1850 AUDIOOP_MAXPP_METHODDEF
1851 AUDIOOP_AVGPP_METHODDEF
1852 AUDIOOP_RMS_METHODDEF
1853 AUDIOOP_FINDFIT_METHODDEF
1854 AUDIOOP_FINDMAX_METHODDEF
1855 AUDIOOP_FINDFACTOR_METHODDEF
1856 AUDIOOP_CROSS_METHODDEF
1857 AUDIOOP_MUL_METHODDEF
1858 AUDIOOP_ADD_METHODDEF
1859 AUDIOOP_BIAS_METHODDEF
1860 AUDIOOP_ULAW2LIN_METHODDEF
1861 AUDIOOP_LIN2ULAW_METHODDEF
1862 AUDIOOP_ALAW2LIN_METHODDEF
1863 AUDIOOP_LIN2ALAW_METHODDEF
1864 AUDIOOP_LIN2LIN_METHODDEF
1865 AUDIOOP_ADPCM2LIN_METHODDEF
1866 AUDIOOP_LIN2ADPCM_METHODDEF
1867 AUDIOOP_TOMONO_METHODDEF
1868 AUDIOOP_TOSTEREO_METHODDEF
1869 AUDIOOP_GETSAMPLE_METHODDEF
1870 AUDIOOP_REVERSE_METHODDEF
1871 AUDIOOP_BYTESWAP_METHODDEF
1872 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001874};
1875
Martin v. Löwis1a214512008-06-11 05:26:20 +00001876
1877static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 PyModuleDef_HEAD_INIT,
1879 "audioop",
1880 NULL,
1881 -1,
1882 audioop_methods,
1883 NULL,
1884 NULL,
1885 NULL,
1886 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001887};
1888
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001889PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001890PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 PyObject *m, *d;
1893 m = PyModule_Create(&audioopmodule);
1894 if (m == NULL)
1895 return NULL;
1896 d = PyModule_GetDict(m);
1897 if (d == NULL)
1898 return NULL;
1899 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1900 if (AudioopError != NULL)
1901 PyDict_SetItemString(d,"error",AudioopError);
1902 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001903}