blob: 91f585c8f0391b89cd93e1643c8faa175b44db34 [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
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Anthony Baxter17471432006-03-20 05:58:21 +000018typedef short PyInt16;
19
Guido van Rossum7b1e9741994-08-29 10:46:42 +000020#if defined(__CHAR_UNSIGNED__)
21#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000022/* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000026
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020027static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
Victor Stinnere5b79c52018-06-06 17:51:07 +020028/* -1 trick is needed on Windows to support -0x80000000 without a warning */
29static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020030static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
31
32static int
33fbound(double val, double minval, double maxval)
34{
Victor Stinnerb17d4092018-06-06 17:12:39 +020035 if (val > maxval) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020036 val = maxval;
Victor Stinnerb17d4092018-06-06 17:12:39 +020037 }
38 else if (val < minval + 1.0) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020039 val = minval;
Victor Stinnerb17d4092018-06-06 17:12:39 +020040 }
41
42 /* Round towards minus infinity (-inf) */
43 val = floor(val);
44
45 /* Cast double to integer: round towards zero */
46 return (int)val;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020047}
48
49
Anthony Baxterfa869072006-03-20 05:21:58 +000050/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000051** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
52
Anthony Baxterfa869072006-03-20 05:21:58 +000053/* From g711.c:
54 *
55 * December 30, 1994:
56 * Functions linear2alaw, linear2ulaw have been updated to correctly
57 * convert unquantized 16 bit values.
58 * Tables for direct u- to A-law and A- to u-law conversions have been
59 * corrected.
60 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
61 * bli@cpk.auc.dk
62 *
63 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000064#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
65#define CLIP 32635
Martin Panter4f23cab2016-05-08 13:45:55 +000066#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Anthony Baxter17471432006-03-20 05:58:21 +000067#define QUANT_MASK (0xf) /* Quantization field mask. */
68#define SEG_SHIFT (4) /* Left shift for segment number. */
69#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000070
Anthony Baxter17471432006-03-20 05:58:21 +000071static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
72 0x1FF, 0x3FF, 0x7FF, 0xFFF};
73static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
74 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
Anthony Baxterfa869072006-03-20 05:21:58 +000075
Neal Norwitz49c65d02006-03-20 06:34:06 +000076static PyInt16
77search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000078{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000079 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000080
Antoine Pitrouc83ea132010-05-09 14:46:46 +000081 for (i = 0; i < size; i++) {
82 if (val <= *table++)
83 return (i);
84 }
85 return (size);
Anthony Baxterfa869072006-03-20 05:21:58 +000086}
87#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
88#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000089
Neal Norwitz49c65d02006-03-20 06:34:06 +000090static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000091 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
92 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
93 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
94 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
95 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
96 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
97 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
98 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
99 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
100 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
101 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
102 -1052, -988, -924, -876, -844, -812, -780,
103 -748, -716, -684, -652, -620, -588, -556,
104 -524, -492, -460, -428, -396, -372, -356,
105 -340, -324, -308, -292, -276, -260, -244,
106 -228, -212, -196, -180, -164, -148, -132,
107 -120, -112, -104, -96, -88, -80, -72,
108 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000109 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21:58 +0000110 27004, 25980, 24956, 23932, 22908, 21884, 20860,
111 19836, 18812, 17788, 16764, 15996, 15484, 14972,
112 14460, 13948, 13436, 12924, 12412, 11900, 11388,
113 10876, 10364, 9852, 9340, 8828, 8316, 7932,
114 7676, 7420, 7164, 6908, 6652, 6396, 6140,
115 5884, 5628, 5372, 5116, 4860, 4604, 4348,
116 4092, 3900, 3772, 3644, 3516, 3388, 3260,
117 3132, 3004, 2876, 2748, 2620, 2492, 2364,
118 2236, 2108, 1980, 1884, 1820, 1756, 1692,
119 1628, 1564, 1500, 1436, 1372, 1308, 1244,
120 1180, 1116, 1052, 988, 924, 876, 844,
121 812, 780, 748, 716, 684, 652, 620,
122 588, 556, 524, 492, 460, 428, 396,
123 372, 356, 340, 324, 308, 292, 276,
124 260, 244, 228, 212, 196, 180, 164,
125 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000126 80, 72, 64, 56, 48, 40, 32,
127 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000128};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000129
Anthony Baxterfa869072006-03-20 05:21:58 +0000130/*
131 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panterb362f752015-11-02 03:37:02 +0000132 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000133 * the data shifted such that it only contains information in the lower
134 * 14-bits.
135 *
136 * In order to simplify the encoding process, the original linear magnitude
137 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
138 * (33 - 8191). The result can be seen in the following encoding table:
139 *
Anthony Baxter17471432006-03-20 05:58:21 +0000140 * Biased Linear Input Code Compressed Code
141 * ------------------------ ---------------
142 * 00000001wxyza 000wxyz
143 * 0000001wxyzab 001wxyz
144 * 000001wxyzabc 010wxyz
145 * 00001wxyzabcd 011wxyz
146 * 0001wxyzabcde 100wxyz
147 * 001wxyzabcdef 101wxyz
148 * 01wxyzabcdefg 110wxyz
149 * 1wxyzabcdefgh 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000150 *
151 * Each biased linear code has a leading 1 which identifies the segment
152 * number. The value of the segment number is equal to 7 minus the number
153 * of leading 0's. The quantization interval is directly available as the
154 * four bits wxyz. * The trailing bits (a - h) are ignored.
155 *
156 * Ordinarily the complement of the resulting code word is used for
157 * transmission, and so the code word is complemented before it is returned.
158 *
159 * For further information see John C. Bellamy's Digital Telephony, 1982,
160 * John Wiley & Sons, pps 98-111 and 472-476.
161 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000162static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000163st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000164{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000165 PyInt16 mask;
166 PyInt16 seg;
167 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000168
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000169 /* The original sox code does this in the calling function, not here */
170 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000171
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000172 /* u-law inverts all bits */
173 /* Get the sign and the magnitude of the value. */
174 if (pcm_val < 0) {
175 pcm_val = -pcm_val;
176 mask = 0x7F;
177 } else {
178 mask = 0xFF;
179 }
180 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
181 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000182
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000183 /* Convert the scaled magnitude to segment number. */
184 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000185
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000186 /*
187 * Combine the sign, segment, quantization bits;
188 * and complement the code word.
189 */
190 if (seg >= 8) /* out of range, return maximum value. */
191 return (unsigned char) (0x7F ^ mask);
192 else {
193 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
194 return (uval ^ mask);
195 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000196
197}
198
Neal Norwitz49c65d02006-03-20 06:34:06 +0000199static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000200 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
201 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
202 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
203 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
204 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
205 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
206 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
207 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
208 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
209 -13568, -344, -328, -376, -360, -280, -264,
210 -312, -296, -472, -456, -504, -488, -408,
211 -392, -440, -424, -88, -72, -120, -104,
212 -24, -8, -56, -40, -216, -200, -248,
213 -232, -152, -136, -184, -168, -1376, -1312,
214 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
215 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
216 -688, -656, -752, -720, -560, -528, -624,
217 -592, -944, -912, -1008, -976, -816, -784,
218 -880, -848, 5504, 5248, 6016, 5760, 4480,
219 4224, 4992, 4736, 7552, 7296, 8064, 7808,
220 6528, 6272, 7040, 6784, 2752, 2624, 3008,
221 2880, 2240, 2112, 2496, 2368, 3776, 3648,
222 4032, 3904, 3264, 3136, 3520, 3392, 22016,
223 20992, 24064, 23040, 17920, 16896, 19968, 18944,
224 30208, 29184, 32256, 31232, 26112, 25088, 28160,
225 27136, 11008, 10496, 12032, 11520, 8960, 8448,
226 9984, 9472, 15104, 14592, 16128, 15616, 13056,
227 12544, 14080, 13568, 344, 328, 376, 360,
228 280, 264, 312, 296, 472, 456, 504,
229 488, 408, 392, 440, 424, 88, 72,
230 120, 104, 24, 8, 56, 40, 216,
231 200, 248, 232, 152, 136, 184, 168,
232 1376, 1312, 1504, 1440, 1120, 1056, 1248,
233 1184, 1888, 1824, 2016, 1952, 1632, 1568,
234 1760, 1696, 688, 656, 752, 720, 560,
235 528, 624, 592, 944, 912, 1008, 976,
236 816, 784, 880, 848
237};
238
239/*
Martin Panter4f23cab2016-05-08 13:45:55 +0000240 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
241 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000242 * the data shifted such that it only contains information in the lower
243 * 13-bits.
244 *
Anthony Baxter17471432006-03-20 05:58:21 +0000245 * Linear Input Code Compressed Code
246 * ------------------------ ---------------
247 * 0000000wxyza 000wxyz
248 * 0000001wxyza 001wxyz
249 * 000001wxyzab 010wxyz
250 * 00001wxyzabc 011wxyz
251 * 0001wxyzabcd 100wxyz
252 * 001wxyzabcde 101wxyz
253 * 01wxyzabcdef 110wxyz
254 * 1wxyzabcdefg 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000255 *
256 * For further information see John C. Bellamy's Digital Telephony, 1982,
257 * John Wiley & Sons, pps 98-111 and 472-476.
258 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000259static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000260st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000261{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000262 PyInt16 mask;
263 short seg;
264 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000265
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000266 /* The original sox code does this in the calling function, not here */
267 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000268
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000269 /* A-law using even bit inversion */
270 if (pcm_val >= 0) {
271 mask = 0xD5; /* sign (7th) bit = 1 */
272 } else {
273 mask = 0x55; /* sign bit = 0 */
274 pcm_val = -pcm_val - 1;
275 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000276
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000277 /* Convert the scaled magnitude to segment number. */
278 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000279
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000280 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000281
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000282 if (seg >= 8) /* out of range, return maximum value. */
283 return (unsigned char) (0x7F ^ mask);
284 else {
285 aval = (unsigned char) seg << SEG_SHIFT;
286 if (seg < 2)
287 aval |= (pcm_val >> 1) & QUANT_MASK;
288 else
289 aval |= (pcm_val >> seg) & QUANT_MASK;
290 return (aval ^ mask);
291 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000292}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000293/* End of code taken from sox */
294
Guido van Rossumb64e6351992-07-06 14:21:56 +0000295/* Intel ADPCM step variation table */
296static int indexTable[16] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000297 -1, -1, -1, -1, 2, 4, 6, 8,
298 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000299};
300
301static int stepsizeTable[89] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000302 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
303 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
304 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
305 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
306 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
307 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
308 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
309 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
310 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000311};
Brett Cannon9824e7f2010-05-03 23:42:40 +0000312
Guido van Rossumb66efa01992-06-01 16:01:24 +0000313#define CHARP(cp, i) ((signed char *)(cp+i))
314#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000315#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000316
317
318
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000319static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000320
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000321static int
322audioop_check_size(int size)
323{
324 if (size != 1 && size != 2 && size != 4) {
325 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
326 return 0;
327 }
328 else
329 return 1;
330}
331
332static int
333audioop_check_parameters(int len, int size)
334{
335 if (!audioop_check_size(size))
336 return 0;
337 if (len % size != 0) {
338 PyErr_SetString(AudioopError, "not a whole number of frames");
339 return 0;
340 }
341 return 1;
342}
343
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000344static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000345audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000346{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000347 signed char *cp;
348 int len, size, val = 0;
349 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000350
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
352 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000353 if (!audioop_check_parameters(len, size))
354 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000355 if ( i < 0 || i >= len/size ) {
356 PyErr_SetString(AudioopError, "Index out of range");
357 return 0;
358 }
359 if ( size == 1 ) val = (int)*CHARP(cp, i);
360 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
361 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
362 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000363}
364
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000365static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000366audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000367{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000368 signed char *cp;
369 int len, size, val = 0;
370 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200371 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000372
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000373 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
374 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000375 if (!audioop_check_parameters(len, size))
376 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000377 for ( i=0; i<len; i+= size) {
378 if ( size == 1 ) val = (int)*CHARP(cp, i);
379 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
380 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200381 if (val < 0) absval = (-val);
382 else absval = val;
383 if (absval > max) max = absval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000384 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200385 if (max <= INT_MAX)
386 return PyInt_FromLong(max);
387 else
388 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000389}
390
391static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000392audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000393{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000394 signed char *cp;
395 int len, size, val = 0;
396 int i;
Victor Stinnere5b79c52018-06-06 17:51:07 +0200397 /* -1 trick below is needed on Windows to support -0x80000000 without
398 a warning */
399 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000400
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000401 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
402 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000403 if (!audioop_check_parameters(len, size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000404 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000405 for (i = 0; i < len; i += size) {
406 if (size == 1) val = (int) *CHARP(cp, i);
407 else if (size == 2) val = (int) *SHORTP(cp, i);
408 else if (size == 4) val = (int) *LONGP(cp, i);
409 if (val > max) max = val;
410 if (val < min) min = val;
411 }
412 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000413}
414
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000415static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000416audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000417{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000418 signed char *cp;
419 int len, size, val = 0;
420 int i;
421 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000422
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000423 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
424 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000425 if (!audioop_check_parameters(len, size))
426 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000427 for ( i=0; i<len; i+= size) {
428 if ( size == 1 ) val = (int)*CHARP(cp, i);
429 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
430 else if ( size == 4 ) val = (int)*LONGP(cp, i);
431 avg += val;
432 }
433 if ( len == 0 )
434 val = 0;
435 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200436 val = (int)floor(avg / (double)(len/size));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000437 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000438}
439
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000440static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000441audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000442{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000443 signed char *cp;
444 int len, size, val = 0;
445 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200446 unsigned int res;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000447 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000448
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000449 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
450 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000451 if (!audioop_check_parameters(len, size))
452 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000453 for ( i=0; i<len; i+= size) {
454 if ( size == 1 ) val = (int)*CHARP(cp, i);
455 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
456 else if ( size == 4 ) val = (int)*LONGP(cp, i);
457 sum_squares += (double)val*(double)val;
458 }
459 if ( len == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200460 res = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000461 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200462 res = (unsigned int)sqrt(sum_squares / (double)(len/size));
463 if (res <= INT_MAX)
464 return PyInt_FromLong(res);
465 else
466 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000467}
468
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000469static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000470{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000471 int i;
472 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000473
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000474 for( i=0; i<len; i++) {
475 sum = sum + (double)a[i]*(double)b[i];
476 }
477 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000478}
479
480/*
481** Findfit tries to locate a sample within another sample. Its main use
482** is in echo-cancellation (to find the feedback of the output signal in
483** the input signal).
484** The method used is as follows:
485**
486** let R be the reference signal (length n) and A the input signal (length N)
487** with N > n, and let all sums be over i from 0 to n-1.
488**
489** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
490** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
491** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
492**
493** Next, we compute the relative distance between the original signal and
494** the modified signal and minimize that over j:
495** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
496** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
497**
498** In the code variables correspond as follows:
Anthony Baxter17471432006-03-20 05:58:21 +0000499** cp1 A
500** cp2 R
501** len1 N
502** len2 n
503** aj_m1 A[j-1]
504** aj_lm1 A[j+n-1]
505** sum_ri_2 sum(R[i]^2)
506** sum_aij_2 sum(A[i+j]^2)
507** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000508**
509** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
510** is completely recalculated each step.
511*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000512static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000513audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000514{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000515 short *cp1, *cp2;
516 int len1, len2;
517 int j, best_j;
518 double aj_m1, aj_lm1;
519 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000520
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000521 /* Passing a short** for an 's' argument is correct only
522 if the string contents is aligned for interpretation
523 as short[]. Due to the definition of PyStringObject,
524 this is currently (Python 2.6) the case. */
525 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
526 (char**)&cp1, &len1, (char**)&cp2, &len2) )
527 return 0;
528 if ( len1 & 1 || len2 & 1 ) {
529 PyErr_SetString(AudioopError, "Strings should be even-sized");
530 return 0;
531 }
532 len1 >>= 1;
533 len2 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000534
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000535 if ( len1 < len2 ) {
536 PyErr_SetString(AudioopError, "First sample should be longer");
537 return 0;
538 }
539 sum_ri_2 = _sum2(cp2, cp2, len2);
540 sum_aij_2 = _sum2(cp1, cp1, len2);
541 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000542
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000543 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000544
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000545 best_result = result;
546 best_j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000547
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000548 for (j=1; j<=len1-len2; j++) {
549 aj_m1 = (double)cp1[j-1];
550 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000551
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000552 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
553 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000554
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000555 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
556 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000557
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000558 if ( result < best_result ) {
559 best_result = result;
560 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000561 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000562
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000563 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000564
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000565 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
566
567 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000568}
569
570/*
571** findfactor finds a factor f so that the energy in A-fB is minimal.
572** See the comment for findfit for details.
573*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000574static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000575audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000576{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000577 short *cp1, *cp2;
578 int len1, len2;
579 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000580
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000581 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
582 (char**)&cp1, &len1, (char**)&cp2, &len2) )
583 return 0;
584 if ( len1 & 1 || len2 & 1 ) {
585 PyErr_SetString(AudioopError, "Strings should be even-sized");
586 return 0;
587 }
588 if ( len1 != len2 ) {
589 PyErr_SetString(AudioopError, "Samples should be same size");
590 return 0;
591 }
592 len2 >>= 1;
593 sum_ri_2 = _sum2(cp2, cp2, len2);
594 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000595
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000596 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000597
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000598 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000599}
600
601/*
602** findmax returns the index of the n-sized segment of the input sample
603** that contains the most energy.
604*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000606audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000607{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000608 short *cp1;
609 int len1, len2;
610 int j, best_j;
611 double aj_m1, aj_lm1;
612 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000613
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000614 if ( !PyArg_ParseTuple(args, "s#i:findmax",
615 (char**)&cp1, &len1, &len2) )
616 return 0;
617 if ( len1 & 1 ) {
618 PyErr_SetString(AudioopError, "Strings should be even-sized");
619 return 0;
620 }
621 len1 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000622
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000623 if ( len2 < 0 || len1 < len2 ) {
624 PyErr_SetString(AudioopError, "Input sample should be longer");
625 return 0;
626 }
627
628 result = _sum2(cp1, cp1, len2);
629
630 best_result = result;
631 best_j = 0;
632
633 for (j=1; j<=len1-len2; j++) {
634 aj_m1 = (double)cp1[j-1];
635 aj_lm1 = (double)cp1[j+len2-1];
636
637 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
638
639 if ( result > best_result ) {
640 best_result = result;
641 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000642 }
Jack Jansena90805f1993-02-17 14:29:28 +0000643
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000644 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000645
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000646 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000647}
648
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000650audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000651{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000652 signed char *cp;
653 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
654 prevextreme = 0;
655 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200656 double sum = 0.0;
657 unsigned int avg;
658 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000659
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
661 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000662 if (!audioop_check_parameters(len, size))
663 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200664 if (len <= size*2)
665 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000666 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
667 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
668 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200669 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000670 for ( i=size; i<len; i+= size) {
671 if ( size == 1 ) val = (int)*CHARP(cp, i);
672 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
673 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200674 if (val != prevval) {
675 diff = val < prevval;
676 if (prevdiff == !diff) {
677 /* Derivative changed sign. Compute difference to last
678 ** extreme value and remember.
679 */
680 if (prevextremevalid) {
681 sum += fabs((double)prevval - (double)prevextreme);
682 nextreme++;
683 }
684 prevextremevalid = 1;
685 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000686 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200687 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000688 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200689 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000690 }
691 if ( nextreme == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200692 avg = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000693 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200694 avg = (unsigned int)(sum / (double)nextreme);
695 if (avg <= INT_MAX)
696 return PyInt_FromLong(avg);
697 else
698 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000699}
700
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000701static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000702audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000703{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000704 signed char *cp;
705 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
706 prevextreme = 0;
707 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200708 unsigned int max = 0, extremediff;
709 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000710
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000711 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
712 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000713 if (!audioop_check_parameters(len, size))
714 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200715 if (len <= size)
716 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000717 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
718 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
719 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200720 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000721 for ( i=size; i<len; i+= size) {
722 if ( size == 1 ) val = (int)*CHARP(cp, i);
723 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
724 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200725 if (val != prevval) {
726 diff = val < prevval;
727 if (prevdiff == !diff) {
728 /* Derivative changed sign. Compute difference to
729 ** last extreme value and remember.
730 */
731 if (prevextremevalid) {
732 if (prevval < prevextreme)
733 extremediff = (unsigned int)prevextreme -
734 (unsigned int)prevval;
735 else
736 extremediff = (unsigned int)prevval -
737 (unsigned int)prevextreme;
738 if ( extremediff > max )
739 max = extremediff;
740 }
741 prevextremevalid = 1;
742 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000743 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200744 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000745 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200746 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000747 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200748 if (max <= INT_MAX)
749 return PyInt_FromLong(max);
750 else
751 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000752}
753
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000754static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000755audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000756{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000757 signed char *cp;
758 int len, size, val = 0;
759 int i;
760 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000762 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
763 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000764 if (!audioop_check_parameters(len, size))
765 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000766 ncross = -1;
767 prevval = 17; /* Anything <> 0,1 */
768 for ( i=0; i<len; i+= size) {
769 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
770 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
771 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
772 val = val & 1;
773 if ( val != prevval ) ncross++;
774 prevval = val;
775 }
776 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000777}
778
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000779static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000780audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000781{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 signed char *cp, *ncp;
783 int len, size, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200784 double factor, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000785 PyObject *rv;
786 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000788 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
789 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000790 if (!audioop_check_parameters(len, size))
791 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000792
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200793 maxval = (double) maxvals[size];
794 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000795
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000796 rv = PyString_FromStringAndSize(NULL, len);
797 if ( rv == 0 )
798 return 0;
799 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000800
801
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000802 for ( i=0; i < len; i += size ) {
803 if ( size == 1 ) val = (int)*CHARP(cp, i);
804 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
805 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Victor Stinnerb17d4092018-06-06 17:12:39 +0200806 fval = (double)val * factor;
807 val = fbound(fval, minval, maxval);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000808 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
809 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
810 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
811 }
812 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000813}
814
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000815static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000816audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000817{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000818 signed char *cp, *ncp;
819 int len, size, val1 = 0, val2 = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200820 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000821 PyObject *rv;
822 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000823
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000824 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
825 &cp, &len, &size, &fac1, &fac2 ) )
826 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000827 if (!audioop_check_parameters(len, size))
828 return NULL;
829 if (((len / size) & 1) != 0) {
830 PyErr_SetString(AudioopError, "not a whole number of frames");
831 return NULL;
832 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000833
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200834 maxval = (double) maxvals[size];
835 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000836
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000837 rv = PyString_FromStringAndSize(NULL, len/2);
838 if ( rv == 0 )
839 return 0;
840 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000841
842
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000843 for ( i=0; i < len; i += size*2 ) {
844 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
845 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
846 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
847 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
848 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
849 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
Victor Stinnerb17d4092018-06-06 17:12:39 +0200850 fval = (double)val1 * fac1 + (double)val2 * fac2;
851 val1 = fbound(fval, minval, maxval);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000852 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
853 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
854 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
855 }
856 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000857}
858
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000859static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000860audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000861{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 signed char *cp, *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +0000863 int len, size, val1, val2, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200864 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000865 PyObject *rv;
866 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000867
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000868 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
869 &cp, &len, &size, &fac1, &fac2 ) )
870 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000871 if (!audioop_check_parameters(len, size))
872 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000873
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200874 maxval = (double) maxvals[size];
875 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000876
Mark Dickinson932e1622010-05-10 16:07:42 +0000877 if (len > INT_MAX/2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000878 PyErr_SetString(PyExc_MemoryError,
879 "not enough memory for output buffer");
880 return 0;
881 }
Gregory P. Smith9d534572008-06-11 07:41:16 +0000882
Mark Dickinson932e1622010-05-10 16:07:42 +0000883 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000884 if ( rv == 0 )
885 return 0;
886 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000887
888
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000889 for ( i=0; i < len; i += size ) {
890 if ( size == 1 ) val = (int)*CHARP(cp, i);
891 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
892 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893
Victor Stinnerb17d4092018-06-06 17:12:39 +0200894 fval = (double)val * fac1;
895 val1 = fbound(fval, minval, maxval);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000896
Victor Stinnerb17d4092018-06-06 17:12:39 +0200897 fval = (double)val * fac2;
898 val2 = fbound(fval, minval, maxval);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000899
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000900 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
901 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
902 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000903
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000904 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
905 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
906 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
907 }
908 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000909}
910
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000911static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000912audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000913{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000914 signed char *cp1, *cp2, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200915 int len1, len2, size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000916 PyObject *rv;
917 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000918
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000919 if ( !PyArg_ParseTuple(args, "s#s#i:add",
920 &cp1, &len1, &cp2, &len2, &size ) )
921 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000922 if (!audioop_check_parameters(len1, size))
923 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000924 if ( len1 != len2 ) {
925 PyErr_SetString(AudioopError, "Lengths should be the same");
926 return 0;
927 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000928
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200929 maxval = maxvals[size];
930 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000931
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000932 rv = PyString_FromStringAndSize(NULL, len1);
933 if ( rv == 0 )
934 return 0;
935 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000936
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000937 for ( i=0; i < len1; i += size ) {
938 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
939 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
940 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000941
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000942 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
943 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
944 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000945
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200946 if (size < 4) {
947 newval = val1 + val2;
948 /* truncate in case of overflow */
949 if (newval > maxval)
950 newval = maxval;
951 else if (newval < minval)
952 newval = minval;
953 }
954 else {
955 double fval = (double)val1 + (double)val2;
956 /* truncate in case of overflow */
Victor Stinnerb17d4092018-06-06 17:12:39 +0200957 newval = fbound(fval, minval, maxval);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200958 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000959
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000960 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
961 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
962 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
963 }
964 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000965}
966
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000967static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000968audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000969{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000970 signed char *cp, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200971 int len, size;
972 unsigned int val = 0, mask;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000973 PyObject *rv;
974 int i;
975 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000976
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000977 if ( !PyArg_ParseTuple(args, "s#ii:bias",
978 &cp, &len, &size , &bias) )
979 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000980
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000981 if (!audioop_check_parameters(len, size))
982 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000983
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000984 rv = PyString_FromStringAndSize(NULL, len);
985 if ( rv == 0 )
986 return 0;
987 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000988
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200989 mask = masks[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000990
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000991 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200992 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
993 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
994 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000995
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200996 val += (unsigned int)bias;
997 /* wrap around in case of overflow */
998 val &= mask;
999
1000 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
1001 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
1002 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001003 }
1004 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001005}
1006
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001007static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001008audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001009{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001010 signed char *cp;
1011 unsigned char *ncp;
1012 int len, size, val = 0;
1013 PyObject *rv;
1014 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001015
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001016 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1017 &cp, &len, &size) )
1018 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001019
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001020 if (!audioop_check_parameters(len, size))
1021 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001022
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001023 rv = PyString_FromStringAndSize(NULL, len);
1024 if ( rv == 0 )
1025 return 0;
1026 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001027
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001028 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001029 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1030 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1031 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansen337b20e1993-02-23 13:39:57 +00001032
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001033 j = len - i - size;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001034
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001035 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1036 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1037 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001038 }
1039 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001040}
1041
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001042static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001043audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001044{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001045 signed char *cp;
1046 unsigned char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001047 int len, size, size2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001048 PyObject *rv;
1049 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001050
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001051 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1052 &cp, &len, &size, &size2) )
1053 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001054
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001055 if (!audioop_check_parameters(len, size))
1056 return NULL;
1057 if (!audioop_check_size(size2))
1058 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001059
Mark Dickinson932e1622010-05-10 16:07:42 +00001060 if (len/size > INT_MAX/size2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001061 PyErr_SetString(PyExc_MemoryError,
1062 "not enough memory for output buffer");
1063 return 0;
1064 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001065 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001066 if ( rv == 0 )
1067 return 0;
1068 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001069
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001070 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001071 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1072 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1073 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansena90805f1993-02-17 14:29:28 +00001074
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001075 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1076 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1077 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001078 }
1079 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001080}
1081
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001082static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001083gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001084{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001085 while (b > 0) {
1086 int tmp = a % b;
1087 a = b;
1088 b = tmp;
1089 }
1090 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001091}
1092
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001093static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001094audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001095{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001096 char *cp, *ncp;
1097 int len, size, nchannels, inrate, outrate, weightA, weightB;
1098 int chan, d, *prev_i, *cur_i, cur_o;
Oren Milmanbc80fd12017-08-26 21:56:31 +03001099 PyObject *state, *samps, *str, *rv = NULL, *channel;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001100 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001101
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001102 weightA = 1;
1103 weightB = 0;
1104 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1105 &nchannels, &inrate, &outrate, &state,
1106 &weightA, &weightB))
1107 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001108 if (!audioop_check_size(size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001109 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001110 if (nchannels < 1) {
1111 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1112 return NULL;
1113 }
1114 bytes_per_frame = size * nchannels;
1115 if (bytes_per_frame / nchannels != size) {
1116 /* This overflow test is rigorously correct because
1117 both multiplicands are >= 1. Use the argument names
1118 from the docs for the error msg. */
1119 PyErr_SetString(PyExc_OverflowError,
1120 "width * nchannels too big for a C int");
1121 return NULL;
1122 }
1123 if (weightA < 1 || weightB < 0) {
1124 PyErr_SetString(AudioopError,
1125 "weightA should be >= 1, weightB should be >= 0");
1126 return NULL;
1127 }
1128 if (len % bytes_per_frame != 0) {
1129 PyErr_SetString(AudioopError, "not a whole number of frames");
1130 return NULL;
1131 }
1132 if (inrate <= 0 || outrate <= 0) {
1133 PyErr_SetString(AudioopError, "sampling rate not > 0");
1134 return NULL;
1135 }
1136 /* divide inrate and outrate by their greatest common divisor */
1137 d = gcd(inrate, outrate);
1138 inrate /= d;
1139 outrate /= d;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001140 /* divide weightA and weightB by their greatest common divisor */
1141 d = gcd(weightA, weightB);
1142 weightA /= d;
Serhiy Storchaka1e953402015-05-30 00:53:26 +03001143 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001144
Mark Dickinson932e1622010-05-10 16:07:42 +00001145 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001146 PyErr_SetString(PyExc_MemoryError,
1147 "not enough memory for output buffer");
1148 return 0;
1149 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001150 prev_i = (int *) malloc(nchannels * sizeof(int));
1151 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001152 if (prev_i == NULL || cur_i == NULL) {
1153 (void) PyErr_NoMemory();
1154 goto exit;
1155 }
1156
1157 len /= bytes_per_frame; /* # of frames */
1158
1159 if (state == Py_None) {
1160 d = -outrate;
1161 for (chan = 0; chan < nchannels; chan++)
1162 prev_i[chan] = cur_i[chan] = 0;
1163 }
1164 else {
Oren Milmanbc80fd12017-08-26 21:56:31 +03001165 if (!PyTuple_Check(state)) {
1166 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1167 goto exit;
1168 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001169 if (!PyArg_ParseTuple(state,
1170 "iO!;audioop.ratecv: illegal state argument",
1171 &d, &PyTuple_Type, &samps))
1172 goto exit;
1173 if (PyTuple_Size(samps) != nchannels) {
1174 PyErr_SetString(AudioopError,
1175 "illegal state argument");
1176 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001177 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001178 for (chan = 0; chan < nchannels; chan++) {
Oren Milmanbc80fd12017-08-26 21:56:31 +03001179 channel = PyTuple_GetItem(samps, chan);
1180 if (!PyTuple_Check(channel)) {
1181 PyErr_SetString(PyExc_TypeError,
1182 "ratecv(): illegal state argument");
1183 goto exit;
1184 }
1185 if (!PyArg_ParseTuple(channel,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001186 "ii:ratecv", &prev_i[chan],
1187 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001188 goto exit;
1189 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001190 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001191
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001192 /* str <- Space for the output buffer. */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001193 if (len == 0)
1194 str = PyString_FromStringAndSize(NULL, 0);
1195 else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001196 /* There are len input frames, so we need (mathematically)
1197 ceiling(len*outrate/inrate) output frames, and each frame
1198 requires bytes_per_frame bytes. Computing this
1199 without spurious overflow is the challenge; we can
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001200 settle for a reasonable upper bound, though, in this
1201 case ceiling(len/inrate) * outrate. */
1202
1203 /* compute ceiling(len/inrate) without overflow */
1204 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1205 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001206 str = NULL;
1207 else
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001208 str = PyString_FromStringAndSize(NULL,
1209 q * outrate * bytes_per_frame);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001210 }
1211 if (str == NULL) {
1212 PyErr_SetString(PyExc_MemoryError,
1213 "not enough memory for output buffer");
1214 goto exit;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001215 }
1216 ncp = PyString_AsString(str);
1217
1218 for (;;) {
1219 while (d < 0) {
1220 if (len == 0) {
1221 samps = PyTuple_New(nchannels);
1222 if (samps == NULL)
1223 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001224 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001225 PyTuple_SetItem(samps, chan,
1226 Py_BuildValue("(ii)",
1227 prev_i[chan],
1228 cur_i[chan]));
1229 if (PyErr_Occurred())
1230 goto exit;
1231 /* We have checked before that the length
1232 * of the string fits into int. */
1233 len = (int)(ncp - PyString_AsString(str));
1234 if (len == 0) {
1235 /*don't want to resize to zero length*/
1236 rv = PyString_FromStringAndSize("", 0);
1237 Py_DECREF(str);
1238 str = rv;
1239 } else if (_PyString_Resize(&str, len) < 0)
1240 goto exit;
1241 rv = Py_BuildValue("(O(iO))", str, d, samps);
1242 Py_DECREF(samps);
1243 Py_DECREF(str);
1244 goto exit; /* return rv */
1245 }
1246 for (chan = 0; chan < nchannels; chan++) {
1247 prev_i[chan] = cur_i[chan];
1248 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001249 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001250 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001251 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001252 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001253 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001254 cp += size;
1255 /* implements a simple digital filter */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001256 cur_i[chan] = (int)(
1257 ((double)weightA * (double)cur_i[chan] +
1258 (double)weightB * (double)prev_i[chan]) /
1259 ((double)weightA + (double)weightB));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001260 }
1261 len--;
1262 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001263 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001264 while (d >= 0) {
1265 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001266 cur_o = (int)(((double)prev_i[chan] * (double)d +
1267 (double)cur_i[chan] * (double)(outrate - d)) /
1268 (double)outrate);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001269 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001270 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001271 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001272 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001273 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001274 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001275 ncp += size;
1276 }
1277 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001278 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001279 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001280 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001281 if (prev_i != NULL)
1282 free(prev_i);
1283 if (cur_i != NULL)
1284 free(cur_i);
1285 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001286}
Guido van Rossum1851a671997-02-14 16:14:03 +00001287
Roger E. Massec905fff1997-01-17 18:12:04 +00001288static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001289audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001290{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001291 signed char *cp;
1292 unsigned char *ncp;
1293 int len, size, val = 0;
1294 PyObject *rv;
1295 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001296
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001297 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1298 &cp, &len, &size) )
1299 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001300
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001301 if (!audioop_check_parameters(len, size))
1302 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001303
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001304 rv = PyString_FromStringAndSize(NULL, len/size);
1305 if ( rv == 0 )
1306 return 0;
1307 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001308
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001309 for ( i=0; i < len; i += size ) {
1310 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1311 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1312 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001313
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001314 *ncp++ = st_14linear2ulaw(val);
1315 }
1316 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001317}
1318
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001319static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001320audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001321{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001322 unsigned char *cp;
1323 unsigned char cval;
1324 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001325 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001326 PyObject *rv;
1327 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001328
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001329 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1330 &cp, &len, &size) )
1331 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001332
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001333 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001334 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001335
Mark Dickinson932e1622010-05-10 16:07:42 +00001336 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001337 PyErr_SetString(PyExc_MemoryError,
1338 "not enough memory for output buffer");
1339 return 0;
1340 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001341 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001342 if ( rv == 0 )
1343 return 0;
1344 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001345
Mark Dickinson932e1622010-05-10 16:07:42 +00001346 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001347 cval = *cp++;
1348 val = st_ulaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001349
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001350 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1351 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1352 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1353 }
1354 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001355}
1356
1357static PyObject *
1358audioop_lin2alaw(PyObject *self, PyObject *args)
1359{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001360 signed char *cp;
1361 unsigned char *ncp;
1362 int len, size, val = 0;
1363 PyObject *rv;
1364 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001365
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001366 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1367 &cp, &len, &size) )
1368 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001369
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001370 if (!audioop_check_parameters(len, size))
1371 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001372
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001373 rv = PyString_FromStringAndSize(NULL, len/size);
1374 if ( rv == 0 )
1375 return 0;
1376 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001377
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001378 for ( i=0; i < len; i += size ) {
1379 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1380 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1381 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001382
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001383 *ncp++ = st_linear2alaw(val);
1384 }
1385 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001386}
1387
1388static PyObject *
1389audioop_alaw2lin(PyObject *self, PyObject *args)
1390{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001391 unsigned char *cp;
1392 unsigned char cval;
1393 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001394 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001395 PyObject *rv;
1396 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001397
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001398 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1399 &cp, &len, &size) )
1400 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001401
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001402 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001403 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001404
Mark Dickinson932e1622010-05-10 16:07:42 +00001405 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001406 PyErr_SetString(PyExc_MemoryError,
1407 "not enough memory for output buffer");
1408 return 0;
1409 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001410 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001411 if ( rv == 0 )
1412 return 0;
1413 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001414
Mark Dickinson932e1622010-05-10 16:07:42 +00001415 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001416 cval = *cp++;
1417 val = st_alaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001418
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001419 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1420 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1421 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1422 }
1423 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001424}
1425
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001426static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001427audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001428{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001429 signed char *cp;
1430 signed char *ncp;
1431 int len, size, val = 0, step, valpred, delta,
1432 index, sign, vpdiff, diff;
1433 PyObject *rv, *state, *str;
1434 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001435
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001436 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1437 &cp, &len, &size, &state) )
1438 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001439
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001440 if (!audioop_check_parameters(len, size))
1441 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001442
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001443 /* Decode state, should have (value, step) */
1444 if ( state == Py_None ) {
1445 /* First time, it seems. Set defaults */
1446 valpred = 0;
1447 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001448 }
1449 else if (!PyTuple_Check(state)) {
1450 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1451 return NULL;
1452 }
1453 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1454 return NULL;
1455 }
1456 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1457 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1458 PyErr_SetString(PyExc_ValueError, "bad state");
1459 return NULL;
1460 }
1461
1462 str = PyString_FromStringAndSize(NULL, len/(size*2));
1463 if ( str == 0 )
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001464 return 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001465 ncp = (signed char *)PyString_AsString(str);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001466
1467 step = stepsizeTable[index];
1468 bufferstep = 1;
1469
1470 for ( i=0; i < len; i += size ) {
1471 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1472 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1473 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1474
1475 /* Step 1 - compute difference with previous value */
1476 diff = val - valpred;
1477 sign = (diff < 0) ? 8 : 0;
1478 if ( sign ) diff = (-diff);
1479
1480 /* Step 2 - Divide and clamp */
1481 /* Note:
1482 ** This code *approximately* computes:
1483 ** delta = diff*4/step;
1484 ** vpdiff = (delta+0.5)*step/4;
1485 ** but in shift step bits are dropped. The net result of this
1486 ** is that even if you have fast mul/div hardware you cannot
1487 ** put it to good use since the fixup would be too expensive.
1488 */
1489 delta = 0;
1490 vpdiff = (step >> 3);
1491
1492 if ( diff >= step ) {
1493 delta = 4;
1494 diff -= step;
1495 vpdiff += step;
1496 }
1497 step >>= 1;
1498 if ( diff >= step ) {
1499 delta |= 2;
1500 diff -= step;
1501 vpdiff += step;
1502 }
1503 step >>= 1;
1504 if ( diff >= step ) {
1505 delta |= 1;
1506 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001507 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001508
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001509 /* Step 3 - Update previous value */
1510 if ( sign )
1511 valpred -= vpdiff;
1512 else
1513 valpred += vpdiff;
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001514
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001515 /* Step 4 - Clamp previous value to 16 bits */
1516 if ( valpred > 32767 )
1517 valpred = 32767;
1518 else if ( valpred < -32768 )
1519 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001520
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001521 /* Step 5 - Assemble value, update index and step values */
1522 delta |= sign;
1523
1524 index += indexTable[delta];
1525 if ( index < 0 ) index = 0;
1526 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001527 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001528
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001529 /* Step 6 - Output value */
1530 if ( bufferstep ) {
1531 outputbuffer = (delta << 4) & 0xf0;
1532 } else {
1533 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001534 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001535 bufferstep = !bufferstep;
1536 }
1537 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1538 Py_DECREF(str);
1539 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001540}
1541
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001542static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001543audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001544{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001545 signed char *cp;
1546 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001547 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001548 PyObject *rv, *str, *state;
1549 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001550
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001551 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1552 &cp, &len, &size, &state) )
1553 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001554
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001555 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001556 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001557
1558 /* Decode state, should have (value, step) */
1559 if ( state == Py_None ) {
1560 /* First time, it seems. Set defaults */
1561 valpred = 0;
1562 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001563 }
1564 else if (!PyTuple_Check(state)) {
1565 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1566 return NULL;
1567 }
1568 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1569 return NULL;
1570 }
1571 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1572 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1573 PyErr_SetString(PyExc_ValueError, "bad state");
1574 return NULL;
1575 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001576
Mark Dickinson932e1622010-05-10 16:07:42 +00001577 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001578 PyErr_SetString(PyExc_MemoryError,
1579 "not enough memory for output buffer");
1580 return 0;
1581 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001582 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001583 if ( str == 0 )
1584 return 0;
1585 ncp = (signed char *)PyString_AsString(str);
1586
1587 step = stepsizeTable[index];
1588 bufferstep = 0;
1589
Mark Dickinson932e1622010-05-10 16:07:42 +00001590 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001591 /* Step 1 - get the delta value and compute next index */
1592 if ( bufferstep ) {
1593 delta = inputbuffer & 0xf;
1594 } else {
1595 inputbuffer = *cp++;
1596 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001597 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001598
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001599 bufferstep = !bufferstep;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001600
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001601 /* Step 2 - Find new index value (for later) */
1602 index += indexTable[delta];
1603 if ( index < 0 ) index = 0;
1604 if ( index > 88 ) index = 88;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001605
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001606 /* Step 3 - Separate sign and magnitude */
1607 sign = delta & 8;
1608 delta = delta & 7;
1609
1610 /* Step 4 - Compute difference and new predicted value */
1611 /*
1612 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1613 ** in adpcm_coder.
1614 */
1615 vpdiff = step >> 3;
1616 if ( delta & 4 ) vpdiff += step;
1617 if ( delta & 2 ) vpdiff += step>>1;
1618 if ( delta & 1 ) vpdiff += step>>2;
1619
1620 if ( sign )
1621 valpred -= vpdiff;
1622 else
1623 valpred += vpdiff;
1624
1625 /* Step 5 - clamp output value */
1626 if ( valpred > 32767 )
1627 valpred = 32767;
1628 else if ( valpred < -32768 )
1629 valpred = -32768;
1630
1631 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001632 step = stepsizeTable[index];
Brett Cannon9824e7f2010-05-03 23:42:40 +00001633
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001634 /* Step 6 - Output value */
1635 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1636 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1637 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1638 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001639
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001640 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1641 Py_DECREF(str);
1642 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001643}
1644
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001645static PyMethodDef audioop_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001646 { "max", audioop_max, METH_VARARGS },
1647 { "minmax", audioop_minmax, METH_VARARGS },
1648 { "avg", audioop_avg, METH_VARARGS },
1649 { "maxpp", audioop_maxpp, METH_VARARGS },
1650 { "avgpp", audioop_avgpp, METH_VARARGS },
1651 { "rms", audioop_rms, METH_VARARGS },
1652 { "findfit", audioop_findfit, METH_VARARGS },
1653 { "findmax", audioop_findmax, METH_VARARGS },
1654 { "findfactor", audioop_findfactor, METH_VARARGS },
1655 { "cross", audioop_cross, METH_VARARGS },
1656 { "mul", audioop_mul, METH_VARARGS },
1657 { "add", audioop_add, METH_VARARGS },
1658 { "bias", audioop_bias, METH_VARARGS },
1659 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1660 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1661 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1662 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1663 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1664 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1665 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1666 { "tomono", audioop_tomono, METH_VARARGS },
1667 { "tostereo", audioop_tostereo, METH_VARARGS },
1668 { "getsample", audioop_getsample, METH_VARARGS },
1669 { "reverse", audioop_reverse, METH_VARARGS },
1670 { "ratecv", audioop_ratecv, METH_VARARGS },
1671 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001672};
1673
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001674PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001675initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001676{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001677 PyObject *m, *d;
1678 m = Py_InitModule("audioop", audioop_methods);
1679 if (m == NULL)
1680 return;
1681 d = PyModule_GetDict(m);
1682 if (d == NULL)
1683 return;
1684 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1685 if (AudioopError != NULL)
1686 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001687}