blob: bbc458f9b71f7ad5314a016b1d08b9fdca5cc3d1 [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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000049#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
50#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
115 * stored in a unsigned char. This function should only be called with
116 * 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/*
220 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
221 * stored in a unsigned char. This function should only be called with
222 * 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400410audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width,
411 Py_ssize_t index)
412/*[clinic end generated code: output=3995e189fdc8ec16 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 Storchaka8d00d732014-01-25 11:57:59 +0200437audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800438/*[clinic end generated code: output=85047ee1001f2305 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 Storchaka8d00d732014-01-25 11:57:59 +0200465audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800466/*[clinic end generated code: output=ae8f5513c64fd569 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 Storchaka8d00d732014-01-25 11:57:59 +0200494audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800495/*[clinic end generated code: output=7fccd645c95f4860 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 Storchaka8d00d732014-01-25 11:57:59 +0200523audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800524/*[clinic end generated code: output=7b398702c81b709d 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400597audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment,
598 Py_buffer *reference)
599/*[clinic end generated code: output=609eedf5d823d6dd 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400666audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment,
667 Py_buffer *reference)
668/*[clinic end generated code: output=5566a8c55de54f99 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400708audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment,
709 Py_ssize_t length)
710/*[clinic end generated code: output=01fe796fad2573bb 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 Storchaka8d00d732014-01-25 11:57:59 +0200762audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800763/*[clinic end generated code: output=06c8380fd6e34207 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 Storchaka8d00d732014-01-25 11:57:59 +0200819audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800820/*[clinic end generated code: output=c300c0bd7e8535c0 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 Storchaka8d00d732014-01-25 11:57:59 +0200872audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800873/*[clinic end generated code: output=99e6572d7d7cdbf1 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400903audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width,
904 double factor)
905/*[clinic end generated code: output=1c7c31191ac86b10 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400945audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width,
946 double lfactor, double rfactor)
947/*[clinic end generated code: output=553f547c5e29e3b6 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 *
Larry Hastings89964c42015-04-14 18:07:59 -0400994audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width,
995 double lfactor, double rfactor)
996/*[clinic end generated code: output=697bb6ba41e9dd2c 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 *
Larry Hastings89964c42015-04-14 18:07:59 -04001042audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1,
1043 Py_buffer *fragment2, int width)
1044/*[clinic end generated code: output=fe6c12f143e0b027 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 *
Larry Hastings89964c42015-04-14 18:07:59 -04001101audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1102 int bias)
1103/*[clinic end generated code: output=ac1f4dda20a01c26 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001104{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001105 signed char *ncp;
1106 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001107 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001108 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001109
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001110 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001111 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001113 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001114 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001115 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 ncp = (signed char *)PyBytes_AsString(rv);
1117
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001118 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001120 for (i = 0; i < fragment->len; i += width) {
1121 if (width == 1)
1122 val = GETINTX(unsigned char, fragment->buf, i);
1123 else if (width == 2)
1124 val = GETINTX(unsigned short, fragment->buf, i);
1125 else if (width == 3)
1126 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001127 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001128 assert(width == 4);
1129 val = GETINTX(PY_UINT32_T, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001130 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001132 val += (unsigned int)bias;
1133 /* wrap around in case of overflow */
1134 val &= mask;
1135
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001136 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001137 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001138 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001139 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001140 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001141 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001142 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001143 assert(width == 4);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001144 SETINTX(PY_UINT32_T, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001145 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 }
1147 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001148}
1149
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001150/*[clinic input]
1151audioop.reverse
1152
1153 fragment: Py_buffer
1154 width: int
1155 /
1156
1157Reverse the samples in a fragment and returns the modified fragment.
1158[clinic start generated code]*/
1159
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001160static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001161audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001162/*[clinic end generated code: output=6ec3c91337f5925e input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001165 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001166 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001167
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001168 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001169 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001170
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001171 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001172 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001173 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 ncp = (unsigned char *)PyBytes_AsString(rv);
1175
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001176 for (i = 0; i < fragment->len; i += width) {
1177 int val = GETRAWSAMPLE(width, fragment->buf, i);
1178 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 }
1180 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001181}
1182
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001183/*[clinic input]
1184audioop.byteswap
1185
1186 fragment: Py_buffer
1187 width: int
1188 /
1189
1190Convert big-endian samples to little-endian and vice versa.
1191[clinic start generated code]*/
1192
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001193static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001194audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001195/*[clinic end generated code: output=bfe4aa584b7a3f5b input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001196{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001197 unsigned char *ncp;
1198 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001199 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001200
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001201 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001202 return NULL;
1203
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001204 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001205 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001206 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001207 ncp = (unsigned char *)PyBytes_AsString(rv);
1208
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001209 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001210 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001211 for (j = 0; j < width; j++)
1212 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001213 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001214 return rv;
1215}
1216
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001217/*[clinic input]
1218audioop.lin2lin
1219
1220 fragment: Py_buffer
1221 width: int
1222 newwidth: int
1223 /
1224
1225Convert samples between 1-, 2-, 3- and 4-byte formats.
1226[clinic start generated code]*/
1227
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001228static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001229audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1230 int newwidth)
1231/*[clinic end generated code: output=cb6ca950d1df9898 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001234 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001235 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001236
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001237 if (!audioop_check_parameters(fragment->len, width))
1238 return NULL;
1239 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001240 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001241
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001242 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 PyErr_SetString(PyExc_MemoryError,
1244 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001245 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001247 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001248 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001249 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 ncp = (unsigned char *)PyBytes_AsString(rv);
1251
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001252 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1253 int val = GETSAMPLE32(width, fragment->buf, i);
1254 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 }
1256 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001257}
1258
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001259static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001260gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 while (b > 0) {
1263 int tmp = a % b;
1264 a = b;
1265 b = tmp;
1266 }
1267 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001268}
1269
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001270/*[clinic input]
1271audioop.ratecv
1272
1273 fragment: Py_buffer
1274 width: int
1275 nchannels: int
1276 inrate: int
1277 outrate: int
1278 state: object
1279 weightA: int = 1
1280 weightB: int = 0
1281 /
1282
1283Convert the frame rate of the input fragment.
1284[clinic start generated code]*/
1285
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001286static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001287audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1288 int nchannels, int inrate, int outrate, PyObject *state,
1289 int weightA, int weightB)
1290/*[clinic end generated code: output=59e1787bfa49b9d9 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001291{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001293 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001295 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001297
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001298 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 if (nchannels < 1) {
1301 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001302 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001304 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 /* This overflow test is rigorously correct because
1306 both multiplicands are >= 1. Use the argument names
1307 from the docs for the error msg. */
1308 PyErr_SetString(PyExc_OverflowError,
1309 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001310 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001312 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 if (weightA < 1 || weightB < 0) {
1314 PyErr_SetString(AudioopError,
1315 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001316 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001318 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001319 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001321 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 }
1323 if (inrate <= 0 || outrate <= 0) {
1324 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001325 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 }
1327 /* divide inrate and outrate by their greatest common divisor */
1328 d = gcd(inrate, outrate);
1329 inrate /= d;
1330 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001331 /* divide weightA and weightB by their greatest common divisor */
1332 d = gcd(weightA, weightB);
1333 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001334 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001335
Mark Dickinson85eacea2010-05-10 16:27:45 +00001336 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 PyErr_SetString(PyExc_MemoryError,
1338 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001339 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001341 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1342 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if (prev_i == NULL || cur_i == NULL) {
1344 (void) PyErr_NoMemory();
1345 goto exit;
1346 }
1347
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001348 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349
1350 if (state == Py_None) {
1351 d = -outrate;
1352 for (chan = 0; chan < nchannels; chan++)
1353 prev_i[chan] = cur_i[chan] = 0;
1354 }
1355 else {
1356 if (!PyArg_ParseTuple(state,
1357 "iO!;audioop.ratecv: illegal state argument",
1358 &d, &PyTuple_Type, &samps))
1359 goto exit;
1360 if (PyTuple_Size(samps) != nchannels) {
1361 PyErr_SetString(AudioopError,
1362 "illegal state argument");
1363 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001364 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 for (chan = 0; chan < nchannels; chan++) {
1366 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1367 "ii:ratecv", &prev_i[chan],
1368 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001369 goto exit;
1370 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001374 if (len == 0)
1375 str = PyBytes_FromStringAndSize(NULL, 0);
1376 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 /* There are len input frames, so we need (mathematically)
1378 ceiling(len*outrate/inrate) output frames, and each frame
1379 requires bytes_per_frame bytes. Computing this
1380 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001381 settle for a reasonable upper bound, though, in this
1382 case ceiling(len/inrate) * outrate. */
1383
1384 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001385 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001386 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 str = NULL;
1388 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001389 str = PyBytes_FromStringAndSize(NULL,
1390 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001391 }
1392 if (str == NULL) {
1393 PyErr_SetString(PyExc_MemoryError,
1394 "not enough memory for output buffer");
1395 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 }
1397 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001398 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399
1400 for (;;) {
1401 while (d < 0) {
1402 if (len == 0) {
1403 samps = PyTuple_New(nchannels);
1404 if (samps == NULL)
1405 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001406 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 PyTuple_SetItem(samps, chan,
1408 Py_BuildValue("(ii)",
1409 prev_i[chan],
1410 cur_i[chan]));
1411 if (PyErr_Occurred())
1412 goto exit;
1413 /* We have checked before that the length
1414 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001415 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 rv = PyBytes_FromStringAndSize
1417 (PyBytes_AsString(str), len);
1418 Py_DECREF(str);
1419 str = rv;
1420 if (str == NULL)
1421 goto exit;
1422 rv = Py_BuildValue("(O(iO))", str, d, samps);
1423 Py_DECREF(samps);
1424 Py_DECREF(str);
1425 goto exit; /* return rv */
1426 }
1427 for (chan = 0; chan < nchannels; chan++) {
1428 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001429 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1430 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001432 cur_i[chan] = (int)(
1433 ((double)weightA * (double)cur_i[chan] +
1434 (double)weightB * (double)prev_i[chan]) /
1435 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 }
1437 len--;
1438 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001439 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 while (d >= 0) {
1441 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001442 cur_o = (int)(((double)prev_i[chan] * (double)d +
1443 (double)cur_i[chan] * (double)(outrate - d)) /
1444 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001445 SETSAMPLE32(width, ncp, 0, cur_o);
1446 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 }
1448 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001449 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001451 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001452 PyMem_Free(prev_i);
1453 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001455}
Guido van Rossum1851a671997-02-14 16:14:03 +00001456
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001457/*[clinic input]
1458audioop.lin2ulaw
1459
1460 fragment: Py_buffer
1461 width: int
1462 /
1463
1464Convert samples in the audio fragment to u-LAW encoding.
1465[clinic start generated code]*/
1466
Roger E. Massec905fff1997-01-17 18:12:04 +00001467static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001468audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001469/*[clinic end generated code: output=26263cc877c5e1bc input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001472 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001473 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001474
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001475 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001476 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001477
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001478 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001479 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001480 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 ncp = (unsigned char *)PyBytes_AsString(rv);
1482
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001483 for (i = 0; i < fragment->len; i += width) {
1484 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001485 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 }
1487 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001488}
1489
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001490/*[clinic input]
1491audioop.ulaw2lin
1492
1493 fragment: Py_buffer
1494 width: int
1495 /
1496
1497Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1498[clinic start generated code]*/
1499
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001500static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001501audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001502/*[clinic end generated code: output=9864cb34e3a1d876 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001506 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001507 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001508
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001509 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001510 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001512 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 PyErr_SetString(PyExc_MemoryError,
1514 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001515 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001517 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001518 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001519 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 ncp = (signed char *)PyBytes_AsString(rv);
1521
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001522 cp = fragment->buf;
1523 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001524 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001525 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 }
1527 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001528}
1529
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001530/*[clinic input]
1531audioop.lin2alaw
1532
1533 fragment: Py_buffer
1534 width: int
1535 /
1536
1537Convert samples in the audio fragment to a-LAW encoding.
1538[clinic start generated code]*/
1539
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001540static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001541audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001542/*[clinic end generated code: output=d5bf14bd0fe6fdcd input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001545 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001546 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001547
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001548 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001549 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001550
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001551 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001552 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001553 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 ncp = (unsigned char *)PyBytes_AsString(rv);
1555
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001556 for (i = 0; i < fragment->len; i += width) {
1557 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001558 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 }
1560 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001561}
1562
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001563/*[clinic input]
1564audioop.alaw2lin
1565
1566 fragment: Py_buffer
1567 width: int
1568 /
1569
1570Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1571[clinic start generated code]*/
1572
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001573static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001574audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001575/*[clinic end generated code: output=d2b604ddd036e1cd input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001579 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001580 int val;
1581 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001582
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001583 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001584 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001586 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 PyErr_SetString(PyExc_MemoryError,
1588 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001589 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001591 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001592 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001593 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001595 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001597 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001598 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001599 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 }
1601 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001602}
1603
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001604/*[clinic input]
1605audioop.lin2adpcm
1606
1607 fragment: Py_buffer
1608 width: int
1609 state: object
1610 /
1611
1612Convert samples to 4 bit Intel/DVI ADPCM encoding.
1613[clinic start generated code]*/
1614
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001615static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001616audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1617 PyObject *state)
1618/*[clinic end generated code: output=93f0996f592b5ce5 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001621 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001622 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001624 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001625 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001626
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001627 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001628 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 /* Decode state, should have (value, step) */
1631 if ( state == Py_None ) {
1632 /* First time, it seems. Set defaults */
1633 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001635 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001636 else if (!PyTuple_Check(state)) {
1637 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1638 return NULL;
1639 }
1640 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1641 return NULL;
1642 }
1643 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1644 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1645 PyErr_SetString(PyExc_ValueError, "bad state");
1646 return NULL;
1647 }
1648
1649 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1650 if (str == NULL)
1651 return NULL;
1652 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653
1654 step = stepsizeTable[index];
1655 bufferstep = 1;
1656
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001657 for (i = 0; i < fragment->len; i += width) {
1658 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659
1660 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001661 if (val < valpred) {
1662 diff = valpred - val;
1663 sign = 8;
1664 }
1665 else {
1666 diff = val - valpred;
1667 sign = 0;
1668 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669
1670 /* Step 2 - Divide and clamp */
1671 /* Note:
1672 ** This code *approximately* computes:
1673 ** delta = diff*4/step;
1674 ** vpdiff = (delta+0.5)*step/4;
1675 ** but in shift step bits are dropped. The net result of this
1676 ** is that even if you have fast mul/div hardware you cannot
1677 ** put it to good use since the fixup would be too expensive.
1678 */
1679 delta = 0;
1680 vpdiff = (step >> 3);
1681
1682 if ( diff >= step ) {
1683 delta = 4;
1684 diff -= step;
1685 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001686 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 step >>= 1;
1688 if ( diff >= step ) {
1689 delta |= 2;
1690 diff -= step;
1691 vpdiff += step;
1692 }
1693 step >>= 1;
1694 if ( diff >= step ) {
1695 delta |= 1;
1696 vpdiff += step;
1697 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 /* Step 3 - Update previous value */
1700 if ( sign )
1701 valpred -= vpdiff;
1702 else
1703 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 /* Step 4 - Clamp previous value to 16 bits */
1706 if ( valpred > 32767 )
1707 valpred = 32767;
1708 else if ( valpred < -32768 )
1709 valpred = -32768;
1710
1711 /* Step 5 - Assemble value, update index and step values */
1712 delta |= sign;
1713
1714 index += indexTable[delta];
1715 if ( index < 0 ) index = 0;
1716 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001717 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001719 /* Step 6 - Output value */
1720 if ( bufferstep ) {
1721 outputbuffer = (delta << 4) & 0xf0;
1722 } else {
1723 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001724 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 bufferstep = !bufferstep;
1726 }
1727 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001728 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001730}
1731
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001732/*[clinic input]
1733audioop.adpcm2lin
1734
1735 fragment: Py_buffer
1736 width: int
1737 state: object
1738 /
1739
1740Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1741[clinic start generated code]*/
1742
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001743static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001744audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1745 PyObject *state)
1746/*[clinic end generated code: output=236cf6dc2c829181 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 signed char *cp;
1749 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001750 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001751 int valpred, step, delta, index, sign, vpdiff;
1752 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001753 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001754
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001755 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001756 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 /* Decode state, should have (value, step) */
1759 if ( state == Py_None ) {
1760 /* First time, it seems. Set defaults */
1761 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001763 }
1764 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001765 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001766 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001767 }
1768 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001769 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001770 }
1771 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1772 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1773 PyErr_SetString(PyExc_ValueError, "bad state");
1774 return NULL;
1775 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001777 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 PyErr_SetString(PyExc_MemoryError,
1779 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001780 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001782 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001783 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001784 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001785 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001787 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788
1789 step = stepsizeTable[index];
1790 bufferstep = 0;
1791
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001792 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 /* Step 1 - get the delta value and compute next index */
1794 if ( bufferstep ) {
1795 delta = inputbuffer & 0xf;
1796 } else {
1797 inputbuffer = *cp++;
1798 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001799 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 bufferstep = !bufferstep;
1802
1803 /* Step 2 - Find new index value (for later) */
1804 index += indexTable[delta];
1805 if ( index < 0 ) index = 0;
1806 if ( index > 88 ) index = 88;
1807
1808 /* Step 3 - Separate sign and magnitude */
1809 sign = delta & 8;
1810 delta = delta & 7;
1811
1812 /* Step 4 - Compute difference and new predicted value */
1813 /*
1814 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1815 ** in adpcm_coder.
1816 */
1817 vpdiff = step >> 3;
1818 if ( delta & 4 ) vpdiff += step;
1819 if ( delta & 2 ) vpdiff += step>>1;
1820 if ( delta & 1 ) vpdiff += step>>2;
1821
1822 if ( sign )
1823 valpred -= vpdiff;
1824 else
1825 valpred += vpdiff;
1826
1827 /* Step 5 - clamp output value */
1828 if ( valpred > 32767 )
1829 valpred = 32767;
1830 else if ( valpred < -32768 )
1831 valpred = -32768;
1832
1833 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001834 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001837 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1841 Py_DECREF(str);
1842 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001843}
1844
Larry Hastingsf256c222014-01-25 21:30:37 -08001845#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001846
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001847static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001848 AUDIOOP_MAX_METHODDEF
1849 AUDIOOP_MINMAX_METHODDEF
1850 AUDIOOP_AVG_METHODDEF
1851 AUDIOOP_MAXPP_METHODDEF
1852 AUDIOOP_AVGPP_METHODDEF
1853 AUDIOOP_RMS_METHODDEF
1854 AUDIOOP_FINDFIT_METHODDEF
1855 AUDIOOP_FINDMAX_METHODDEF
1856 AUDIOOP_FINDFACTOR_METHODDEF
1857 AUDIOOP_CROSS_METHODDEF
1858 AUDIOOP_MUL_METHODDEF
1859 AUDIOOP_ADD_METHODDEF
1860 AUDIOOP_BIAS_METHODDEF
1861 AUDIOOP_ULAW2LIN_METHODDEF
1862 AUDIOOP_LIN2ULAW_METHODDEF
1863 AUDIOOP_ALAW2LIN_METHODDEF
1864 AUDIOOP_LIN2ALAW_METHODDEF
1865 AUDIOOP_LIN2LIN_METHODDEF
1866 AUDIOOP_ADPCM2LIN_METHODDEF
1867 AUDIOOP_LIN2ADPCM_METHODDEF
1868 AUDIOOP_TOMONO_METHODDEF
1869 AUDIOOP_TOSTEREO_METHODDEF
1870 AUDIOOP_GETSAMPLE_METHODDEF
1871 AUDIOOP_REVERSE_METHODDEF
1872 AUDIOOP_BYTESWAP_METHODDEF
1873 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001875};
1876
Martin v. Löwis1a214512008-06-11 05:26:20 +00001877
1878static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 PyModuleDef_HEAD_INIT,
1880 "audioop",
1881 NULL,
1882 -1,
1883 audioop_methods,
1884 NULL,
1885 NULL,
1886 NULL,
1887 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001888};
1889
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001890PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001891PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 PyObject *m, *d;
1894 m = PyModule_Create(&audioopmodule);
1895 if (m == NULL)
1896 return NULL;
1897 d = PyModule_GetDict(m);
1898 if (d == NULL)
1899 return NULL;
1900 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1901 if (AudioopError != NULL)
1902 PyDict_SetItemString(d,"error",AudioopError);
1903 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001904}