blob: dcd7788d6218620295b99ce9f3ff64c946f00f0b [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"
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007
Guido van Rossum7b1e9741994-08-29 10:46:42 +00008#if defined(__CHAR_UNSIGNED__)
9#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000010/* This module currently does not work on systems where only unsigned
11 characters are available. Take it out of Setup. Sorry. */
12#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000013#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000014
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020015static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
Tim Goldenfa6ab0f2013-10-31 10:25:47 +000016/* -1 trick is needed on Windows to support -0x80000000 without a warning */
17static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020018static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
19
20static int
21fbound(double val, double minval, double maxval)
22{
23 if (val > maxval)
24 val = maxval;
25 else if (val < minval + 1)
26 val = minval;
Victor Stinnerf2b9a342013-05-07 23:49:15 +020027 return (int)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020028}
29
30
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000031/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000032** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
33
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034/* From g711.c:
35 *
36 * December 30, 1994:
37 * Functions linear2alaw, linear2ulaw have been updated to correctly
38 * convert unquantized 16 bit values.
39 * Tables for direct u- to A-law and A- to u-law conversions have been
40 * corrected.
41 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
42 * bli@cpk.auc.dk
43 *
44 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000045#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
46#define CLIP 32635
Martin Panter4c359642016-05-08 13:53:41 +000047#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048#define QUANT_MASK (0xf) /* Quantization field mask. */
49#define SEG_SHIFT (4) /* Left shift for segment number. */
50#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000051
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070052static const int16_t seg_aend[8] = {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020053 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
54};
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070055static const int16_t seg_uend[8] = {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020056 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF
57};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000058
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070059static int16_t
60search(int16_t val, const int16_t *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 for (i = 0; i < size; i++) {
65 if (val <= *table++)
66 return (i);
67 }
68 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069}
70#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
71#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000072
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070073static const int16_t _st_ulaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000074 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
75 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
76 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
77 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
78 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
79 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
80 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
81 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
82 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
83 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
84 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
85 -1052, -988, -924, -876, -844, -812, -780,
86 -748, -716, -684, -652, -620, -588, -556,
87 -524, -492, -460, -428, -396, -372, -356,
88 -340, -324, -308, -292, -276, -260, -244,
89 -228, -212, -196, -180, -164, -148, -132,
90 -120, -112, -104, -96, -88, -80, -72,
91 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000093 27004, 25980, 24956, 23932, 22908, 21884, 20860,
94 19836, 18812, 17788, 16764, 15996, 15484, 14972,
95 14460, 13948, 13436, 12924, 12412, 11900, 11388,
96 10876, 10364, 9852, 9340, 8828, 8316, 7932,
97 7676, 7420, 7164, 6908, 6652, 6396, 6140,
98 5884, 5628, 5372, 5116, 4860, 4604, 4348,
99 4092, 3900, 3772, 3644, 3516, 3388, 3260,
100 3132, 3004, 2876, 2748, 2620, 2492, 2364,
101 2236, 2108, 1980, 1884, 1820, 1756, 1692,
102 1628, 1564, 1500, 1436, 1372, 1308, 1244,
103 1180, 1116, 1052, 988, 924, 876, 844,
104 812, 780, 748, 716, 684, 652, 620,
105 588, 556, 524, 492, 460, 428, 396,
106 372, 356, 340, 324, 308, 292, 276,
107 260, 244, 228, 212, 196, 180, 164,
108 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 80, 72, 64, 56, 48, 40, 32,
110 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000111};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000112
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000113/*
114 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000115 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000116 * the data shifted such that it only contains information in the lower
117 * 14-bits.
118 *
119 * In order to simplify the encoding process, the original linear magnitude
120 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
121 * (33 - 8191). The result can be seen in the following encoding table:
122 *
123 * Biased Linear Input Code Compressed Code
124 * ------------------------ ---------------
125 * 00000001wxyza 000wxyz
126 * 0000001wxyzab 001wxyz
127 * 000001wxyzabc 010wxyz
128 * 00001wxyzabcd 011wxyz
129 * 0001wxyzabcde 100wxyz
130 * 001wxyzabcdef 101wxyz
131 * 01wxyzabcdefg 110wxyz
132 * 1wxyzabcdefgh 111wxyz
133 *
134 * Each biased linear code has a leading 1 which identifies the segment
135 * number. The value of the segment number is equal to 7 minus the number
136 * of leading 0's. The quantization interval is directly available as the
137 * four bits wxyz. * The trailing bits (a - h) are ignored.
138 *
139 * Ordinarily the complement of the resulting code word is used for
140 * transmission, and so the code word is complemented before it is returned.
141 *
142 * For further information see John C. Bellamy's Digital Telephony, 1982,
143 * John Wiley & Sons, pps 98-111 and 472-476.
144 */
145static unsigned char
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700146st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000147{
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700148 int16_t mask;
149 int16_t seg;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 /* u-law inverts all bits */
153 /* Get the sign and the magnitude of the value. */
154 if (pcm_val < 0) {
155 pcm_val = -pcm_val;
156 mask = 0x7F;
157 } else {
158 mask = 0xFF;
159 }
160 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
161 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 /* Convert the scaled magnitude to segment number. */
164 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 /*
167 * Combine the sign, segment, quantization bits;
168 * and complement the code word.
169 */
170 if (seg >= 8) /* out of range, return maximum value. */
171 return (unsigned char) (0x7F ^ mask);
172 else {
173 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
174 return (uval ^ mask);
175 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000176
177}
178
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700179static const int16_t _st_alaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000180 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
181 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
182 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
183 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
184 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
185 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
186 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
187 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
188 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
189 -13568, -344, -328, -376, -360, -280, -264,
190 -312, -296, -472, -456, -504, -488, -408,
191 -392, -440, -424, -88, -72, -120, -104,
192 -24, -8, -56, -40, -216, -200, -248,
193 -232, -152, -136, -184, -168, -1376, -1312,
194 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
195 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
196 -688, -656, -752, -720, -560, -528, -624,
197 -592, -944, -912, -1008, -976, -816, -784,
198 -880, -848, 5504, 5248, 6016, 5760, 4480,
199 4224, 4992, 4736, 7552, 7296, 8064, 7808,
200 6528, 6272, 7040, 6784, 2752, 2624, 3008,
201 2880, 2240, 2112, 2496, 2368, 3776, 3648,
202 4032, 3904, 3264, 3136, 3520, 3392, 22016,
203 20992, 24064, 23040, 17920, 16896, 19968, 18944,
204 30208, 29184, 32256, 31232, 26112, 25088, 28160,
205 27136, 11008, 10496, 12032, 11520, 8960, 8448,
206 9984, 9472, 15104, 14592, 16128, 15616, 13056,
207 12544, 14080, 13568, 344, 328, 376, 360,
208 280, 264, 312, 296, 472, 456, 504,
209 488, 408, 392, 440, 424, 88, 72,
210 120, 104, 24, 8, 56, 40, 216,
211 200, 248, 232, 152, 136, 184, 168,
212 1376, 1312, 1504, 1440, 1120, 1056, 1248,
213 1184, 1888, 1824, 2016, 1952, 1632, 1568,
214 1760, 1696, 688, 656, 752, 720, 560,
215 528, 624, 592, 944, 912, 1008, 976,
216 816, 784, 880, 848
217};
218
219/*
Martin Panter4c359642016-05-08 13:53:41 +0000220 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000221 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000222 * the data shifted such that it only contains information in the lower
223 * 13-bits.
224 *
225 * Linear Input Code Compressed Code
226 * ------------------------ ---------------
227 * 0000000wxyza 000wxyz
228 * 0000001wxyza 001wxyz
229 * 000001wxyzab 010wxyz
230 * 00001wxyzabc 011wxyz
231 * 0001wxyzabcd 100wxyz
232 * 001wxyzabcde 101wxyz
233 * 01wxyzabcdef 110wxyz
234 * 1wxyzabcdefg 111wxyz
235 *
236 * For further information see John C. Bellamy's Digital Telephony, 1982,
237 * John Wiley & Sons, pps 98-111 and 472-476.
238 */
239static unsigned char
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700240st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000241{
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700242 int16_t mask;
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300243 int16_t seg;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
252 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200273static const int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200278static const int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289
Serhiy Storchaka23a78272013-11-11 07:47:35 +0200290#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
291#define SETINTX(T, cp, i, val) do { \
292 *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300293 } while (0)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000294
295
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300296#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300297#define GETINT16(cp, i) GETINTX(int16_t, (cp), (i))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700298#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i))
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300299
300#if WORDS_BIGENDIAN
301#define GETINT24(cp, i) ( \
302 ((unsigned char *)(cp) + (i))[2] + \
303 (((unsigned char *)(cp) + (i))[1] << 8) + \
304 (((signed char *)(cp) + (i))[0] << 16) )
305#else
306#define GETINT24(cp, i) ( \
307 ((unsigned char *)(cp) + (i))[0] + \
308 (((unsigned char *)(cp) + (i))[1] << 8) + \
309 (((signed char *)(cp) + (i))[2] << 16) )
310#endif
311
312
313#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300314#define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700315#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val))
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300316
317#if WORDS_BIGENDIAN
318#define SETINT24(cp, i, val) do { \
319 ((unsigned char *)(cp) + (i))[2] = (int)(val); \
320 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
321 ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
322 } while (0)
323#else
324#define SETINT24(cp, i, val) do { \
325 ((unsigned char *)(cp) + (i))[0] = (int)(val); \
326 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
327 ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
328 } while (0)
329#endif
330
331
332#define GETRAWSAMPLE(size, cp, i) ( \
333 (size == 1) ? (int)GETINT8((cp), (i)) : \
334 (size == 2) ? (int)GETINT16((cp), (i)) : \
335 (size == 3) ? (int)GETINT24((cp), (i)) : \
336 (int)GETINT32((cp), (i)))
337
338#define SETRAWSAMPLE(size, cp, i, val) do { \
339 if (size == 1) \
340 SETINT8((cp), (i), (val)); \
341 else if (size == 2) \
342 SETINT16((cp), (i), (val)); \
343 else if (size == 3) \
344 SETINT24((cp), (i), (val)); \
345 else \
346 SETINT32((cp), (i), (val)); \
347 } while(0)
348
349
350#define GETSAMPLE32(size, cp, i) ( \
351 (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
352 (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
353 (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \
354 (int)GETINT32((cp), (i)))
355
356#define SETSAMPLE32(size, cp, i, val) do { \
357 if (size == 1) \
358 SETINT8((cp), (i), (val) >> 24); \
359 else if (size == 2) \
360 SETINT16((cp), (i), (val) >> 16); \
361 else if (size == 3) \
362 SETINT24((cp), (i), (val) >> 8); \
363 else \
364 SETINT32((cp), (i), (val)); \
365 } while(0)
366
Guido van Rossumb66efa01992-06-01 16:01:24 +0000367
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000368static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000369
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000370static int
371audioop_check_size(int size)
372{
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300373 if (size < 1 || size > 4) {
374 PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000375 return 0;
376 }
377 else
378 return 1;
379}
380
381static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000382audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000383{
384 if (!audioop_check_size(size))
385 return 0;
386 if (len % size != 0) {
387 PyErr_SetString(AudioopError, "not a whole number of frames");
388 return 0;
389 }
390 return 1;
391}
392
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200393/*[clinic input]
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200394module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200395[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300396/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200397
398/*[clinic input]
399audioop.getsample
400
401 fragment: Py_buffer
402 width: int
403 index: Py_ssize_t
404 /
405
406Return the value of sample index from the fragment.
407[clinic start generated code]*/
408
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300410audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400411 Py_ssize_t index)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300412/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000413{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200414 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000415
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200416 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000417 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200418 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200420 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200422 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200423 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000424}
425
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200426/*[clinic input]
427audioop.max
428
429 fragment: Py_buffer
430 width: int
431 /
432
433Return the maximum of the absolute value of all samples in a fragment.
434[clinic start generated code]*/
435
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300437audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
438/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000439{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200440 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200441 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000442
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200443 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000444 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200445 for (i = 0; i < fragment->len; i += width) {
446 int val = GETRAWSAMPLE(width, fragment->buf, i);
Martin Panter6fb90902016-07-19 03:05:42 +0000447 /* Cast to unsigned before negating. Unsigned overflow is well-
448 defined, but signed overflow is not. */
Steve Dowera4391912016-09-06 19:09:15 -0700449 if (val < 0) absval = (unsigned int)-(int64_t)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200450 else absval = val;
451 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200453 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000454}
455
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200456/*[clinic input]
457audioop.minmax
458
459 fragment: Py_buffer
460 width: int
461 /
462
463Return the minimum and maximum values of all samples in the sound fragment.
464[clinic start generated code]*/
465
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300467audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
468/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000469{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200470 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000471 /* -1 trick below is needed on Windows to support -0x80000000 without
472 a warning */
473 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000474
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200475 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200477 for (i = 0; i < fragment->len; i += width) {
478 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 if (val > max) max = val;
480 if (val < min) min = val;
481 }
482 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000483}
484
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200485/*[clinic input]
486audioop.avg
487
488 fragment: Py_buffer
489 width: int
490 /
491
492Return the average over all samples in the fragment.
493[clinic start generated code]*/
494
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300496audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
497/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000498{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200499 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200500 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300501 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000502
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200503 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000504 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200505 for (i = 0; i < fragment->len; i += width)
506 sum += GETRAWSAMPLE(width, fragment->buf, i);
507 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300508 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200510 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300511 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000512}
513
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200514/*[clinic input]
515audioop.rms
516
517 fragment: Py_buffer
518 width: int
519 /
520
521Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
522[clinic start generated code]*/
523
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300525audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
526/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000527{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200528 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200529 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000531
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200532 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000533 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200534 for (i = 0; i < fragment->len; i += width) {
535 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300536 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200538 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200539 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200541 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200542 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000543}
544
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300545static double _sum2(const int16_t *a, const int16_t *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000546{
Mark Dickinson81fece22010-05-11 13:34:35 +0000547 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 for( i=0; i<len; i++) {
551 sum = sum + (double)a[i]*(double)b[i];
552 }
553 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000554}
555
556/*
557** Findfit tries to locate a sample within another sample. Its main use
558** is in echo-cancellation (to find the feedback of the output signal in
559** the input signal).
560** The method used is as follows:
561**
562** let R be the reference signal (length n) and A the input signal (length N)
563** with N > n, and let all sums be over i from 0 to n-1.
564**
565** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
566** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
567** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
568**
569** Next, we compute the relative distance between the original signal and
570** the modified signal and minimize that over j:
571** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
572** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
573**
574** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000575** cp1 A
576** cp2 R
577** len1 N
578** len2 n
579** aj_m1 A[j-1]
580** aj_lm1 A[j+n-1]
581** sum_ri_2 sum(R[i]^2)
582** sum_aij_2 sum(A[i+j]^2)
583** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000584**
585** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
586** is completely recalculated each step.
587*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200588/*[clinic input]
589audioop.findfit
590
591 fragment: Py_buffer
592 reference: Py_buffer
593 /
594
595Try to match reference as well as possible to a portion of fragment.
596[clinic start generated code]*/
597
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300599audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400600 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300601/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000602{
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300603 const int16_t *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000604 Py_ssize_t len1, len2;
605 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 double aj_m1, aj_lm1;
607 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000608
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200609 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200611 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 }
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300613 cp1 = (const int16_t *)fragment->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200614 len1 = fragment->len >> 1;
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300615 cp2 = (const int16_t *)reference->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200616 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000617
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200618 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200620 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 }
622 sum_ri_2 = _sum2(cp2, cp2, len2);
623 sum_aij_2 = _sum2(cp1, cp1, len2);
624 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 best_result = result;
629 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 for ( j=1; j<=len1-len2; j++) {
632 aj_m1 = (double)cp1[j-1];
633 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
636 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
639 / sum_aij_2;
640
641 if ( result < best_result ) {
642 best_result = result;
643 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000644 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 }
647
648 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
649
Mark Dickinson81fece22010-05-11 13:34:35 +0000650 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000651}
652
653/*
654** findfactor finds a factor f so that the energy in A-fB is minimal.
655** See the comment for findfit for details.
656*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200657/*[clinic input]
658audioop.findfactor
659
660 fragment: Py_buffer
661 reference: Py_buffer
662 /
663
664Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
665[clinic start generated code]*/
666
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300668audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400669 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300670/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000671{
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300672 const int16_t *cp1, *cp2;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200673 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000675
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200676 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200678 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200680 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200682 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 }
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300684 cp1 = (const int16_t *)fragment->buf;
685 cp2 = (const int16_t *)reference->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200686 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200687 sum_ri_2 = _sum2(cp2, cp2, len);
688 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000693}
694
695/*
696** findmax returns the index of the n-sized segment of the input sample
697** that contains the most energy.
698*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200699/*[clinic input]
700audioop.findmax
701
702 fragment: Py_buffer
703 length: Py_ssize_t
704 /
705
706Search fragment for a slice of specified number of samples with maximum energy.
707[clinic start generated code]*/
708
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300710audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400711 Py_ssize_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300712/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000713{
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300714 const int16_t *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200715 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000716 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 double aj_m1, aj_lm1;
718 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000719
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200720 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200722 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 }
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300724 cp1 = (const int16_t *)fragment->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200725 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200727 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200729 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 }
731
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200732 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733
734 best_result = result;
735 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200737 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200739 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740
741 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
742
743 if ( result > best_result ) {
744 best_result = result;
745 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000746 }
Jack Jansena90805f1993-02-17 14:29:28 +0000747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000749
Mark Dickinson81fece22010-05-11 13:34:35 +0000750 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000751}
752
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200753/*[clinic input]
754audioop.avgpp
755
756 fragment: Py_buffer
757 width: int
758 /
759
760Return the average peak-peak value over all samples in the fragment.
761[clinic start generated code]*/
762
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000763static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300764audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
765/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000766{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200767 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200768 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200769 double sum = 0.0;
770 unsigned int avg;
771 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000772
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200773 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000774 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200775 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200776 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200777 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200778 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200779 for (i = width; i < fragment->len; i += width) {
780 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200781 if (val != prevval) {
782 diff = val < prevval;
783 if (prevdiff == !diff) {
784 /* Derivative changed sign. Compute difference to last
785 ** extreme value and remember.
786 */
787 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300788 if (prevval < prevextreme)
789 sum += (double)((unsigned int)prevextreme -
790 (unsigned int)prevval);
791 else
792 sum += (double)((unsigned int)prevval -
793 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200794 nextreme++;
795 }
796 prevextremevalid = 1;
797 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200799 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200801 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 }
803 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200804 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200806 avg = (unsigned int)(sum / (double)nextreme);
807 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000808}
809
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200810/*[clinic input]
811audioop.maxpp
812
813 fragment: Py_buffer
814 width: int
815 /
816
817Return the maximum peak-peak value in the sound fragment.
818[clinic start generated code]*/
819
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000820static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300821audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
822/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000823{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200824 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200825 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200826 unsigned int max = 0, extremediff;
827 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000828
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200829 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000830 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200831 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200832 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200833 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200834 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200835 for (i = width; i < fragment->len; i += width) {
836 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200837 if (val != prevval) {
838 diff = val < prevval;
839 if (prevdiff == !diff) {
840 /* Derivative changed sign. Compute difference to
841 ** last extreme value and remember.
842 */
843 if (prevextremevalid) {
844 if (prevval < prevextreme)
845 extremediff = (unsigned int)prevextreme -
846 (unsigned int)prevval;
847 else
848 extremediff = (unsigned int)prevval -
849 (unsigned int)prevextreme;
850 if ( extremediff > max )
851 max = extremediff;
852 }
853 prevextremevalid = 1;
854 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200856 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200858 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200860 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000861}
862
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200863/*[clinic input]
864audioop.cross
865
866 fragment: Py_buffer
867 width: int
868 /
869
870Return the number of zero crossings in the fragment passed as an argument.
871[clinic start generated code]*/
872
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300874audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
875/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200877 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000878 int prevval;
879 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200881 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000882 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 ncross = -1;
884 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200885 for (i = 0; i < fragment->len; i += width) {
886 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300887 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 prevval = val;
889 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000890 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000891}
892
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200893/*[clinic input]
894audioop.mul
895
896 fragment: Py_buffer
897 width: int
898 factor: double
899 /
900
901Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
902[clinic start generated code]*/
903
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000904static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300905audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400906 double factor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300907/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000908{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200909 signed char *ncp;
910 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200911 double maxval, minval;
912 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000913
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200914 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000915 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200917 maxval = (double) maxvals[width];
918 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200920 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200921 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200922 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 ncp = (signed char *)PyBytes_AsString(rv);
924
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200925 for (i = 0; i < fragment->len; i += width) {
926 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300927 val *= factor;
928 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200929 SETRAWSAMPLE(width, ncp, i, (int)val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 }
931 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000932}
933
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200934/*[clinic input]
935audioop.tomono
936
937 fragment: Py_buffer
938 width: int
939 lfactor: double
940 rfactor: double
941 /
942
943Convert a stereo fragment to a mono fragment.
944[clinic start generated code]*/
945
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300947audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400948 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300949/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000952 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200953 double maxval, minval;
954 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000955
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200956 cp = fragment->buf;
957 len = fragment->len;
958 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200959 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200960 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000961 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200962 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000963 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200965 maxval = (double) maxvals[width];
966 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967
968 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200969 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200970 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 ncp = (signed char *)PyBytes_AsString(rv);
972
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200973 for (i = 0; i < len; i += width*2) {
974 double val1 = GETRAWSAMPLE(width, cp, i);
975 double val2 = GETRAWSAMPLE(width, cp, i + width);
976 double val = val1*lfactor + val2*rfactor;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300977 val = floor(fbound(val, minval, maxval));
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200978 SETRAWSAMPLE(width, ncp, i/2, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000981}
982
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200983/*[clinic input]
984audioop.tostereo
985
986 fragment: Py_buffer
987 width: int
988 lfactor: double
989 rfactor: double
990 /
991
992Generate a stereo fragment from a mono fragment.
993[clinic start generated code]*/
994
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300996audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400997 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300998/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000999{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001000 signed char *ncp;
1001 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001002 double maxval, minval;
1003 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001004
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001005 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001006 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001007
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001008 maxval = (double) maxvals[width];
1009 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001010
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001011 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 PyErr_SetString(PyExc_MemoryError,
1013 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001014 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001016
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001017 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001018 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001019 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001021
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001022 for (i = 0; i < fragment->len; i += width) {
1023 double val = GETRAWSAMPLE(width, fragment->buf, i);
1024 int val1 = (int)floor(fbound(val*lfactor, minval, maxval));
1025 int val2 = (int)floor(fbound(val*rfactor, minval, maxval));
1026 SETRAWSAMPLE(width, ncp, i*2, val1);
1027 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 }
1029 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001030}
1031
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001032/*[clinic input]
1033audioop.add
1034
1035 fragment1: Py_buffer
1036 fragment2: Py_buffer
1037 width: int
1038 /
1039
1040Return a fragment which is the addition of the two samples passed as parameters.
1041[clinic start generated code]*/
1042
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001044audioop_add_impl(PyObject *module, Py_buffer *fragment1,
Larry Hastings89964c42015-04-14 18:07:59 -04001045 Py_buffer *fragment2, int width)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001046/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001047{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001048 signed char *ncp;
1049 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001050 int minval, maxval, newval;
1051 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001052
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001053 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001054 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001055 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001057 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001059
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001060 maxval = maxvals[width];
1061 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001062
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001063 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001064 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001065 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001067
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001068 for (i = 0; i < fragment1->len; i += width) {
1069 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1070 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001072 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001073 newval = val1 + val2;
1074 /* truncate in case of overflow */
1075 if (newval > maxval)
1076 newval = maxval;
1077 else if (newval < minval)
1078 newval = minval;
1079 }
1080 else {
1081 double fval = (double)val1 + (double)val2;
1082 /* truncate in case of overflow */
1083 newval = (int)floor(fbound(fval, minval, maxval));
1084 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001086 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 }
1088 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001089}
1090
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001091/*[clinic input]
1092audioop.bias
1093
1094 fragment: Py_buffer
1095 width: int
1096 bias: int
1097 /
1098
1099Return a fragment that is the original fragment with a bias added to each sample.
1100[clinic start generated code]*/
1101
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001103audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
1104/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001105{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001106 signed char *ncp;
1107 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001108 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001109 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001110
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001111 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001112 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001114 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001115 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001116 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 ncp = (signed char *)PyBytes_AsString(rv);
1118
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001119 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001121 for (i = 0; i < fragment->len; i += width) {
1122 if (width == 1)
1123 val = GETINTX(unsigned char, fragment->buf, i);
1124 else if (width == 2)
Serhiy Storchaka8be17402016-09-11 14:48:16 +03001125 val = GETINTX(uint16_t, fragment->buf, i);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001126 else if (width == 3)
1127 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001128 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001129 assert(width == 4);
Benjamin Peterson9b3d7702016-09-06 13:24:00 -07001130 val = GETINTX(uint32_t, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001131 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001133 val += (unsigned int)bias;
1134 /* wrap around in case of overflow */
1135 val &= mask;
1136
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001137 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001138 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001139 else if (width == 2)
Serhiy Storchaka8be17402016-09-11 14:48:16 +03001140 SETINTX(uint16_t, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001141 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001142 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001143 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001144 assert(width == 4);
Benjamin Peterson9b3d7702016-09-06 13:24:00 -07001145 SETINTX(uint32_t, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001146 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 }
1148 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001149}
1150
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001151/*[clinic input]
1152audioop.reverse
1153
1154 fragment: Py_buffer
1155 width: int
1156 /
1157
1158Reverse the samples in a fragment and returns the modified fragment.
1159[clinic start generated code]*/
1160
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001162audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
1163/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001166 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001167 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001168
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001169 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001170 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001171
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001172 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001173 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001174 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 ncp = (unsigned char *)PyBytes_AsString(rv);
1176
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001177 for (i = 0; i < fragment->len; i += width) {
1178 int val = GETRAWSAMPLE(width, fragment->buf, i);
1179 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 }
1181 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001182}
1183
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001184/*[clinic input]
1185audioop.byteswap
1186
1187 fragment: Py_buffer
1188 width: int
1189 /
1190
1191Convert big-endian samples to little-endian and vice versa.
1192[clinic start generated code]*/
1193
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001194static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001195audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
1196/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001197{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001198 unsigned char *ncp;
1199 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001200 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001201
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001202 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001203 return NULL;
1204
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001205 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001206 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001207 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001208 ncp = (unsigned char *)PyBytes_AsString(rv);
1209
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001210 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001211 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001212 for (j = 0; j < width; j++)
1213 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001214 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001215 return rv;
1216}
1217
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001218/*[clinic input]
1219audioop.lin2lin
1220
1221 fragment: Py_buffer
1222 width: int
1223 newwidth: int
1224 /
1225
1226Convert samples between 1-, 2-, 3- and 4-byte formats.
1227[clinic start generated code]*/
1228
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001230audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001231 int newwidth)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001232/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001235 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001236 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001237
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001238 if (!audioop_check_parameters(fragment->len, width))
1239 return NULL;
1240 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001241 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001242
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001243 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 PyErr_SetString(PyExc_MemoryError,
1245 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001246 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001248 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001249 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001250 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 ncp = (unsigned char *)PyBytes_AsString(rv);
1252
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001253 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1254 int val = GETSAMPLE32(width, fragment->buf, i);
1255 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 }
1257 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001258}
1259
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001260static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001261gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 while (b > 0) {
1264 int tmp = a % b;
1265 a = b;
1266 b = tmp;
1267 }
1268 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001269}
1270
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001271/*[clinic input]
1272audioop.ratecv
1273
1274 fragment: Py_buffer
1275 width: int
1276 nchannels: int
1277 inrate: int
1278 outrate: int
1279 state: object
1280 weightA: int = 1
1281 weightB: int = 0
1282 /
1283
1284Convert the frame rate of the input fragment.
1285[clinic start generated code]*/
1286
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001288audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001289 int nchannels, int inrate, int outrate, PyObject *state,
1290 int weightA, int weightB)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001291/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001294 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 int chan, d, *prev_i, *cur_i, cur_o;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001296 PyObject *samps, *str, *rv = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001298
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001299 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 if (nchannels < 1) {
1302 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001303 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001305 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 /* This overflow test is rigorously correct because
1307 both multiplicands are >= 1. Use the argument names
1308 from the docs for the error msg. */
1309 PyErr_SetString(PyExc_OverflowError,
1310 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001311 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001313 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 if (weightA < 1 || weightB < 0) {
1315 PyErr_SetString(AudioopError,
1316 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001317 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001319 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001320 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001322 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 }
1324 if (inrate <= 0 || outrate <= 0) {
1325 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001326 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 }
1328 /* divide inrate and outrate by their greatest common divisor */
1329 d = gcd(inrate, outrate);
1330 inrate /= d;
1331 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001332 /* divide weightA and weightB by their greatest common divisor */
1333 d = gcd(weightA, weightB);
1334 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001335 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001336
Benjamin Peterson2f8bfef2016-09-07 09:26:18 -07001337 if ((size_t)nchannels > SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 PyErr_SetString(PyExc_MemoryError,
1339 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001340 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001342 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1343 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 if (prev_i == NULL || cur_i == NULL) {
1345 (void) PyErr_NoMemory();
1346 goto exit;
1347 }
1348
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001349 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350
1351 if (state == Py_None) {
1352 d = -outrate;
1353 for (chan = 0; chan < nchannels; chan++)
1354 prev_i[chan] = cur_i[chan] = 0;
1355 }
1356 else {
1357 if (!PyArg_ParseTuple(state,
1358 "iO!;audioop.ratecv: illegal state argument",
1359 &d, &PyTuple_Type, &samps))
1360 goto exit;
1361 if (PyTuple_Size(samps) != nchannels) {
1362 PyErr_SetString(AudioopError,
1363 "illegal state argument");
1364 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001365 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 for (chan = 0; chan < nchannels; chan++) {
1367 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1368 "ii:ratecv", &prev_i[chan],
1369 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001370 goto exit;
1371 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001375 if (len == 0)
1376 str = PyBytes_FromStringAndSize(NULL, 0);
1377 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 /* There are len input frames, so we need (mathematically)
1379 ceiling(len*outrate/inrate) output frames, and each frame
1380 requires bytes_per_frame bytes. Computing this
1381 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001382 settle for a reasonable upper bound, though, in this
1383 case ceiling(len/inrate) * outrate. */
1384
1385 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001386 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001387 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 str = NULL;
1389 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001390 str = PyBytes_FromStringAndSize(NULL,
1391 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001392 }
1393 if (str == NULL) {
1394 PyErr_SetString(PyExc_MemoryError,
1395 "not enough memory for output buffer");
1396 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 }
1398 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001399 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400
1401 for (;;) {
1402 while (d < 0) {
1403 if (len == 0) {
1404 samps = PyTuple_New(nchannels);
1405 if (samps == NULL)
1406 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001407 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 PyTuple_SetItem(samps, chan,
1409 Py_BuildValue("(ii)",
1410 prev_i[chan],
1411 cur_i[chan]));
1412 if (PyErr_Occurred())
1413 goto exit;
1414 /* We have checked before that the length
1415 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001416 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 rv = PyBytes_FromStringAndSize
1418 (PyBytes_AsString(str), len);
1419 Py_DECREF(str);
1420 str = rv;
1421 if (str == NULL)
1422 goto exit;
1423 rv = Py_BuildValue("(O(iO))", str, d, samps);
1424 Py_DECREF(samps);
1425 Py_DECREF(str);
1426 goto exit; /* return rv */
1427 }
1428 for (chan = 0; chan < nchannels; chan++) {
1429 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001430 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1431 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001433 cur_i[chan] = (int)(
1434 ((double)weightA * (double)cur_i[chan] +
1435 (double)weightB * (double)prev_i[chan]) /
1436 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 }
1438 len--;
1439 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001440 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 while (d >= 0) {
1442 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001443 cur_o = (int)(((double)prev_i[chan] * (double)d +
1444 (double)cur_i[chan] * (double)(outrate - d)) /
1445 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001446 SETSAMPLE32(width, ncp, 0, cur_o);
1447 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 }
1449 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001450 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001452 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001453 PyMem_Free(prev_i);
1454 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001456}
Guido van Rossum1851a671997-02-14 16:14:03 +00001457
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001458/*[clinic input]
1459audioop.lin2ulaw
1460
1461 fragment: Py_buffer
1462 width: int
1463 /
1464
1465Convert samples in the audio fragment to u-LAW encoding.
1466[clinic start generated code]*/
1467
Roger E. Massec905fff1997-01-17 18:12:04 +00001468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001469audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1470/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001473 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001474 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001475
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001476 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001477 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001478
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001479 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001480 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001481 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 ncp = (unsigned char *)PyBytes_AsString(rv);
1483
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001484 for (i = 0; i < fragment->len; i += width) {
1485 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001486 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 }
1488 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001489}
1490
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001491/*[clinic input]
1492audioop.ulaw2lin
1493
1494 fragment: Py_buffer
1495 width: int
1496 /
1497
1498Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1499[clinic start generated code]*/
1500
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001502audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1503/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001507 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001508 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001509
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001510 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001511 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001513 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 PyErr_SetString(PyExc_MemoryError,
1515 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001516 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001518 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001519 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001520 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 ncp = (signed char *)PyBytes_AsString(rv);
1522
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001523 cp = fragment->buf;
1524 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001525 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001526 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 }
1528 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001529}
1530
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001531/*[clinic input]
1532audioop.lin2alaw
1533
1534 fragment: Py_buffer
1535 width: int
1536 /
1537
1538Convert samples in the audio fragment to a-LAW encoding.
1539[clinic start generated code]*/
1540
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001542audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1543/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001546 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001547 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001548
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001549 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001550 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001551
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001552 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001553 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001554 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 ncp = (unsigned char *)PyBytes_AsString(rv);
1556
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001557 for (i = 0; i < fragment->len; i += width) {
1558 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001559 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 }
1561 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001562}
1563
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001564/*[clinic input]
1565audioop.alaw2lin
1566
1567 fragment: Py_buffer
1568 width: int
1569 /
1570
1571Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1572[clinic start generated code]*/
1573
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001575audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1576/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001577{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001580 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001581 int val;
1582 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001583
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001584 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001585 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001587 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 PyErr_SetString(PyExc_MemoryError,
1589 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001590 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001592 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001593 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001594 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001596 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001598 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001599 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001600 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 }
1602 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001603}
1604
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001605/*[clinic input]
1606audioop.lin2adpcm
1607
1608 fragment: Py_buffer
1609 width: int
1610 state: object
1611 /
1612
1613Convert samples to 4 bit Intel/DVI ADPCM encoding.
1614[clinic start generated code]*/
1615
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001617audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001618 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001619/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001622 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001623 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001625 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001626 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001627
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001628 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001629 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 /* Decode state, should have (value, step) */
1632 if ( state == Py_None ) {
1633 /* First time, it seems. Set defaults */
1634 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001636 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001637 else if (!PyTuple_Check(state)) {
1638 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1639 return NULL;
1640 }
1641 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1642 return NULL;
1643 }
1644 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1645 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1646 PyErr_SetString(PyExc_ValueError, "bad state");
1647 return NULL;
1648 }
1649
1650 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1651 if (str == NULL)
1652 return NULL;
1653 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654
1655 step = stepsizeTable[index];
1656 bufferstep = 1;
1657
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001658 for (i = 0; i < fragment->len; i += width) {
1659 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660
1661 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001662 if (val < valpred) {
1663 diff = valpred - val;
1664 sign = 8;
1665 }
1666 else {
1667 diff = val - valpred;
1668 sign = 0;
1669 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670
1671 /* Step 2 - Divide and clamp */
1672 /* Note:
1673 ** This code *approximately* computes:
1674 ** delta = diff*4/step;
1675 ** vpdiff = (delta+0.5)*step/4;
1676 ** but in shift step bits are dropped. The net result of this
1677 ** is that even if you have fast mul/div hardware you cannot
1678 ** put it to good use since the fixup would be too expensive.
1679 */
1680 delta = 0;
1681 vpdiff = (step >> 3);
1682
1683 if ( diff >= step ) {
1684 delta = 4;
1685 diff -= step;
1686 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001687 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 step >>= 1;
1689 if ( diff >= step ) {
1690 delta |= 2;
1691 diff -= step;
1692 vpdiff += step;
1693 }
1694 step >>= 1;
1695 if ( diff >= step ) {
1696 delta |= 1;
1697 vpdiff += step;
1698 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 /* Step 3 - Update previous value */
1701 if ( sign )
1702 valpred -= vpdiff;
1703 else
1704 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 /* Step 4 - Clamp previous value to 16 bits */
1707 if ( valpred > 32767 )
1708 valpred = 32767;
1709 else if ( valpred < -32768 )
1710 valpred = -32768;
1711
1712 /* Step 5 - Assemble value, update index and step values */
1713 delta |= sign;
1714
1715 index += indexTable[delta];
1716 if ( index < 0 ) index = 0;
1717 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001718 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 /* Step 6 - Output value */
1721 if ( bufferstep ) {
1722 outputbuffer = (delta << 4) & 0xf0;
1723 } else {
1724 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001725 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 bufferstep = !bufferstep;
1727 }
1728 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001729 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001731}
1732
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001733/*[clinic input]
1734audioop.adpcm2lin
1735
1736 fragment: Py_buffer
1737 width: int
1738 state: object
1739 /
1740
1741Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1742[clinic start generated code]*/
1743
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001745audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001746 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001747/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 signed char *cp;
1750 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001751 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001752 int valpred, step, delta, index, sign, vpdiff;
1753 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001754 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001755
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001756 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001757 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 /* Decode state, should have (value, step) */
1760 if ( state == Py_None ) {
1761 /* First time, it seems. Set defaults */
1762 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001764 }
1765 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001766 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001767 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001768 }
1769 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001770 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001771 }
1772 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1773 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1774 PyErr_SetString(PyExc_ValueError, "bad state");
1775 return NULL;
1776 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001778 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 PyErr_SetString(PyExc_MemoryError,
1780 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001781 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001783 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001784 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001785 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001786 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001788 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789
1790 step = stepsizeTable[index];
1791 bufferstep = 0;
1792
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001793 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 /* Step 1 - get the delta value and compute next index */
1795 if ( bufferstep ) {
1796 delta = inputbuffer & 0xf;
1797 } else {
1798 inputbuffer = *cp++;
1799 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001800 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 bufferstep = !bufferstep;
1803
1804 /* Step 2 - Find new index value (for later) */
1805 index += indexTable[delta];
1806 if ( index < 0 ) index = 0;
1807 if ( index > 88 ) index = 88;
1808
1809 /* Step 3 - Separate sign and magnitude */
1810 sign = delta & 8;
1811 delta = delta & 7;
1812
1813 /* Step 4 - Compute difference and new predicted value */
1814 /*
1815 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1816 ** in adpcm_coder.
1817 */
1818 vpdiff = step >> 3;
1819 if ( delta & 4 ) vpdiff += step;
1820 if ( delta & 2 ) vpdiff += step>>1;
1821 if ( delta & 1 ) vpdiff += step>>2;
1822
1823 if ( sign )
1824 valpred -= vpdiff;
1825 else
1826 valpred += vpdiff;
1827
1828 /* Step 5 - clamp output value */
1829 if ( valpred > 32767 )
1830 valpred = 32767;
1831 else if ( valpred < -32768 )
1832 valpred = -32768;
1833
1834 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001835 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001838 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1842 Py_DECREF(str);
1843 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001844}
1845
Larry Hastingsf256c222014-01-25 21:30:37 -08001846#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001847
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001848static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001849 AUDIOOP_MAX_METHODDEF
1850 AUDIOOP_MINMAX_METHODDEF
1851 AUDIOOP_AVG_METHODDEF
1852 AUDIOOP_MAXPP_METHODDEF
1853 AUDIOOP_AVGPP_METHODDEF
1854 AUDIOOP_RMS_METHODDEF
1855 AUDIOOP_FINDFIT_METHODDEF
1856 AUDIOOP_FINDMAX_METHODDEF
1857 AUDIOOP_FINDFACTOR_METHODDEF
1858 AUDIOOP_CROSS_METHODDEF
1859 AUDIOOP_MUL_METHODDEF
1860 AUDIOOP_ADD_METHODDEF
1861 AUDIOOP_BIAS_METHODDEF
1862 AUDIOOP_ULAW2LIN_METHODDEF
1863 AUDIOOP_LIN2ULAW_METHODDEF
1864 AUDIOOP_ALAW2LIN_METHODDEF
1865 AUDIOOP_LIN2ALAW_METHODDEF
1866 AUDIOOP_LIN2LIN_METHODDEF
1867 AUDIOOP_ADPCM2LIN_METHODDEF
1868 AUDIOOP_LIN2ADPCM_METHODDEF
1869 AUDIOOP_TOMONO_METHODDEF
1870 AUDIOOP_TOSTEREO_METHODDEF
1871 AUDIOOP_GETSAMPLE_METHODDEF
1872 AUDIOOP_REVERSE_METHODDEF
1873 AUDIOOP_BYTESWAP_METHODDEF
1874 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001876};
1877
Martin v. Löwis1a214512008-06-11 05:26:20 +00001878
1879static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 PyModuleDef_HEAD_INIT,
1881 "audioop",
1882 NULL,
1883 -1,
1884 audioop_methods,
1885 NULL,
1886 NULL,
1887 NULL,
1888 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001889};
1890
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001891PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001892PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 PyObject *m, *d;
1895 m = PyModule_Create(&audioopmodule);
1896 if (m == NULL)
1897 return NULL;
1898 d = PyModule_GetDict(m);
1899 if (d == NULL)
1900 return NULL;
1901 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1902 if (AudioopError != NULL)
1903 PyDict_SetItemString(d,"error",AudioopError);
1904 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001905}