blob: 80c8a2a8e5210b7e40fad056d7782cd2f9836d26 [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;
Oren Milman1d1d3e92017-08-20 18:35:36 +03001296 PyObject *samps, *str, *rv = NULL, *channel;
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 {
Oren Milman1d1d3e92017-08-20 18:35:36 +03001357 if (!PyTuple_Check(state)) {
1358 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1359 goto exit;
1360 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 if (!PyArg_ParseTuple(state,
Oren Milman1d1d3e92017-08-20 18:35:36 +03001362 "iO!;ratecv(): illegal state argument",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 &d, &PyTuple_Type, &samps))
1364 goto exit;
1365 if (PyTuple_Size(samps) != nchannels) {
1366 PyErr_SetString(AudioopError,
1367 "illegal state argument");
1368 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001369 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 for (chan = 0; chan < nchannels; chan++) {
Oren Milman1d1d3e92017-08-20 18:35:36 +03001371 channel = PyTuple_GetItem(samps, chan);
1372 if (!PyTuple_Check(channel)) {
1373 PyErr_SetString(PyExc_TypeError,
1374 "ratecv(): illegal state argument");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001375 goto exit;
Oren Milman1d1d3e92017-08-20 18:35:36 +03001376 }
1377 if (!PyArg_ParseTuple(channel,
1378 "ii;ratecv(): illegal state argument",
1379 &prev_i[chan], &cur_i[chan]))
1380 {
1381 goto exit;
1382 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001383 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001387 if (len == 0)
1388 str = PyBytes_FromStringAndSize(NULL, 0);
1389 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 /* There are len input frames, so we need (mathematically)
1391 ceiling(len*outrate/inrate) output frames, and each frame
1392 requires bytes_per_frame bytes. Computing this
1393 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001394 settle for a reasonable upper bound, though, in this
1395 case ceiling(len/inrate) * outrate. */
1396
1397 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001398 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001399 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 str = NULL;
1401 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001402 str = PyBytes_FromStringAndSize(NULL,
1403 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001404 }
1405 if (str == NULL) {
1406 PyErr_SetString(PyExc_MemoryError,
1407 "not enough memory for output buffer");
1408 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 }
1410 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001411 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412
1413 for (;;) {
1414 while (d < 0) {
1415 if (len == 0) {
1416 samps = PyTuple_New(nchannels);
1417 if (samps == NULL)
1418 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001419 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 PyTuple_SetItem(samps, chan,
1421 Py_BuildValue("(ii)",
1422 prev_i[chan],
1423 cur_i[chan]));
1424 if (PyErr_Occurred())
1425 goto exit;
1426 /* We have checked before that the length
1427 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001428 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 rv = PyBytes_FromStringAndSize
1430 (PyBytes_AsString(str), len);
1431 Py_DECREF(str);
1432 str = rv;
1433 if (str == NULL)
1434 goto exit;
1435 rv = Py_BuildValue("(O(iO))", str, d, samps);
1436 Py_DECREF(samps);
1437 Py_DECREF(str);
1438 goto exit; /* return rv */
1439 }
1440 for (chan = 0; chan < nchannels; chan++) {
1441 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001442 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1443 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001445 cur_i[chan] = (int)(
1446 ((double)weightA * (double)cur_i[chan] +
1447 (double)weightB * (double)prev_i[chan]) /
1448 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 }
1450 len--;
1451 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001452 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 while (d >= 0) {
1454 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001455 cur_o = (int)(((double)prev_i[chan] * (double)d +
1456 (double)cur_i[chan] * (double)(outrate - d)) /
1457 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001458 SETSAMPLE32(width, ncp, 0, cur_o);
1459 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 }
1461 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001462 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001464 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001465 PyMem_Free(prev_i);
1466 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001468}
Guido van Rossum1851a671997-02-14 16:14:03 +00001469
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001470/*[clinic input]
1471audioop.lin2ulaw
1472
1473 fragment: Py_buffer
1474 width: int
1475 /
1476
1477Convert samples in the audio fragment to u-LAW encoding.
1478[clinic start generated code]*/
1479
Roger E. Massec905fff1997-01-17 18:12:04 +00001480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001481audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1482/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001485 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001486 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001487
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001488 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001489 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001490
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001491 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001492 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001493 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 ncp = (unsigned char *)PyBytes_AsString(rv);
1495
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001496 for (i = 0; i < fragment->len; i += width) {
1497 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001498 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 }
1500 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001501}
1502
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001503/*[clinic input]
1504audioop.ulaw2lin
1505
1506 fragment: Py_buffer
1507 width: int
1508 /
1509
1510Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1511[clinic start generated code]*/
1512
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001513static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001514audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1515/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001519 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001520 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001521
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001522 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001523 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001525 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 PyErr_SetString(PyExc_MemoryError,
1527 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001528 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001530 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001531 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001532 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 ncp = (signed char *)PyBytes_AsString(rv);
1534
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001535 cp = fragment->buf;
1536 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001537 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001538 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 }
1540 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001541}
1542
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001543/*[clinic input]
1544audioop.lin2alaw
1545
1546 fragment: Py_buffer
1547 width: int
1548 /
1549
1550Convert samples in the audio fragment to a-LAW encoding.
1551[clinic start generated code]*/
1552
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001553static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001554audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1555/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001558 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001559 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001560
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001561 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001562 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001563
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001564 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001565 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001566 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 ncp = (unsigned char *)PyBytes_AsString(rv);
1568
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001569 for (i = 0; i < fragment->len; i += width) {
1570 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001571 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 }
1573 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001574}
1575
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001576/*[clinic input]
1577audioop.alaw2lin
1578
1579 fragment: Py_buffer
1580 width: int
1581 /
1582
1583Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1584[clinic start generated code]*/
1585
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001586static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001587audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1588/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001592 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001593 int val;
1594 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001595
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001596 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001597 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001599 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 PyErr_SetString(PyExc_MemoryError,
1601 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001602 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001604 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001605 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001606 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001608 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001610 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001611 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001612 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 }
1614 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001615}
1616
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001617/*[clinic input]
1618audioop.lin2adpcm
1619
1620 fragment: Py_buffer
1621 width: int
1622 state: object
1623 /
1624
1625Convert samples to 4 bit Intel/DVI ADPCM encoding.
1626[clinic start generated code]*/
1627
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001629audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001630 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001631/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001634 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001635 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001637 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001638 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001639
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001640 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001641 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 /* Decode state, should have (value, step) */
1644 if ( state == Py_None ) {
1645 /* First time, it seems. Set defaults */
1646 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001648 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001649 else if (!PyTuple_Check(state)) {
1650 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1651 return NULL;
1652 }
Oren Milman1d1d3e92017-08-20 18:35:36 +03001653 else if (!PyArg_ParseTuple(state, "ii;lin2adpcm(): illegal state argument",
1654 &valpred, &index))
1655 {
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001656 return NULL;
1657 }
1658 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1659 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1660 PyErr_SetString(PyExc_ValueError, "bad state");
1661 return NULL;
1662 }
1663
1664 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1665 if (str == NULL)
1666 return NULL;
1667 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668
1669 step = stepsizeTable[index];
1670 bufferstep = 1;
1671
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001672 for (i = 0; i < fragment->len; i += width) {
1673 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674
1675 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001676 if (val < valpred) {
1677 diff = valpred - val;
1678 sign = 8;
1679 }
1680 else {
1681 diff = val - valpred;
1682 sign = 0;
1683 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684
1685 /* Step 2 - Divide and clamp */
1686 /* Note:
1687 ** This code *approximately* computes:
1688 ** delta = diff*4/step;
1689 ** vpdiff = (delta+0.5)*step/4;
1690 ** but in shift step bits are dropped. The net result of this
1691 ** is that even if you have fast mul/div hardware you cannot
1692 ** put it to good use since the fixup would be too expensive.
1693 */
1694 delta = 0;
1695 vpdiff = (step >> 3);
1696
1697 if ( diff >= step ) {
1698 delta = 4;
1699 diff -= step;
1700 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001701 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 step >>= 1;
1703 if ( diff >= step ) {
1704 delta |= 2;
1705 diff -= step;
1706 vpdiff += step;
1707 }
1708 step >>= 1;
1709 if ( diff >= step ) {
1710 delta |= 1;
1711 vpdiff += step;
1712 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 /* Step 3 - Update previous value */
1715 if ( sign )
1716 valpred -= vpdiff;
1717 else
1718 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 /* Step 4 - Clamp previous value to 16 bits */
1721 if ( valpred > 32767 )
1722 valpred = 32767;
1723 else if ( valpred < -32768 )
1724 valpred = -32768;
1725
1726 /* Step 5 - Assemble value, update index and step values */
1727 delta |= sign;
1728
1729 index += indexTable[delta];
1730 if ( index < 0 ) index = 0;
1731 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001732 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734 /* Step 6 - Output value */
1735 if ( bufferstep ) {
1736 outputbuffer = (delta << 4) & 0xf0;
1737 } else {
1738 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001739 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 bufferstep = !bufferstep;
1741 }
1742 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001743 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001745}
1746
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001747/*[clinic input]
1748audioop.adpcm2lin
1749
1750 fragment: Py_buffer
1751 width: int
1752 state: object
1753 /
1754
1755Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1756[clinic start generated code]*/
1757
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001759audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001760 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001761/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 signed char *cp;
1764 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001765 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001766 int valpred, step, delta, index, sign, vpdiff;
1767 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001768 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001769
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001770 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001771 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 /* Decode state, should have (value, step) */
1774 if ( state == Py_None ) {
1775 /* First time, it seems. Set defaults */
1776 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001778 }
1779 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001780 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001781 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001782 }
Oren Milman1d1d3e92017-08-20 18:35:36 +03001783 else if (!PyArg_ParseTuple(state, "ii;adpcm2lin(): illegal state argument",
1784 &valpred, &index))
1785 {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001786 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001787 }
1788 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1789 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1790 PyErr_SetString(PyExc_ValueError, "bad state");
1791 return NULL;
1792 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001794 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 PyErr_SetString(PyExc_MemoryError,
1796 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001797 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001799 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001800 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001801 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001802 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001804 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805
1806 step = stepsizeTable[index];
1807 bufferstep = 0;
1808
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001809 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 /* Step 1 - get the delta value and compute next index */
1811 if ( bufferstep ) {
1812 delta = inputbuffer & 0xf;
1813 } else {
1814 inputbuffer = *cp++;
1815 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001816 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001817
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 bufferstep = !bufferstep;
1819
1820 /* Step 2 - Find new index value (for later) */
1821 index += indexTable[delta];
1822 if ( index < 0 ) index = 0;
1823 if ( index > 88 ) index = 88;
1824
1825 /* Step 3 - Separate sign and magnitude */
1826 sign = delta & 8;
1827 delta = delta & 7;
1828
1829 /* Step 4 - Compute difference and new predicted value */
1830 /*
1831 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1832 ** in adpcm_coder.
1833 */
1834 vpdiff = step >> 3;
1835 if ( delta & 4 ) vpdiff += step;
1836 if ( delta & 2 ) vpdiff += step>>1;
1837 if ( delta & 1 ) vpdiff += step>>2;
1838
1839 if ( sign )
1840 valpred -= vpdiff;
1841 else
1842 valpred += vpdiff;
1843
1844 /* Step 5 - clamp output value */
1845 if ( valpred > 32767 )
1846 valpred = 32767;
1847 else if ( valpred < -32768 )
1848 valpred = -32768;
1849
1850 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001851 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001854 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1858 Py_DECREF(str);
1859 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001860}
1861
Larry Hastingsf256c222014-01-25 21:30:37 -08001862#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001863
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001864static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001865 AUDIOOP_MAX_METHODDEF
1866 AUDIOOP_MINMAX_METHODDEF
1867 AUDIOOP_AVG_METHODDEF
1868 AUDIOOP_MAXPP_METHODDEF
1869 AUDIOOP_AVGPP_METHODDEF
1870 AUDIOOP_RMS_METHODDEF
1871 AUDIOOP_FINDFIT_METHODDEF
1872 AUDIOOP_FINDMAX_METHODDEF
1873 AUDIOOP_FINDFACTOR_METHODDEF
1874 AUDIOOP_CROSS_METHODDEF
1875 AUDIOOP_MUL_METHODDEF
1876 AUDIOOP_ADD_METHODDEF
1877 AUDIOOP_BIAS_METHODDEF
1878 AUDIOOP_ULAW2LIN_METHODDEF
1879 AUDIOOP_LIN2ULAW_METHODDEF
1880 AUDIOOP_ALAW2LIN_METHODDEF
1881 AUDIOOP_LIN2ALAW_METHODDEF
1882 AUDIOOP_LIN2LIN_METHODDEF
1883 AUDIOOP_ADPCM2LIN_METHODDEF
1884 AUDIOOP_LIN2ADPCM_METHODDEF
1885 AUDIOOP_TOMONO_METHODDEF
1886 AUDIOOP_TOSTEREO_METHODDEF
1887 AUDIOOP_GETSAMPLE_METHODDEF
1888 AUDIOOP_REVERSE_METHODDEF
1889 AUDIOOP_BYTESWAP_METHODDEF
1890 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001892};
1893
Martin v. Löwis1a214512008-06-11 05:26:20 +00001894
1895static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyModuleDef_HEAD_INIT,
1897 "audioop",
1898 NULL,
1899 -1,
1900 audioop_methods,
1901 NULL,
1902 NULL,
1903 NULL,
1904 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001905};
1906
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001907PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001908PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 PyObject *m, *d;
1911 m = PyModule_Create(&audioopmodule);
1912 if (m == NULL)
1913 return NULL;
1914 d = PyModule_GetDict(m);
1915 if (d == NULL)
1916 return NULL;
1917 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1918 if (AudioopError != NULL)
1919 PyDict_SetItemString(d,"error",AudioopError);
1920 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001921}