blob: 44e5198b3cf8983ac599e28653e4bce7c4a54eae [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"
Steve Dowera4391912016-09-06 19:09:15 -07007#include <inttypes.h>
Guido van Rossumb66efa01992-06-01 16:01:24 +00008
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009typedef short PyInt16;
10
Guido van Rossum7b1e9741994-08-29 10:46:42 +000011#if defined(__CHAR_UNSIGNED__)
12#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013/* This module currently does not work on systems where only unsigned
14 characters are available. Take it out of Setup. Sorry. */
15#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000016#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000017
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020018static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
Tim Goldenfa6ab0f2013-10-31 10:25:47 +000019/* -1 trick is needed on Windows to support -0x80000000 without a warning */
20static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020021static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
22
23static int
24fbound(double val, double minval, double maxval)
25{
26 if (val > maxval)
27 val = maxval;
28 else if (val < minval + 1)
29 val = minval;
Victor Stinnerf2b9a342013-05-07 23:49:15 +020030 return (int)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020031}
32
33
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000035** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037/* From g711.c:
38 *
39 * December 30, 1994:
40 * Functions linear2alaw, linear2ulaw have been updated to correctly
41 * convert unquantized 16 bit values.
42 * Tables for direct u- to A-law and A- to u-law conversions have been
43 * corrected.
44 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
45 * bli@cpk.auc.dk
46 *
47 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000048#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
49#define CLIP 32635
Martin Panter4c359642016-05-08 13:53:41 +000050#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000051#define QUANT_MASK (0xf) /* Quantization field mask. */
52#define SEG_SHIFT (4) /* Left shift for segment number. */
53#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000054
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020055static const PyInt16 seg_aend[8] = {
56 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
57};
58static const PyInt16 seg_uend[8] = {
59 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF
60};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000061
62static PyInt16
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020063search(PyInt16 val, const PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 for (i = 0; i < size; i++) {
68 if (val <= *table++)
69 return (i);
70 }
71 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000072}
73#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
74#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000075
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020076static const PyInt16 _st_ulaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000077 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
78 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
79 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
80 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
81 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
82 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
83 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
84 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
85 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
86 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
87 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
88 -1052, -988, -924, -876, -844, -812, -780,
89 -748, -716, -684, -652, -620, -588, -556,
90 -524, -492, -460, -428, -396, -372, -356,
91 -340, -324, -308, -292, -276, -260, -244,
92 -228, -212, -196, -180, -164, -148, -132,
93 -120, -112, -104, -96, -88, -80, -72,
94 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000096 27004, 25980, 24956, 23932, 22908, 21884, 20860,
97 19836, 18812, 17788, 16764, 15996, 15484, 14972,
98 14460, 13948, 13436, 12924, 12412, 11900, 11388,
99 10876, 10364, 9852, 9340, 8828, 8316, 7932,
100 7676, 7420, 7164, 6908, 6652, 6396, 6140,
101 5884, 5628, 5372, 5116, 4860, 4604, 4348,
102 4092, 3900, 3772, 3644, 3516, 3388, 3260,
103 3132, 3004, 2876, 2748, 2620, 2492, 2364,
104 2236, 2108, 1980, 1884, 1820, 1756, 1692,
105 1628, 1564, 1500, 1436, 1372, 1308, 1244,
106 1180, 1116, 1052, 988, 924, 876, 844,
107 812, 780, 748, 716, 684, 652, 620,
108 588, 556, 524, 492, 460, 428, 396,
109 372, 356, 340, 324, 308, 292, 276,
110 260, 244, 228, 212, 196, 180, 164,
111 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 80, 72, 64, 56, 48, 40, 32,
113 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000114};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000115
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000116/*
117 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000118 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000119 * the data shifted such that it only contains information in the lower
120 * 14-bits.
121 *
122 * In order to simplify the encoding process, the original linear magnitude
123 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
124 * (33 - 8191). The result can be seen in the following encoding table:
125 *
126 * Biased Linear Input Code Compressed Code
127 * ------------------------ ---------------
128 * 00000001wxyza 000wxyz
129 * 0000001wxyzab 001wxyz
130 * 000001wxyzabc 010wxyz
131 * 00001wxyzabcd 011wxyz
132 * 0001wxyzabcde 100wxyz
133 * 001wxyzabcdef 101wxyz
134 * 01wxyzabcdefg 110wxyz
135 * 1wxyzabcdefgh 111wxyz
136 *
137 * Each biased linear code has a leading 1 which identifies the segment
138 * number. The value of the segment number is equal to 7 minus the number
139 * of leading 0's. The quantization interval is directly available as the
140 * four bits wxyz. * The trailing bits (a - h) are ignored.
141 *
142 * Ordinarily the complement of the resulting code word is used for
143 * transmission, and so the code word is complemented before it is returned.
144 *
145 * For further information see John C. Bellamy's Digital Telephony, 1982,
146 * John Wiley & Sons, pps 98-111 and 472-476.
147 */
148static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 PyInt16 mask;
152 PyInt16 seg;
153 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 /* u-law inverts all bits */
156 /* Get the sign and the magnitude of the value. */
157 if (pcm_val < 0) {
158 pcm_val = -pcm_val;
159 mask = 0x7F;
160 } else {
161 mask = 0xFF;
162 }
163 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
164 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 /* Convert the scaled magnitude to segment number. */
167 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 /*
170 * Combine the sign, segment, quantization bits;
171 * and complement the code word.
172 */
173 if (seg >= 8) /* out of range, return maximum value. */
174 return (unsigned char) (0x7F ^ mask);
175 else {
176 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
177 return (uval ^ mask);
178 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000179
180}
181
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200182static const PyInt16 _st_alaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000183 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
184 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
185 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
186 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
187 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
188 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
189 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
190 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
191 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
192 -13568, -344, -328, -376, -360, -280, -264,
193 -312, -296, -472, -456, -504, -488, -408,
194 -392, -440, -424, -88, -72, -120, -104,
195 -24, -8, -56, -40, -216, -200, -248,
196 -232, -152, -136, -184, -168, -1376, -1312,
197 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
198 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
199 -688, -656, -752, -720, -560, -528, -624,
200 -592, -944, -912, -1008, -976, -816, -784,
201 -880, -848, 5504, 5248, 6016, 5760, 4480,
202 4224, 4992, 4736, 7552, 7296, 8064, 7808,
203 6528, 6272, 7040, 6784, 2752, 2624, 3008,
204 2880, 2240, 2112, 2496, 2368, 3776, 3648,
205 4032, 3904, 3264, 3136, 3520, 3392, 22016,
206 20992, 24064, 23040, 17920, 16896, 19968, 18944,
207 30208, 29184, 32256, 31232, 26112, 25088, 28160,
208 27136, 11008, 10496, 12032, 11520, 8960, 8448,
209 9984, 9472, 15104, 14592, 16128, 15616, 13056,
210 12544, 14080, 13568, 344, 328, 376, 360,
211 280, 264, 312, 296, 472, 456, 504,
212 488, 408, 392, 440, 424, 88, 72,
213 120, 104, 24, 8, 56, 40, 216,
214 200, 248, 232, 152, 136, 184, 168,
215 1376, 1312, 1504, 1440, 1120, 1056, 1248,
216 1184, 1888, 1824, 2016, 1952, 1632, 1568,
217 1760, 1696, 688, 656, 752, 720, 560,
218 528, 624, 592, 944, 912, 1008, 976,
219 816, 784, 880, 848
220};
221
222/*
Martin Panter4c359642016-05-08 13:53:41 +0000223 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000224 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000225 * the data shifted such that it only contains information in the lower
226 * 13-bits.
227 *
228 * Linear Input Code Compressed Code
229 * ------------------------ ---------------
230 * 0000000wxyza 000wxyz
231 * 0000001wxyza 001wxyz
232 * 000001wxyzab 010wxyz
233 * 00001wxyzabc 011wxyz
234 * 0001wxyzabcd 100wxyz
235 * 001wxyzabcde 101wxyz
236 * 01wxyzabcdef 110wxyz
237 * 1wxyzabcdefg 111wxyz
238 *
239 * For further information see John C. Bellamy's Digital Telephony, 1982,
240 * John Wiley & Sons, pps 98-111 and 472-476.
241 */
242static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 PyInt16 mask;
246 short seg;
247 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 /* A-law using even bit inversion */
250 if (pcm_val >= 0) {
251 mask = 0xD5; /* sign (7th) bit = 1 */
252 } else {
253 mask = 0x55; /* sign bit = 0 */
254 pcm_val = -pcm_val - 1;
255 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 /* Convert the scaled magnitude to segment number. */
258 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 if (seg >= 8) /* out of range, return maximum value. */
263 return (unsigned char) (0x7F ^ mask);
264 else {
265 aval = (unsigned char) seg << SEG_SHIFT;
266 if (seg < 2)
267 aval |= (pcm_val >> 1) & QUANT_MASK;
268 else
269 aval |= (pcm_val >> seg) & QUANT_MASK;
270 return (aval ^ mask);
271 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000272}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000273/* End of code taken from sox */
274
Guido van Rossumb64e6351992-07-06 14:21:56 +0000275/* Intel ADPCM step variation table */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200276static const int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 -1, -1, -1, -1, 2, 4, 6, 8,
278 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000279};
280
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200281static const int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
283 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
284 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
285 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
286 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
287 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
288 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
289 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
290 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000291};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292
Serhiy Storchaka23a78272013-11-11 07:47:35 +0200293#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
294#define SETINTX(T, cp, i, val) do { \
295 *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300296 } while (0)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000297
298
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300299#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
300#define GETINT16(cp, i) GETINTX(short, (cp), (i))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700301#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i))
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300302
303#if WORDS_BIGENDIAN
304#define GETINT24(cp, i) ( \
305 ((unsigned char *)(cp) + (i))[2] + \
306 (((unsigned char *)(cp) + (i))[1] << 8) + \
307 (((signed char *)(cp) + (i))[0] << 16) )
308#else
309#define GETINT24(cp, i) ( \
310 ((unsigned char *)(cp) + (i))[0] + \
311 (((unsigned char *)(cp) + (i))[1] << 8) + \
312 (((signed char *)(cp) + (i))[2] << 16) )
313#endif
314
315
316#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
317#define SETINT16(cp, i, val) SETINTX(short, (cp), (i), (val))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700318#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val))
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300319
320#if WORDS_BIGENDIAN
321#define SETINT24(cp, i, val) do { \
322 ((unsigned char *)(cp) + (i))[2] = (int)(val); \
323 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
324 ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
325 } while (0)
326#else
327#define SETINT24(cp, i, val) do { \
328 ((unsigned char *)(cp) + (i))[0] = (int)(val); \
329 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
330 ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
331 } while (0)
332#endif
333
334
335#define GETRAWSAMPLE(size, cp, i) ( \
336 (size == 1) ? (int)GETINT8((cp), (i)) : \
337 (size == 2) ? (int)GETINT16((cp), (i)) : \
338 (size == 3) ? (int)GETINT24((cp), (i)) : \
339 (int)GETINT32((cp), (i)))
340
341#define SETRAWSAMPLE(size, cp, i, val) do { \
342 if (size == 1) \
343 SETINT8((cp), (i), (val)); \
344 else if (size == 2) \
345 SETINT16((cp), (i), (val)); \
346 else if (size == 3) \
347 SETINT24((cp), (i), (val)); \
348 else \
349 SETINT32((cp), (i), (val)); \
350 } while(0)
351
352
353#define GETSAMPLE32(size, cp, i) ( \
354 (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
355 (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
356 (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \
357 (int)GETINT32((cp), (i)))
358
359#define SETSAMPLE32(size, cp, i, val) do { \
360 if (size == 1) \
361 SETINT8((cp), (i), (val) >> 24); \
362 else if (size == 2) \
363 SETINT16((cp), (i), (val) >> 16); \
364 else if (size == 3) \
365 SETINT24((cp), (i), (val) >> 8); \
366 else \
367 SETINT32((cp), (i), (val)); \
368 } while(0)
369
Guido van Rossumb66efa01992-06-01 16:01:24 +0000370
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000371static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000372
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000373static int
374audioop_check_size(int size)
375{
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300376 if (size < 1 || size > 4) {
377 PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000378 return 0;
379 }
380 else
381 return 1;
382}
383
384static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000385audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000386{
387 if (!audioop_check_size(size))
388 return 0;
389 if (len % size != 0) {
390 PyErr_SetString(AudioopError, "not a whole number of frames");
391 return 0;
392 }
393 return 1;
394}
395
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200396/*[clinic input]
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200397module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200398[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300399/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200400
401/*[clinic input]
402audioop.getsample
403
404 fragment: Py_buffer
405 width: int
406 index: Py_ssize_t
407 /
408
409Return the value of sample index from the fragment.
410[clinic start generated code]*/
411
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300413audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400414 Py_ssize_t index)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300415/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000416{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200417 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000418
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200419 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000420 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200421 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200423 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200425 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200426 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000427}
428
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200429/*[clinic input]
430audioop.max
431
432 fragment: Py_buffer
433 width: int
434 /
435
436Return the maximum of the absolute value of all samples in a fragment.
437[clinic start generated code]*/
438
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000439static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300440audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
441/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000442{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200443 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200444 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000445
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200446 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000447 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200448 for (i = 0; i < fragment->len; i += width) {
449 int val = GETRAWSAMPLE(width, fragment->buf, i);
Martin Panter6fb90902016-07-19 03:05:42 +0000450 /* Cast to unsigned before negating. Unsigned overflow is well-
451 defined, but signed overflow is not. */
Steve Dowera4391912016-09-06 19:09:15 -0700452 if (val < 0) absval = (unsigned int)-(int64_t)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200453 else absval = val;
454 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200456 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000457}
458
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200459/*[clinic input]
460audioop.minmax
461
462 fragment: Py_buffer
463 width: int
464 /
465
466Return the minimum and maximum values of all samples in the sound fragment.
467[clinic start generated code]*/
468
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300470audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
471/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000472{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200473 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000474 /* -1 trick below is needed on Windows to support -0x80000000 without
475 a warning */
476 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000477
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200478 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200480 for (i = 0; i < fragment->len; i += width) {
481 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 if (val > max) max = val;
483 if (val < min) min = val;
484 }
485 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000486}
487
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200488/*[clinic input]
489audioop.avg
490
491 fragment: Py_buffer
492 width: int
493 /
494
495Return the average over all samples in the fragment.
496[clinic start generated code]*/
497
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300499audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
500/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000501{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200502 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200503 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300504 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000505
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200506 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000507 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200508 for (i = 0; i < fragment->len; i += width)
509 sum += GETRAWSAMPLE(width, fragment->buf, i);
510 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300511 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200513 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300514 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000515}
516
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200517/*[clinic input]
518audioop.rms
519
520 fragment: Py_buffer
521 width: int
522 /
523
524Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
525[clinic start generated code]*/
526
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300528audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
529/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000530{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200531 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200532 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000534
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200535 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000536 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200537 for (i = 0; i < fragment->len; i += width) {
538 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300539 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200541 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200542 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200544 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200545 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000546}
547
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200548static double _sum2(const short *a, const short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000549{
Mark Dickinson81fece22010-05-11 13:34:35 +0000550 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 for( i=0; i<len; i++) {
554 sum = sum + (double)a[i]*(double)b[i];
555 }
556 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000557}
558
559/*
560** Findfit tries to locate a sample within another sample. Its main use
561** is in echo-cancellation (to find the feedback of the output signal in
562** the input signal).
563** The method used is as follows:
564**
565** let R be the reference signal (length n) and A the input signal (length N)
566** with N > n, and let all sums be over i from 0 to n-1.
567**
568** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
569** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
570** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
571**
572** Next, we compute the relative distance between the original signal and
573** the modified signal and minimize that over j:
574** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
575** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
576**
577** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000578** cp1 A
579** cp2 R
580** len1 N
581** len2 n
582** aj_m1 A[j-1]
583** aj_lm1 A[j+n-1]
584** sum_ri_2 sum(R[i]^2)
585** sum_aij_2 sum(A[i+j]^2)
586** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000587**
588** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
589** is completely recalculated each step.
590*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200591/*[clinic input]
592audioop.findfit
593
594 fragment: Py_buffer
595 reference: Py_buffer
596 /
597
598Try to match reference as well as possible to a portion of fragment.
599[clinic start generated code]*/
600
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300602audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400603 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300604/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000605{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200606 const short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000607 Py_ssize_t len1, len2;
608 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 double aj_m1, aj_lm1;
610 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000611
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200612 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200614 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200616 cp1 = (const short *)fragment->buf;
617 len1 = fragment->len >> 1;
618 cp2 = (const short *)reference->buf;
619 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000620
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200621 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200623 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 }
625 sum_ri_2 = _sum2(cp2, cp2, len2);
626 sum_aij_2 = _sum2(cp1, cp1, len2);
627 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 best_result = result;
632 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 for ( j=1; j<=len1-len2; j++) {
635 aj_m1 = (double)cp1[j-1];
636 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
639 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
642 / sum_aij_2;
643
644 if ( result < best_result ) {
645 best_result = result;
646 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000647 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 }
650
651 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
652
Mark Dickinson81fece22010-05-11 13:34:35 +0000653 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000654}
655
656/*
657** findfactor finds a factor f so that the energy in A-fB is minimal.
658** See the comment for findfit for details.
659*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200660/*[clinic input]
661audioop.findfactor
662
663 fragment: Py_buffer
664 reference: Py_buffer
665 /
666
667Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
668[clinic start generated code]*/
669
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300671audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400672 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300673/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000674{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200675 const short *cp1, *cp2;
676 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000678
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200679 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200681 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200683 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200685 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200687 cp1 = (const short *)fragment->buf;
688 cp2 = (const short *)reference->buf;
689 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200690 sum_ri_2 = _sum2(cp2, cp2, len);
691 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000696}
697
698/*
699** findmax returns the index of the n-sized segment of the input sample
700** that contains the most energy.
701*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200702/*[clinic input]
703audioop.findmax
704
705 fragment: Py_buffer
706 length: Py_ssize_t
707 /
708
709Search fragment for a slice of specified number of samples with maximum energy.
710[clinic start generated code]*/
711
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300713audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400714 Py_ssize_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300715/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000716{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200717 const short *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200718 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000719 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 double aj_m1, aj_lm1;
721 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000722
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200723 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200725 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200727 cp1 = (const short *)fragment->buf;
728 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200730 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200732 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 }
734
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200735 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736
737 best_result = result;
738 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200740 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200742 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743
744 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
745
746 if ( result > best_result ) {
747 best_result = result;
748 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000749 }
Jack Jansena90805f1993-02-17 14:29:28 +0000750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000752
Mark Dickinson81fece22010-05-11 13:34:35 +0000753 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000754}
755
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200756/*[clinic input]
757audioop.avgpp
758
759 fragment: Py_buffer
760 width: int
761 /
762
763Return the average peak-peak value over all samples in the fragment.
764[clinic start generated code]*/
765
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300767audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
768/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000769{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200770 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200771 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200772 double sum = 0.0;
773 unsigned int avg;
774 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000775
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200776 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000777 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200778 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200779 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200780 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200781 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200782 for (i = width; i < fragment->len; i += width) {
783 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200784 if (val != prevval) {
785 diff = val < prevval;
786 if (prevdiff == !diff) {
787 /* Derivative changed sign. Compute difference to last
788 ** extreme value and remember.
789 */
790 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300791 if (prevval < prevextreme)
792 sum += (double)((unsigned int)prevextreme -
793 (unsigned int)prevval);
794 else
795 sum += (double)((unsigned int)prevval -
796 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200797 nextreme++;
798 }
799 prevextremevalid = 1;
800 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200802 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200804 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 }
806 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200807 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200809 avg = (unsigned int)(sum / (double)nextreme);
810 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000811}
812
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200813/*[clinic input]
814audioop.maxpp
815
816 fragment: Py_buffer
817 width: int
818 /
819
820Return the maximum peak-peak value in the sound fragment.
821[clinic start generated code]*/
822
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000823static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300824audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
825/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000826{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200827 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200828 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200829 unsigned int max = 0, extremediff;
830 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000831
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200832 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000833 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200834 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200835 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200836 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200837 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200838 for (i = width; i < fragment->len; i += width) {
839 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200840 if (val != prevval) {
841 diff = val < prevval;
842 if (prevdiff == !diff) {
843 /* Derivative changed sign. Compute difference to
844 ** last extreme value and remember.
845 */
846 if (prevextremevalid) {
847 if (prevval < prevextreme)
848 extremediff = (unsigned int)prevextreme -
849 (unsigned int)prevval;
850 else
851 extremediff = (unsigned int)prevval -
852 (unsigned int)prevextreme;
853 if ( extremediff > max )
854 max = extremediff;
855 }
856 prevextremevalid = 1;
857 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200859 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200861 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200863 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000864}
865
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200866/*[clinic input]
867audioop.cross
868
869 fragment: Py_buffer
870 width: int
871 /
872
873Return the number of zero crossings in the fragment passed as an argument.
874[clinic start generated code]*/
875
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300877audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
878/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000879{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200880 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000881 int prevval;
882 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200884 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000885 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 ncross = -1;
887 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200888 for (i = 0; i < fragment->len; i += width) {
889 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300890 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 prevval = val;
892 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000893 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000894}
895
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200896/*[clinic input]
897audioop.mul
898
899 fragment: Py_buffer
900 width: int
901 factor: double
902 /
903
904Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
905[clinic start generated code]*/
906
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300908audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400909 double factor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300910/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000911{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200912 signed char *ncp;
913 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200914 double maxval, minval;
915 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000916
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200917 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000918 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200920 maxval = (double) maxvals[width];
921 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200923 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200924 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200925 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 ncp = (signed char *)PyBytes_AsString(rv);
927
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200928 for (i = 0; i < fragment->len; i += width) {
929 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300930 val *= factor;
931 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200932 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 }
934 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000935}
936
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200937/*[clinic input]
938audioop.tomono
939
940 fragment: Py_buffer
941 width: int
942 lfactor: double
943 rfactor: double
944 /
945
946Convert a stereo fragment to a mono fragment.
947[clinic start generated code]*/
948
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300950audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400951 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300952/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000955 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200956 double maxval, minval;
957 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000958
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200959 cp = fragment->buf;
960 len = fragment->len;
961 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200962 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200963 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000964 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200965 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000966 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200968 maxval = (double) maxvals[width];
969 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970
971 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200972 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200973 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 ncp = (signed char *)PyBytes_AsString(rv);
975
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200976 for (i = 0; i < len; i += width*2) {
977 double val1 = GETRAWSAMPLE(width, cp, i);
978 double val2 = GETRAWSAMPLE(width, cp, i + width);
979 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300980 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200981 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000984}
985
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200986/*[clinic input]
987audioop.tostereo
988
989 fragment: Py_buffer
990 width: int
991 lfactor: double
992 rfactor: double
993 /
994
995Generate a stereo fragment from a mono fragment.
996[clinic start generated code]*/
997
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000998static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300999audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001000 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001001/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001002{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001003 signed char *ncp;
1004 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001005 double maxval, minval;
1006 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001007
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001008 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001009 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001010
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001011 maxval = (double) maxvals[width];
1012 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001013
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001014 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 PyErr_SetString(PyExc_MemoryError,
1016 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001017 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001019
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001020 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001021 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001022 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001024
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001025 for (i = 0; i < fragment->len; i += width) {
1026 double val = GETRAWSAMPLE(width, fragment->buf, i);
1027 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1028 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1029 SETRAWSAMPLE(width, ncp, i*2, val1);
1030 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 }
1032 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001033}
1034
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001035/*[clinic input]
1036audioop.add
1037
1038 fragment1: Py_buffer
1039 fragment2: Py_buffer
1040 width: int
1041 /
1042
1043Return a fragment which is the addition of the two samples passed as parameters.
1044[clinic start generated code]*/
1045
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001047audioop_add_impl(PyObject *module, Py_buffer *fragment1,
Larry Hastings89964c42015-04-14 18:07:59 -04001048 Py_buffer *fragment2, int width)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001049/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001050{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001051 signed char *ncp;
1052 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001053 int minval, maxval, newval;
1054 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001055
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001056 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001057 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001058 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001060 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001062
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001063 maxval = maxvals[width];
1064 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001065
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001066 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001067 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001068 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001070
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001071 for (i = 0; i < fragment1->len; i += width) {
1072 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1073 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001075 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001076 newval = val1 + val2;
1077 /* truncate in case of overflow */
1078 if (newval > maxval)
1079 newval = maxval;
1080 else if (newval < minval)
1081 newval = minval;
1082 }
1083 else {
1084 double fval = (double)val1 + (double)val2;
1085 /* truncate in case of overflow */
1086 newval = (int)floor(fbound(fval, minval, maxval));
1087 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001089 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 }
1091 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001092}
1093
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001094/*[clinic input]
1095audioop.bias
1096
1097 fragment: Py_buffer
1098 width: int
1099 bias: int
1100 /
1101
1102Return a fragment that is the original fragment with a bias added to each sample.
1103[clinic start generated code]*/
1104
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001105static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001106audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
1107/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001108{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001109 signed char *ncp;
1110 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001111 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001112 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001113
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001114 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001115 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001117 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001118 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001119 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 ncp = (signed char *)PyBytes_AsString(rv);
1121
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001122 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001124 for (i = 0; i < fragment->len; i += width) {
1125 if (width == 1)
1126 val = GETINTX(unsigned char, fragment->buf, i);
1127 else if (width == 2)
1128 val = GETINTX(unsigned short, fragment->buf, i);
1129 else if (width == 3)
1130 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001131 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001132 assert(width == 4);
Benjamin Peterson9b3d7702016-09-06 13:24:00 -07001133 val = GETINTX(uint32_t, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001134 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001136 val += (unsigned int)bias;
1137 /* wrap around in case of overflow */
1138 val &= mask;
1139
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001140 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001141 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001142 else if (width == 2)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001143 SETINTX(unsigned short, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001144 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001145 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001146 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001147 assert(width == 4);
Benjamin Peterson9b3d7702016-09-06 13:24:00 -07001148 SETINTX(uint32_t, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001149 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 }
1151 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001152}
1153
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001154/*[clinic input]
1155audioop.reverse
1156
1157 fragment: Py_buffer
1158 width: int
1159 /
1160
1161Reverse the samples in a fragment and returns the modified fragment.
1162[clinic start generated code]*/
1163
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001164static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001165audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
1166/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001169 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001170 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001171
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001172 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001173 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001174
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001175 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001176 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001177 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 ncp = (unsigned char *)PyBytes_AsString(rv);
1179
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001180 for (i = 0; i < fragment->len; i += width) {
1181 int val = GETRAWSAMPLE(width, fragment->buf, i);
1182 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 }
1184 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001185}
1186
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001187/*[clinic input]
1188audioop.byteswap
1189
1190 fragment: Py_buffer
1191 width: int
1192 /
1193
1194Convert big-endian samples to little-endian and vice versa.
1195[clinic start generated code]*/
1196
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001198audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
1199/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001200{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001201 unsigned char *ncp;
1202 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001203 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001204
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001205 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001206 return NULL;
1207
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001208 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001209 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001210 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001211 ncp = (unsigned char *)PyBytes_AsString(rv);
1212
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001213 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001214 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001215 for (j = 0; j < width; j++)
1216 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001217 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001218 return rv;
1219}
1220
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001221/*[clinic input]
1222audioop.lin2lin
1223
1224 fragment: Py_buffer
1225 width: int
1226 newwidth: int
1227 /
1228
1229Convert samples between 1-, 2-, 3- and 4-byte formats.
1230[clinic start generated code]*/
1231
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001233audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001234 int newwidth)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001235/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001238 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001239 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001240
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001241 if (!audioop_check_parameters(fragment->len, width))
1242 return NULL;
1243 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001244 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001245
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001246 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 PyErr_SetString(PyExc_MemoryError,
1248 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001249 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001251 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001252 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001253 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 ncp = (unsigned char *)PyBytes_AsString(rv);
1255
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001256 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1257 int val = GETSAMPLE32(width, fragment->buf, i);
1258 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 }
1260 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001261}
1262
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001263static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001264gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 while (b > 0) {
1267 int tmp = a % b;
1268 a = b;
1269 b = tmp;
1270 }
1271 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001272}
1273
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001274/*[clinic input]
1275audioop.ratecv
1276
1277 fragment: Py_buffer
1278 width: int
1279 nchannels: int
1280 inrate: int
1281 outrate: int
1282 state: object
1283 weightA: int = 1
1284 weightB: int = 0
1285 /
1286
1287Convert the frame rate of the input fragment.
1288[clinic start generated code]*/
1289
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001291audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001292 int nchannels, int inrate, int outrate, PyObject *state,
1293 int weightA, int weightB)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001294/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001297 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001299 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001301
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001302 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 if (nchannels < 1) {
1305 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001306 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001308 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 /* This overflow test is rigorously correct because
1310 both multiplicands are >= 1. Use the argument names
1311 from the docs for the error msg. */
1312 PyErr_SetString(PyExc_OverflowError,
1313 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001314 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001316 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 if (weightA < 1 || weightB < 0) {
1318 PyErr_SetString(AudioopError,
1319 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001320 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001322 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001323 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001325 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 }
1327 if (inrate <= 0 || outrate <= 0) {
1328 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001329 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 }
1331 /* divide inrate and outrate by their greatest common divisor */
1332 d = gcd(inrate, outrate);
1333 inrate /= d;
1334 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001335 /* divide weightA and weightB by their greatest common divisor */
1336 d = gcd(weightA, weightB);
1337 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001338 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001339
Benjamin Peterson2f8bfef2016-09-07 09:26:18 -07001340 if ((size_t)nchannels > SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 PyErr_SetString(PyExc_MemoryError,
1342 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001343 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001345 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1346 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 if (prev_i == NULL || cur_i == NULL) {
1348 (void) PyErr_NoMemory();
1349 goto exit;
1350 }
1351
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001352 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353
1354 if (state == Py_None) {
1355 d = -outrate;
1356 for (chan = 0; chan < nchannels; chan++)
1357 prev_i[chan] = cur_i[chan] = 0;
1358 }
1359 else {
1360 if (!PyArg_ParseTuple(state,
1361 "iO!;audioop.ratecv: illegal state argument",
1362 &d, &PyTuple_Type, &samps))
1363 goto exit;
1364 if (PyTuple_Size(samps) != nchannels) {
1365 PyErr_SetString(AudioopError,
1366 "illegal state argument");
1367 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001368 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 for (chan = 0; chan < nchannels; chan++) {
1370 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1371 "ii:ratecv", &prev_i[chan],
1372 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001373 goto exit;
1374 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001378 if (len == 0)
1379 str = PyBytes_FromStringAndSize(NULL, 0);
1380 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 /* There are len input frames, so we need (mathematically)
1382 ceiling(len*outrate/inrate) output frames, and each frame
1383 requires bytes_per_frame bytes. Computing this
1384 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001385 settle for a reasonable upper bound, though, in this
1386 case ceiling(len/inrate) * outrate. */
1387
1388 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001389 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001390 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 str = NULL;
1392 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001393 str = PyBytes_FromStringAndSize(NULL,
1394 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001395 }
1396 if (str == NULL) {
1397 PyErr_SetString(PyExc_MemoryError,
1398 "not enough memory for output buffer");
1399 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 }
1401 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001402 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403
1404 for (;;) {
1405 while (d < 0) {
1406 if (len == 0) {
1407 samps = PyTuple_New(nchannels);
1408 if (samps == NULL)
1409 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001410 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 PyTuple_SetItem(samps, chan,
1412 Py_BuildValue("(ii)",
1413 prev_i[chan],
1414 cur_i[chan]));
1415 if (PyErr_Occurred())
1416 goto exit;
1417 /* We have checked before that the length
1418 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001419 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 rv = PyBytes_FromStringAndSize
1421 (PyBytes_AsString(str), len);
1422 Py_DECREF(str);
1423 str = rv;
1424 if (str == NULL)
1425 goto exit;
1426 rv = Py_BuildValue("(O(iO))", str, d, samps);
1427 Py_DECREF(samps);
1428 Py_DECREF(str);
1429 goto exit; /* return rv */
1430 }
1431 for (chan = 0; chan < nchannels; chan++) {
1432 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001433 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1434 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001436 cur_i[chan] = (int)(
1437 ((double)weightA * (double)cur_i[chan] +
1438 (double)weightB * (double)prev_i[chan]) /
1439 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 }
1441 len--;
1442 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001443 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 while (d >= 0) {
1445 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001446 cur_o = (int)(((double)prev_i[chan] * (double)d +
1447 (double)cur_i[chan] * (double)(outrate - d)) /
1448 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001449 SETSAMPLE32(width, ncp, 0, cur_o);
1450 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 }
1452 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001453 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001455 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001456 PyMem_Free(prev_i);
1457 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001459}
Guido van Rossum1851a671997-02-14 16:14:03 +00001460
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001461/*[clinic input]
1462audioop.lin2ulaw
1463
1464 fragment: Py_buffer
1465 width: int
1466 /
1467
1468Convert samples in the audio fragment to u-LAW encoding.
1469[clinic start generated code]*/
1470
Roger E. Massec905fff1997-01-17 18:12:04 +00001471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001472audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1473/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001476 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001477 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001478
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001479 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001480 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001481
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001482 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001483 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001484 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 ncp = (unsigned char *)PyBytes_AsString(rv);
1486
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001487 for (i = 0; i < fragment->len; i += width) {
1488 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001489 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 }
1491 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001492}
1493
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001494/*[clinic input]
1495audioop.ulaw2lin
1496
1497 fragment: Py_buffer
1498 width: int
1499 /
1500
1501Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1502[clinic start generated code]*/
1503
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001505audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1506/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001507{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001510 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001511 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001512
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001513 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001514 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001516 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 PyErr_SetString(PyExc_MemoryError,
1518 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001519 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001521 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001522 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001523 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 ncp = (signed char *)PyBytes_AsString(rv);
1525
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001526 cp = fragment->buf;
1527 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001528 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001529 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 }
1531 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001532}
1533
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001534/*[clinic input]
1535audioop.lin2alaw
1536
1537 fragment: Py_buffer
1538 width: int
1539 /
1540
1541Convert samples in the audio fragment to a-LAW encoding.
1542[clinic start generated code]*/
1543
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001544static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001545audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1546/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001549 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001550 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001551
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001552 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001553 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001554
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001555 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001556 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001557 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 ncp = (unsigned char *)PyBytes_AsString(rv);
1559
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001560 for (i = 0; i < fragment->len; i += width) {
1561 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001562 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 }
1564 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001565}
1566
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001567/*[clinic input]
1568audioop.alaw2lin
1569
1570 fragment: Py_buffer
1571 width: int
1572 /
1573
1574Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1575[clinic start generated code]*/
1576
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001577static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001578audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1579/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001580{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001583 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001584 int val;
1585 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001586
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001587 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001588 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001590 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 PyErr_SetString(PyExc_MemoryError,
1592 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001593 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001595 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001596 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001597 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001599 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001601 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001602 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001603 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 }
1605 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001606}
1607
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001608/*[clinic input]
1609audioop.lin2adpcm
1610
1611 fragment: Py_buffer
1612 width: int
1613 state: object
1614 /
1615
1616Convert samples to 4 bit Intel/DVI ADPCM encoding.
1617[clinic start generated code]*/
1618
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001619static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001620audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001621 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001622/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001625 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001626 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001628 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001629 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001630
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001631 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001632 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 /* Decode state, should have (value, step) */
1635 if ( state == Py_None ) {
1636 /* First time, it seems. Set defaults */
1637 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001639 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001640 else if (!PyTuple_Check(state)) {
1641 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1642 return NULL;
1643 }
1644 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1645 return NULL;
1646 }
1647 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1648 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1649 PyErr_SetString(PyExc_ValueError, "bad state");
1650 return NULL;
1651 }
1652
1653 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1654 if (str == NULL)
1655 return NULL;
1656 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657
1658 step = stepsizeTable[index];
1659 bufferstep = 1;
1660
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001661 for (i = 0; i < fragment->len; i += width) {
1662 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663
1664 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001665 if (val < valpred) {
1666 diff = valpred - val;
1667 sign = 8;
1668 }
1669 else {
1670 diff = val - valpred;
1671 sign = 0;
1672 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673
1674 /* Step 2 - Divide and clamp */
1675 /* Note:
1676 ** This code *approximately* computes:
1677 ** delta = diff*4/step;
1678 ** vpdiff = (delta+0.5)*step/4;
1679 ** but in shift step bits are dropped. The net result of this
1680 ** is that even if you have fast mul/div hardware you cannot
1681 ** put it to good use since the fixup would be too expensive.
1682 */
1683 delta = 0;
1684 vpdiff = (step >> 3);
1685
1686 if ( diff >= step ) {
1687 delta = 4;
1688 diff -= step;
1689 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001690 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 step >>= 1;
1692 if ( diff >= step ) {
1693 delta |= 2;
1694 diff -= step;
1695 vpdiff += step;
1696 }
1697 step >>= 1;
1698 if ( diff >= step ) {
1699 delta |= 1;
1700 vpdiff += step;
1701 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 /* Step 3 - Update previous value */
1704 if ( sign )
1705 valpred -= vpdiff;
1706 else
1707 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001709 /* Step 4 - Clamp previous value to 16 bits */
1710 if ( valpred > 32767 )
1711 valpred = 32767;
1712 else if ( valpred < -32768 )
1713 valpred = -32768;
1714
1715 /* Step 5 - Assemble value, update index and step values */
1716 delta |= sign;
1717
1718 index += indexTable[delta];
1719 if ( index < 0 ) index = 0;
1720 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001721 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 /* Step 6 - Output value */
1724 if ( bufferstep ) {
1725 outputbuffer = (delta << 4) & 0xf0;
1726 } else {
1727 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001728 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 bufferstep = !bufferstep;
1730 }
1731 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001732 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001734}
1735
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001736/*[clinic input]
1737audioop.adpcm2lin
1738
1739 fragment: Py_buffer
1740 width: int
1741 state: object
1742 /
1743
1744Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1745[clinic start generated code]*/
1746
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001748audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001749 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001750/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 signed char *cp;
1753 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001754 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001755 int valpred, step, delta, index, sign, vpdiff;
1756 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001757 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001758
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001759 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001760 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 /* Decode state, should have (value, step) */
1763 if ( state == Py_None ) {
1764 /* First time, it seems. Set defaults */
1765 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001767 }
1768 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001769 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001770 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001771 }
1772 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001773 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001774 }
1775 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1776 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1777 PyErr_SetString(PyExc_ValueError, "bad state");
1778 return NULL;
1779 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001781 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 PyErr_SetString(PyExc_MemoryError,
1783 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001784 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001786 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001787 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001788 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001789 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001791 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792
1793 step = stepsizeTable[index];
1794 bufferstep = 0;
1795
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001796 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 /* Step 1 - get the delta value and compute next index */
1798 if ( bufferstep ) {
1799 delta = inputbuffer & 0xf;
1800 } else {
1801 inputbuffer = *cp++;
1802 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001803 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 bufferstep = !bufferstep;
1806
1807 /* Step 2 - Find new index value (for later) */
1808 index += indexTable[delta];
1809 if ( index < 0 ) index = 0;
1810 if ( index > 88 ) index = 88;
1811
1812 /* Step 3 - Separate sign and magnitude */
1813 sign = delta & 8;
1814 delta = delta & 7;
1815
1816 /* Step 4 - Compute difference and new predicted value */
1817 /*
1818 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1819 ** in adpcm_coder.
1820 */
1821 vpdiff = step >> 3;
1822 if ( delta & 4 ) vpdiff += step;
1823 if ( delta & 2 ) vpdiff += step>>1;
1824 if ( delta & 1 ) vpdiff += step>>2;
1825
1826 if ( sign )
1827 valpred -= vpdiff;
1828 else
1829 valpred += vpdiff;
1830
1831 /* Step 5 - clamp output value */
1832 if ( valpred > 32767 )
1833 valpred = 32767;
1834 else if ( valpred < -32768 )
1835 valpred = -32768;
1836
1837 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001838 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001841 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1845 Py_DECREF(str);
1846 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001847}
1848
Larry Hastingsf256c222014-01-25 21:30:37 -08001849#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001850
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001851static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001852 AUDIOOP_MAX_METHODDEF
1853 AUDIOOP_MINMAX_METHODDEF
1854 AUDIOOP_AVG_METHODDEF
1855 AUDIOOP_MAXPP_METHODDEF
1856 AUDIOOP_AVGPP_METHODDEF
1857 AUDIOOP_RMS_METHODDEF
1858 AUDIOOP_FINDFIT_METHODDEF
1859 AUDIOOP_FINDMAX_METHODDEF
1860 AUDIOOP_FINDFACTOR_METHODDEF
1861 AUDIOOP_CROSS_METHODDEF
1862 AUDIOOP_MUL_METHODDEF
1863 AUDIOOP_ADD_METHODDEF
1864 AUDIOOP_BIAS_METHODDEF
1865 AUDIOOP_ULAW2LIN_METHODDEF
1866 AUDIOOP_LIN2ULAW_METHODDEF
1867 AUDIOOP_ALAW2LIN_METHODDEF
1868 AUDIOOP_LIN2ALAW_METHODDEF
1869 AUDIOOP_LIN2LIN_METHODDEF
1870 AUDIOOP_ADPCM2LIN_METHODDEF
1871 AUDIOOP_LIN2ADPCM_METHODDEF
1872 AUDIOOP_TOMONO_METHODDEF
1873 AUDIOOP_TOSTEREO_METHODDEF
1874 AUDIOOP_GETSAMPLE_METHODDEF
1875 AUDIOOP_REVERSE_METHODDEF
1876 AUDIOOP_BYTESWAP_METHODDEF
1877 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001879};
1880
Martin v. Löwis1a214512008-06-11 05:26:20 +00001881
1882static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 PyModuleDef_HEAD_INIT,
1884 "audioop",
1885 NULL,
1886 -1,
1887 audioop_methods,
1888 NULL,
1889 NULL,
1890 NULL,
1891 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001892};
1893
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001894PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001895PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 PyObject *m, *d;
1898 m = PyModule_Create(&audioopmodule);
1899 if (m == NULL)
1900 return NULL;
1901 d = PyModule_GetDict(m);
1902 if (d == NULL)
1903 return NULL;
1904 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1905 if (AudioopError != NULL)
1906 PyDict_SetItemString(d,"error",AudioopError);
1907 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001908}