blob: 7712e79cf7886b8262e6cf7ad0587251acb072a1 [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 *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200410audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, Py_ssize_t index)
Larry Hastings581ee362014-01-28 05:00:08 -0800411/*[clinic end generated code: output=f4482497e6f6e78f input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000412{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200413 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000414
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200415 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000416 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200417 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200419 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200421 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200422 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000423}
424
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200425/*[clinic input]
426audioop.max
427
428 fragment: Py_buffer
429 width: int
430 /
431
432Return the maximum of the absolute value of all samples in a fragment.
433[clinic start generated code]*/
434
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000435static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200436audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800437/*[clinic end generated code: output=85047ee1001f2305 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000438{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200439 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200440 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000441
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200442 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000443 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200444 for (i = 0; i < fragment->len; i += width) {
445 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200446 if (val < 0) absval = (-val);
447 else absval = val;
448 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200450 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000451}
452
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200453/*[clinic input]
454audioop.minmax
455
456 fragment: Py_buffer
457 width: int
458 /
459
460Return the minimum and maximum values of all samples in the sound fragment.
461[clinic start generated code]*/
462
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000463static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200464audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800465/*[clinic end generated code: output=ae8f5513c64fd569 input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000466{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200467 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000468 /* -1 trick below is needed on Windows to support -0x80000000 without
469 a warning */
470 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000471
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200472 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200474 for (i = 0; i < fragment->len; i += width) {
475 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 if (val > max) max = val;
477 if (val < min) min = val;
478 }
479 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000480}
481
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200482/*[clinic input]
483audioop.avg
484
485 fragment: Py_buffer
486 width: int
487 /
488
489Return the average over all samples in the fragment.
490[clinic start generated code]*/
491
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000492static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200493audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800494/*[clinic end generated code: output=7fccd645c95f4860 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000495{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200496 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200497 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300498 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000499
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200500 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000501 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200502 for (i = 0; i < fragment->len; i += width)
503 sum += GETRAWSAMPLE(width, fragment->buf, i);
504 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300505 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200507 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300508 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000509}
510
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200511/*[clinic input]
512audioop.rms
513
514 fragment: Py_buffer
515 width: int
516 /
517
518Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
519[clinic start generated code]*/
520
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000521static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200522audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800523/*[clinic end generated code: output=7b398702c81b709d input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000524{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200525 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200526 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000528
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200529 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000530 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200531 for (i = 0; i < fragment->len; i += width) {
532 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300533 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200535 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200536 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200538 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200539 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000540}
541
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200542static double _sum2(const short *a, const short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000543{
Mark Dickinson81fece22010-05-11 13:34:35 +0000544 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 for( i=0; i<len; i++) {
548 sum = sum + (double)a[i]*(double)b[i];
549 }
550 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000551}
552
553/*
554** Findfit tries to locate a sample within another sample. Its main use
555** is in echo-cancellation (to find the feedback of the output signal in
556** the input signal).
557** The method used is as follows:
558**
559** let R be the reference signal (length n) and A the input signal (length N)
560** with N > n, and let all sums be over i from 0 to n-1.
561**
562** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
563** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
564** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
565**
566** Next, we compute the relative distance between the original signal and
567** the modified signal and minimize that over j:
568** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
569** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
570**
571** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000572** cp1 A
573** cp2 R
574** len1 N
575** len2 n
576** aj_m1 A[j-1]
577** aj_lm1 A[j+n-1]
578** sum_ri_2 sum(R[i]^2)
579** sum_aij_2 sum(A[i+j]^2)
580** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000581**
582** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
583** is completely recalculated each step.
584*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200585/*[clinic input]
586audioop.findfit
587
588 fragment: Py_buffer
589 reference: Py_buffer
590 /
591
592Try to match reference as well as possible to a portion of fragment.
593[clinic start generated code]*/
594
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000595static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200596audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference)
Larry Hastings581ee362014-01-28 05:00:08 -0800597/*[clinic end generated code: output=505fd04d4244db31 input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000598{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200599 const short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000600 Py_ssize_t len1, len2;
601 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 double aj_m1, aj_lm1;
603 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000604
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200605 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200607 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200609 cp1 = (const short *)fragment->buf;
610 len1 = fragment->len >> 1;
611 cp2 = (const short *)reference->buf;
612 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000613
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200614 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200616 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 }
618 sum_ri_2 = _sum2(cp2, cp2, len2);
619 sum_aij_2 = _sum2(cp1, cp1, len2);
620 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 best_result = result;
625 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 for ( j=1; j<=len1-len2; j++) {
628 aj_m1 = (double)cp1[j-1];
629 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
632 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
635 / sum_aij_2;
636
637 if ( result < best_result ) {
638 best_result = result;
639 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000640 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 }
643
644 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
645
Mark Dickinson81fece22010-05-11 13:34:35 +0000646 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000647}
648
649/*
650** findfactor finds a factor f so that the energy in A-fB is minimal.
651** See the comment for findfit for details.
652*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200653/*[clinic input]
654audioop.findfactor
655
656 fragment: Py_buffer
657 reference: Py_buffer
658 /
659
660Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
661[clinic start generated code]*/
662
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000663static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200664audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference)
Larry Hastings581ee362014-01-28 05:00:08 -0800665/*[clinic end generated code: output=ddf35a1e57575ce4 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000666{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200667 const short *cp1, *cp2;
668 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000670
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200671 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200673 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200675 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200677 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200679 cp1 = (const short *)fragment->buf;
680 cp2 = (const short *)reference->buf;
681 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200682 sum_ri_2 = _sum2(cp2, cp2, len);
683 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000688}
689
690/*
691** findmax returns the index of the n-sized segment of the input sample
692** that contains the most energy.
693*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200694/*[clinic input]
695audioop.findmax
696
697 fragment: Py_buffer
698 length: Py_ssize_t
699 /
700
701Search fragment for a slice of specified number of samples with maximum energy.
702[clinic start generated code]*/
703
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000704static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200705audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, Py_ssize_t length)
Larry Hastings581ee362014-01-28 05:00:08 -0800706/*[clinic end generated code: output=21d0c2a1e5655134 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000707{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200708 const short *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200709 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000710 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 double aj_m1, aj_lm1;
712 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000713
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200714 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200716 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200718 cp1 = (const short *)fragment->buf;
719 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200721 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200723 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 }
725
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200726 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727
728 best_result = result;
729 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200731 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200733 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734
735 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
736
737 if ( result > best_result ) {
738 best_result = result;
739 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000740 }
Jack Jansena90805f1993-02-17 14:29:28 +0000741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000743
Mark Dickinson81fece22010-05-11 13:34:35 +0000744 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000745}
746
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200747/*[clinic input]
748audioop.avgpp
749
750 fragment: Py_buffer
751 width: int
752 /
753
754Return the average peak-peak value over all samples in the fragment.
755[clinic start generated code]*/
756
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000757static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200758audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800759/*[clinic end generated code: output=06c8380fd6e34207 input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000760{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200761 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200762 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200763 double sum = 0.0;
764 unsigned int avg;
765 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000766
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200767 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000768 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200769 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200770 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200771 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200772 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200773 for (i = width; i < fragment->len; i += width) {
774 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200775 if (val != prevval) {
776 diff = val < prevval;
777 if (prevdiff == !diff) {
778 /* Derivative changed sign. Compute difference to last
779 ** extreme value and remember.
780 */
781 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300782 if (prevval < prevextreme)
783 sum += (double)((unsigned int)prevextreme -
784 (unsigned int)prevval);
785 else
786 sum += (double)((unsigned int)prevval -
787 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200788 nextreme++;
789 }
790 prevextremevalid = 1;
791 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200793 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200795 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 }
797 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200798 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200800 avg = (unsigned int)(sum / (double)nextreme);
801 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000802}
803
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200804/*[clinic input]
805audioop.maxpp
806
807 fragment: Py_buffer
808 width: int
809 /
810
811Return the maximum peak-peak value in the sound fragment.
812[clinic start generated code]*/
813
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000814static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200815audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800816/*[clinic end generated code: output=c300c0bd7e8535c0 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000817{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200818 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200819 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200820 unsigned int max = 0, extremediff;
821 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000822
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200823 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000824 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200825 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200826 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200827 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200828 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200829 for (i = width; i < fragment->len; i += width) {
830 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200831 if (val != prevval) {
832 diff = val < prevval;
833 if (prevdiff == !diff) {
834 /* Derivative changed sign. Compute difference to
835 ** last extreme value and remember.
836 */
837 if (prevextremevalid) {
838 if (prevval < prevextreme)
839 extremediff = (unsigned int)prevextreme -
840 (unsigned int)prevval;
841 else
842 extremediff = (unsigned int)prevval -
843 (unsigned int)prevextreme;
844 if ( extremediff > max )
845 max = extremediff;
846 }
847 prevextremevalid = 1;
848 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200850 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200852 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200854 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000855}
856
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200857/*[clinic input]
858audioop.cross
859
860 fragment: Py_buffer
861 width: int
862 /
863
864Return the number of zero crossings in the fragment passed as an argument.
865[clinic start generated code]*/
866
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000867static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200868audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800869/*[clinic end generated code: output=99e6572d7d7cdbf1 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000870{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200871 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000872 int prevval;
873 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000874
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200875 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000876 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 ncross = -1;
878 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200879 for (i = 0; i < fragment->len; i += width) {
880 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300881 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 prevval = val;
883 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000884 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000885}
886
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200887/*[clinic input]
888audioop.mul
889
890 fragment: Py_buffer
891 width: int
892 factor: double
893 /
894
895Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
896[clinic start generated code]*/
897
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000898static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200899audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, double factor)
Larry Hastings581ee362014-01-28 05:00:08 -0800900/*[clinic end generated code: output=a697ebbd5852d38f input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000901{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200902 signed char *ncp;
903 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200904 double maxval, minval;
905 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200907 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000908 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200910 maxval = (double) maxvals[width];
911 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200913 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200914 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200915 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 ncp = (signed char *)PyBytes_AsString(rv);
917
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200918 for (i = 0; i < fragment->len; i += width) {
919 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300920 val *= factor;
921 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200922 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 }
924 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000925}
926
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200927/*[clinic input]
928audioop.tomono
929
930 fragment: Py_buffer
931 width: int
932 lfactor: double
933 rfactor: double
934 /
935
936Convert a stereo fragment to a mono fragment.
937[clinic start generated code]*/
938
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000939static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200940audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor)
Larry Hastings581ee362014-01-28 05:00:08 -0800941/*[clinic end generated code: output=436e7710521661dd input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000944 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200945 double maxval, minval;
946 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000947
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200948 cp = fragment->buf;
949 len = fragment->len;
950 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200951 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200952 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000953 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200954 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000955 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200957 maxval = (double) maxvals[width];
958 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959
960 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200961 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200962 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 ncp = (signed char *)PyBytes_AsString(rv);
964
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200965 for (i = 0; i < len; i += width*2) {
966 double val1 = GETRAWSAMPLE(width, cp, i);
967 double val2 = GETRAWSAMPLE(width, cp, i + width);
968 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300969 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200970 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000973}
974
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200975/*[clinic input]
976audioop.tostereo
977
978 fragment: Py_buffer
979 width: int
980 lfactor: double
981 rfactor: double
982 /
983
984Generate a stereo fragment from a mono fragment.
985[clinic start generated code]*/
986
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000987static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200988audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor)
Larry Hastings581ee362014-01-28 05:00:08 -0800989/*[clinic end generated code: output=6ff50681c87f4c1c input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000990{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200991 signed char *ncp;
992 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200993 double maxval, minval;
994 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000995
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200996 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000997 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000998
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200999 maxval = (double) maxvals[width];
1000 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001001
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001002 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 PyErr_SetString(PyExc_MemoryError,
1004 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001005 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001007
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001008 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001009 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001010 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001012
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001013 for (i = 0; i < fragment->len; i += width) {
1014 double val = GETRAWSAMPLE(width, fragment->buf, i);
1015 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1016 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1017 SETRAWSAMPLE(width, ncp, i*2, val1);
1018 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 }
1020 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001021}
1022
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001023/*[clinic input]
1024audioop.add
1025
1026 fragment1: Py_buffer
1027 fragment2: Py_buffer
1028 width: int
1029 /
1030
1031Return a fragment which is the addition of the two samples passed as parameters.
1032[clinic start generated code]*/
1033
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001034static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001035audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, Py_buffer *fragment2, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001036/*[clinic end generated code: output=f9218bf9ea75c3f1 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001037{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001038 signed char *ncp;
1039 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001040 int minval, maxval, newval;
1041 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001042
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001043 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001044 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001045 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001047 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001049
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001050 maxval = maxvals[width];
1051 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001052
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001053 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001054 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001055 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001057
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001058 for (i = 0; i < fragment1->len; i += width) {
1059 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1060 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001062 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001063 newval = val1 + val2;
1064 /* truncate in case of overflow */
1065 if (newval > maxval)
1066 newval = maxval;
1067 else if (newval < minval)
1068 newval = minval;
1069 }
1070 else {
1071 double fval = (double)val1 + (double)val2;
1072 /* truncate in case of overflow */
1073 newval = (int)floor(fbound(fval, minval, maxval));
1074 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001076 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 }
1078 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001079}
1080
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001081/*[clinic input]
1082audioop.bias
1083
1084 fragment: Py_buffer
1085 width: int
1086 bias: int
1087 /
1088
1089Return a fragment that is the original fragment with a bias added to each sample.
1090[clinic start generated code]*/
1091
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001092static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001093audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, int bias)
Larry Hastings581ee362014-01-28 05:00:08 -08001094/*[clinic end generated code: output=8ec80b3f5d510a51 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001095{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001096 signed char *ncp;
1097 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001098 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001099 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001100
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001101 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001102 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001104 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001105 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001106 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 ncp = (signed char *)PyBytes_AsString(rv);
1108
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001109 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001111 for (i = 0; i < fragment->len; i += width) {
1112 if (width == 1)
1113 val = GETINTX(unsigned char, fragment->buf, i);
1114 else if (width == 2)
1115 val = GETINTX(unsigned short, fragment->buf, i);
1116 else if (width == 3)
1117 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001118 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001119 assert(width == 4);
1120 val = GETINTX(PY_UINT32_T, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001121 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001123 val += (unsigned int)bias;
1124 /* wrap around in case of overflow */
1125 val &= mask;
1126
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001127 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001128 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001129 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001130 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001131 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001132 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001133 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001134 assert(width == 4);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001135 SETINTX(PY_UINT32_T, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001136 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 }
1138 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001139}
1140
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001141/*[clinic input]
1142audioop.reverse
1143
1144 fragment: Py_buffer
1145 width: int
1146 /
1147
1148Reverse the samples in a fragment and returns the modified fragment.
1149[clinic start generated code]*/
1150
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001151static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001152audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001153/*[clinic end generated code: output=6ec3c91337f5925e input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001156 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001157 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001158
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001159 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001160 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001161
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001162 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001163 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001164 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 ncp = (unsigned char *)PyBytes_AsString(rv);
1166
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001167 for (i = 0; i < fragment->len; i += width) {
1168 int val = GETRAWSAMPLE(width, fragment->buf, i);
1169 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 }
1171 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001172}
1173
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001174/*[clinic input]
1175audioop.byteswap
1176
1177 fragment: Py_buffer
1178 width: int
1179 /
1180
1181Convert big-endian samples to little-endian and vice versa.
1182[clinic start generated code]*/
1183
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001184static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001185audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001186/*[clinic end generated code: output=bfe4aa584b7a3f5b input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001187{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001188 unsigned char *ncp;
1189 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001190 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001191
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001192 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001193 return NULL;
1194
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001195 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001196 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001197 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001198 ncp = (unsigned char *)PyBytes_AsString(rv);
1199
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001200 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001201 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001202 for (j = 0; j < width; j++)
1203 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001204 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001205 return rv;
1206}
1207
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001208/*[clinic input]
1209audioop.lin2lin
1210
1211 fragment: Py_buffer
1212 width: int
1213 newwidth: int
1214 /
1215
1216Convert samples between 1-, 2-, 3- and 4-byte formats.
1217[clinic start generated code]*/
1218
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001219static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001220audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, int newwidth)
Larry Hastings581ee362014-01-28 05:00:08 -08001221/*[clinic end generated code: output=3f9468a74472a93e input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001224 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001225 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001226
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001227 if (!audioop_check_parameters(fragment->len, width))
1228 return NULL;
1229 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001230 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001231
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001232 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 PyErr_SetString(PyExc_MemoryError,
1234 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001235 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001237 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001238 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001239 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 ncp = (unsigned char *)PyBytes_AsString(rv);
1241
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001242 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1243 int val = GETSAMPLE32(width, fragment->buf, i);
1244 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 }
1246 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001247}
1248
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001249static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001250gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 while (b > 0) {
1253 int tmp = a % b;
1254 a = b;
1255 b = tmp;
1256 }
1257 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001258}
1259
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001260/*[clinic input]
1261audioop.ratecv
1262
1263 fragment: Py_buffer
1264 width: int
1265 nchannels: int
1266 inrate: int
1267 outrate: int
1268 state: object
1269 weightA: int = 1
1270 weightB: int = 0
1271 /
1272
1273Convert the frame rate of the input fragment.
1274[clinic start generated code]*/
1275
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001276static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001277audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB)
Larry Hastings581ee362014-01-28 05:00:08 -08001278/*[clinic end generated code: output=5585dddc4b5ff236 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001281 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001283 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001285
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001286 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (nchannels < 1) {
1289 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001290 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001292 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 /* This overflow test is rigorously correct because
1294 both multiplicands are >= 1. Use the argument names
1295 from the docs for the error msg. */
1296 PyErr_SetString(PyExc_OverflowError,
1297 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001298 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001300 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 if (weightA < 1 || weightB < 0) {
1302 PyErr_SetString(AudioopError,
1303 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001304 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001306 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001307 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001309 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 }
1311 if (inrate <= 0 || outrate <= 0) {
1312 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001313 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 }
1315 /* divide inrate and outrate by their greatest common divisor */
1316 d = gcd(inrate, outrate);
1317 inrate /= d;
1318 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001319 /* divide weightA and weightB by their greatest common divisor */
1320 d = gcd(weightA, weightB);
1321 weightA /= d;
1322 weightA /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001323
Mark Dickinson85eacea2010-05-10 16:27:45 +00001324 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 PyErr_SetString(PyExc_MemoryError,
1326 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001327 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001329 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1330 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 if (prev_i == NULL || cur_i == NULL) {
1332 (void) PyErr_NoMemory();
1333 goto exit;
1334 }
1335
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001336 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337
1338 if (state == Py_None) {
1339 d = -outrate;
1340 for (chan = 0; chan < nchannels; chan++)
1341 prev_i[chan] = cur_i[chan] = 0;
1342 }
1343 else {
1344 if (!PyArg_ParseTuple(state,
1345 "iO!;audioop.ratecv: illegal state argument",
1346 &d, &PyTuple_Type, &samps))
1347 goto exit;
1348 if (PyTuple_Size(samps) != nchannels) {
1349 PyErr_SetString(AudioopError,
1350 "illegal state argument");
1351 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001352 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 for (chan = 0; chan < nchannels; chan++) {
1354 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1355 "ii:ratecv", &prev_i[chan],
1356 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001357 goto exit;
1358 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001362 if (len == 0)
1363 str = PyBytes_FromStringAndSize(NULL, 0);
1364 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 /* There are len input frames, so we need (mathematically)
1366 ceiling(len*outrate/inrate) output frames, and each frame
1367 requires bytes_per_frame bytes. Computing this
1368 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001369 settle for a reasonable upper bound, though, in this
1370 case ceiling(len/inrate) * outrate. */
1371
1372 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001373 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001374 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 str = NULL;
1376 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001377 str = PyBytes_FromStringAndSize(NULL,
1378 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001379 }
1380 if (str == NULL) {
1381 PyErr_SetString(PyExc_MemoryError,
1382 "not enough memory for output buffer");
1383 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 }
1385 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001386 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387
1388 for (;;) {
1389 while (d < 0) {
1390 if (len == 0) {
1391 samps = PyTuple_New(nchannels);
1392 if (samps == NULL)
1393 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001394 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 PyTuple_SetItem(samps, chan,
1396 Py_BuildValue("(ii)",
1397 prev_i[chan],
1398 cur_i[chan]));
1399 if (PyErr_Occurred())
1400 goto exit;
1401 /* We have checked before that the length
1402 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001403 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 rv = PyBytes_FromStringAndSize
1405 (PyBytes_AsString(str), len);
1406 Py_DECREF(str);
1407 str = rv;
1408 if (str == NULL)
1409 goto exit;
1410 rv = Py_BuildValue("(O(iO))", str, d, samps);
1411 Py_DECREF(samps);
1412 Py_DECREF(str);
1413 goto exit; /* return rv */
1414 }
1415 for (chan = 0; chan < nchannels; chan++) {
1416 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001417 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1418 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001420 cur_i[chan] = (int)(
1421 ((double)weightA * (double)cur_i[chan] +
1422 (double)weightB * (double)prev_i[chan]) /
1423 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 }
1425 len--;
1426 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001427 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 while (d >= 0) {
1429 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001430 cur_o = (int)(((double)prev_i[chan] * (double)d +
1431 (double)cur_i[chan] * (double)(outrate - d)) /
1432 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001433 SETSAMPLE32(width, ncp, 0, cur_o);
1434 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 }
1436 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001437 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001439 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001440 PyMem_Free(prev_i);
1441 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001443}
Guido van Rossum1851a671997-02-14 16:14:03 +00001444
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001445/*[clinic input]
1446audioop.lin2ulaw
1447
1448 fragment: Py_buffer
1449 width: int
1450 /
1451
1452Convert samples in the audio fragment to u-LAW encoding.
1453[clinic start generated code]*/
1454
Roger E. Massec905fff1997-01-17 18:12:04 +00001455static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001456audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001457/*[clinic end generated code: output=26263cc877c5e1bc input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001460 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001461 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001462
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001463 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001464 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001465
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001466 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001467 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001468 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 ncp = (unsigned char *)PyBytes_AsString(rv);
1470
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001471 for (i = 0; i < fragment->len; i += width) {
1472 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001473 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 }
1475 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001476}
1477
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001478/*[clinic input]
1479audioop.ulaw2lin
1480
1481 fragment: Py_buffer
1482 width: int
1483 /
1484
1485Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1486[clinic start generated code]*/
1487
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001488static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001489audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001490/*[clinic end generated code: output=9864cb34e3a1d876 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001494 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001495 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001496
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001497 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001498 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001500 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 PyErr_SetString(PyExc_MemoryError,
1502 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001503 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001505 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001506 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001507 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 ncp = (signed char *)PyBytes_AsString(rv);
1509
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001510 cp = fragment->buf;
1511 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001512 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001513 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 }
1515 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001516}
1517
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001518/*[clinic input]
1519audioop.lin2alaw
1520
1521 fragment: Py_buffer
1522 width: int
1523 /
1524
1525Convert samples in the audio fragment to a-LAW encoding.
1526[clinic start generated code]*/
1527
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001528static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001529audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001530/*[clinic end generated code: output=d5bf14bd0fe6fdcd input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001533 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001534 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001535
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001536 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001537 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001538
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001539 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001540 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001541 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 ncp = (unsigned char *)PyBytes_AsString(rv);
1543
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001544 for (i = 0; i < fragment->len; i += width) {
1545 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001546 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 }
1548 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001549}
1550
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001551/*[clinic input]
1552audioop.alaw2lin
1553
1554 fragment: Py_buffer
1555 width: int
1556 /
1557
1558Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1559[clinic start generated code]*/
1560
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001561static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001562audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001563/*[clinic end generated code: output=d2b604ddd036e1cd input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001567 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001568 int val;
1569 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001570
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001571 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001572 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001574 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 PyErr_SetString(PyExc_MemoryError,
1576 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001577 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001579 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001580 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001581 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001583 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001585 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001586 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001587 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 }
1589 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001590}
1591
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001592/*[clinic input]
1593audioop.lin2adpcm
1594
1595 fragment: Py_buffer
1596 width: int
1597 state: object
1598 /
1599
1600Convert samples to 4 bit Intel/DVI ADPCM encoding.
1601[clinic start generated code]*/
1602
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001603static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001604audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state)
Larry Hastings581ee362014-01-28 05:00:08 -08001605/*[clinic end generated code: output=4654c29d2731fafe input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001606{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001608 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001609 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001611 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001612 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001613
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001614 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001615 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001617 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001618 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001619 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 ncp = (signed char *)PyBytes_AsString(str);
1621
1622 /* Decode state, should have (value, step) */
1623 if ( state == Py_None ) {
1624 /* First time, it seems. Set defaults */
1625 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 index = 0;
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001627 } else if (!PyTuple_Check(state)) {
1628 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Benjamin Peterson08673c52014-01-26 10:24:24 -05001629 goto exit;
1630 } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1631 goto exit;
1632 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633
1634 step = stepsizeTable[index];
1635 bufferstep = 1;
1636
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001637 for (i = 0; i < fragment->len; i += width) {
1638 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639
1640 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001641 if (val < valpred) {
1642 diff = valpred - val;
1643 sign = 8;
1644 }
1645 else {
1646 diff = val - valpred;
1647 sign = 0;
1648 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649
1650 /* Step 2 - Divide and clamp */
1651 /* Note:
1652 ** This code *approximately* computes:
1653 ** delta = diff*4/step;
1654 ** vpdiff = (delta+0.5)*step/4;
1655 ** but in shift step bits are dropped. The net result of this
1656 ** is that even if you have fast mul/div hardware you cannot
1657 ** put it to good use since the fixup would be too expensive.
1658 */
1659 delta = 0;
1660 vpdiff = (step >> 3);
1661
1662 if ( diff >= step ) {
1663 delta = 4;
1664 diff -= step;
1665 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001666 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 step >>= 1;
1668 if ( diff >= step ) {
1669 delta |= 2;
1670 diff -= step;
1671 vpdiff += step;
1672 }
1673 step >>= 1;
1674 if ( diff >= step ) {
1675 delta |= 1;
1676 vpdiff += step;
1677 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 /* Step 3 - Update previous value */
1680 if ( sign )
1681 valpred -= vpdiff;
1682 else
1683 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 /* Step 4 - Clamp previous value to 16 bits */
1686 if ( valpred > 32767 )
1687 valpred = 32767;
1688 else if ( valpred < -32768 )
1689 valpred = -32768;
1690
1691 /* Step 5 - Assemble value, update index and step values */
1692 delta |= sign;
1693
1694 index += indexTable[delta];
1695 if ( index < 0 ) index = 0;
1696 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001697 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 /* Step 6 - Output value */
1700 if ( bufferstep ) {
1701 outputbuffer = (delta << 4) & 0xf0;
1702 } else {
1703 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001704 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 bufferstep = !bufferstep;
1706 }
1707 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Benjamin Peterson08673c52014-01-26 10:24:24 -05001708
1709 exit:
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001710 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001712}
1713
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001714/*[clinic input]
1715audioop.adpcm2lin
1716
1717 fragment: Py_buffer
1718 width: int
1719 state: object
1720 /
1721
1722Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1723[clinic start generated code]*/
1724
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001725static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001726audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state)
Larry Hastings581ee362014-01-28 05:00:08 -08001727/*[clinic end generated code: output=371965cdcc0aa69b input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 signed char *cp;
1730 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001731 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001732 int valpred, step, delta, index, sign, vpdiff;
1733 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001734 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001735
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001736 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001737 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 /* Decode state, should have (value, step) */
1740 if ( state == Py_None ) {
1741 /* First time, it seems. Set defaults */
1742 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 index = 0;
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001744 } else if (!PyTuple_Check(state)) {
1745 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001746 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001747 } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index))
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001748 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001750 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 PyErr_SetString(PyExc_MemoryError,
1752 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001753 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001755 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001756 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001757 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001758 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001760 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761
1762 step = stepsizeTable[index];
1763 bufferstep = 0;
1764
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001765 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 /* Step 1 - get the delta value and compute next index */
1767 if ( bufferstep ) {
1768 delta = inputbuffer & 0xf;
1769 } else {
1770 inputbuffer = *cp++;
1771 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001772 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 bufferstep = !bufferstep;
1775
1776 /* Step 2 - Find new index value (for later) */
1777 index += indexTable[delta];
1778 if ( index < 0 ) index = 0;
1779 if ( index > 88 ) index = 88;
1780
1781 /* Step 3 - Separate sign and magnitude */
1782 sign = delta & 8;
1783 delta = delta & 7;
1784
1785 /* Step 4 - Compute difference and new predicted value */
1786 /*
1787 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1788 ** in adpcm_coder.
1789 */
1790 vpdiff = step >> 3;
1791 if ( delta & 4 ) vpdiff += step;
1792 if ( delta & 2 ) vpdiff += step>>1;
1793 if ( delta & 1 ) vpdiff += step>>2;
1794
1795 if ( sign )
1796 valpred -= vpdiff;
1797 else
1798 valpred += vpdiff;
1799
1800 /* Step 5 - clamp output value */
1801 if ( valpred > 32767 )
1802 valpred = 32767;
1803 else if ( valpred < -32768 )
1804 valpred = -32768;
1805
1806 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001807 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001810 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1814 Py_DECREF(str);
1815 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001816}
1817
Larry Hastingsf256c222014-01-25 21:30:37 -08001818#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001819
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001820static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001821 AUDIOOP_MAX_METHODDEF
1822 AUDIOOP_MINMAX_METHODDEF
1823 AUDIOOP_AVG_METHODDEF
1824 AUDIOOP_MAXPP_METHODDEF
1825 AUDIOOP_AVGPP_METHODDEF
1826 AUDIOOP_RMS_METHODDEF
1827 AUDIOOP_FINDFIT_METHODDEF
1828 AUDIOOP_FINDMAX_METHODDEF
1829 AUDIOOP_FINDFACTOR_METHODDEF
1830 AUDIOOP_CROSS_METHODDEF
1831 AUDIOOP_MUL_METHODDEF
1832 AUDIOOP_ADD_METHODDEF
1833 AUDIOOP_BIAS_METHODDEF
1834 AUDIOOP_ULAW2LIN_METHODDEF
1835 AUDIOOP_LIN2ULAW_METHODDEF
1836 AUDIOOP_ALAW2LIN_METHODDEF
1837 AUDIOOP_LIN2ALAW_METHODDEF
1838 AUDIOOP_LIN2LIN_METHODDEF
1839 AUDIOOP_ADPCM2LIN_METHODDEF
1840 AUDIOOP_LIN2ADPCM_METHODDEF
1841 AUDIOOP_TOMONO_METHODDEF
1842 AUDIOOP_TOSTEREO_METHODDEF
1843 AUDIOOP_GETSAMPLE_METHODDEF
1844 AUDIOOP_REVERSE_METHODDEF
1845 AUDIOOP_BYTESWAP_METHODDEF
1846 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001848};
1849
Martin v. Löwis1a214512008-06-11 05:26:20 +00001850
1851static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 PyModuleDef_HEAD_INIT,
1853 "audioop",
1854 NULL,
1855 -1,
1856 audioop_methods,
1857 NULL,
1858 NULL,
1859 NULL,
1860 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001861};
1862
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001863PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001864PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 PyObject *m, *d;
1867 m = PyModule_Create(&audioopmodule);
1868 if (m == NULL)
1869 return NULL;
1870 d = PyModule_GetDict(m);
1871 if (d == NULL)
1872 return NULL;
1873 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1874 if (AudioopError != NULL)
1875 PyDict_SetItemString(d,"error",AudioopError);
1876 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001877}