blob: f4fdeb23ffa95a2c7abc0dd24dba513b752c6608 [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{
Victor Stinner45e4efb2018-06-06 15:50:50 +020023 if (val > maxval) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020024 val = maxval;
Victor Stinner45e4efb2018-06-06 15:50:50 +020025 }
26 else if (val < minval + 1.0) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020027 val = minval;
Victor Stinner45e4efb2018-06-06 15:50:50 +020028 }
29
30 /* Round towards minus infinity (-inf) */
31 val = floor(val);
32
33 /* Cast double to integer: round towards zero */
Victor Stinnerf2b9a342013-05-07 23:49:15 +020034 return (int)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020035}
36
37
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000038/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000039** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
40
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000041/* From g711.c:
42 *
43 * December 30, 1994:
44 * Functions linear2alaw, linear2ulaw have been updated to correctly
45 * convert unquantized 16 bit values.
46 * Tables for direct u- to A-law and A- to u-law conversions have been
47 * corrected.
48 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
49 * bli@cpk.auc.dk
50 *
51 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000052#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
53#define CLIP 32635
Martin Panter4c359642016-05-08 13:53:41 +000054#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055#define QUANT_MASK (0xf) /* Quantization field mask. */
56#define SEG_SHIFT (4) /* Left shift for segment number. */
57#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000058
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070059static const int16_t seg_aend[8] = {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020060 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
61};
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070062static const int16_t seg_uend[8] = {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020063 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF
64};
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000065
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070066static int16_t
67search(int16_t val, const int16_t *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 for (i = 0; i < size; i++) {
72 if (val <= *table++)
73 return (i);
74 }
75 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000076}
77#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
78#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000079
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -070080static const int16_t _st_ulaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000081 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
82 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
83 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
84 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
85 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
86 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
87 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
88 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
89 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
90 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
91 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
92 -1052, -988, -924, -876, -844, -812, -780,
93 -748, -716, -684, -652, -620, -588, -556,
94 -524, -492, -460, -428, -396, -372, -356,
95 -340, -324, -308, -292, -276, -260, -244,
96 -228, -212, -196, -180, -164, -148, -132,
97 -120, -112, -104, -96, -88, -80, -72,
98 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000100 27004, 25980, 24956, 23932, 22908, 21884, 20860,
101 19836, 18812, 17788, 16764, 15996, 15484, 14972,
102 14460, 13948, 13436, 12924, 12412, 11900, 11388,
103 10876, 10364, 9852, 9340, 8828, 8316, 7932,
104 7676, 7420, 7164, 6908, 6652, 6396, 6140,
105 5884, 5628, 5372, 5116, 4860, 4604, 4348,
106 4092, 3900, 3772, 3644, 3516, 3388, 3260,
107 3132, 3004, 2876, 2748, 2620, 2492, 2364,
108 2236, 2108, 1980, 1884, 1820, 1756, 1692,
109 1628, 1564, 1500, 1436, 1372, 1308, 1244,
110 1180, 1116, 1052, 988, 924, 876, 844,
111 812, 780, 748, 716, 684, 652, 620,
112 588, 556, 524, 492, 460, 428, 396,
113 372, 356, 340, 324, 308, 292, 276,
114 260, 244, 228, 212, 196, 180, 164,
115 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 80, 72, 64, 56, 48, 40, 32,
117 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000118};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000119
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000120/*
121 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000122 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000123 * the data shifted such that it only contains information in the lower
124 * 14-bits.
125 *
126 * In order to simplify the encoding process, the original linear magnitude
127 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
128 * (33 - 8191). The result can be seen in the following encoding table:
129 *
130 * Biased Linear Input Code Compressed Code
131 * ------------------------ ---------------
132 * 00000001wxyza 000wxyz
133 * 0000001wxyzab 001wxyz
134 * 000001wxyzabc 010wxyz
135 * 00001wxyzabcd 011wxyz
136 * 0001wxyzabcde 100wxyz
137 * 001wxyzabcdef 101wxyz
138 * 01wxyzabcdefg 110wxyz
139 * 1wxyzabcdefgh 111wxyz
140 *
141 * Each biased linear code has a leading 1 which identifies the segment
142 * number. The value of the segment number is equal to 7 minus the number
143 * of leading 0's. The quantization interval is directly available as the
144 * four bits wxyz. * The trailing bits (a - h) are ignored.
145 *
146 * Ordinarily the complement of the resulting code word is used for
147 * transmission, and so the code word is complemented before it is returned.
148 *
149 * For further information see John C. Bellamy's Digital Telephony, 1982,
150 * John Wiley & Sons, pps 98-111 and 472-476.
151 */
152static unsigned char
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700153st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000154{
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700155 int16_t mask;
156 int16_t seg;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 /* u-law inverts all bits */
160 /* Get the sign and the magnitude of the value. */
161 if (pcm_val < 0) {
162 pcm_val = -pcm_val;
163 mask = 0x7F;
164 } else {
165 mask = 0xFF;
166 }
167 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
168 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 /* Convert the scaled magnitude to segment number. */
171 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 /*
174 * Combine the sign, segment, quantization bits;
175 * and complement the code word.
176 */
177 if (seg >= 8) /* out of range, return maximum value. */
178 return (unsigned char) (0x7F ^ mask);
179 else {
180 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
181 return (uval ^ mask);
182 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000183
184}
185
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700186static const int16_t _st_alaw2linear16[256] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000187 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
188 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
189 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
190 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
191 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
192 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
193 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
194 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
195 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
196 -13568, -344, -328, -376, -360, -280, -264,
197 -312, -296, -472, -456, -504, -488, -408,
198 -392, -440, -424, -88, -72, -120, -104,
199 -24, -8, -56, -40, -216, -200, -248,
200 -232, -152, -136, -184, -168, -1376, -1312,
201 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
202 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
203 -688, -656, -752, -720, -560, -528, -624,
204 -592, -944, -912, -1008, -976, -816, -784,
205 -880, -848, 5504, 5248, 6016, 5760, 4480,
206 4224, 4992, 4736, 7552, 7296, 8064, 7808,
207 6528, 6272, 7040, 6784, 2752, 2624, 3008,
208 2880, 2240, 2112, 2496, 2368, 3776, 3648,
209 4032, 3904, 3264, 3136, 3520, 3392, 22016,
210 20992, 24064, 23040, 17920, 16896, 19968, 18944,
211 30208, 29184, 32256, 31232, 26112, 25088, 28160,
212 27136, 11008, 10496, 12032, 11520, 8960, 8448,
213 9984, 9472, 15104, 14592, 16128, 15616, 13056,
214 12544, 14080, 13568, 344, 328, 376, 360,
215 280, 264, 312, 296, 472, 456, 504,
216 488, 408, 392, 440, 424, 88, 72,
217 120, 104, 24, 8, 56, 40, 216,
218 200, 248, 232, 152, 136, 184, 168,
219 1376, 1312, 1504, 1440, 1120, 1056, 1248,
220 1184, 1888, 1824, 2016, 1952, 1632, 1568,
221 1760, 1696, 688, 656, 752, 720, 560,
222 528, 624, 592, 944, 912, 1008, 976,
223 816, 784, 880, 848
224};
225
226/*
Martin Panter4c359642016-05-08 13:53:41 +0000227 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
Martin Panter7462b6492015-11-02 03:37:02 +0000228 * stored in an unsigned char. This function should only be called with
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000229 * the data shifted such that it only contains information in the lower
230 * 13-bits.
231 *
232 * Linear Input Code Compressed Code
233 * ------------------------ ---------------
234 * 0000000wxyza 000wxyz
235 * 0000001wxyza 001wxyz
236 * 000001wxyzab 010wxyz
237 * 00001wxyzabc 011wxyz
238 * 0001wxyzabcd 100wxyz
239 * 001wxyzabcde 101wxyz
240 * 01wxyzabcdef 110wxyz
241 * 1wxyzabcdefg 111wxyz
242 *
243 * For further information see John C. Bellamy's Digital Telephony, 1982,
244 * John Wiley & Sons, pps 98-111 and 472-476.
245 */
246static unsigned char
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700247st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000248{
Benjamin Petersonbb0b0d92016-09-08 15:08:02 -0700249 int16_t mask;
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300250 int16_t seg;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 /* A-law using even bit inversion */
254 if (pcm_val >= 0) {
255 mask = 0xD5; /* sign (7th) bit = 1 */
256 } else {
257 mask = 0x55; /* sign bit = 0 */
258 pcm_val = -pcm_val - 1;
259 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 /* Convert the scaled magnitude to segment number. */
262 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 if (seg >= 8) /* out of range, return maximum value. */
267 return (unsigned char) (0x7F ^ mask);
268 else {
269 aval = (unsigned char) seg << SEG_SHIFT;
270 if (seg < 2)
271 aval |= (pcm_val >> 1) & QUANT_MASK;
272 else
273 aval |= (pcm_val >> seg) & QUANT_MASK;
274 return (aval ^ mask);
275 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000276}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000277/* End of code taken from sox */
278
Guido van Rossumb64e6351992-07-06 14:21:56 +0000279/* Intel ADPCM step variation table */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200280static const int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 -1, -1, -1, -1, 2, 4, 6, 8,
282 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000283};
284
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200285static const int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
287 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
288 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
289 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
290 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
291 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
292 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
293 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
294 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000295};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296
Serhiy Storchaka23a78272013-11-11 07:47:35 +0200297#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i)))
298#define SETINTX(T, cp, i, val) do { \
299 *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300300 } while (0)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000301
302
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300303#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300304#define GETINT16(cp, i) GETINTX(int16_t, (cp), (i))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700305#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i))
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300306
307#if WORDS_BIGENDIAN
308#define GETINT24(cp, i) ( \
309 ((unsigned char *)(cp) + (i))[2] + \
310 (((unsigned char *)(cp) + (i))[1] << 8) + \
311 (((signed char *)(cp) + (i))[0] << 16) )
312#else
313#define GETINT24(cp, i) ( \
314 ((unsigned char *)(cp) + (i))[0] + \
315 (((unsigned char *)(cp) + (i))[1] << 8) + \
316 (((signed char *)(cp) + (i))[2] << 16) )
317#endif
318
319
320#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300321#define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val))
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700322#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val))
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300323
324#if WORDS_BIGENDIAN
325#define SETINT24(cp, i, val) do { \
326 ((unsigned char *)(cp) + (i))[2] = (int)(val); \
327 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
328 ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \
329 } while (0)
330#else
331#define SETINT24(cp, i, val) do { \
332 ((unsigned char *)(cp) + (i))[0] = (int)(val); \
333 ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \
334 ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \
335 } while (0)
336#endif
337
338
339#define GETRAWSAMPLE(size, cp, i) ( \
340 (size == 1) ? (int)GETINT8((cp), (i)) : \
341 (size == 2) ? (int)GETINT16((cp), (i)) : \
342 (size == 3) ? (int)GETINT24((cp), (i)) : \
343 (int)GETINT32((cp), (i)))
344
345#define SETRAWSAMPLE(size, cp, i, val) do { \
346 if (size == 1) \
347 SETINT8((cp), (i), (val)); \
348 else if (size == 2) \
349 SETINT16((cp), (i), (val)); \
350 else if (size == 3) \
351 SETINT24((cp), (i), (val)); \
352 else \
353 SETINT32((cp), (i), (val)); \
354 } while(0)
355
356
357#define GETSAMPLE32(size, cp, i) ( \
358 (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
359 (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
360 (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \
361 (int)GETINT32((cp), (i)))
362
363#define SETSAMPLE32(size, cp, i, val) do { \
364 if (size == 1) \
365 SETINT8((cp), (i), (val) >> 24); \
366 else if (size == 2) \
367 SETINT16((cp), (i), (val) >> 16); \
368 else if (size == 3) \
369 SETINT24((cp), (i), (val) >> 8); \
370 else \
371 SETINT32((cp), (i), (val)); \
372 } while(0)
373
Guido van Rossumb66efa01992-06-01 16:01:24 +0000374
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000375static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000376
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000377static int
378audioop_check_size(int size)
379{
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300380 if (size < 1 || size > 4) {
381 PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000382 return 0;
383 }
384 else
385 return 1;
386}
387
388static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000389audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000390{
391 if (!audioop_check_size(size))
392 return 0;
393 if (len % size != 0) {
394 PyErr_SetString(AudioopError, "not a whole number of frames");
395 return 0;
396 }
397 return 1;
398}
399
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200400/*[clinic input]
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200401module audioop
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200402[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300403/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200404
405/*[clinic input]
406audioop.getsample
407
408 fragment: Py_buffer
409 width: int
410 index: Py_ssize_t
411 /
412
413Return the value of sample index from the fragment.
414[clinic start generated code]*/
415
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300417audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400418 Py_ssize_t index)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300419/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000420{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200421 int val;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000422
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200423 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000424 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200425 if (index < 0 || index >= fragment->len/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 PyErr_SetString(AudioopError, "Index out of range");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200427 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200429 val = GETRAWSAMPLE(width, fragment->buf, index*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200430 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000431}
432
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200433/*[clinic input]
434audioop.max
435
436 fragment: Py_buffer
437 width: int
438 /
439
440Return the maximum of the absolute value of all samples in a fragment.
441[clinic start generated code]*/
442
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000443static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300444audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
445/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000446{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200447 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200448 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000449
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200450 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000451 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200452 for (i = 0; i < fragment->len; i += width) {
453 int val = GETRAWSAMPLE(width, fragment->buf, i);
Martin Panter6fb90902016-07-19 03:05:42 +0000454 /* Cast to unsigned before negating. Unsigned overflow is well-
455 defined, but signed overflow is not. */
Steve Dowera4391912016-09-06 19:09:15 -0700456 if (val < 0) absval = (unsigned int)-(int64_t)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200457 else absval = val;
458 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200460 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000461}
462
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200463/*[clinic input]
464audioop.minmax
465
466 fragment: Py_buffer
467 width: int
468 /
469
470Return the minimum and maximum values of all samples in the sound fragment.
471[clinic start generated code]*/
472
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300474audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
475/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000476{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200477 Py_ssize_t i;
Tim Goldenfa6ab0f2013-10-31 10:25:47 +0000478 /* -1 trick below is needed on Windows to support -0x80000000 without
479 a warning */
480 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000481
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200482 if (!audioop_check_parameters(fragment->len, width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200484 for (i = 0; i < fragment->len; i += width) {
485 int val = GETRAWSAMPLE(width, fragment->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (val > max) max = val;
487 if (val < min) min = val;
488 }
489 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000490}
491
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200492/*[clinic input]
493audioop.avg
494
495 fragment: Py_buffer
496 width: int
497 /
498
499Return the average over all samples in the fragment.
500[clinic start generated code]*/
501
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300503audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
504/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000505{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200506 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200507 int avg;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300508 double sum = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000509
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200510 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000511 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200512 for (i = 0; i < fragment->len; i += width)
513 sum += GETRAWSAMPLE(width, fragment->buf, i);
514 if (fragment->len == 0)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300515 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200517 avg = (int)floor(sum / (double)(fragment->len/width));
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300518 return PyLong_FromLong(avg);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000519}
520
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200521/*[clinic input]
522audioop.rms
523
524 fragment: Py_buffer
525 width: int
526 /
527
528Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).
529[clinic start generated code]*/
530
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300532audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
533/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000534{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200535 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200536 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000538
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200539 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000540 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200541 for (i = 0; i < fragment->len; i += width) {
542 double val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300543 sum_squares += val*val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200545 if (fragment->len == 0)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200546 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 else
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200548 res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width));
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200549 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000550}
551
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300552static double _sum2(const int16_t *a, const int16_t *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000553{
Mark Dickinson81fece22010-05-11 13:34:35 +0000554 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 for( i=0; i<len; i++) {
558 sum = sum + (double)a[i]*(double)b[i];
559 }
560 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000561}
562
563/*
564** Findfit tries to locate a sample within another sample. Its main use
565** is in echo-cancellation (to find the feedback of the output signal in
566** the input signal).
567** The method used is as follows:
568**
569** let R be the reference signal (length n) and A the input signal (length N)
570** with N > n, and let all sums be over i from 0 to n-1.
571**
572** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
573** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
574** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
575**
576** Next, we compute the relative distance between the original signal and
577** the modified signal and minimize that over j:
578** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
579** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
580**
581** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000582** cp1 A
583** cp2 R
584** len1 N
585** len2 n
586** aj_m1 A[j-1]
587** aj_lm1 A[j+n-1]
588** sum_ri_2 sum(R[i]^2)
589** sum_aij_2 sum(A[i+j]^2)
590** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000591**
592** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
593** is completely recalculated each step.
594*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200595/*[clinic input]
596audioop.findfit
597
598 fragment: Py_buffer
599 reference: Py_buffer
600 /
601
602Try to match reference as well as possible to a portion of fragment.
603[clinic start generated code]*/
604
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300606audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400607 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300608/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000609{
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300610 const int16_t *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000611 Py_ssize_t len1, len2;
612 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 double aj_m1, aj_lm1;
614 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000615
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200616 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200618 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 }
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300620 cp1 = (const int16_t *)fragment->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200621 len1 = fragment->len >> 1;
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300622 cp2 = (const int16_t *)reference->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200623 len2 = reference->len >> 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000624
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200625 if (len1 < len2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 PyErr_SetString(AudioopError, "First sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200627 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 }
629 sum_ri_2 = _sum2(cp2, cp2, len2);
630 sum_aij_2 = _sum2(cp1, cp1, len2);
631 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 best_result = result;
636 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 for ( j=1; j<=len1-len2; j++) {
639 aj_m1 = (double)cp1[j-1];
640 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
643 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
646 / sum_aij_2;
647
648 if ( result < best_result ) {
649 best_result = result;
650 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000651 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 }
654
655 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
656
Mark Dickinson81fece22010-05-11 13:34:35 +0000657 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000658}
659
660/*
661** findfactor finds a factor f so that the energy in A-fB is minimal.
662** See the comment for findfit for details.
663*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200664/*[clinic input]
665audioop.findfactor
666
667 fragment: Py_buffer
668 reference: Py_buffer
669 /
670
671Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.
672[clinic start generated code]*/
673
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300675audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400676 Py_buffer *reference)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300677/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000678{
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300679 const int16_t *cp1, *cp2;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200680 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000682
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200683 if (fragment->len & 1 || reference->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200685 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200687 if (fragment->len != reference->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 PyErr_SetString(AudioopError, "Samples should be same size");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200689 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 }
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300691 cp1 = (const int16_t *)fragment->buf;
692 cp2 = (const int16_t *)reference->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200693 len = fragment->len >> 1;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200694 sum_ri_2 = _sum2(cp2, cp2, len);
695 sum_aij_ri = _sum2(cp1, cp2, len);
Jack Jansena90805f1993-02-17 14:29:28 +0000696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000700}
701
702/*
703** findmax returns the index of the n-sized segment of the input sample
704** that contains the most energy.
705*/
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200706/*[clinic input]
707audioop.findmax
708
709 fragment: Py_buffer
710 length: Py_ssize_t
711 /
712
713Search fragment for a slice of specified number of samples with maximum energy.
714[clinic start generated code]*/
715
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300717audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
Larry Hastings89964c42015-04-14 18:07:59 -0400718 Py_ssize_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300719/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/
Jack Jansena90805f1993-02-17 14:29:28 +0000720{
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300721 const int16_t *cp1;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200722 Py_ssize_t len1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000723 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 double aj_m1, aj_lm1;
725 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000726
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200727 if (fragment->len & 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 PyErr_SetString(AudioopError, "Strings should be even-sized");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200729 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 }
Serhiy Storchaka8be17402016-09-11 14:48:16 +0300731 cp1 = (const int16_t *)fragment->buf;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200732 len1 = fragment->len >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200734 if (length < 0 || len1 < length) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 PyErr_SetString(AudioopError, "Input sample should be longer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200736 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 }
738
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200739 result = _sum2(cp1, cp1, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740
741 best_result = result;
742 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200744 for ( j=1; j<=len1-length; j++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 aj_m1 = (double)cp1[j-1];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200746 aj_lm1 = (double)cp1[j+length-1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747
748 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
749
750 if ( result > best_result ) {
751 best_result = result;
752 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000753 }
Jack Jansena90805f1993-02-17 14:29:28 +0000754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000756
Mark Dickinson81fece22010-05-11 13:34:35 +0000757 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000758}
759
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200760/*[clinic input]
761audioop.avgpp
762
763 fragment: Py_buffer
764 width: int
765 /
766
767Return the average peak-peak value over all samples in the fragment.
768[clinic start generated code]*/
769
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300771audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
772/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000773{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200774 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200775 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200776 double sum = 0.0;
777 unsigned int avg;
778 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000779
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200780 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000781 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200782 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200783 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200784 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200785 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200786 for (i = width; i < fragment->len; i += width) {
787 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200788 if (val != prevval) {
789 diff = val < prevval;
790 if (prevdiff == !diff) {
791 /* Derivative changed sign. Compute difference to last
792 ** extreme value and remember.
793 */
794 if (prevextremevalid) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300795 if (prevval < prevextreme)
796 sum += (double)((unsigned int)prevextreme -
797 (unsigned int)prevval);
798 else
799 sum += (double)((unsigned int)prevval -
800 (unsigned int)prevextreme);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200801 nextreme++;
802 }
803 prevextremevalid = 1;
804 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200806 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200808 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 }
810 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200811 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200813 avg = (unsigned int)(sum / (double)nextreme);
814 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000815}
816
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200817/*[clinic input]
818audioop.maxpp
819
820 fragment: Py_buffer
821 width: int
822 /
823
824Return the maximum peak-peak value in the sound fragment.
825[clinic start generated code]*/
826
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300828audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
829/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000830{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200831 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200832 int prevval, prevextremevalid = 0, prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200833 unsigned int max = 0, extremediff;
834 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000835
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200836 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000837 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200838 if (fragment->len <= width)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200839 return PyLong_FromLong(0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200840 prevval = GETRAWSAMPLE(width, fragment->buf, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200841 prevdiff = 17; /* Anything != 0, 1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200842 for (i = width; i < fragment->len; i += width) {
843 int val = GETRAWSAMPLE(width, fragment->buf, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200844 if (val != prevval) {
845 diff = val < prevval;
846 if (prevdiff == !diff) {
847 /* Derivative changed sign. Compute difference to
848 ** last extreme value and remember.
849 */
850 if (prevextremevalid) {
851 if (prevval < prevextreme)
852 extremediff = (unsigned int)prevextreme -
853 (unsigned int)prevval;
854 else
855 extremediff = (unsigned int)prevval -
856 (unsigned int)prevextreme;
857 if ( extremediff > max )
858 max = extremediff;
859 }
860 prevextremevalid = 1;
861 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200863 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200865 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200867 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000868}
869
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200870/*[clinic input]
871audioop.cross
872
873 fragment: Py_buffer
874 width: int
875 /
876
877Return the number of zero crossings in the fragment passed as an argument.
878[clinic start generated code]*/
879
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300881audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
882/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200884 Py_ssize_t i;
Mark Dickinson81fece22010-05-11 13:34:35 +0000885 int prevval;
886 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000887
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200888 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000889 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 ncross = -1;
891 prevval = 17; /* Anything <> 0,1 */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200892 for (i = 0; i < fragment->len; i += width) {
893 int val = GETRAWSAMPLE(width, fragment->buf, i) < 0;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +0300894 if (val != prevval) ncross++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 prevval = val;
896 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000897 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000898}
899
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200900/*[clinic input]
901audioop.mul
902
903 fragment: Py_buffer
904 width: int
905 factor: double
906 /
907
908Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.
909[clinic start generated code]*/
910
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300912audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400913 double factor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300914/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000915{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200916 signed char *ncp;
917 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200918 double maxval, minval;
919 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000920
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200921 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000922 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200924 maxval = (double) maxvals[width];
925 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200927 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200928 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200929 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 ncp = (signed char *)PyBytes_AsString(rv);
931
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200932 for (i = 0; i < fragment->len; i += width) {
933 double val = GETRAWSAMPLE(width, fragment->buf, i);
Victor Stinner45e4efb2018-06-06 15:50:50 +0200934 int ival = fbound(val * factor, minval, maxval);
935 SETRAWSAMPLE(width, ncp, i, ival);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 }
937 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000938}
939
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200940/*[clinic input]
941audioop.tomono
942
943 fragment: Py_buffer
944 width: int
945 lfactor: double
946 rfactor: double
947 /
948
949Convert a stereo fragment to a mono fragment.
950[clinic start generated code]*/
951
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300953audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -0400954 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300955/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +0000956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000958 Py_ssize_t len, i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200959 double maxval, minval;
960 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000961
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200962 cp = fragment->buf;
963 len = fragment->len;
964 if (!audioop_check_parameters(len, width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200965 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200966 if (((len / width) & 1) != 0) {
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000967 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200968 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000969 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200971 maxval = (double) maxvals[width];
972 minval = (double) minvals[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973
974 rv = PyBytes_FromStringAndSize(NULL, len/2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +0200975 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200976 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 ncp = (signed char *)PyBytes_AsString(rv);
978
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200979 for (i = 0; i < len; i += width*2) {
980 double val1 = GETRAWSAMPLE(width, cp, i);
981 double val2 = GETRAWSAMPLE(width, cp, i + width);
Victor Stinner45e4efb2018-06-06 15:50:50 +0200982 double val = val1 * lfactor + val2 * rfactor;
983 int ival = fbound(val, minval, maxval);
984 SETRAWSAMPLE(width, ncp, i/2, ival);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000987}
988
Serhiy Storchaka8d00d732014-01-25 11:57:59 +0200989/*[clinic input]
990audioop.tostereo
991
992 fragment: Py_buffer
993 width: int
994 lfactor: double
995 rfactor: double
996 /
997
998Generate a stereo fragment from a mono fragment.
999[clinic start generated code]*/
1000
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001002audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001003 double lfactor, double rfactor)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001004/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001005{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001006 signed char *ncp;
1007 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001008 double maxval, minval;
1009 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001010
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001011 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001012 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001013
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001014 maxval = (double) maxvals[width];
1015 minval = (double) minvals[width];
Guido van Rossumb66efa01992-06-01 16:01:24 +00001016
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001017 if (fragment->len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 PyErr_SetString(PyExc_MemoryError,
1019 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001020 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001022
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001023 rv = PyBytes_FromStringAndSize(NULL, fragment->len*2);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001024 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001025 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001027
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001028 for (i = 0; i < fragment->len; i += width) {
1029 double val = GETRAWSAMPLE(width, fragment->buf, i);
Victor Stinner45e4efb2018-06-06 15:50:50 +02001030 int val1 = fbound(val * lfactor, minval, maxval);
1031 int val2 = fbound(val * rfactor, minval, maxval);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001032 SETRAWSAMPLE(width, ncp, i*2, val1);
1033 SETRAWSAMPLE(width, ncp, i*2 + width, val2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 }
1035 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001036}
1037
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001038/*[clinic input]
1039audioop.add
1040
1041 fragment1: Py_buffer
1042 fragment2: Py_buffer
1043 width: int
1044 /
1045
1046Return a fragment which is the addition of the two samples passed as parameters.
1047[clinic start generated code]*/
1048
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001049static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001050audioop_add_impl(PyObject *module, Py_buffer *fragment1,
Larry Hastings89964c42015-04-14 18:07:59 -04001051 Py_buffer *fragment2, int width)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001052/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001053{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001054 signed char *ncp;
1055 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001056 int minval, maxval, newval;
1057 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001058
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001059 if (!audioop_check_parameters(fragment1->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001060 return NULL;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001061 if (fragment1->len != fragment2->len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 PyErr_SetString(AudioopError, "Lengths should be the same");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001063 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001065
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001066 maxval = maxvals[width];
1067 minval = minvals[width];
Guido van Rossum1851a671997-02-14 16:14:03 +00001068
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001069 rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001070 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001071 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001073
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001074 for (i = 0; i < fragment1->len; i += width) {
1075 int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
1076 int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001078 if (width < 4) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001079 newval = val1 + val2;
1080 /* truncate in case of overflow */
1081 if (newval > maxval)
1082 newval = maxval;
1083 else if (newval < minval)
1084 newval = minval;
1085 }
1086 else {
1087 double fval = (double)val1 + (double)val2;
1088 /* truncate in case of overflow */
Victor Stinner45e4efb2018-06-06 15:50:50 +02001089 newval = fbound(fval, minval, maxval);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001090 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001092 SETRAWSAMPLE(width, ncp, i, newval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 }
1094 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001095}
1096
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001097/*[clinic input]
1098audioop.bias
1099
1100 fragment: Py_buffer
1101 width: int
1102 bias: int
1103 /
1104
1105Return a fragment that is the original fragment with a bias added to each sample.
1106[clinic start generated code]*/
1107
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001109audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
1110/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001111{
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001112 signed char *ncp;
1113 Py_ssize_t i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001114 unsigned int val = 0, mask;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001115 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001116
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001117 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001118 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001120 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001121 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001122 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 ncp = (signed char *)PyBytes_AsString(rv);
1124
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001125 mask = masks[width];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001127 for (i = 0; i < fragment->len; i += width) {
1128 if (width == 1)
1129 val = GETINTX(unsigned char, fragment->buf, i);
1130 else if (width == 2)
Serhiy Storchaka8be17402016-09-11 14:48:16 +03001131 val = GETINTX(uint16_t, fragment->buf, i);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001132 else if (width == 3)
1133 val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu;
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001134 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001135 assert(width == 4);
Benjamin Peterson9b3d7702016-09-06 13:24:00 -07001136 val = GETINTX(uint32_t, fragment->buf, i);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001137 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001139 val += (unsigned int)bias;
1140 /* wrap around in case of overflow */
1141 val &= mask;
1142
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001143 if (width == 1)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001144 SETINTX(unsigned char, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001145 else if (width == 2)
Serhiy Storchaka8be17402016-09-11 14:48:16 +03001146 SETINTX(uint16_t, ncp, i, val);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001147 else if (width == 3)
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001148 SETINT24(ncp, i, (int)val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001149 else {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001150 assert(width == 4);
Benjamin Peterson9b3d7702016-09-06 13:24:00 -07001151 SETINTX(uint32_t, ncp, i, val);
Serhiy Storchakace82eb22013-10-20 09:42:26 +03001152 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 }
1154 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001155}
1156
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001157/*[clinic input]
1158audioop.reverse
1159
1160 fragment: Py_buffer
1161 width: int
1162 /
1163
1164Reverse the samples in a fragment and returns the modified fragment.
1165[clinic start generated code]*/
1166
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001168audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
1169/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/
Jack Jansen337b20e1993-02-23 13:39:57 +00001170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001172 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001173 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001174
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001175 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001176 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001177
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001178 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001179 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001180 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 ncp = (unsigned char *)PyBytes_AsString(rv);
1182
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001183 for (i = 0; i < fragment->len; i += width) {
1184 int val = GETRAWSAMPLE(width, fragment->buf, i);
1185 SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 }
1187 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001188}
1189
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001190/*[clinic input]
1191audioop.byteswap
1192
1193 fragment: Py_buffer
1194 width: int
1195 /
1196
1197Convert big-endian samples to little-endian and vice versa.
1198[clinic start generated code]*/
1199
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001200static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001201audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
1202/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001203{
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001204 unsigned char *ncp;
1205 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001206 PyObject *rv;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001207
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001208 if (!audioop_check_parameters(fragment->len, width))
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001209 return NULL;
1210
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001211 rv = PyBytes_FromStringAndSize(NULL, fragment->len);
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001212 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001213 return NULL;
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001214 ncp = (unsigned char *)PyBytes_AsString(rv);
1215
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001216 for (i = 0; i < fragment->len; i += width) {
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001217 int j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001218 for (j = 0; j < width; j++)
1219 ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001220 }
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001221 return rv;
1222}
1223
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001224/*[clinic input]
1225audioop.lin2lin
1226
1227 fragment: Py_buffer
1228 width: int
1229 newwidth: int
1230 /
1231
1232Convert samples between 1-, 2-, 3- and 4-byte formats.
1233[clinic start generated code]*/
1234
Serhiy Storchaka3062c9a2013-11-23 22:26:01 +02001235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001236audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001237 int newwidth)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001238/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/
Jack Jansena90805f1993-02-17 14:29:28 +00001239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001241 Py_ssize_t i, j;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001242 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001243
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001244 if (!audioop_check_parameters(fragment->len, width))
1245 return NULL;
1246 if (!audioop_check_size(newwidth))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001247 return NULL;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001248
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001249 if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 PyErr_SetString(PyExc_MemoryError,
1251 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001252 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001254 rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001255 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001256 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 ncp = (unsigned char *)PyBytes_AsString(rv);
1258
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001259 for (i = j = 0; i < fragment->len; i += width, j += newwidth) {
1260 int val = GETSAMPLE32(width, fragment->buf, i);
1261 SETSAMPLE32(newwidth, ncp, j, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 }
1263 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001264}
1265
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001266static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001267gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 while (b > 0) {
1270 int tmp = a % b;
1271 a = b;
1272 b = tmp;
1273 }
1274 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001275}
1276
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001277/*[clinic input]
1278audioop.ratecv
1279
1280 fragment: Py_buffer
1281 width: int
1282 nchannels: int
1283 inrate: int
1284 outrate: int
1285 state: object
1286 weightA: int = 1
1287 weightB: int = 0
1288 /
1289
1290Convert the frame rate of the input fragment.
1291[clinic start generated code]*/
1292
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001294audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001295 int nchannels, int inrate, int outrate, PyObject *state,
1296 int weightA, int weightB)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001297/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/
Roger E. Massec905fff1997-01-17 18:12:04 +00001298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001300 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 int chan, d, *prev_i, *cur_i, cur_o;
Oren Milman1d1d3e92017-08-20 18:35:36 +03001302 PyObject *samps, *str, *rv = NULL, *channel;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001304
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001305 if (!audioop_check_size(width))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 if (nchannels < 1) {
1308 PyErr_SetString(AudioopError, "# of channels should be >= 1");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001309 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001311 if (width > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 /* This overflow test is rigorously correct because
1313 both multiplicands are >= 1. Use the argument names
1314 from the docs for the error msg. */
1315 PyErr_SetString(PyExc_OverflowError,
1316 "width * nchannels too big for a C int");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001317 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001319 bytes_per_frame = width * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (weightA < 1 || weightB < 0) {
1321 PyErr_SetString(AudioopError,
1322 "weightA should be >= 1, weightB should be >= 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001323 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 }
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001325 assert(fragment->len >= 0);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001326 if (fragment->len % bytes_per_frame != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 PyErr_SetString(AudioopError, "not a whole number of frames");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001328 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 }
1330 if (inrate <= 0 || outrate <= 0) {
1331 PyErr_SetString(AudioopError, "sampling rate not > 0");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001332 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 }
1334 /* divide inrate and outrate by their greatest common divisor */
1335 d = gcd(inrate, outrate);
1336 inrate /= d;
1337 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001338 /* divide weightA and weightB by their greatest common divisor */
1339 d = gcd(weightA, weightB);
1340 weightA /= d;
Serhiy Storchaka50451eb2015-05-30 00:53:26 +03001341 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001342
Benjamin Peterson2f8bfef2016-09-07 09:26:18 -07001343 if ((size_t)nchannels > SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 PyErr_SetString(PyExc_MemoryError,
1345 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001346 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001348 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1349 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 if (prev_i == NULL || cur_i == NULL) {
1351 (void) PyErr_NoMemory();
1352 goto exit;
1353 }
1354
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001355 len = fragment->len / bytes_per_frame; /* # of frames */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356
1357 if (state == Py_None) {
1358 d = -outrate;
1359 for (chan = 0; chan < nchannels; chan++)
1360 prev_i[chan] = cur_i[chan] = 0;
1361 }
1362 else {
Oren Milman1d1d3e92017-08-20 18:35:36 +03001363 if (!PyTuple_Check(state)) {
1364 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1365 goto exit;
1366 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 if (!PyArg_ParseTuple(state,
Oren Milman1d1d3e92017-08-20 18:35:36 +03001368 "iO!;ratecv(): illegal state argument",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 &d, &PyTuple_Type, &samps))
1370 goto exit;
1371 if (PyTuple_Size(samps) != nchannels) {
1372 PyErr_SetString(AudioopError,
1373 "illegal state argument");
1374 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001375 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 for (chan = 0; chan < nchannels; chan++) {
Oren Milman1d1d3e92017-08-20 18:35:36 +03001377 channel = PyTuple_GetItem(samps, chan);
1378 if (!PyTuple_Check(channel)) {
1379 PyErr_SetString(PyExc_TypeError,
1380 "ratecv(): illegal state argument");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001381 goto exit;
Oren Milman1d1d3e92017-08-20 18:35:36 +03001382 }
1383 if (!PyArg_ParseTuple(channel,
1384 "ii;ratecv(): illegal state argument",
1385 &prev_i[chan], &cur_i[chan]))
1386 {
1387 goto exit;
1388 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001389 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001393 if (len == 0)
1394 str = PyBytes_FromStringAndSize(NULL, 0);
1395 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 /* There are len input frames, so we need (mathematically)
1397 ceiling(len*outrate/inrate) output frames, and each frame
1398 requires bytes_per_frame bytes. Computing this
1399 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001400 settle for a reasonable upper bound, though, in this
1401 case ceiling(len/inrate) * outrate. */
1402
1403 /* compute ceiling(len/inrate) without overflow */
Christian Heimesc4ab9a42014-01-27 01:12:00 +01001404 Py_ssize_t q = 1 + (len - 1) / inrate;
Mark Dickinson81fece22010-05-11 13:34:35 +00001405 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 str = NULL;
1407 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001408 str = PyBytes_FromStringAndSize(NULL,
1409 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001410 }
1411 if (str == NULL) {
1412 PyErr_SetString(PyExc_MemoryError,
1413 "not enough memory for output buffer");
1414 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 }
1416 ncp = PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001417 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418
1419 for (;;) {
1420 while (d < 0) {
1421 if (len == 0) {
1422 samps = PyTuple_New(nchannels);
1423 if (samps == NULL)
1424 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001425 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyTuple_SetItem(samps, chan,
1427 Py_BuildValue("(ii)",
1428 prev_i[chan],
1429 cur_i[chan]));
1430 if (PyErr_Occurred())
1431 goto exit;
1432 /* We have checked before that the length
1433 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001434 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 rv = PyBytes_FromStringAndSize
1436 (PyBytes_AsString(str), len);
1437 Py_DECREF(str);
1438 str = rv;
1439 if (str == NULL)
1440 goto exit;
1441 rv = Py_BuildValue("(O(iO))", str, d, samps);
1442 Py_DECREF(samps);
1443 Py_DECREF(str);
1444 goto exit; /* return rv */
1445 }
1446 for (chan = 0; chan < nchannels; chan++) {
1447 prev_i[chan] = cur_i[chan];
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001448 cur_i[chan] = GETSAMPLE32(width, cp, 0);
1449 cp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001451 cur_i[chan] = (int)(
1452 ((double)weightA * (double)cur_i[chan] +
1453 (double)weightB * (double)prev_i[chan]) /
1454 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 }
1456 len--;
1457 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001458 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 while (d >= 0) {
1460 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001461 cur_o = (int)(((double)prev_i[chan] * (double)d +
1462 (double)cur_i[chan] * (double)(outrate - d)) /
1463 (double)outrate);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001464 SETSAMPLE32(width, ncp, 0, cur_o);
1465 ncp += width;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 }
1467 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001468 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001470 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001471 PyMem_Free(prev_i);
1472 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001474}
Guido van Rossum1851a671997-02-14 16:14:03 +00001475
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001476/*[clinic input]
1477audioop.lin2ulaw
1478
1479 fragment: Py_buffer
1480 width: int
1481 /
1482
1483Convert samples in the audio fragment to u-LAW encoding.
1484[clinic start generated code]*/
1485
Roger E. Massec905fff1997-01-17 18:12:04 +00001486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001487audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
1488/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001491 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001492 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001493
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001494 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001495 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001496
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001497 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001498 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001499 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 ncp = (unsigned char *)PyBytes_AsString(rv);
1501
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001502 for (i = 0; i < fragment->len; i += width) {
1503 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001504 *ncp++ = st_14linear2ulaw(val >> 18);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 }
1506 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001507}
1508
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001509/*[clinic input]
1510audioop.ulaw2lin
1511
1512 fragment: Py_buffer
1513 width: int
1514 /
1515
1516Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.
1517[clinic start generated code]*/
1518
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001520audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1521/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/
Guido van Rossumb66efa01992-06-01 16:01:24 +00001522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001525 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001526 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001527
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001528 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001529 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001531 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 PyErr_SetString(PyExc_MemoryError,
1533 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001534 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001536 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001537 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001538 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 ncp = (signed char *)PyBytes_AsString(rv);
1540
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001541 cp = fragment->buf;
1542 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001543 int val = st_ulaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001544 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 }
1546 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001547}
1548
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001549/*[clinic input]
1550audioop.lin2alaw
1551
1552 fragment: Py_buffer
1553 width: int
1554 /
1555
1556Convert samples in the audio fragment to a-LAW encoding.
1557[clinic start generated code]*/
1558
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001560audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
1561/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 unsigned char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001564 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001565 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001566
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001567 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001568 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001569
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001570 rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001571 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001572 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 ncp = (unsigned char *)PyBytes_AsString(rv);
1574
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001575 for (i = 0; i < fragment->len; i += width) {
1576 int val = GETSAMPLE32(width, fragment->buf, i);
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001577 *ncp++ = st_linear2alaw(val >> 19);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 }
1579 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001580}
1581
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001582/*[clinic input]
1583audioop.alaw2lin
1584
1585 fragment: Py_buffer
1586 width: int
1587 /
1588
1589Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.
1590[clinic start generated code]*/
1591
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001593audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
1594/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001595{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 unsigned char *cp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001598 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001599 int val;
1600 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001601
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001602 if (!audioop_check_size(width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001603 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001605 if (fragment->len > PY_SSIZE_T_MAX/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 PyErr_SetString(PyExc_MemoryError,
1607 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001608 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001610 rv = PyBytes_FromStringAndSize(NULL, fragment->len*width);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001611 if (rv == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001612 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 ncp = (signed char *)PyBytes_AsString(rv);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001614 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001616 for (i = 0; i < fragment->len*width; i += width) {
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001617 val = st_alaw2linear16(*cp++) << 16;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001618 SETSAMPLE32(width, ncp, i, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 }
1620 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001621}
1622
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001623/*[clinic input]
1624audioop.lin2adpcm
1625
1626 fragment: Py_buffer
1627 width: int
1628 state: object
1629 /
1630
1631Convert samples to 4 bit Intel/DVI ADPCM encoding.
1632[clinic start generated code]*/
1633
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001635audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001636 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001637/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001640 Py_ssize_t i;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001641 int step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 index, sign, vpdiff, diff;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001643 PyObject *rv = NULL, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001644 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001645
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001646 if (!audioop_check_parameters(fragment->len, width))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001647 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 /* Decode state, should have (value, step) */
1650 if ( state == Py_None ) {
1651 /* First time, it seems. Set defaults */
1652 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 index = 0;
Benjamin Peterson08673c52014-01-26 10:24:24 -05001654 }
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001655 else if (!PyTuple_Check(state)) {
1656 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1657 return NULL;
1658 }
Oren Milman1d1d3e92017-08-20 18:35:36 +03001659 else if (!PyArg_ParseTuple(state, "ii;lin2adpcm(): illegal state argument",
1660 &valpred, &index))
1661 {
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001662 return NULL;
1663 }
1664 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1665 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1666 PyErr_SetString(PyExc_ValueError, "bad state");
1667 return NULL;
1668 }
1669
1670 str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2));
1671 if (str == NULL)
1672 return NULL;
1673 ncp = (signed char *)PyBytes_AsString(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674
1675 step = stepsizeTable[index];
1676 bufferstep = 1;
1677
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001678 for (i = 0; i < fragment->len; i += width) {
1679 int val = GETSAMPLE32(width, fragment->buf, i) >> 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680
1681 /* Step 1 - compute difference with previous value */
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001682 if (val < valpred) {
1683 diff = valpred - val;
1684 sign = 8;
1685 }
1686 else {
1687 diff = val - valpred;
1688 sign = 0;
1689 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690
1691 /* Step 2 - Divide and clamp */
1692 /* Note:
1693 ** This code *approximately* computes:
1694 ** delta = diff*4/step;
1695 ** vpdiff = (delta+0.5)*step/4;
1696 ** but in shift step bits are dropped. The net result of this
1697 ** is that even if you have fast mul/div hardware you cannot
1698 ** put it to good use since the fixup would be too expensive.
1699 */
1700 delta = 0;
1701 vpdiff = (step >> 3);
1702
1703 if ( diff >= step ) {
1704 delta = 4;
1705 diff -= step;
1706 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001707 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 step >>= 1;
1709 if ( diff >= step ) {
1710 delta |= 2;
1711 diff -= step;
1712 vpdiff += step;
1713 }
1714 step >>= 1;
1715 if ( diff >= step ) {
1716 delta |= 1;
1717 vpdiff += step;
1718 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 /* Step 3 - Update previous value */
1721 if ( sign )
1722 valpred -= vpdiff;
1723 else
1724 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 /* Step 4 - Clamp previous value to 16 bits */
1727 if ( valpred > 32767 )
1728 valpred = 32767;
1729 else if ( valpred < -32768 )
1730 valpred = -32768;
1731
1732 /* Step 5 - Assemble value, update index and step values */
1733 delta |= sign;
1734
1735 index += indexTable[delta];
1736 if ( index < 0 ) index = 0;
1737 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001738 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 /* Step 6 - Output value */
1741 if ( bufferstep ) {
1742 outputbuffer = (delta << 4) & 0xf0;
1743 } else {
1744 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001745 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 bufferstep = !bufferstep;
1747 }
1748 rv = Py_BuildValue("(O(ii))", str, valpred, index);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001749 Py_DECREF(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001751}
1752
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001753/*[clinic input]
1754audioop.adpcm2lin
1755
1756 fragment: Py_buffer
1757 width: int
1758 state: object
1759 /
1760
1761Decode an Intel/DVI ADPCM coded fragment to a linear fragment.
1762[clinic start generated code]*/
1763
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001765audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Larry Hastings89964c42015-04-14 18:07:59 -04001766 PyObject *state)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001767/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/
Guido van Rossumb64e6351992-07-06 14:21:56 +00001768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 signed char *cp;
1770 signed char *ncp;
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001771 Py_ssize_t i, outlen;
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001772 int valpred, step, delta, index, sign, vpdiff;
1773 PyObject *rv, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001774 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001775
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001776 if (!audioop_check_size(width))
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001777 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 /* Decode state, should have (value, step) */
1780 if ( state == Py_None ) {
1781 /* First time, it seems. Set defaults */
1782 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 index = 0;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001784 }
1785 else if (!PyTuple_Check(state)) {
Victor Stinnerdaeffd22014-01-03 03:26:47 +01001786 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001787 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001788 }
Oren Milman1d1d3e92017-08-20 18:35:36 +03001789 else if (!PyArg_ParseTuple(state, "ii;adpcm2lin(): illegal state argument",
1790 &valpred, &index))
1791 {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001792 return NULL;
Serhiy Storchaka449e2be2015-06-28 17:52:09 +03001793 }
1794 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1795 (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) {
1796 PyErr_SetString(PyExc_ValueError, "bad state");
1797 return NULL;
1798 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001800 if (fragment->len > (PY_SSIZE_T_MAX/2)/width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 PyErr_SetString(PyExc_MemoryError,
1802 "not enough memory for output buffer");
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001803 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 }
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001805 outlen = fragment->len*width*2;
Serhiy Storchakaeaea5e92013-10-19 21:10:46 +03001806 str = PyBytes_FromStringAndSize(NULL, outlen);
Serhiy Storchaka711e91b2013-11-10 21:44:36 +02001807 if (str == NULL)
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001808 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 ncp = (signed char *)PyBytes_AsString(str);
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001810 cp = fragment->buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811
1812 step = stepsizeTable[index];
1813 bufferstep = 0;
1814
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001815 for (i = 0; i < outlen; i += width) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 /* Step 1 - get the delta value and compute next index */
1817 if ( bufferstep ) {
1818 delta = inputbuffer & 0xf;
1819 } else {
1820 inputbuffer = *cp++;
1821 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001822 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 bufferstep = !bufferstep;
1825
1826 /* Step 2 - Find new index value (for later) */
1827 index += indexTable[delta];
1828 if ( index < 0 ) index = 0;
1829 if ( index > 88 ) index = 88;
1830
1831 /* Step 3 - Separate sign and magnitude */
1832 sign = delta & 8;
1833 delta = delta & 7;
1834
1835 /* Step 4 - Compute difference and new predicted value */
1836 /*
1837 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1838 ** in adpcm_coder.
1839 */
1840 vpdiff = step >> 3;
1841 if ( delta & 4 ) vpdiff += step;
1842 if ( delta & 2 ) vpdiff += step>>1;
1843 if ( delta & 1 ) vpdiff += step>>2;
1844
1845 if ( sign )
1846 valpred -= vpdiff;
1847 else
1848 valpred += vpdiff;
1849
1850 /* Step 5 - clamp output value */
1851 if ( valpred > 32767 )
1852 valpred = 32767;
1853 else if ( valpred < -32768 )
1854 valpred = -32768;
1855
1856 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001857 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 /* Step 6 - Output value */
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001860 SETSAMPLE32(width, ncp, i, valpred << 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1864 Py_DECREF(str);
1865 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001866}
1867
Larry Hastingsf256c222014-01-25 21:30:37 -08001868#include "clinic/audioop.c.h"
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001869
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001870static PyMethodDef audioop_methods[] = {
Serhiy Storchaka8d00d732014-01-25 11:57:59 +02001871 AUDIOOP_MAX_METHODDEF
1872 AUDIOOP_MINMAX_METHODDEF
1873 AUDIOOP_AVG_METHODDEF
1874 AUDIOOP_MAXPP_METHODDEF
1875 AUDIOOP_AVGPP_METHODDEF
1876 AUDIOOP_RMS_METHODDEF
1877 AUDIOOP_FINDFIT_METHODDEF
1878 AUDIOOP_FINDMAX_METHODDEF
1879 AUDIOOP_FINDFACTOR_METHODDEF
1880 AUDIOOP_CROSS_METHODDEF
1881 AUDIOOP_MUL_METHODDEF
1882 AUDIOOP_ADD_METHODDEF
1883 AUDIOOP_BIAS_METHODDEF
1884 AUDIOOP_ULAW2LIN_METHODDEF
1885 AUDIOOP_LIN2ULAW_METHODDEF
1886 AUDIOOP_ALAW2LIN_METHODDEF
1887 AUDIOOP_LIN2ALAW_METHODDEF
1888 AUDIOOP_LIN2LIN_METHODDEF
1889 AUDIOOP_ADPCM2LIN_METHODDEF
1890 AUDIOOP_LIN2ADPCM_METHODDEF
1891 AUDIOOP_TOMONO_METHODDEF
1892 AUDIOOP_TOSTEREO_METHODDEF
1893 AUDIOOP_GETSAMPLE_METHODDEF
1894 AUDIOOP_REVERSE_METHODDEF
1895 AUDIOOP_BYTESWAP_METHODDEF
1896 AUDIOOP_RATECV_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001898};
1899
Martin v. Löwis1a214512008-06-11 05:26:20 +00001900
1901static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 PyModuleDef_HEAD_INIT,
1903 "audioop",
1904 NULL,
1905 -1,
1906 audioop_methods,
1907 NULL,
1908 NULL,
1909 NULL,
1910 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001911};
1912
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001913PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001914PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 PyObject *m, *d;
1917 m = PyModule_Create(&audioopmodule);
1918 if (m == NULL)
1919 return NULL;
1920 d = PyModule_GetDict(m);
1921 if (d == NULL)
1922 return NULL;
1923 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1924 if (AudioopError != NULL)
1925 PyDict_SetItemString(d,"error",AudioopError);
1926 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001927}