blob: d97a3697b2041388a579e0cbb2f9c35ec3b361b2 [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
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020054static const PyInt16 seg_aend[8] = {
55 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
56};
57static const PyInt16 seg_uend[8] = {
58 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF
59};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000060
61static PyInt16
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020062search(PyInt16 val, const PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 for (i = 0; i < size; i++) {
67 if (val <= *table++)
68 return (i);
69 }
70 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000071}
72#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
73#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000074
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020075static const PyInt16 _st_ulaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000076 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
77 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
78 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
79 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
80 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
81 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
82 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
83 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
84 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
85 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
86 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
87 -1052, -988, -924, -876, -844, -812, -780,
88 -748, -716, -684, -652, -620, -588, -556,
89 -524, -492, -460, -428, -396, -372, -356,
90 -340, -324, -308, -292, -276, -260, -244,
91 -228, -212, -196, -180, -164, -148, -132,
92 -120, -112, -104, -96, -88, -80, -72,
93 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000095 27004, 25980, 24956, 23932, 22908, 21884, 20860,
96 19836, 18812, 17788, 16764, 15996, 15484, 14972,
97 14460, 13948, 13436, 12924, 12412, 11900, 11388,
98 10876, 10364, 9852, 9340, 8828, 8316, 7932,
99 7676, 7420, 7164, 6908, 6652, 6396, 6140,
100 5884, 5628, 5372, 5116, 4860, 4604, 4348,
101 4092, 3900, 3772, 3644, 3516, 3388, 3260,
102 3132, 3004, 2876, 2748, 2620, 2492, 2364,
103 2236, 2108, 1980, 1884, 1820, 1756, 1692,
104 1628, 1564, 1500, 1436, 1372, 1308, 1244,
105 1180, 1116, 1052, 988, 924, 876, 844,
106 812, 780, 748, 716, 684, 652, 620,
107 588, 556, 524, 492, 460, 428, 396,
108 372, 356, 340, 324, 308, 292, 276,
109 260, 244, 228, 212, 196, 180, 164,
110 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 80, 72, 64, 56, 48, 40, 32,
112 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000113};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000114
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000115/*
116 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000117 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000118 * the data shifted such that it only contains information in the lower
119 * 14-bits.
120 *
121 * In order to simplify the encoding process, the original linear magnitude
122 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
123 * (33 - 8191). The result can be seen in the following encoding table:
124 *
125 * Biased Linear Input Code Compressed Code
126 * ------------------------ ---------------
127 * 00000001wxyza 000wxyz
128 * 0000001wxyzab 001wxyz
129 * 000001wxyzabc 010wxyz
130 * 00001wxyzabcd 011wxyz
131 * 0001wxyzabcde 100wxyz
132 * 001wxyzabcdef 101wxyz
133 * 01wxyzabcdefg 110wxyz
134 * 1wxyzabcdefgh 111wxyz
135 *
136 * Each biased linear code has a leading 1 which identifies the segment
137 * number. The value of the segment number is equal to 7 minus the number
138 * of leading 0's. The quantization interval is directly available as the
139 * four bits wxyz. * The trailing bits (a - h) are ignored.
140 *
141 * Ordinarily the complement of the resulting code word is used for
142 * transmission, and so the code word is complemented before it is returned.
143 *
144 * For further information see John C. Bellamy's Digital Telephony, 1982,
145 * John Wiley & Sons, pps 98-111 and 472-476.
146 */
147static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000149{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 PyInt16 mask;
151 PyInt16 seg;
152 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 /* u-law inverts all bits */
155 /* Get the sign and the magnitude of the value. */
156 if (pcm_val < 0) {
157 pcm_val = -pcm_val;
158 mask = 0x7F;
159 } else {
160 mask = 0xFF;
161 }
162 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
163 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 /* Convert the scaled magnitude to segment number. */
166 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 /*
169 * Combine the sign, segment, quantization bits;
170 * and complement the code word.
171 */
172 if (seg >= 8) /* out of range, return maximum value. */
173 return (unsigned char) (0x7F ^ mask);
174 else {
175 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
176 return (uval ^ mask);
177 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000178
179}
180
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200181static const PyInt16 _st_alaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000182 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
183 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
184 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
185 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
186 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
187 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
188 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
189 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
190 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
191 -13568, -344, -328, -376, -360, -280, -264,
192 -312, -296, -472, -456, -504, -488, -408,
193 -392, -440, -424, -88, -72, -120, -104,
194 -24, -8, -56, -40, -216, -200, -248,
195 -232, -152, -136, -184, -168, -1376, -1312,
196 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
197 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
198 -688, -656, -752, -720, -560, -528, -624,
199 -592, -944, -912, -1008, -976, -816, -784,
200 -880, -848, 5504, 5248, 6016, 5760, 4480,
201 4224, 4992, 4736, 7552, 7296, 8064, 7808,
202 6528, 6272, 7040, 6784, 2752, 2624, 3008,
203 2880, 2240, 2112, 2496, 2368, 3776, 3648,
204 4032, 3904, 3264, 3136, 3520, 3392, 22016,
205 20992, 24064, 23040, 17920, 16896, 19968, 18944,
206 30208, 29184, 32256, 31232, 26112, 25088, 28160,
207 27136, 11008, 10496, 12032, 11520, 8960, 8448,
208 9984, 9472, 15104, 14592, 16128, 15616, 13056,
209 12544, 14080, 13568, 344, 328, 376, 360,
210 280, 264, 312, 296, 472, 456, 504,
211 488, 408, 392, 440, 424, 88, 72,
212 120, 104, 24, 8, 56, 40, 216,
213 200, 248, 232, 152, 136, 184, 168,
214 1376, 1312, 1504, 1440, 1120, 1056, 1248,
215 1184, 1888, 1824, 2016, 1952, 1632, 1568,
216 1760, 1696, 688, 656, 752, 720, 560,
217 528, 624, 592, 944, 912, 1008, 976,
218 816, 784, 880, 848
219};
220
221/*
222 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000223 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000224 * the data shifted such that it only contains information in the lower
225 * 13-bits.
226 *
227 * Linear Input Code Compressed Code
228 * ------------------------ ---------------
229 * 0000000wxyza 000wxyz
230 * 0000001wxyza 001wxyz
231 * 000001wxyzab 010wxyz
232 * 00001wxyzabc 011wxyz
233 * 0001wxyzabcd 100wxyz
234 * 001wxyzabcde 101wxyz
235 * 01wxyzabcdef 110wxyz
236 * 1wxyzabcdefg 111wxyz
237 *
238 * For further information see John C. Bellamy's Digital Telephony, 1982,
239 * John Wiley & Sons, pps 98-111 and 472-476.
240 */
241static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 PyInt16 mask;
245 short seg;
246 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 /* A-law using even bit inversion */
249 if (pcm_val >= 0) {
250 mask = 0xD5; /* sign (7th) bit = 1 */
251 } else {
252 mask = 0x55; /* sign bit = 0 */
253 pcm_val = -pcm_val - 1;
254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Convert the scaled magnitude to segment number. */
257 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (seg >= 8) /* out of range, return maximum value. */
262 return (unsigned char) (0x7F ^ mask);
263 else {
264 aval = (unsigned char) seg << SEG_SHIFT;
265 if (seg < 2)
266 aval |= (pcm_val >> 1) & QUANT_MASK;
267 else
268 aval |= (pcm_val >> seg) & QUANT_MASK;
269 return (aval ^ mask);
270 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000271}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000272/* End of code taken from sox */
273
Guido van Rossumb64e6351992-07-06 14:21:56 +0000274/* Intel ADPCM step variation table */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200275static const int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 -1, -1, -1, -1, 2, 4, 6, 8,
277 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000278};
279
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200280static const int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
282 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
283 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
284 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
285 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
286 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
287 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
288 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
289 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000290};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291
Serhiy Storchaka23a78272013-11-11 07:47:35 +0200292#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
293#define SETINTX(T, cp, i, val) do { \
294 *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300295 } while (0)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000296
297
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300298#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
299#define GETINT16(cp, i) GETINTX(short, (cp), (i))
300#define GETINT32(cp, i) GETINTX(PY_INT32_T, (cp), (i))
301
302#if WORDS_BIGENDIAN
303#define GETINT24(cp, i) ( \
304 ((unsigned char *)(cp) + (i))[2] + \
305 (((unsigned char *)(cp) + (i))[1] << 8) + \
306 (((signed char *)(cp) + (i))[0] << 16) )
307#else
308#define GETINT24(cp, i) ( \
309 ((unsigned char *)(cp) + (i))[0] + \
310 (((unsigned char *)(cp) + (i))[1] << 8) + \
311 (((signed char *)(cp) + (i))[2] << 16) )
312#endif
313
314
315#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
316#define SETINT16(cp, i, val) SETINTX(short, (cp), (i), (val))
317#define SETINT32(cp, i, val) SETINTX(PY_INT32_T, (cp), (i), (val))
318
319#if WORDS_BIGENDIAN
320#define SETINT24(cp, i, val) do { \
321 ((unsigned char *)(cp) + (i))[2] = (int)(val); \
322 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
323 ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
324 } while (0)
325#else
326#define SETINT24(cp, i, val) do { \
327 ((unsigned char *)(cp) + (i))[0] = (int)(val); \
328 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
329 ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
330 } while (0)
331#endif
332
333
334#define GETRAWSAMPLE(size, cp, i) ( \
335 (size == 1) ? (int)GETINT8((cp), (i)) : \
336 (size == 2) ? (int)GETINT16((cp), (i)) : \
337 (size == 3) ? (int)GETINT24((cp), (i)) : \
338 (int)GETINT32((cp), (i)))
339
340#define SETRAWSAMPLE(size, cp, i, val) do { \
341 if (size == 1) \
342 SETINT8((cp), (i), (val)); \
343 else if (size == 2) \
344 SETINT16((cp), (i), (val)); \
345 else if (size == 3) \
346 SETINT24((cp), (i), (val)); \
347 else \
348 SETINT32((cp), (i), (val)); \
349 } while(0)
350
351
352#define GETSAMPLE32(size, cp, i) ( \
353 (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
354 (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
355 (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \
356 (int)GETINT32((cp), (i)))
357
358#define SETSAMPLE32(size, cp, i, val) do { \
359 if (size == 1) \
360 SETINT8((cp), (i), (val) >> 24); \
361 else if (size == 2) \
362 SETINT16((cp), (i), (val) >> 16); \
363 else if (size == 3) \
364 SETINT24((cp), (i), (val) >> 8); \
365 else \
366 SETINT32((cp), (i), (val)); \
367 } while(0)
368
Guido van Rossumb66efa01992-06-01 16:01:24 +0000369
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000370static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000371
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000372static int
373audioop_check_size(int size)
374{
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300375 if (size < 1 || size > 4) {
376 PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000377 return 0;
378 }
379 else
380 return 1;
381}
382
383static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000384audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000385{
386 if (!audioop_check_size(size))
387 return 0;
388 if (len % size != 0) {
389 PyErr_SetString(AudioopError, "not a whole number of frames");
390 return 0;
391 }
392 return 1;
393}
394
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200395/*[clinic input]
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200396module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200397[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300398/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200399
400/*[clinic input]
401audioop.getsample
402
403 fragment: Py_buffer
404 width: int
405 index: Py_ssize_t
406 /
407
408Return the value of sample index from the fragment.
409[clinic start generated code]*/
410
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400412audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width,
413 Py_ssize_t index)
414/*[clinic end generated code: output=3995e189fdc8ec16 input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000415{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200416 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000417
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200418 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000419 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200420 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200422 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200424 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200425 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000426}
427
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200428/*[clinic input]
429audioop.max
430
431 fragment: Py_buffer
432 width: int
433 /
434
435Return the maximum of the absolute value of all samples in a fragment.
436[clinic start generated code]*/
437
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000438static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200439audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800440/*[clinic end generated code: output=85047ee1001f2305 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000441{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200442 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200443 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000444
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200445 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000446 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200447 for (i = 0; i < fragment->len; i += width) {
448 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200449 if (val < 0) absval = (-val);
450 else absval = val;
451 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200453 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000454}
455
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200456/*[clinic input]
457audioop.minmax
458
459 fragment: Py_buffer
460 width: int
461 /
462
463Return the minimum and maximum values of all samples in the sound fragment.
464[clinic start generated code]*/
465
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000466static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200467audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800468/*[clinic end generated code: output=ae8f5513c64fd569 input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000469{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200470 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000471 /* -1 trick below is needed on Windows to support -0x80000000 without
472 a warning */
473 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000474
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200475 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200477 for (i = 0; i < fragment->len; i += width) {
478 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 if (val > max) max = val;
480 if (val < min) min = val;
481 }
482 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000483}
484
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200485/*[clinic input]
486audioop.avg
487
488 fragment: Py_buffer
489 width: int
490 /
491
492Return the average over all samples in the fragment.
493[clinic start generated code]*/
494
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000495static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200496audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800497/*[clinic end generated code: output=7fccd645c95f4860 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000498{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200499 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200500 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300501 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000502
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200503 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000504 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200505 for (i = 0; i < fragment->len; i += width)
506 sum += GETRAWSAMPLE(width, fragment->buf, i);
507 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300508 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200510 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300511 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000512}
513
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200514/*[clinic input]
515audioop.rms
516
517 fragment: Py_buffer
518 width: int
519 /
520
521Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
522[clinic start generated code]*/
523
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200525audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800526/*[clinic end generated code: output=7b398702c81b709d input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000527{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200528 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200529 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000531
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200532 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000533 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200534 for (i = 0; i < fragment->len; i += width) {
535 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300536 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200538 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200539 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200541 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200542 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000543}
544
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200545static double _sum2(const short *a, const short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000546{
Mark Dickinson81fece22010-05-11 13:34:35 +0000547 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 for( i=0; i<len; i++) {
551 sum = sum + (double)a[i]*(double)b[i];
552 }
553 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000554}
555
556/*
557** Findfit tries to locate a sample within another sample. Its main use
558** is in echo-cancellation (to find the feedback of the output signal in
559** the input signal).
560** The method used is as follows:
561**
562** let R be the reference signal (length n) and A the input signal (length N)
563** with N > n, and let all sums be over i from 0 to n-1.
564**
565** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
566** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
567** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
568**
569** Next, we compute the relative distance between the original signal and
570** the modified signal and minimize that over j:
571** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
572** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
573**
574** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000575** cp1 A
576** cp2 R
577** len1 N
578** len2 n
579** aj_m1 A[j-1]
580** aj_lm1 A[j+n-1]
581** sum_ri_2 sum(R[i]^2)
582** sum_aij_2 sum(A[i+j]^2)
583** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000584**
585** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
586** is completely recalculated each step.
587*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200588/*[clinic input]
589audioop.findfit
590
591 fragment: Py_buffer
592 reference: Py_buffer
593 /
594
595Try to match reference as well as possible to a portion of fragment.
596[clinic start generated code]*/
597
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000598static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400599audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment,
600 Py_buffer *reference)
601/*[clinic end generated code: output=609eedf5d823d6dd input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000602{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200603 const short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000604 Py_ssize_t len1, len2;
605 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 double aj_m1, aj_lm1;
607 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000608
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200609 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200611 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200613 cp1 = (const short *)fragment->buf;
614 len1 = fragment->len >> 1;
615 cp2 = (const short *)reference->buf;
616 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000617
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200618 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200620 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 }
622 sum_ri_2 = _sum2(cp2, cp2, len2);
623 sum_aij_2 = _sum2(cp1, cp1, len2);
624 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 best_result = result;
629 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 for ( j=1; j<=len1-len2; j++) {
632 aj_m1 = (double)cp1[j-1];
633 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
636 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
639 / sum_aij_2;
640
641 if ( result < best_result ) {
642 best_result = result;
643 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000644 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 }
647
648 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
649
Mark Dickinson81fece22010-05-11 13:34:35 +0000650 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000651}
652
653/*
654** findfactor finds a factor f so that the energy in A-fB is minimal.
655** See the comment for findfit for details.
656*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200657/*[clinic input]
658audioop.findfactor
659
660 fragment: Py_buffer
661 reference: Py_buffer
662 /
663
664Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
665[clinic start generated code]*/
666
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000667static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400668audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment,
669 Py_buffer *reference)
670/*[clinic end generated code: output=5566a8c55de54f99 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000671{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200672 const short *cp1, *cp2;
673 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000675
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200676 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 PyErr_SetString(AudioopError, "Strings should be even-sized");
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 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200682 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200684 cp1 = (const short *)fragment->buf;
685 cp2 = (const short *)reference->buf;
686 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200687 sum_ri_2 = _sum2(cp2, cp2, len);
688 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000693}
694
695/*
696** findmax returns the index of the n-sized segment of the input sample
697** that contains the most energy.
698*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200699/*[clinic input]
700audioop.findmax
701
702 fragment: Py_buffer
703 length: Py_ssize_t
704 /
705
706Search fragment for a slice of specified number of samples with maximum energy.
707[clinic start generated code]*/
708
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000709static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400710audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment,
711 Py_ssize_t length)
712/*[clinic end generated code: output=01fe796fad2573bb input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000713{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200714 const short *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200715 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000716 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 double aj_m1, aj_lm1;
718 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000719
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200720 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200722 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200724 cp1 = (const short *)fragment->buf;
725 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200727 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200729 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 }
731
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200732 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733
734 best_result = result;
735 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200737 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200739 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740
741 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
742
743 if ( result > best_result ) {
744 best_result = result;
745 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000746 }
Jack Jansena90805f1993-02-17 14:29:28 +0000747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000749
Mark Dickinson81fece22010-05-11 13:34:35 +0000750 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000751}
752
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200753/*[clinic input]
754audioop.avgpp
755
756 fragment: Py_buffer
757 width: int
758 /
759
760Return the average peak-peak value over all samples in the fragment.
761[clinic start generated code]*/
762
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000763static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200764audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800765/*[clinic end generated code: output=06c8380fd6e34207 input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000766{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200767 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200768 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200769 double sum = 0.0;
770 unsigned int avg;
771 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000772
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200773 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000774 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200775 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200776 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200777 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200778 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200779 for (i = width; i < fragment->len; i += width) {
780 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200781 if (val != prevval) {
782 diff = val < prevval;
783 if (prevdiff == !diff) {
784 /* Derivative changed sign. Compute difference to last
785 ** extreme value and remember.
786 */
787 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300788 if (prevval < prevextreme)
789 sum += (double)((unsigned int)prevextreme -
790 (unsigned int)prevval);
791 else
792 sum += (double)((unsigned int)prevval -
793 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200794 nextreme++;
795 }
796 prevextremevalid = 1;
797 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200799 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200801 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 }
803 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200804 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200806 avg = (unsigned int)(sum / (double)nextreme);
807 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000808}
809
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200810/*[clinic input]
811audioop.maxpp
812
813 fragment: Py_buffer
814 width: int
815 /
816
817Return the maximum peak-peak value in the sound fragment.
818[clinic start generated code]*/
819
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000820static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200821audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800822/*[clinic end generated code: output=c300c0bd7e8535c0 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000823{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200824 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200825 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200826 unsigned int max = 0, extremediff;
827 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000828
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200829 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000830 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200831 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200832 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200833 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200834 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200835 for (i = width; i < fragment->len; i += width) {
836 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200837 if (val != prevval) {
838 diff = val < prevval;
839 if (prevdiff == !diff) {
840 /* Derivative changed sign. Compute difference to
841 ** last extreme value and remember.
842 */
843 if (prevextremevalid) {
844 if (prevval < prevextreme)
845 extremediff = (unsigned int)prevextreme -
846 (unsigned int)prevval;
847 else
848 extremediff = (unsigned int)prevval -
849 (unsigned int)prevextreme;
850 if ( extremediff > max )
851 max = extremediff;
852 }
853 prevextremevalid = 1;
854 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200856 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200858 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200860 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000861}
862
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200863/*[clinic input]
864audioop.cross
865
866 fragment: Py_buffer
867 width: int
868 /
869
870Return the number of zero crossings in the fragment passed as an argument.
871[clinic start generated code]*/
872
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200874audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -0800875/*[clinic end generated code: output=99e6572d7d7cdbf1 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200877 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000878 int prevval;
879 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200881 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000882 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 ncross = -1;
884 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200885 for (i = 0; i < fragment->len; i += width) {
886 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300887 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 prevval = val;
889 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000890 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000891}
892
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200893/*[clinic input]
894audioop.mul
895
896 fragment: Py_buffer
897 width: int
898 factor: double
899 /
900
901Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
902[clinic start generated code]*/
903
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000904static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400905audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width,
906 double factor)
907/*[clinic end generated code: output=1c7c31191ac86b10 input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000908{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200909 signed char *ncp;
910 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200911 double maxval, minval;
912 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000913
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200914 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000915 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200917 maxval = (double) maxvals[width];
918 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200920 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200921 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200922 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 ncp = (signed char *)PyBytes_AsString(rv);
924
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200925 for (i = 0; i < fragment->len; i += width) {
926 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300927 val *= factor;
928 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200929 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 }
931 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000932}
933
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200934/*[clinic input]
935audioop.tomono
936
937 fragment: Py_buffer
938 width: int
939 lfactor: double
940 rfactor: double
941 /
942
943Convert a stereo fragment to a mono fragment.
944[clinic start generated code]*/
945
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000946static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400947audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width,
948 double lfactor, double rfactor)
949/*[clinic end generated code: output=553f547c5e29e3b6 input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000952 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200953 double maxval, minval;
954 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000955
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200956 cp = fragment->buf;
957 len = fragment->len;
958 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200959 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200960 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000961 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200962 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000963 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200965 maxval = (double) maxvals[width];
966 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967
968 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200969 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200970 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 ncp = (signed char *)PyBytes_AsString(rv);
972
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200973 for (i = 0; i < len; i += width*2) {
974 double val1 = GETRAWSAMPLE(width, cp, i);
975 double val2 = GETRAWSAMPLE(width, cp, i + width);
976 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300977 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200978 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000981}
982
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200983/*[clinic input]
984audioop.tostereo
985
986 fragment: Py_buffer
987 width: int
988 lfactor: double
989 rfactor: double
990 /
991
992Generate a stereo fragment from a mono fragment.
993[clinic start generated code]*/
994
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000995static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -0400996audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width,
997 double lfactor, double rfactor)
998/*[clinic end generated code: output=697bb6ba41e9dd2c input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000999{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001000 signed char *ncp;
1001 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001002 double maxval, minval;
1003 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001004
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001005 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001006 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001007
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001008 maxval = (double) maxvals[width];
1009 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001010
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001011 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 PyErr_SetString(PyExc_MemoryError,
1013 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001014 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001016
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001017 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001018 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001019 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001021
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001022 for (i = 0; i < fragment->len; i += width) {
1023 double val = GETRAWSAMPLE(width, fragment->buf, i);
1024 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1025 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1026 SETRAWSAMPLE(width, ncp, i*2, val1);
1027 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 }
1029 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001030}
1031
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001032/*[clinic input]
1033audioop.add
1034
1035 fragment1: Py_buffer
1036 fragment2: Py_buffer
1037 width: int
1038 /
1039
1040Return a fragment which is the addition of the two samples passed as parameters.
1041[clinic start generated code]*/
1042
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001043static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001044audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1,
1045 Py_buffer *fragment2, int width)
1046/*[clinic end generated code: output=fe6c12f143e0b027 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001047{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001048 signed char *ncp;
1049 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001050 int minval, maxval, newval;
1051 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001052
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001053 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001054 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001055 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001057 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001059
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001060 maxval = maxvals[width];
1061 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001062
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001063 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001064 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001065 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001067
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001068 for (i = 0; i < fragment1->len; i += width) {
1069 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1070 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001072 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001073 newval = val1 + val2;
1074 /* truncate in case of overflow */
1075 if (newval > maxval)
1076 newval = maxval;
1077 else if (newval < minval)
1078 newval = minval;
1079 }
1080 else {
1081 double fval = (double)val1 + (double)val2;
1082 /* truncate in case of overflow */
1083 newval = (int)floor(fbound(fval, minval, maxval));
1084 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001086 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 }
1088 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001089}
1090
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001091/*[clinic input]
1092audioop.bias
1093
1094 fragment: Py_buffer
1095 width: int
1096 bias: int
1097 /
1098
1099Return a fragment that is the original fragment with a bias added to each sample.
1100[clinic start generated code]*/
1101
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001102static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001103audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1104 int bias)
1105/*[clinic end generated code: output=ac1f4dda20a01c26 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001106{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001107 signed char *ncp;
1108 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001109 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001110 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001111
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001112 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001113 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001115 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001116 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001117 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 ncp = (signed char *)PyBytes_AsString(rv);
1119
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001120 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001122 for (i = 0; i < fragment->len; i += width) {
1123 if (width == 1)
1124 val = GETINTX(unsigned char, fragment->buf, i);
1125 else if (width == 2)
1126 val = GETINTX(unsigned short, fragment->buf, i);
1127 else if (width == 3)
1128 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001129 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001130 assert(width == 4);
1131 val = GETINTX(PY_UINT32_T, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001132 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001134 val += (unsigned int)bias;
1135 /* wrap around in case of overflow */
1136 val &= mask;
1137
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001138 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001139 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001140 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001141 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001142 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001143 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001144 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001145 assert(width == 4);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001146 SETINTX(PY_UINT32_T, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001147 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 }
1149 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001150}
1151
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001152/*[clinic input]
1153audioop.reverse
1154
1155 fragment: Py_buffer
1156 width: int
1157 /
1158
1159Reverse the samples in a fragment and returns the modified fragment.
1160[clinic start generated code]*/
1161
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001162static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001163audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001164/*[clinic end generated code: output=6ec3c91337f5925e input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001167 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001168 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001169
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001170 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001171 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001172
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001173 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001174 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001175 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 ncp = (unsigned char *)PyBytes_AsString(rv);
1177
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001178 for (i = 0; i < fragment->len; i += width) {
1179 int val = GETRAWSAMPLE(width, fragment->buf, i);
1180 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 }
1182 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001183}
1184
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001185/*[clinic input]
1186audioop.byteswap
1187
1188 fragment: Py_buffer
1189 width: int
1190 /
1191
1192Convert big-endian samples to little-endian and vice versa.
1193[clinic start generated code]*/
1194
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001195static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001196audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001197/*[clinic end generated code: output=bfe4aa584b7a3f5b input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001198{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001199 unsigned char *ncp;
1200 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001201 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001202
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001203 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001204 return NULL;
1205
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001206 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001207 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001208 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001209 ncp = (unsigned char *)PyBytes_AsString(rv);
1210
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001211 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001212 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001213 for (j = 0; j < width; j++)
1214 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001215 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001216 return rv;
1217}
1218
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001219/*[clinic input]
1220audioop.lin2lin
1221
1222 fragment: Py_buffer
1223 width: int
1224 newwidth: int
1225 /
1226
1227Convert samples between 1-, 2-, 3- and 4-byte formats.
1228[clinic start generated code]*/
1229
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001230static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001231audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1232 int newwidth)
1233/*[clinic end generated code: output=cb6ca950d1df9898 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001236 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001237 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001238
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001239 if (!audioop_check_parameters(fragment->len, width))
1240 return NULL;
1241 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001242 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001243
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001244 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 PyErr_SetString(PyExc_MemoryError,
1246 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001247 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001249 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001250 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001251 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 ncp = (unsigned char *)PyBytes_AsString(rv);
1253
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001254 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1255 int val = GETSAMPLE32(width, fragment->buf, i);
1256 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 }
1258 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001259}
1260
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001261static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001262gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 while (b > 0) {
1265 int tmp = a % b;
1266 a = b;
1267 b = tmp;
1268 }
1269 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001270}
1271
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001272/*[clinic input]
1273audioop.ratecv
1274
1275 fragment: Py_buffer
1276 width: int
1277 nchannels: int
1278 inrate: int
1279 outrate: int
1280 state: object
1281 weightA: int = 1
1282 weightB: int = 0
1283 /
1284
1285Convert the frame rate of the input fragment.
1286[clinic start generated code]*/
1287
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001288static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001289audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1290 int nchannels, int inrate, int outrate, PyObject *state,
1291 int weightA, int weightB)
1292/*[clinic end generated code: output=59e1787bfa49b9d9 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001295 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001297 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001299
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001300 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 if (nchannels < 1) {
1303 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001304 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001306 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 /* This overflow test is rigorously correct because
1308 both multiplicands are >= 1. Use the argument names
1309 from the docs for the error msg. */
1310 PyErr_SetString(PyExc_OverflowError,
1311 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001312 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001314 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 if (weightA < 1 || weightB < 0) {
1316 PyErr_SetString(AudioopError,
1317 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001318 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001320 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001321 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001323 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 }
1325 if (inrate <= 0 || outrate <= 0) {
1326 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001327 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 }
1329 /* divide inrate and outrate by their greatest common divisor */
1330 d = gcd(inrate, outrate);
1331 inrate /= d;
1332 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001333 /* divide weightA and weightB by their greatest common divisor */
1334 d = gcd(weightA, weightB);
1335 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001336 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001337
Mark Dickinson85eacea2010-05-10 16:27:45 +00001338 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 PyErr_SetString(PyExc_MemoryError,
1340 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001341 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001343 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1344 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (prev_i == NULL || cur_i == NULL) {
1346 (void) PyErr_NoMemory();
1347 goto exit;
1348 }
1349
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001350 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351
1352 if (state == Py_None) {
1353 d = -outrate;
1354 for (chan = 0; chan < nchannels; chan++)
1355 prev_i[chan] = cur_i[chan] = 0;
1356 }
1357 else {
1358 if (!PyArg_ParseTuple(state,
1359 "iO!;audioop.ratecv: illegal state argument",
1360 &d, &PyTuple_Type, &samps))
1361 goto exit;
1362 if (PyTuple_Size(samps) != nchannels) {
1363 PyErr_SetString(AudioopError,
1364 "illegal state argument");
1365 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001366 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 for (chan = 0; chan < nchannels; chan++) {
1368 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1369 "ii:ratecv", &prev_i[chan],
1370 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001371 goto exit;
1372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001376 if (len == 0)
1377 str = PyBytes_FromStringAndSize(NULL, 0);
1378 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 /* There are len input frames, so we need (mathematically)
1380 ceiling(len*outrate/inrate) output frames, and each frame
1381 requires bytes_per_frame bytes. Computing this
1382 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001383 settle for a reasonable upper bound, though, in this
1384 case ceiling(len/inrate) * outrate. */
1385
1386 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001387 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001388 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 str = NULL;
1390 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001391 str = PyBytes_FromStringAndSize(NULL,
1392 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001393 }
1394 if (str == NULL) {
1395 PyErr_SetString(PyExc_MemoryError,
1396 "not enough memory for output buffer");
1397 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 }
1399 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001400 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401
1402 for (;;) {
1403 while (d < 0) {
1404 if (len == 0) {
1405 samps = PyTuple_New(nchannels);
1406 if (samps == NULL)
1407 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001408 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 PyTuple_SetItem(samps, chan,
1410 Py_BuildValue("(ii)",
1411 prev_i[chan],
1412 cur_i[chan]));
1413 if (PyErr_Occurred())
1414 goto exit;
1415 /* We have checked before that the length
1416 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001417 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 rv = PyBytes_FromStringAndSize
1419 (PyBytes_AsString(str), len);
1420 Py_DECREF(str);
1421 str = rv;
1422 if (str == NULL)
1423 goto exit;
1424 rv = Py_BuildValue("(O(iO))", str, d, samps);
1425 Py_DECREF(samps);
1426 Py_DECREF(str);
1427 goto exit; /* return rv */
1428 }
1429 for (chan = 0; chan < nchannels; chan++) {
1430 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001431 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1432 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001434 cur_i[chan] = (int)(
1435 ((double)weightA * (double)cur_i[chan] +
1436 (double)weightB * (double)prev_i[chan]) /
1437 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 }
1439 len--;
1440 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001441 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 while (d >= 0) {
1443 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001444 cur_o = (int)(((double)prev_i[chan] * (double)d +
1445 (double)cur_i[chan] * (double)(outrate - d)) /
1446 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001447 SETSAMPLE32(width, ncp, 0, cur_o);
1448 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 }
1450 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001451 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001453 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001454 PyMem_Free(prev_i);
1455 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001457}
Guido van Rossum1851a671997-02-14 16:14:03 +00001458
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001459/*[clinic input]
1460audioop.lin2ulaw
1461
1462 fragment: Py_buffer
1463 width: int
1464 /
1465
1466Convert samples in the audio fragment to u-LAW encoding.
1467[clinic start generated code]*/
1468
Roger E. Massec905fff1997-01-17 18:12:04 +00001469static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001470audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001471/*[clinic end generated code: output=26263cc877c5e1bc input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001474 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001475 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001476
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001477 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001478 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001479
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001480 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001481 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001482 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 ncp = (unsigned char *)PyBytes_AsString(rv);
1484
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001485 for (i = 0; i < fragment->len; i += width) {
1486 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001487 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 }
1489 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001490}
1491
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001492/*[clinic input]
1493audioop.ulaw2lin
1494
1495 fragment: Py_buffer
1496 width: int
1497 /
1498
1499Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1500[clinic start generated code]*/
1501
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001502static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001503audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001504/*[clinic end generated code: output=9864cb34e3a1d876 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001508 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001509 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001510
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001511 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001512 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001514 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 PyErr_SetString(PyExc_MemoryError,
1516 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001517 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001519 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001520 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001521 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 ncp = (signed char *)PyBytes_AsString(rv);
1523
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001524 cp = fragment->buf;
1525 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001526 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001527 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 }
1529 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001530}
1531
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001532/*[clinic input]
1533audioop.lin2alaw
1534
1535 fragment: Py_buffer
1536 width: int
1537 /
1538
1539Convert samples in the audio fragment to a-LAW encoding.
1540[clinic start generated code]*/
1541
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001542static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001543audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001544/*[clinic end generated code: output=d5bf14bd0fe6fdcd input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001547 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001548 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001549
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001550 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001551 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001552
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001553 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001554 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001555 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 ncp = (unsigned char *)PyBytes_AsString(rv);
1557
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001558 for (i = 0; i < fragment->len; i += width) {
1559 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001560 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 }
1562 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001563}
1564
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001565/*[clinic input]
1566audioop.alaw2lin
1567
1568 fragment: Py_buffer
1569 width: int
1570 /
1571
1572Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1573[clinic start generated code]*/
1574
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001575static PyObject *
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001576audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width)
Larry Hastings581ee362014-01-28 05:00:08 -08001577/*[clinic end generated code: output=d2b604ddd036e1cd input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001578{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001581 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001582 int val;
1583 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001584
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001585 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001586 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001588 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 PyErr_SetString(PyExc_MemoryError,
1590 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001591 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001593 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001594 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001595 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001597 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001599 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001600 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001601 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 }
1603 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001604}
1605
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001606/*[clinic input]
1607audioop.lin2adpcm
1608
1609 fragment: Py_buffer
1610 width: int
1611 state: object
1612 /
1613
1614Convert samples to 4 bit Intel/DVI ADPCM encoding.
1615[clinic start generated code]*/
1616
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001617static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001618audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1619 PyObject *state)
1620/*[clinic end generated code: output=93f0996f592b5ce5 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001623 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001624 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001626 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001627 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001628
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001629 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001630 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 /* Decode state, should have (value, step) */
1633 if ( state == Py_None ) {
1634 /* First time, it seems. Set defaults */
1635 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001637 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001638 else if (!PyTuple_Check(state)) {
1639 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1640 return NULL;
1641 }
1642 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1643 return NULL;
1644 }
1645 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1646 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1647 PyErr_SetString(PyExc_ValueError, "bad state");
1648 return NULL;
1649 }
1650
1651 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1652 if (str == NULL)
1653 return NULL;
1654 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655
1656 step = stepsizeTable[index];
1657 bufferstep = 1;
1658
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001659 for (i = 0; i < fragment->len; i += width) {
1660 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661
1662 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001663 if (val < valpred) {
1664 diff = valpred - val;
1665 sign = 8;
1666 }
1667 else {
1668 diff = val - valpred;
1669 sign = 0;
1670 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671
1672 /* Step 2 - Divide and clamp */
1673 /* Note:
1674 ** This code *approximately* computes:
1675 ** delta = diff*4/step;
1676 ** vpdiff = (delta+0.5)*step/4;
1677 ** but in shift step bits are dropped. The net result of this
1678 ** is that even if you have fast mul/div hardware you cannot
1679 ** put it to good use since the fixup would be too expensive.
1680 */
1681 delta = 0;
1682 vpdiff = (step >> 3);
1683
1684 if ( diff >= step ) {
1685 delta = 4;
1686 diff -= step;
1687 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001688 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 step >>= 1;
1690 if ( diff >= step ) {
1691 delta |= 2;
1692 diff -= step;
1693 vpdiff += step;
1694 }
1695 step >>= 1;
1696 if ( diff >= step ) {
1697 delta |= 1;
1698 vpdiff += step;
1699 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 /* Step 3 - Update previous value */
1702 if ( sign )
1703 valpred -= vpdiff;
1704 else
1705 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 /* Step 4 - Clamp previous value to 16 bits */
1708 if ( valpred > 32767 )
1709 valpred = 32767;
1710 else if ( valpred < -32768 )
1711 valpred = -32768;
1712
1713 /* Step 5 - Assemble value, update index and step values */
1714 delta |= sign;
1715
1716 index += indexTable[delta];
1717 if ( index < 0 ) index = 0;
1718 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001719 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001720
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 /* Step 6 - Output value */
1722 if ( bufferstep ) {
1723 outputbuffer = (delta << 4) & 0xf0;
1724 } else {
1725 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001726 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 bufferstep = !bufferstep;
1728 }
1729 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001730 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001732}
1733
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001734/*[clinic input]
1735audioop.adpcm2lin
1736
1737 fragment: Py_buffer
1738 width: int
1739 state: object
1740 /
1741
1742Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1743[clinic start generated code]*/
1744
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001745static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001746audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width,
1747 PyObject *state)
1748/*[clinic end generated code: output=236cf6dc2c829181 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 signed char *cp;
1751 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001752 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001753 int valpred, step, delta, index, sign, vpdiff;
1754 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001755 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001756
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001757 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001758 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 /* Decode state, should have (value, step) */
1761 if ( state == Py_None ) {
1762 /* First time, it seems. Set defaults */
1763 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001765 }
1766 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001767 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001768 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001769 }
1770 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001771 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001772 }
1773 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1774 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1775 PyErr_SetString(PyExc_ValueError, "bad state");
1776 return NULL;
1777 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001779 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 PyErr_SetString(PyExc_MemoryError,
1781 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001782 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001784 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001785 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001786 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001787 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001789 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790
1791 step = stepsizeTable[index];
1792 bufferstep = 0;
1793
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001794 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 /* Step 1 - get the delta value and compute next index */
1796 if ( bufferstep ) {
1797 delta = inputbuffer & 0xf;
1798 } else {
1799 inputbuffer = *cp++;
1800 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001801 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 bufferstep = !bufferstep;
1804
1805 /* Step 2 - Find new index value (for later) */
1806 index += indexTable[delta];
1807 if ( index < 0 ) index = 0;
1808 if ( index > 88 ) index = 88;
1809
1810 /* Step 3 - Separate sign and magnitude */
1811 sign = delta & 8;
1812 delta = delta & 7;
1813
1814 /* Step 4 - Compute difference and new predicted value */
1815 /*
1816 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1817 ** in adpcm_coder.
1818 */
1819 vpdiff = step >> 3;
1820 if ( delta & 4 ) vpdiff += step;
1821 if ( delta & 2 ) vpdiff += step>>1;
1822 if ( delta & 1 ) vpdiff += step>>2;
1823
1824 if ( sign )
1825 valpred -= vpdiff;
1826 else
1827 valpred += vpdiff;
1828
1829 /* Step 5 - clamp output value */
1830 if ( valpred > 32767 )
1831 valpred = 32767;
1832 else if ( valpred < -32768 )
1833 valpred = -32768;
1834
1835 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001836 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001839 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1843 Py_DECREF(str);
1844 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001845}
1846
Larry Hastingsf256c222014-01-25 21:30:37 -08001847#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001848
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001849static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001850 AUDIOOP_MAX_METHODDEF
1851 AUDIOOP_MINMAX_METHODDEF
1852 AUDIOOP_AVG_METHODDEF
1853 AUDIOOP_MAXPP_METHODDEF
1854 AUDIOOP_AVGPP_METHODDEF
1855 AUDIOOP_RMS_METHODDEF
1856 AUDIOOP_FINDFIT_METHODDEF
1857 AUDIOOP_FINDMAX_METHODDEF
1858 AUDIOOP_FINDFACTOR_METHODDEF
1859 AUDIOOP_CROSS_METHODDEF
1860 AUDIOOP_MUL_METHODDEF
1861 AUDIOOP_ADD_METHODDEF
1862 AUDIOOP_BIAS_METHODDEF
1863 AUDIOOP_ULAW2LIN_METHODDEF
1864 AUDIOOP_LIN2ULAW_METHODDEF
1865 AUDIOOP_ALAW2LIN_METHODDEF
1866 AUDIOOP_LIN2ALAW_METHODDEF
1867 AUDIOOP_LIN2LIN_METHODDEF
1868 AUDIOOP_ADPCM2LIN_METHODDEF
1869 AUDIOOP_LIN2ADPCM_METHODDEF
1870 AUDIOOP_TOMONO_METHODDEF
1871 AUDIOOP_TOSTEREO_METHODDEF
1872 AUDIOOP_GETSAMPLE_METHODDEF
1873 AUDIOOP_REVERSE_METHODDEF
1874 AUDIOOP_BYTESWAP_METHODDEF
1875 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001877};
1878
Martin v. Löwis1a214512008-06-11 05:26:20 +00001879
1880static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 PyModuleDef_HEAD_INIT,
1882 "audioop",
1883 NULL,
1884 -1,
1885 audioop_methods,
1886 NULL,
1887 NULL,
1888 NULL,
1889 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001890};
1891
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001892PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001893PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001894{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 PyObject *m, *d;
1896 m = PyModule_Create(&audioopmodule);
1897 if (m == NULL)
1898 return NULL;
1899 d = PyModule_GetDict(m);
1900 if (d == NULL)
1901 return NULL;
1902 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1903 if (AudioopError != NULL)
1904 PyDict_SetItemString(d,"error",AudioopError);
1905 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001906}