blob: 2d287f249b4afd4569899ba8a8483f0e310153e6 [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]
394output preset file
395module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200396[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800397/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5619f935f269199a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200398
399/*[clinic input]
400audioop.getsample
401
402 fragment: Py_buffer
403 width: int
404 index: Py_ssize_t
405 /
406
407Return the value of sample index from the fragment.
408[clinic start generated code]*/
409
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000410static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200411audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, Py_ssize_t index)
Larry Hastings581ee362014-01-28 05:00:08 -0800412/*[clinic end generated code: output=f4482497e6f6e78f 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 *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200597audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference)
Larry Hastings581ee362014-01-28 05:00:08 -0800598/*[clinic end generated code: output=505fd04d4244db31 input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000599{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200600 const short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000601 Py_ssize_t len1, len2;
602 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 double aj_m1, aj_lm1;
604 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000605
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200606 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200608 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200610 cp1 = (const short *)fragment->buf;
611 len1 = fragment->len >> 1;
612 cp2 = (const short *)reference->buf;
613 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000614
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200615 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200617 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 }
619 sum_ri_2 = _sum2(cp2, cp2, len2);
620 sum_aij_2 = _sum2(cp1, cp1, len2);
621 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 best_result = result;
626 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 for ( j=1; j<=len1-len2; j++) {
629 aj_m1 = (double)cp1[j-1];
630 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
633 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
636 / sum_aij_2;
637
638 if ( result < best_result ) {
639 best_result = result;
640 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000641 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 }
644
645 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
646
Mark Dickinson81fece22010-05-11 13:34:35 +0000647 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000648}
649
650/*
651** findfactor finds a factor f so that the energy in A-fB is minimal.
652** See the comment for findfit for details.
653*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200654/*[clinic input]
655audioop.findfactor
656
657 fragment: Py_buffer
658 reference: Py_buffer
659 /
660
661Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
662[clinic start generated code]*/
663
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000664static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200665audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference)
Larry Hastings581ee362014-01-28 05:00:08 -0800666/*[clinic end generated code: output=ddf35a1e57575ce4 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000667{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200668 const short *cp1, *cp2;
669 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000671
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200672 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200674 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200676 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200678 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200680 cp1 = (const short *)fragment->buf;
681 cp2 = (const short *)reference->buf;
682 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200683 sum_ri_2 = _sum2(cp2, cp2, len);
684 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000689}
690
691/*
692** findmax returns the index of the n-sized segment of the input sample
693** that contains the most energy.
694*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200695/*[clinic input]
696audioop.findmax
697
698 fragment: Py_buffer
699 length: Py_ssize_t
700 /
701
702Search fragment for a slice of specified number of samples with maximum energy.
703[clinic start generated code]*/
704
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000705static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200706audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, Py_ssize_t length)
Larry Hastings581ee362014-01-28 05:00:08 -0800707/*[clinic end generated code: output=21d0c2a1e5655134 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000708{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200709 const short *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200710 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000711 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 double aj_m1, aj_lm1;
713 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000714
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200715 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200717 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200719 cp1 = (const short *)fragment->buf;
720 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200722 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200724 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 }
726
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200727 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728
729 best_result = result;
730 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200732 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200734 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735
736 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
737
738 if ( result > best_result ) {
739 best_result = result;
740 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000741 }
Jack Jansena90805f1993-02-17 14:29:28 +0000742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000744
Mark Dickinson81fece22010-05-11 13:34:35 +0000745 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000746}
747
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200748/*[clinic input]
749audioop.avgpp
750
751 fragment: Py_buffer
752 width: int
753 /
754
755Return the average peak-peak value over all samples in the fragment.
756[clinic start generated code]*/
757
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000758static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200759audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800760/*[clinic end generated code: output=06c8380fd6e34207 input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000761{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200762 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200763 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200764 double sum = 0.0;
765 unsigned int avg;
766 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000767
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200768 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000769 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200770 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200771 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200772 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200773 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200774 for (i = width; i < fragment->len; i += width) {
775 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200776 if (val != prevval) {
777 diff = val < prevval;
778 if (prevdiff == !diff) {
779 /* Derivative changed sign. Compute difference to last
780 ** extreme value and remember.
781 */
782 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300783 if (prevval < prevextreme)
784 sum += (double)((unsigned int)prevextreme -
785 (unsigned int)prevval);
786 else
787 sum += (double)((unsigned int)prevval -
788 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200789 nextreme++;
790 }
791 prevextremevalid = 1;
792 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200794 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000795 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200796 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 }
798 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200799 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200801 avg = (unsigned int)(sum / (double)nextreme);
802 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000803}
804
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200805/*[clinic input]
806audioop.maxpp
807
808 fragment: Py_buffer
809 width: int
810 /
811
812Return the maximum peak-peak value in the sound fragment.
813[clinic start generated code]*/
814
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000815static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200816audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800817/*[clinic end generated code: output=c300c0bd7e8535c0 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000818{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200819 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200820 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200821 unsigned int max = 0, extremediff;
822 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000823
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200824 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000825 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200826 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200827 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200828 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200829 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200830 for (i = width; i < fragment->len; i += width) {
831 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200832 if (val != prevval) {
833 diff = val < prevval;
834 if (prevdiff == !diff) {
835 /* Derivative changed sign. Compute difference to
836 ** last extreme value and remember.
837 */
838 if (prevextremevalid) {
839 if (prevval < prevextreme)
840 extremediff = (unsigned int)prevextreme -
841 (unsigned int)prevval;
842 else
843 extremediff = (unsigned int)prevval -
844 (unsigned int)prevextreme;
845 if ( extremediff > max )
846 max = extremediff;
847 }
848 prevextremevalid = 1;
849 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200851 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200853 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200855 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000856}
857
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200858/*[clinic input]
859audioop.cross
860
861 fragment: Py_buffer
862 width: int
863 /
864
865Return the number of zero crossings in the fragment passed as an argument.
866[clinic start generated code]*/
867
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000868static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200869audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800870/*[clinic end generated code: output=99e6572d7d7cdbf1 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000871{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200872 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000873 int prevval;
874 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000875
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200876 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000877 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 ncross = -1;
879 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200880 for (i = 0; i < fragment->len; i += width) {
881 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300882 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 prevval = val;
884 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000885 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000886}
887
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200888/*[clinic input]
889audioop.mul
890
891 fragment: Py_buffer
892 width: int
893 factor: double
894 /
895
896Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
897[clinic start generated code]*/
898
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000899static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200900audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, double factor)
Larry Hastings581ee362014-01-28 05:00:08 -0800901/*[clinic end generated code: output=a697ebbd5852d38f input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000902{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200903 signed char *ncp;
904 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200905 double maxval, minval;
906 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000907
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200908 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000909 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200911 maxval = (double) maxvals[width];
912 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200914 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200915 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200916 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 ncp = (signed char *)PyBytes_AsString(rv);
918
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200919 for (i = 0; i < fragment->len; i += width) {
920 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300921 val *= factor;
922 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200923 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 }
925 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000926}
927
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200928/*[clinic input]
929audioop.tomono
930
931 fragment: Py_buffer
932 width: int
933 lfactor: double
934 rfactor: double
935 /
936
937Convert a stereo fragment to a mono fragment.
938[clinic start generated code]*/
939
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000940static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200941audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor)
Larry Hastings581ee362014-01-28 05:00:08 -0800942/*[clinic end generated code: output=436e7710521661dd input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000943{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000945 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200946 double maxval, minval;
947 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000948
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200949 cp = fragment->buf;
950 len = fragment->len;
951 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200952 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200953 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000954 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200955 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000956 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200958 maxval = (double) maxvals[width];
959 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960
961 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200962 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200963 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 ncp = (signed char *)PyBytes_AsString(rv);
965
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200966 for (i = 0; i < len; i += width*2) {
967 double val1 = GETRAWSAMPLE(width, cp, i);
968 double val2 = GETRAWSAMPLE(width, cp, i + width);
969 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300970 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200971 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000974}
975
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200976/*[clinic input]
977audioop.tostereo
978
979 fragment: Py_buffer
980 width: int
981 lfactor: double
982 rfactor: double
983 /
984
985Generate a stereo fragment from a mono fragment.
986[clinic start generated code]*/
987
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000988static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200989audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor)
Larry Hastings581ee362014-01-28 05:00:08 -0800990/*[clinic end generated code: output=6ff50681c87f4c1c input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000991{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200992 signed char *ncp;
993 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200994 double maxval, minval;
995 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000996
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200997 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000998 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000999
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001000 maxval = (double) maxvals[width];
1001 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001002
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001003 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 PyErr_SetString(PyExc_MemoryError,
1005 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001006 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001008
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001009 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001010 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001011 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001013
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001014 for (i = 0; i < fragment->len; i += width) {
1015 double val = GETRAWSAMPLE(width, fragment->buf, i);
1016 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1017 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1018 SETRAWSAMPLE(width, ncp, i*2, val1);
1019 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 }
1021 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001022}
1023
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001024/*[clinic input]
1025audioop.add
1026
1027 fragment1: Py_buffer
1028 fragment2: Py_buffer
1029 width: int
1030 /
1031
1032Return a fragment which is the addition of the two samples passed as parameters.
1033[clinic start generated code]*/
1034
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001035static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001036audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, Py_buffer *fragment2, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001037/*[clinic end generated code: output=f9218bf9ea75c3f1 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001038{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001039 signed char *ncp;
1040 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001041 int minval, maxval, newval;
1042 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001043
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001044 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001045 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001046 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001048 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001050
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001051 maxval = maxvals[width];
1052 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001053
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001054 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001055 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001056 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001058
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001059 for (i = 0; i < fragment1->len; i += width) {
1060 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1061 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001063 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001064 newval = val1 + val2;
1065 /* truncate in case of overflow */
1066 if (newval > maxval)
1067 newval = maxval;
1068 else if (newval < minval)
1069 newval = minval;
1070 }
1071 else {
1072 double fval = (double)val1 + (double)val2;
1073 /* truncate in case of overflow */
1074 newval = (int)floor(fbound(fval, minval, maxval));
1075 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001077 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 }
1079 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001080}
1081
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001082/*[clinic input]
1083audioop.bias
1084
1085 fragment: Py_buffer
1086 width: int
1087 bias: int
1088 /
1089
1090Return a fragment that is the original fragment with a bias added to each sample.
1091[clinic start generated code]*/
1092
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001093static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001094audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, int bias)
Larry Hastings581ee362014-01-28 05:00:08 -08001095/*[clinic end generated code: output=8ec80b3f5d510a51 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001096{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001097 signed char *ncp;
1098 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001099 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001100 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001101
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001102 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001103 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001105 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001106 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001107 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 ncp = (signed char *)PyBytes_AsString(rv);
1109
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001110 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001112 for (i = 0; i < fragment->len; i += width) {
1113 if (width == 1)
1114 val = GETINTX(unsigned char, fragment->buf, i);
1115 else if (width == 2)
1116 val = GETINTX(unsigned short, fragment->buf, i);
1117 else if (width == 3)
1118 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001119 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001120 assert(width == 4);
1121 val = GETINTX(PY_UINT32_T, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001122 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001124 val += (unsigned int)bias;
1125 /* wrap around in case of overflow */
1126 val &= mask;
1127
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001128 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001129 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001130 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001131 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001132 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001133 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001134 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001135 assert(width == 4);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001136 SETINTX(PY_UINT32_T, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001137 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 }
1139 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001140}
1141
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001142/*[clinic input]
1143audioop.reverse
1144
1145 fragment: Py_buffer
1146 width: int
1147 /
1148
1149Reverse the samples in a fragment and returns the modified fragment.
1150[clinic start generated code]*/
1151
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001152static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001153audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001154/*[clinic end generated code: output=6ec3c91337f5925e input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001157 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001158 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001159
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001160 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001161 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001162
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001163 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001164 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001165 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 ncp = (unsigned char *)PyBytes_AsString(rv);
1167
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001168 for (i = 0; i < fragment->len; i += width) {
1169 int val = GETRAWSAMPLE(width, fragment->buf, i);
1170 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 }
1172 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001173}
1174
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001175/*[clinic input]
1176audioop.byteswap
1177
1178 fragment: Py_buffer
1179 width: int
1180 /
1181
1182Convert big-endian samples to little-endian and vice versa.
1183[clinic start generated code]*/
1184
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001185static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001186audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001187/*[clinic end generated code: output=bfe4aa584b7a3f5b input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001188{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001189 unsigned char *ncp;
1190 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001191 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001192
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001193 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001194 return NULL;
1195
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001196 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001197 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001198 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001199 ncp = (unsigned char *)PyBytes_AsString(rv);
1200
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001201 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001202 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001203 for (j = 0; j < width; j++)
1204 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001205 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001206 return rv;
1207}
1208
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001209/*[clinic input]
1210audioop.lin2lin
1211
1212 fragment: Py_buffer
1213 width: int
1214 newwidth: int
1215 /
1216
1217Convert samples between 1-, 2-, 3- and 4-byte formats.
1218[clinic start generated code]*/
1219
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001220static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001221audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, int newwidth)
Larry Hastings581ee362014-01-28 05:00:08 -08001222/*[clinic end generated code: output=3f9468a74472a93e input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001225 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001226 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001227
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001228 if (!audioop_check_parameters(fragment->len, width))
1229 return NULL;
1230 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001231 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001232
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001233 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 PyErr_SetString(PyExc_MemoryError,
1235 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001236 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001238 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001239 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001240 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 ncp = (unsigned char *)PyBytes_AsString(rv);
1242
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001243 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1244 int val = GETSAMPLE32(width, fragment->buf, i);
1245 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 }
1247 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001248}
1249
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001250static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001251gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 while (b > 0) {
1254 int tmp = a % b;
1255 a = b;
1256 b = tmp;
1257 }
1258 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001259}
1260
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001261/*[clinic input]
1262audioop.ratecv
1263
1264 fragment: Py_buffer
1265 width: int
1266 nchannels: int
1267 inrate: int
1268 outrate: int
1269 state: object
1270 weightA: int = 1
1271 weightB: int = 0
1272 /
1273
1274Convert the frame rate of the input fragment.
1275[clinic start generated code]*/
1276
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001277static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001278audioop_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 -08001279/*[clinic end generated code: output=5585dddc4b5ff236 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001282 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001284 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001286
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001287 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 if (nchannels < 1) {
1290 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001291 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001293 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 /* This overflow test is rigorously correct because
1295 both multiplicands are >= 1. Use the argument names
1296 from the docs for the error msg. */
1297 PyErr_SetString(PyExc_OverflowError,
1298 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001299 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001301 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 if (weightA < 1 || weightB < 0) {
1303 PyErr_SetString(AudioopError,
1304 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001305 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001307 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001308 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001310 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 }
1312 if (inrate <= 0 || outrate <= 0) {
1313 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001314 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 }
1316 /* divide inrate and outrate by their greatest common divisor */
1317 d = gcd(inrate, outrate);
1318 inrate /= d;
1319 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001320 /* divide weightA and weightB by their greatest common divisor */
1321 d = gcd(weightA, weightB);
1322 weightA /= d;
1323 weightA /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001324
Mark Dickinson85eacea2010-05-10 16:27:45 +00001325 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 PyErr_SetString(PyExc_MemoryError,
1327 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001328 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001330 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1331 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 if (prev_i == NULL || cur_i == NULL) {
1333 (void) PyErr_NoMemory();
1334 goto exit;
1335 }
1336
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001337 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338
1339 if (state == Py_None) {
1340 d = -outrate;
1341 for (chan = 0; chan < nchannels; chan++)
1342 prev_i[chan] = cur_i[chan] = 0;
1343 }
1344 else {
1345 if (!PyArg_ParseTuple(state,
1346 "iO!;audioop.ratecv: illegal state argument",
1347 &d, &PyTuple_Type, &samps))
1348 goto exit;
1349 if (PyTuple_Size(samps) != nchannels) {
1350 PyErr_SetString(AudioopError,
1351 "illegal state argument");
1352 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001353 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 for (chan = 0; chan < nchannels; chan++) {
1355 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1356 "ii:ratecv", &prev_i[chan],
1357 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001358 goto exit;
1359 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001363 if (len == 0)
1364 str = PyBytes_FromStringAndSize(NULL, 0);
1365 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 /* There are len input frames, so we need (mathematically)
1367 ceiling(len*outrate/inrate) output frames, and each frame
1368 requires bytes_per_frame bytes. Computing this
1369 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001370 settle for a reasonable upper bound, though, in this
1371 case ceiling(len/inrate) * outrate. */
1372
1373 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001374 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001375 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 str = NULL;
1377 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001378 str = PyBytes_FromStringAndSize(NULL,
1379 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001380 }
1381 if (str == NULL) {
1382 PyErr_SetString(PyExc_MemoryError,
1383 "not enough memory for output buffer");
1384 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 }
1386 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001387 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388
1389 for (;;) {
1390 while (d < 0) {
1391 if (len == 0) {
1392 samps = PyTuple_New(nchannels);
1393 if (samps == NULL)
1394 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001395 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 PyTuple_SetItem(samps, chan,
1397 Py_BuildValue("(ii)",
1398 prev_i[chan],
1399 cur_i[chan]));
1400 if (PyErr_Occurred())
1401 goto exit;
1402 /* We have checked before that the length
1403 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001404 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 rv = PyBytes_FromStringAndSize
1406 (PyBytes_AsString(str), len);
1407 Py_DECREF(str);
1408 str = rv;
1409 if (str == NULL)
1410 goto exit;
1411 rv = Py_BuildValue("(O(iO))", str, d, samps);
1412 Py_DECREF(samps);
1413 Py_DECREF(str);
1414 goto exit; /* return rv */
1415 }
1416 for (chan = 0; chan < nchannels; chan++) {
1417 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001418 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1419 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001421 cur_i[chan] = (int)(
1422 ((double)weightA * (double)cur_i[chan] +
1423 (double)weightB * (double)prev_i[chan]) /
1424 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 }
1426 len--;
1427 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001428 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 while (d >= 0) {
1430 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001431 cur_o = (int)(((double)prev_i[chan] * (double)d +
1432 (double)cur_i[chan] * (double)(outrate - d)) /
1433 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001434 SETSAMPLE32(width, ncp, 0, cur_o);
1435 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 }
1437 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001438 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001440 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001441 PyMem_Free(prev_i);
1442 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001444}
Guido van Rossum1851a671997-02-14 16:14:03 +00001445
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001446/*[clinic input]
1447audioop.lin2ulaw
1448
1449 fragment: Py_buffer
1450 width: int
1451 /
1452
1453Convert samples in the audio fragment to u-LAW encoding.
1454[clinic start generated code]*/
1455
Roger E. Massec905fff1997-01-17 18:12:04 +00001456static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001457audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001458/*[clinic end generated code: output=26263cc877c5e1bc input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001461 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001462 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001463
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001464 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001465 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001466
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001467 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001468 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001469 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 ncp = (unsigned char *)PyBytes_AsString(rv);
1471
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001472 for (i = 0; i < fragment->len; i += width) {
1473 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001474 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 }
1476 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001477}
1478
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001479/*[clinic input]
1480audioop.ulaw2lin
1481
1482 fragment: Py_buffer
1483 width: int
1484 /
1485
1486Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1487[clinic start generated code]*/
1488
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001489static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001490audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001491/*[clinic end generated code: output=9864cb34e3a1d876 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001492{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001495 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001496 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001497
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001498 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001499 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001501 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 PyErr_SetString(PyExc_MemoryError,
1503 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001504 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001506 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001507 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001508 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 ncp = (signed char *)PyBytes_AsString(rv);
1510
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001511 cp = fragment->buf;
1512 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001513 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001514 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 }
1516 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001517}
1518
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001519/*[clinic input]
1520audioop.lin2alaw
1521
1522 fragment: Py_buffer
1523 width: int
1524 /
1525
1526Convert samples in the audio fragment to a-LAW encoding.
1527[clinic start generated code]*/
1528
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001529static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001530audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001531/*[clinic end generated code: output=d5bf14bd0fe6fdcd input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001534 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001535 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001536
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001537 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001538 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001539
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001540 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001541 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001542 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 ncp = (unsigned char *)PyBytes_AsString(rv);
1544
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001545 for (i = 0; i < fragment->len; i += width) {
1546 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001547 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 }
1549 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001550}
1551
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001552/*[clinic input]
1553audioop.alaw2lin
1554
1555 fragment: Py_buffer
1556 width: int
1557 /
1558
1559Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1560[clinic start generated code]*/
1561
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001562static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001563audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001564/*[clinic end generated code: output=d2b604ddd036e1cd input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001568 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001569 int val;
1570 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001571
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001572 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001573 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001575 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 PyErr_SetString(PyExc_MemoryError,
1577 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001578 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001580 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001581 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001582 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001584 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001586 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001587 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001588 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 }
1590 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001591}
1592
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001593/*[clinic input]
1594audioop.lin2adpcm
1595
1596 fragment: Py_buffer
1597 width: int
1598 state: object
1599 /
1600
1601Convert samples to 4 bit Intel/DVI ADPCM encoding.
1602[clinic start generated code]*/
1603
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001604static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001605audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state)
Larry Hastings581ee362014-01-28 05:00:08 -08001606/*[clinic end generated code: output=4654c29d2731fafe input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001609 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001610 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001612 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001613 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001614
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001615 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001616 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001618 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001619 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001620 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 ncp = (signed char *)PyBytes_AsString(str);
1622
1623 /* Decode state, should have (value, step) */
1624 if ( state == Py_None ) {
1625 /* First time, it seems. Set defaults */
1626 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 index = 0;
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001628 } else if (!PyTuple_Check(state)) {
1629 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Benjamin Peterson08673c52014-01-26 10:24:24 -05001630 goto exit;
1631 } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1632 goto exit;
1633 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634
1635 step = stepsizeTable[index];
1636 bufferstep = 1;
1637
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001638 for (i = 0; i < fragment->len; i += width) {
1639 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640
1641 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001642 if (val < valpred) {
1643 diff = valpred - val;
1644 sign = 8;
1645 }
1646 else {
1647 diff = val - valpred;
1648 sign = 0;
1649 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650
1651 /* Step 2 - Divide and clamp */
1652 /* Note:
1653 ** This code *approximately* computes:
1654 ** delta = diff*4/step;
1655 ** vpdiff = (delta+0.5)*step/4;
1656 ** but in shift step bits are dropped. The net result of this
1657 ** is that even if you have fast mul/div hardware you cannot
1658 ** put it to good use since the fixup would be too expensive.
1659 */
1660 delta = 0;
1661 vpdiff = (step >> 3);
1662
1663 if ( diff >= step ) {
1664 delta = 4;
1665 diff -= step;
1666 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001667 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 step >>= 1;
1669 if ( diff >= step ) {
1670 delta |= 2;
1671 diff -= step;
1672 vpdiff += step;
1673 }
1674 step >>= 1;
1675 if ( diff >= step ) {
1676 delta |= 1;
1677 vpdiff += step;
1678 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 /* Step 3 - Update previous value */
1681 if ( sign )
1682 valpred -= vpdiff;
1683 else
1684 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 /* Step 4 - Clamp previous value to 16 bits */
1687 if ( valpred > 32767 )
1688 valpred = 32767;
1689 else if ( valpred < -32768 )
1690 valpred = -32768;
1691
1692 /* Step 5 - Assemble value, update index and step values */
1693 delta |= sign;
1694
1695 index += indexTable[delta];
1696 if ( index < 0 ) index = 0;
1697 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001698 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 /* Step 6 - Output value */
1701 if ( bufferstep ) {
1702 outputbuffer = (delta << 4) & 0xf0;
1703 } else {
1704 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001705 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 bufferstep = !bufferstep;
1707 }
1708 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Benjamin Peterson08673c52014-01-26 10:24:24 -05001709
1710 exit:
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001711 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001713}
1714
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001715/*[clinic input]
1716audioop.adpcm2lin
1717
1718 fragment: Py_buffer
1719 width: int
1720 state: object
1721 /
1722
1723Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1724[clinic start generated code]*/
1725
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001726static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001727audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state)
Larry Hastings581ee362014-01-28 05:00:08 -08001728/*[clinic end generated code: output=371965cdcc0aa69b input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 signed char *cp;
1731 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001732 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001733 int valpred, step, delta, index, sign, vpdiff;
1734 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001735 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001736
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001737 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001738 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 /* Decode state, should have (value, step) */
1741 if ( state == Py_None ) {
1742 /* First time, it seems. Set defaults */
1743 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 index = 0;
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001745 } else if (!PyTuple_Check(state)) {
1746 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001747 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001748 } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index))
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001749 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001751 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 PyErr_SetString(PyExc_MemoryError,
1753 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001754 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001756 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001757 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001758 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001759 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001761 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762
1763 step = stepsizeTable[index];
1764 bufferstep = 0;
1765
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001766 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 /* Step 1 - get the delta value and compute next index */
1768 if ( bufferstep ) {
1769 delta = inputbuffer & 0xf;
1770 } else {
1771 inputbuffer = *cp++;
1772 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001773 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 bufferstep = !bufferstep;
1776
1777 /* Step 2 - Find new index value (for later) */
1778 index += indexTable[delta];
1779 if ( index < 0 ) index = 0;
1780 if ( index > 88 ) index = 88;
1781
1782 /* Step 3 - Separate sign and magnitude */
1783 sign = delta & 8;
1784 delta = delta & 7;
1785
1786 /* Step 4 - Compute difference and new predicted value */
1787 /*
1788 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1789 ** in adpcm_coder.
1790 */
1791 vpdiff = step >> 3;
1792 if ( delta & 4 ) vpdiff += step;
1793 if ( delta & 2 ) vpdiff += step>>1;
1794 if ( delta & 1 ) vpdiff += step>>2;
1795
1796 if ( sign )
1797 valpred -= vpdiff;
1798 else
1799 valpred += vpdiff;
1800
1801 /* Step 5 - clamp output value */
1802 if ( valpred > 32767 )
1803 valpred = 32767;
1804 else if ( valpred < -32768 )
1805 valpred = -32768;
1806
1807 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001808 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001811 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1815 Py_DECREF(str);
1816 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001817}
1818
Larry Hastingsf256c222014-01-25 21:30:37 -08001819#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001820
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001821static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001822 AUDIOOP_MAX_METHODDEF
1823 AUDIOOP_MINMAX_METHODDEF
1824 AUDIOOP_AVG_METHODDEF
1825 AUDIOOP_MAXPP_METHODDEF
1826 AUDIOOP_AVGPP_METHODDEF
1827 AUDIOOP_RMS_METHODDEF
1828 AUDIOOP_FINDFIT_METHODDEF
1829 AUDIOOP_FINDMAX_METHODDEF
1830 AUDIOOP_FINDFACTOR_METHODDEF
1831 AUDIOOP_CROSS_METHODDEF
1832 AUDIOOP_MUL_METHODDEF
1833 AUDIOOP_ADD_METHODDEF
1834 AUDIOOP_BIAS_METHODDEF
1835 AUDIOOP_ULAW2LIN_METHODDEF
1836 AUDIOOP_LIN2ULAW_METHODDEF
1837 AUDIOOP_ALAW2LIN_METHODDEF
1838 AUDIOOP_LIN2ALAW_METHODDEF
1839 AUDIOOP_LIN2LIN_METHODDEF
1840 AUDIOOP_ADPCM2LIN_METHODDEF
1841 AUDIOOP_LIN2ADPCM_METHODDEF
1842 AUDIOOP_TOMONO_METHODDEF
1843 AUDIOOP_TOSTEREO_METHODDEF
1844 AUDIOOP_GETSAMPLE_METHODDEF
1845 AUDIOOP_REVERSE_METHODDEF
1846 AUDIOOP_BYTESWAP_METHODDEF
1847 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001849};
1850
Martin v. Löwis1a214512008-06-11 05:26:20 +00001851
1852static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 PyModuleDef_HEAD_INIT,
1854 "audioop",
1855 NULL,
1856 -1,
1857 audioop_methods,
1858 NULL,
1859 NULL,
1860 NULL,
1861 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001862};
1863
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001864PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001865PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 PyObject *m, *d;
1868 m = PyModule_Create(&audioopmodule);
1869 if (m == NULL)
1870 return NULL;
1871 d = PyModule_GetDict(m);
1872 if (d == NULL)
1873 return NULL;
1874 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1875 if (AudioopError != NULL)
1876 PyDict_SetItemString(d,"error",AudioopError);
1877 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001878}