blob: 42290384942146a510d7fa06de8f59d53be64910 [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};
28static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x80000000};
29static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
30
31static int
32fbound(double val, double minval, double maxval)
33{
Victor Stinnerb17d4092018-06-06 17:12:39 +020034 if (val > maxval) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020035 val = maxval;
Victor Stinnerb17d4092018-06-06 17:12:39 +020036 }
37 else if (val < minval + 1.0) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020038 val = minval;
Victor Stinnerb17d4092018-06-06 17:12:39 +020039 }
40
41 /* Round towards minus infinity (-inf) */
42 val = floor(val);
43
44 /* Cast double to integer: round towards zero */
45 return (int)val;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020046}
47
48
Anthony Baxterfa869072006-03-20 05:21:58 +000049/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000050** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
51
Anthony Baxterfa869072006-03-20 05:21:58 +000052/* From g711.c:
53 *
54 * December 30, 1994:
55 * Functions linear2alaw, linear2ulaw have been updated to correctly
56 * convert unquantized 16 bit values.
57 * Tables for direct u- to A-law and A- to u-law conversions have been
58 * corrected.
59 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
60 * bli@cpk.auc.dk
61 *
62 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000063#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
64#define CLIP 32635
Martin Panter4f23cab2016-05-08 13:45:55 +000065#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Anthony Baxter17471432006-03-20 05:58:21 +000066#define QUANT_MASK (0xf) /* Quantization field mask. */
67#define SEG_SHIFT (4) /* Left shift for segment number. */
68#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000069
Anthony Baxter17471432006-03-20 05:58:21 +000070static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
71 0x1FF, 0x3FF, 0x7FF, 0xFFF};
72static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
73 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
Anthony Baxterfa869072006-03-20 05:21:58 +000074
Neal Norwitz49c65d02006-03-20 06:34:06 +000075static PyInt16
76search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000077{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000078 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000079
Antoine Pitrouc83ea132010-05-09 14:46:46 +000080 for (i = 0; i < size; i++) {
81 if (val <= *table++)
82 return (i);
83 }
84 return (size);
Anthony Baxterfa869072006-03-20 05:21:58 +000085}
86#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
87#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000088
Neal Norwitz49c65d02006-03-20 06:34:06 +000089static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000090 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
91 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
92 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
93 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
94 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
95 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
96 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
97 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
98 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
99 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
100 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
101 -1052, -988, -924, -876, -844, -812, -780,
102 -748, -716, -684, -652, -620, -588, -556,
103 -524, -492, -460, -428, -396, -372, -356,
104 -340, -324, -308, -292, -276, -260, -244,
105 -228, -212, -196, -180, -164, -148, -132,
106 -120, -112, -104, -96, -88, -80, -72,
107 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000108 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21:58 +0000109 27004, 25980, 24956, 23932, 22908, 21884, 20860,
110 19836, 18812, 17788, 16764, 15996, 15484, 14972,
111 14460, 13948, 13436, 12924, 12412, 11900, 11388,
112 10876, 10364, 9852, 9340, 8828, 8316, 7932,
113 7676, 7420, 7164, 6908, 6652, 6396, 6140,
114 5884, 5628, 5372, 5116, 4860, 4604, 4348,
115 4092, 3900, 3772, 3644, 3516, 3388, 3260,
116 3132, 3004, 2876, 2748, 2620, 2492, 2364,
117 2236, 2108, 1980, 1884, 1820, 1756, 1692,
118 1628, 1564, 1500, 1436, 1372, 1308, 1244,
119 1180, 1116, 1052, 988, 924, 876, 844,
120 812, 780, 748, 716, 684, 652, 620,
121 588, 556, 524, 492, 460, 428, 396,
122 372, 356, 340, 324, 308, 292, 276,
123 260, 244, 228, 212, 196, 180, 164,
124 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000125 80, 72, 64, 56, 48, 40, 32,
126 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000127};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000128
Anthony Baxterfa869072006-03-20 05:21:58 +0000129/*
130 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panterb362f752015-11-02 03:37:02 +0000131 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000132 * the data shifted such that it only contains information in the lower
133 * 14-bits.
134 *
135 * In order to simplify the encoding process, the original linear magnitude
136 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
137 * (33 - 8191). The result can be seen in the following encoding table:
138 *
Anthony Baxter17471432006-03-20 05:58:21 +0000139 * Biased Linear Input Code Compressed Code
140 * ------------------------ ---------------
141 * 00000001wxyza 000wxyz
142 * 0000001wxyzab 001wxyz
143 * 000001wxyzabc 010wxyz
144 * 00001wxyzabcd 011wxyz
145 * 0001wxyzabcde 100wxyz
146 * 001wxyzabcdef 101wxyz
147 * 01wxyzabcdefg 110wxyz
148 * 1wxyzabcdefgh 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000149 *
150 * Each biased linear code has a leading 1 which identifies the segment
151 * number. The value of the segment number is equal to 7 minus the number
152 * of leading 0's. The quantization interval is directly available as the
153 * four bits wxyz. * The trailing bits (a - h) are ignored.
154 *
155 * Ordinarily the complement of the resulting code word is used for
156 * transmission, and so the code word is complemented before it is returned.
157 *
158 * For further information see John C. Bellamy's Digital Telephony, 1982,
159 * John Wiley & Sons, pps 98-111 and 472-476.
160 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000161static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000162st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000163{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000164 PyInt16 mask;
165 PyInt16 seg;
166 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000167
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000168 /* The original sox code does this in the calling function, not here */
169 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000170
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000171 /* u-law inverts all bits */
172 /* Get the sign and the magnitude of the value. */
173 if (pcm_val < 0) {
174 pcm_val = -pcm_val;
175 mask = 0x7F;
176 } else {
177 mask = 0xFF;
178 }
179 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
180 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000181
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000182 /* Convert the scaled magnitude to segment number. */
183 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000184
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000185 /*
186 * Combine the sign, segment, quantization bits;
187 * and complement the code word.
188 */
189 if (seg >= 8) /* out of range, return maximum value. */
190 return (unsigned char) (0x7F ^ mask);
191 else {
192 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
193 return (uval ^ mask);
194 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000195
196}
197
Neal Norwitz49c65d02006-03-20 06:34:06 +0000198static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000199 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
200 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
201 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
202 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
203 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
204 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
205 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
206 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
207 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
208 -13568, -344, -328, -376, -360, -280, -264,
209 -312, -296, -472, -456, -504, -488, -408,
210 -392, -440, -424, -88, -72, -120, -104,
211 -24, -8, -56, -40, -216, -200, -248,
212 -232, -152, -136, -184, -168, -1376, -1312,
213 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
214 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
215 -688, -656, -752, -720, -560, -528, -624,
216 -592, -944, -912, -1008, -976, -816, -784,
217 -880, -848, 5504, 5248, 6016, 5760, 4480,
218 4224, 4992, 4736, 7552, 7296, 8064, 7808,
219 6528, 6272, 7040, 6784, 2752, 2624, 3008,
220 2880, 2240, 2112, 2496, 2368, 3776, 3648,
221 4032, 3904, 3264, 3136, 3520, 3392, 22016,
222 20992, 24064, 23040, 17920, 16896, 19968, 18944,
223 30208, 29184, 32256, 31232, 26112, 25088, 28160,
224 27136, 11008, 10496, 12032, 11520, 8960, 8448,
225 9984, 9472, 15104, 14592, 16128, 15616, 13056,
226 12544, 14080, 13568, 344, 328, 376, 360,
227 280, 264, 312, 296, 472, 456, 504,
228 488, 408, 392, 440, 424, 88, 72,
229 120, 104, 24, 8, 56, 40, 216,
230 200, 248, 232, 152, 136, 184, 168,
231 1376, 1312, 1504, 1440, 1120, 1056, 1248,
232 1184, 1888, 1824, 2016, 1952, 1632, 1568,
233 1760, 1696, 688, 656, 752, 720, 560,
234 528, 624, 592, 944, 912, 1008, 976,
235 816, 784, 880, 848
236};
237
238/*
Martin Panter4f23cab2016-05-08 13:45:55 +0000239 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
240 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000241 * the data shifted such that it only contains information in the lower
242 * 13-bits.
243 *
Anthony Baxter17471432006-03-20 05:58:21 +0000244 * Linear Input Code Compressed Code
245 * ------------------------ ---------------
246 * 0000000wxyza 000wxyz
247 * 0000001wxyza 001wxyz
248 * 000001wxyzab 010wxyz
249 * 00001wxyzabc 011wxyz
250 * 0001wxyzabcd 100wxyz
251 * 001wxyzabcde 101wxyz
252 * 01wxyzabcdef 110wxyz
253 * 1wxyzabcdefg 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000254 *
255 * For further information see John C. Bellamy's Digital Telephony, 1982,
256 * John Wiley & Sons, pps 98-111 and 472-476.
257 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000258static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000259st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000260{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000261 PyInt16 mask;
262 short seg;
263 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000264
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000265 /* The original sox code does this in the calling function, not here */
266 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000267
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000268 /* A-law using even bit inversion */
269 if (pcm_val >= 0) {
270 mask = 0xD5; /* sign (7th) bit = 1 */
271 } else {
272 mask = 0x55; /* sign bit = 0 */
273 pcm_val = -pcm_val - 1;
274 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000275
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 /* Convert the scaled magnitude to segment number. */
277 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000278
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000280
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000281 if (seg >= 8) /* out of range, return maximum value. */
282 return (unsigned char) (0x7F ^ mask);
283 else {
284 aval = (unsigned char) seg << SEG_SHIFT;
285 if (seg < 2)
286 aval |= (pcm_val >> 1) & QUANT_MASK;
287 else
288 aval |= (pcm_val >> seg) & QUANT_MASK;
289 return (aval ^ mask);
290 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000291}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000292/* End of code taken from sox */
293
Guido van Rossumb64e6351992-07-06 14:21:56 +0000294/* Intel ADPCM step variation table */
295static int indexTable[16] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000296 -1, -1, -1, -1, 2, 4, 6, 8,
297 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000298};
299
300static int stepsizeTable[89] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000301 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
302 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
303 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
304 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
305 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
306 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
307 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
308 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
309 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000310};
Brett Cannon9824e7f2010-05-03 23:42:40 +0000311
Guido van Rossumb66efa01992-06-01 16:01:24 +0000312#define CHARP(cp, i) ((signed char *)(cp+i))
313#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000314#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000315
316
317
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000318static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000319
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000320static int
321audioop_check_size(int size)
322{
323 if (size != 1 && size != 2 && size != 4) {
324 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
325 return 0;
326 }
327 else
328 return 1;
329}
330
331static int
332audioop_check_parameters(int len, int size)
333{
334 if (!audioop_check_size(size))
335 return 0;
336 if (len % size != 0) {
337 PyErr_SetString(AudioopError, "not a whole number of frames");
338 return 0;
339 }
340 return 1;
341}
342
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000343static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000344audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000345{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000346 signed char *cp;
347 int len, size, val = 0;
348 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000349
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000350 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
351 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000352 if (!audioop_check_parameters(len, size))
353 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000354 if ( i < 0 || i >= len/size ) {
355 PyErr_SetString(AudioopError, "Index out of range");
356 return 0;
357 }
358 if ( size == 1 ) val = (int)*CHARP(cp, i);
359 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
360 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
361 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000362}
363
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000364static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000365audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000366{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000367 signed char *cp;
368 int len, size, val = 0;
369 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200370 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000371
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000372 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
373 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000374 if (!audioop_check_parameters(len, size))
375 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000376 for ( i=0; i<len; i+= size) {
377 if ( size == 1 ) val = (int)*CHARP(cp, i);
378 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
379 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200380 if (val < 0) absval = (-val);
381 else absval = val;
382 if (absval > max) max = absval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000383 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200384 if (max <= INT_MAX)
385 return PyInt_FromLong(max);
386 else
387 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000388}
389
390static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000391audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000392{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000393 signed char *cp;
394 int len, size, val = 0;
395 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200396 int min = 0x7fffffff, max = -0x80000000;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000397
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000398 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
399 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000400 if (!audioop_check_parameters(len, size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000401 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000402 for (i = 0; i < len; i += size) {
403 if (size == 1) val = (int) *CHARP(cp, i);
404 else if (size == 2) val = (int) *SHORTP(cp, i);
405 else if (size == 4) val = (int) *LONGP(cp, i);
406 if (val > max) max = val;
407 if (val < min) min = val;
408 }
409 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000410}
411
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000412static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000413audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000414{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000415 signed char *cp;
416 int len, size, val = 0;
417 int i;
418 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000419
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000420 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
421 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000422 if (!audioop_check_parameters(len, size))
423 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000424 for ( i=0; i<len; i+= size) {
425 if ( size == 1 ) val = (int)*CHARP(cp, i);
426 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
427 else if ( size == 4 ) val = (int)*LONGP(cp, i);
428 avg += val;
429 }
430 if ( len == 0 )
431 val = 0;
432 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200433 val = (int)floor(avg / (double)(len/size));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000434 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000435}
436
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000437static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000438audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000439{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000440 signed char *cp;
441 int len, size, val = 0;
442 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200443 unsigned int res;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000444 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000445
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000446 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
447 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000448 if (!audioop_check_parameters(len, size))
449 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000450 for ( i=0; i<len; i+= size) {
451 if ( size == 1 ) val = (int)*CHARP(cp, i);
452 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
453 else if ( size == 4 ) val = (int)*LONGP(cp, i);
454 sum_squares += (double)val*(double)val;
455 }
456 if ( len == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200457 res = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000458 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200459 res = (unsigned int)sqrt(sum_squares / (double)(len/size));
460 if (res <= INT_MAX)
461 return PyInt_FromLong(res);
462 else
463 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000464}
465
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000466static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000467{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000468 int i;
469 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000470
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000471 for( i=0; i<len; i++) {
472 sum = sum + (double)a[i]*(double)b[i];
473 }
474 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000475}
476
477/*
478** Findfit tries to locate a sample within another sample. Its main use
479** is in echo-cancellation (to find the feedback of the output signal in
480** the input signal).
481** The method used is as follows:
482**
483** let R be the reference signal (length n) and A the input signal (length N)
484** with N > n, and let all sums be over i from 0 to n-1.
485**
486** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
487** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
488** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
489**
490** Next, we compute the relative distance between the original signal and
491** the modified signal and minimize that over j:
492** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
493** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
494**
495** In the code variables correspond as follows:
Anthony Baxter17471432006-03-20 05:58:21 +0000496** cp1 A
497** cp2 R
498** len1 N
499** len2 n
500** aj_m1 A[j-1]
501** aj_lm1 A[j+n-1]
502** sum_ri_2 sum(R[i]^2)
503** sum_aij_2 sum(A[i+j]^2)
504** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000505**
506** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
507** is completely recalculated each step.
508*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000509static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000510audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000511{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000512 short *cp1, *cp2;
513 int len1, len2;
514 int j, best_j;
515 double aj_m1, aj_lm1;
516 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000517
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000518 /* Passing a short** for an 's' argument is correct only
519 if the string contents is aligned for interpretation
520 as short[]. Due to the definition of PyStringObject,
521 this is currently (Python 2.6) the case. */
522 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
523 (char**)&cp1, &len1, (char**)&cp2, &len2) )
524 return 0;
525 if ( len1 & 1 || len2 & 1 ) {
526 PyErr_SetString(AudioopError, "Strings should be even-sized");
527 return 0;
528 }
529 len1 >>= 1;
530 len2 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000531
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000532 if ( len1 < len2 ) {
533 PyErr_SetString(AudioopError, "First sample should be longer");
534 return 0;
535 }
536 sum_ri_2 = _sum2(cp2, cp2, len2);
537 sum_aij_2 = _sum2(cp1, cp1, len2);
538 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000539
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000540 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000541
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000542 best_result = result;
543 best_j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000544
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000545 for (j=1; j<=len1-len2; j++) {
546 aj_m1 = (double)cp1[j-1];
547 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000548
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000549 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
550 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000551
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000552 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
553 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000554
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000555 if ( result < best_result ) {
556 best_result = result;
557 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000558 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000559
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000560 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000561
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000562 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
563
564 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000565}
566
567/*
568** findfactor finds a factor f so that the energy in A-fB is minimal.
569** See the comment for findfit for details.
570*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000571static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000572audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000573{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000574 short *cp1, *cp2;
575 int len1, len2;
576 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000577
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000578 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
579 (char**)&cp1, &len1, (char**)&cp2, &len2) )
580 return 0;
581 if ( len1 & 1 || len2 & 1 ) {
582 PyErr_SetString(AudioopError, "Strings should be even-sized");
583 return 0;
584 }
585 if ( len1 != len2 ) {
586 PyErr_SetString(AudioopError, "Samples should be same size");
587 return 0;
588 }
589 len2 >>= 1;
590 sum_ri_2 = _sum2(cp2, cp2, len2);
591 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000592
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000593 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000594
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000595 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000596}
597
598/*
599** findmax returns the index of the n-sized segment of the input sample
600** that contains the most energy.
601*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000602static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000603audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000604{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000605 short *cp1;
606 int len1, len2;
607 int j, best_j;
608 double aj_m1, aj_lm1;
609 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000610
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000611 if ( !PyArg_ParseTuple(args, "s#i:findmax",
612 (char**)&cp1, &len1, &len2) )
613 return 0;
614 if ( len1 & 1 ) {
615 PyErr_SetString(AudioopError, "Strings should be even-sized");
616 return 0;
617 }
618 len1 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000619
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000620 if ( len2 < 0 || len1 < len2 ) {
621 PyErr_SetString(AudioopError, "Input sample should be longer");
622 return 0;
623 }
624
625 result = _sum2(cp1, cp1, len2);
626
627 best_result = result;
628 best_j = 0;
629
630 for (j=1; j<=len1-len2; j++) {
631 aj_m1 = (double)cp1[j-1];
632 aj_lm1 = (double)cp1[j+len2-1];
633
634 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
635
636 if ( result > best_result ) {
637 best_result = result;
638 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000639 }
Jack Jansena90805f1993-02-17 14:29:28 +0000640
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000641 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000642
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000643 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000644}
645
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000646static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000647audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000648{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000649 signed char *cp;
650 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
651 prevextreme = 0;
652 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200653 double sum = 0.0;
654 unsigned int avg;
655 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000656
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000657 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
658 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000659 if (!audioop_check_parameters(len, size))
660 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200661 if (len <= size*2)
662 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000663 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
664 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
665 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200666 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000667 for ( i=size; i<len; i+= size) {
668 if ( size == 1 ) val = (int)*CHARP(cp, i);
669 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
670 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200671 if (val != prevval) {
672 diff = val < prevval;
673 if (prevdiff == !diff) {
674 /* Derivative changed sign. Compute difference to last
675 ** extreme value and remember.
676 */
677 if (prevextremevalid) {
678 sum += fabs((double)prevval - (double)prevextreme);
679 nextreme++;
680 }
681 prevextremevalid = 1;
682 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000683 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200684 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000685 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200686 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000687 }
688 if ( nextreme == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200689 avg = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000690 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200691 avg = (unsigned int)(sum / (double)nextreme);
692 if (avg <= INT_MAX)
693 return PyInt_FromLong(avg);
694 else
695 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000696}
697
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000698static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000699audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000700{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000701 signed char *cp;
702 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
703 prevextreme = 0;
704 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200705 unsigned int max = 0, extremediff;
706 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000707
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000708 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
709 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000710 if (!audioop_check_parameters(len, size))
711 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200712 if (len <= size)
713 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000714 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
715 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
716 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200717 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000718 for ( i=size; i<len; i+= size) {
719 if ( size == 1 ) val = (int)*CHARP(cp, i);
720 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
721 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200722 if (val != prevval) {
723 diff = val < prevval;
724 if (prevdiff == !diff) {
725 /* Derivative changed sign. Compute difference to
726 ** last extreme value and remember.
727 */
728 if (prevextremevalid) {
729 if (prevval < prevextreme)
730 extremediff = (unsigned int)prevextreme -
731 (unsigned int)prevval;
732 else
733 extremediff = (unsigned int)prevval -
734 (unsigned int)prevextreme;
735 if ( extremediff > max )
736 max = extremediff;
737 }
738 prevextremevalid = 1;
739 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000740 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200741 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000742 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200743 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000744 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200745 if (max <= INT_MAX)
746 return PyInt_FromLong(max);
747 else
748 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000749}
750
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000751static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000752audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000753{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000754 signed char *cp;
755 int len, size, val = 0;
756 int i;
757 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000758
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000759 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
760 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000761 if (!audioop_check_parameters(len, size))
762 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000763 ncross = -1;
764 prevval = 17; /* Anything <> 0,1 */
765 for ( i=0; i<len; i+= size) {
766 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
767 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
768 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
769 val = val & 1;
770 if ( val != prevval ) ncross++;
771 prevval = val;
772 }
773 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000774}
775
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000776static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000777audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000778{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000779 signed char *cp, *ncp;
780 int len, size, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200781 double factor, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 PyObject *rv;
783 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000784
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000785 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
786 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000787 if (!audioop_check_parameters(len, size))
788 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000789
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200790 maxval = (double) maxvals[size];
791 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000792
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000793 rv = PyString_FromStringAndSize(NULL, len);
794 if ( rv == 0 )
795 return 0;
796 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000797
798
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000799 for ( i=0; i < len; i += size ) {
800 if ( size == 1 ) val = (int)*CHARP(cp, i);
801 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
802 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Victor Stinnerb17d4092018-06-06 17:12:39 +0200803 fval = (double)val * factor;
804 val = fbound(fval, minval, maxval);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000805 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
806 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
807 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
808 }
809 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000810}
811
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000812static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000813audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000814{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000815 signed char *cp, *ncp;
816 int len, size, val1 = 0, val2 = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200817 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000818 PyObject *rv;
819 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000820
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000821 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
822 &cp, &len, &size, &fac1, &fac2 ) )
823 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000824 if (!audioop_check_parameters(len, size))
825 return NULL;
826 if (((len / size) & 1) != 0) {
827 PyErr_SetString(AudioopError, "not a whole number of frames");
828 return NULL;
829 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000830
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200831 maxval = (double) maxvals[size];
832 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000833
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000834 rv = PyString_FromStringAndSize(NULL, len/2);
835 if ( rv == 0 )
836 return 0;
837 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000838
839
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000840 for ( i=0; i < len; i += size*2 ) {
841 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
842 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
843 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
844 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
845 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
846 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
Victor Stinnerb17d4092018-06-06 17:12:39 +0200847 fval = (double)val1 * fac1 + (double)val2 * fac2;
848 val1 = fbound(fval, minval, maxval);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000849 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
850 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
851 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
852 }
853 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854}
855
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000856static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000857audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000858{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000859 signed char *cp, *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +0000860 int len, size, val1, val2, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200861 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 PyObject *rv;
863 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000864
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000865 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
866 &cp, &len, &size, &fac1, &fac2 ) )
867 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000868 if (!audioop_check_parameters(len, size))
869 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000870
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200871 maxval = (double) maxvals[size];
872 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000873
Mark Dickinson932e1622010-05-10 16:07:42 +0000874 if (len > INT_MAX/2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000875 PyErr_SetString(PyExc_MemoryError,
876 "not enough memory for output buffer");
877 return 0;
878 }
Gregory P. Smith9d534572008-06-11 07:41:16 +0000879
Mark Dickinson932e1622010-05-10 16:07:42 +0000880 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000881 if ( rv == 0 )
882 return 0;
883 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000884
885
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000886 for ( i=0; i < len; i += size ) {
887 if ( size == 1 ) val = (int)*CHARP(cp, i);
888 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
889 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000890
Victor Stinnerb17d4092018-06-06 17:12:39 +0200891 fval = (double)val * fac1;
892 val1 = fbound(fval, minval, maxval);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893
Victor Stinnerb17d4092018-06-06 17:12:39 +0200894 fval = (double)val * fac2;
895 val2 = fbound(fval, minval, maxval);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000896
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000897 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
898 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
899 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000900
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000901 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
902 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
903 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
904 }
905 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906}
907
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000908static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000909audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000910{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000911 signed char *cp1, *cp2, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200912 int len1, len2, size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000913 PyObject *rv;
914 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000915
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000916 if ( !PyArg_ParseTuple(args, "s#s#i:add",
917 &cp1, &len1, &cp2, &len2, &size ) )
918 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000919 if (!audioop_check_parameters(len1, size))
920 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000921 if ( len1 != len2 ) {
922 PyErr_SetString(AudioopError, "Lengths should be the same");
923 return 0;
924 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000925
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200926 maxval = maxvals[size];
927 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000928
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000929 rv = PyString_FromStringAndSize(NULL, len1);
930 if ( rv == 0 )
931 return 0;
932 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000933
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000934 for ( i=0; i < len1; i += size ) {
935 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
936 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
937 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000938
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000939 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
940 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
941 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000942
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200943 if (size < 4) {
944 newval = val1 + val2;
945 /* truncate in case of overflow */
946 if (newval > maxval)
947 newval = maxval;
948 else if (newval < minval)
949 newval = minval;
950 }
951 else {
952 double fval = (double)val1 + (double)val2;
953 /* truncate in case of overflow */
Victor Stinnerb17d4092018-06-06 17:12:39 +0200954 newval = fbound(fval, minval, maxval);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200955 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000956
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000957 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
958 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
959 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
960 }
961 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000962}
963
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000964static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000965audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000966{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 signed char *cp, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200968 int len, size;
969 unsigned int val = 0, mask;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000970 PyObject *rv;
971 int i;
972 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000973
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000974 if ( !PyArg_ParseTuple(args, "s#ii:bias",
975 &cp, &len, &size , &bias) )
976 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000977
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000978 if (!audioop_check_parameters(len, size))
979 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000980
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000981 rv = PyString_FromStringAndSize(NULL, len);
982 if ( rv == 0 )
983 return 0;
984 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000985
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200986 mask = masks[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000987
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000988 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200989 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
990 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
991 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000992
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200993 val += (unsigned int)bias;
994 /* wrap around in case of overflow */
995 val &= mask;
996
997 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
998 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
999 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001000 }
1001 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001002}
1003
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001004static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001005audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001006{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001007 signed char *cp;
1008 unsigned char *ncp;
1009 int len, size, val = 0;
1010 PyObject *rv;
1011 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001012
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001013 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1014 &cp, &len, &size) )
1015 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001016
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001017 if (!audioop_check_parameters(len, size))
1018 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001019
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001020 rv = PyString_FromStringAndSize(NULL, len);
1021 if ( rv == 0 )
1022 return 0;
1023 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001024
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001025 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001026 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1027 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1028 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansen337b20e1993-02-23 13:39:57 +00001029
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001030 j = len - i - size;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001031
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001032 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1033 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1034 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001035 }
1036 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001037}
1038
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001039static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001040audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001041{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001042 signed char *cp;
1043 unsigned char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001044 int len, size, size2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001045 PyObject *rv;
1046 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001047
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001048 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1049 &cp, &len, &size, &size2) )
1050 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001051
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001052 if (!audioop_check_parameters(len, size))
1053 return NULL;
1054 if (!audioop_check_size(size2))
1055 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001056
Mark Dickinson932e1622010-05-10 16:07:42 +00001057 if (len/size > INT_MAX/size2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001058 PyErr_SetString(PyExc_MemoryError,
1059 "not enough memory for output buffer");
1060 return 0;
1061 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001062 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001063 if ( rv == 0 )
1064 return 0;
1065 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001066
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001067 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001068 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1069 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1070 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansena90805f1993-02-17 14:29:28 +00001071
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001072 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1073 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1074 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001075 }
1076 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001077}
1078
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001079static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001080gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001081{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001082 while (b > 0) {
1083 int tmp = a % b;
1084 a = b;
1085 b = tmp;
1086 }
1087 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001088}
1089
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001090static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001091audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001092{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001093 char *cp, *ncp;
1094 int len, size, nchannels, inrate, outrate, weightA, weightB;
1095 int chan, d, *prev_i, *cur_i, cur_o;
Oren Milmanbc80fd12017-08-26 21:56:31 +03001096 PyObject *state, *samps, *str, *rv = NULL, *channel;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001097 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001098
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001099 weightA = 1;
1100 weightB = 0;
1101 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1102 &nchannels, &inrate, &outrate, &state,
1103 &weightA, &weightB))
1104 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001105 if (!audioop_check_size(size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001106 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001107 if (nchannels < 1) {
1108 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1109 return NULL;
1110 }
1111 bytes_per_frame = size * nchannels;
1112 if (bytes_per_frame / nchannels != size) {
1113 /* This overflow test is rigorously correct because
1114 both multiplicands are >= 1. Use the argument names
1115 from the docs for the error msg. */
1116 PyErr_SetString(PyExc_OverflowError,
1117 "width * nchannels too big for a C int");
1118 return NULL;
1119 }
1120 if (weightA < 1 || weightB < 0) {
1121 PyErr_SetString(AudioopError,
1122 "weightA should be >= 1, weightB should be >= 0");
1123 return NULL;
1124 }
1125 if (len % bytes_per_frame != 0) {
1126 PyErr_SetString(AudioopError, "not a whole number of frames");
1127 return NULL;
1128 }
1129 if (inrate <= 0 || outrate <= 0) {
1130 PyErr_SetString(AudioopError, "sampling rate not > 0");
1131 return NULL;
1132 }
1133 /* divide inrate and outrate by their greatest common divisor */
1134 d = gcd(inrate, outrate);
1135 inrate /= d;
1136 outrate /= d;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001137 /* divide weightA and weightB by their greatest common divisor */
1138 d = gcd(weightA, weightB);
1139 weightA /= d;
Serhiy Storchaka1e953402015-05-30 00:53:26 +03001140 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001141
Mark Dickinson932e1622010-05-10 16:07:42 +00001142 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001143 PyErr_SetString(PyExc_MemoryError,
1144 "not enough memory for output buffer");
1145 return 0;
1146 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001147 prev_i = (int *) malloc(nchannels * sizeof(int));
1148 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001149 if (prev_i == NULL || cur_i == NULL) {
1150 (void) PyErr_NoMemory();
1151 goto exit;
1152 }
1153
1154 len /= bytes_per_frame; /* # of frames */
1155
1156 if (state == Py_None) {
1157 d = -outrate;
1158 for (chan = 0; chan < nchannels; chan++)
1159 prev_i[chan] = cur_i[chan] = 0;
1160 }
1161 else {
Oren Milmanbc80fd12017-08-26 21:56:31 +03001162 if (!PyTuple_Check(state)) {
1163 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1164 goto exit;
1165 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001166 if (!PyArg_ParseTuple(state,
1167 "iO!;audioop.ratecv: illegal state argument",
1168 &d, &PyTuple_Type, &samps))
1169 goto exit;
1170 if (PyTuple_Size(samps) != nchannels) {
1171 PyErr_SetString(AudioopError,
1172 "illegal state argument");
1173 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001174 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001175 for (chan = 0; chan < nchannels; chan++) {
Oren Milmanbc80fd12017-08-26 21:56:31 +03001176 channel = PyTuple_GetItem(samps, chan);
1177 if (!PyTuple_Check(channel)) {
1178 PyErr_SetString(PyExc_TypeError,
1179 "ratecv(): illegal state argument");
1180 goto exit;
1181 }
1182 if (!PyArg_ParseTuple(channel,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001183 "ii:ratecv", &prev_i[chan],
1184 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001185 goto exit;
1186 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001187 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001188
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001189 /* str <- Space for the output buffer. */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001190 if (len == 0)
1191 str = PyString_FromStringAndSize(NULL, 0);
1192 else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001193 /* There are len input frames, so we need (mathematically)
1194 ceiling(len*outrate/inrate) output frames, and each frame
1195 requires bytes_per_frame bytes. Computing this
1196 without spurious overflow is the challenge; we can
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001197 settle for a reasonable upper bound, though, in this
1198 case ceiling(len/inrate) * outrate. */
1199
1200 /* compute ceiling(len/inrate) without overflow */
1201 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1202 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001203 str = NULL;
1204 else
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001205 str = PyString_FromStringAndSize(NULL,
1206 q * outrate * bytes_per_frame);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001207 }
1208 if (str == NULL) {
1209 PyErr_SetString(PyExc_MemoryError,
1210 "not enough memory for output buffer");
1211 goto exit;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001212 }
1213 ncp = PyString_AsString(str);
1214
1215 for (;;) {
1216 while (d < 0) {
1217 if (len == 0) {
1218 samps = PyTuple_New(nchannels);
1219 if (samps == NULL)
1220 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001221 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001222 PyTuple_SetItem(samps, chan,
1223 Py_BuildValue("(ii)",
1224 prev_i[chan],
1225 cur_i[chan]));
1226 if (PyErr_Occurred())
1227 goto exit;
1228 /* We have checked before that the length
1229 * of the string fits into int. */
1230 len = (int)(ncp - PyString_AsString(str));
1231 if (len == 0) {
1232 /*don't want to resize to zero length*/
1233 rv = PyString_FromStringAndSize("", 0);
1234 Py_DECREF(str);
1235 str = rv;
1236 } else if (_PyString_Resize(&str, len) < 0)
1237 goto exit;
1238 rv = Py_BuildValue("(O(iO))", str, d, samps);
1239 Py_DECREF(samps);
1240 Py_DECREF(str);
1241 goto exit; /* return rv */
1242 }
1243 for (chan = 0; chan < nchannels; chan++) {
1244 prev_i[chan] = cur_i[chan];
1245 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001246 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001247 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001248 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001249 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001250 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001251 cp += size;
1252 /* implements a simple digital filter */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001253 cur_i[chan] = (int)(
1254 ((double)weightA * (double)cur_i[chan] +
1255 (double)weightB * (double)prev_i[chan]) /
1256 ((double)weightA + (double)weightB));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001257 }
1258 len--;
1259 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001260 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001261 while (d >= 0) {
1262 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001263 cur_o = (int)(((double)prev_i[chan] * (double)d +
1264 (double)cur_i[chan] * (double)(outrate - d)) /
1265 (double)outrate);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001266 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001267 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001268 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001269 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001270 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001271 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001272 ncp += size;
1273 }
1274 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001275 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001276 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001277 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001278 if (prev_i != NULL)
1279 free(prev_i);
1280 if (cur_i != NULL)
1281 free(cur_i);
1282 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001283}
Guido van Rossum1851a671997-02-14 16:14:03 +00001284
Roger E. Massec905fff1997-01-17 18:12:04 +00001285static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001286audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001287{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001288 signed char *cp;
1289 unsigned char *ncp;
1290 int len, size, val = 0;
1291 PyObject *rv;
1292 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001293
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001294 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1295 &cp, &len, &size) )
1296 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001297
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001298 if (!audioop_check_parameters(len, size))
1299 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001300
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001301 rv = PyString_FromStringAndSize(NULL, len/size);
1302 if ( rv == 0 )
1303 return 0;
1304 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001305
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001306 for ( i=0; i < len; i += size ) {
1307 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1308 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1309 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001310
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001311 *ncp++ = st_14linear2ulaw(val);
1312 }
1313 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001314}
1315
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001316static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001317audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001318{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001319 unsigned char *cp;
1320 unsigned char cval;
1321 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001322 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001323 PyObject *rv;
1324 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001325
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001326 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1327 &cp, &len, &size) )
1328 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001329
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001330 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001331 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001332
Mark Dickinson932e1622010-05-10 16:07:42 +00001333 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001334 PyErr_SetString(PyExc_MemoryError,
1335 "not enough memory for output buffer");
1336 return 0;
1337 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001338 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001339 if ( rv == 0 )
1340 return 0;
1341 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001342
Mark Dickinson932e1622010-05-10 16:07:42 +00001343 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001344 cval = *cp++;
1345 val = st_ulaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001346
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001347 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1348 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1349 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1350 }
1351 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001352}
1353
1354static PyObject *
1355audioop_lin2alaw(PyObject *self, PyObject *args)
1356{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001357 signed char *cp;
1358 unsigned char *ncp;
1359 int len, size, val = 0;
1360 PyObject *rv;
1361 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001362
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1364 &cp, &len, &size) )
1365 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001366
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001367 if (!audioop_check_parameters(len, size))
1368 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001369
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001370 rv = PyString_FromStringAndSize(NULL, len/size);
1371 if ( rv == 0 )
1372 return 0;
1373 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001374
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001375 for ( i=0; i < len; i += size ) {
1376 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1377 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1378 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001379
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001380 *ncp++ = st_linear2alaw(val);
1381 }
1382 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001383}
1384
1385static PyObject *
1386audioop_alaw2lin(PyObject *self, PyObject *args)
1387{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001388 unsigned char *cp;
1389 unsigned char cval;
1390 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001391 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001392 PyObject *rv;
1393 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001394
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001395 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1396 &cp, &len, &size) )
1397 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001398
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001399 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001400 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001401
Mark Dickinson932e1622010-05-10 16:07:42 +00001402 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001403 PyErr_SetString(PyExc_MemoryError,
1404 "not enough memory for output buffer");
1405 return 0;
1406 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001407 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001408 if ( rv == 0 )
1409 return 0;
1410 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001411
Mark Dickinson932e1622010-05-10 16:07:42 +00001412 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001413 cval = *cp++;
1414 val = st_alaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001415
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001416 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1417 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1418 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1419 }
1420 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001421}
1422
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001423static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001424audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001425{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001426 signed char *cp;
1427 signed char *ncp;
1428 int len, size, val = 0, step, valpred, delta,
1429 index, sign, vpdiff, diff;
1430 PyObject *rv, *state, *str;
1431 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001432
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001433 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1434 &cp, &len, &size, &state) )
1435 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001436
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001437 if (!audioop_check_parameters(len, size))
1438 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001439
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001440 /* Decode state, should have (value, step) */
1441 if ( state == Py_None ) {
1442 /* First time, it seems. Set defaults */
1443 valpred = 0;
1444 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001445 }
1446 else if (!PyTuple_Check(state)) {
1447 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1448 return NULL;
1449 }
1450 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1451 return NULL;
1452 }
1453 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1454 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1455 PyErr_SetString(PyExc_ValueError, "bad state");
1456 return NULL;
1457 }
1458
1459 str = PyString_FromStringAndSize(NULL, len/(size*2));
1460 if ( str == 0 )
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001461 return 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001462 ncp = (signed char *)PyString_AsString(str);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001463
1464 step = stepsizeTable[index];
1465 bufferstep = 1;
1466
1467 for ( i=0; i < len; i += size ) {
1468 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1469 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1470 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1471
1472 /* Step 1 - compute difference with previous value */
1473 diff = val - valpred;
1474 sign = (diff < 0) ? 8 : 0;
1475 if ( sign ) diff = (-diff);
1476
1477 /* Step 2 - Divide and clamp */
1478 /* Note:
1479 ** This code *approximately* computes:
1480 ** delta = diff*4/step;
1481 ** vpdiff = (delta+0.5)*step/4;
1482 ** but in shift step bits are dropped. The net result of this
1483 ** is that even if you have fast mul/div hardware you cannot
1484 ** put it to good use since the fixup would be too expensive.
1485 */
1486 delta = 0;
1487 vpdiff = (step >> 3);
1488
1489 if ( diff >= step ) {
1490 delta = 4;
1491 diff -= step;
1492 vpdiff += step;
1493 }
1494 step >>= 1;
1495 if ( diff >= step ) {
1496 delta |= 2;
1497 diff -= step;
1498 vpdiff += step;
1499 }
1500 step >>= 1;
1501 if ( diff >= step ) {
1502 delta |= 1;
1503 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001504 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001505
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001506 /* Step 3 - Update previous value */
1507 if ( sign )
1508 valpred -= vpdiff;
1509 else
1510 valpred += vpdiff;
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001511
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001512 /* Step 4 - Clamp previous value to 16 bits */
1513 if ( valpred > 32767 )
1514 valpred = 32767;
1515 else if ( valpred < -32768 )
1516 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001517
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001518 /* Step 5 - Assemble value, update index and step values */
1519 delta |= sign;
1520
1521 index += indexTable[delta];
1522 if ( index < 0 ) index = 0;
1523 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001524 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001525
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001526 /* Step 6 - Output value */
1527 if ( bufferstep ) {
1528 outputbuffer = (delta << 4) & 0xf0;
1529 } else {
1530 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001531 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001532 bufferstep = !bufferstep;
1533 }
1534 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1535 Py_DECREF(str);
1536 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001537}
1538
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001539static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001540audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001541{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001542 signed char *cp;
1543 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001544 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001545 PyObject *rv, *str, *state;
1546 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001547
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001548 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1549 &cp, &len, &size, &state) )
1550 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001551
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001552 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001553 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001554
1555 /* Decode state, should have (value, step) */
1556 if ( state == Py_None ) {
1557 /* First time, it seems. Set defaults */
1558 valpred = 0;
1559 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001560 }
1561 else if (!PyTuple_Check(state)) {
1562 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1563 return NULL;
1564 }
1565 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1566 return NULL;
1567 }
1568 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1569 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1570 PyErr_SetString(PyExc_ValueError, "bad state");
1571 return NULL;
1572 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001573
Mark Dickinson932e1622010-05-10 16:07:42 +00001574 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001575 PyErr_SetString(PyExc_MemoryError,
1576 "not enough memory for output buffer");
1577 return 0;
1578 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001579 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001580 if ( str == 0 )
1581 return 0;
1582 ncp = (signed char *)PyString_AsString(str);
1583
1584 step = stepsizeTable[index];
1585 bufferstep = 0;
1586
Mark Dickinson932e1622010-05-10 16:07:42 +00001587 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001588 /* Step 1 - get the delta value and compute next index */
1589 if ( bufferstep ) {
1590 delta = inputbuffer & 0xf;
1591 } else {
1592 inputbuffer = *cp++;
1593 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001594 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001595
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001596 bufferstep = !bufferstep;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001597
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001598 /* Step 2 - Find new index value (for later) */
1599 index += indexTable[delta];
1600 if ( index < 0 ) index = 0;
1601 if ( index > 88 ) index = 88;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001602
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001603 /* Step 3 - Separate sign and magnitude */
1604 sign = delta & 8;
1605 delta = delta & 7;
1606
1607 /* Step 4 - Compute difference and new predicted value */
1608 /*
1609 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1610 ** in adpcm_coder.
1611 */
1612 vpdiff = step >> 3;
1613 if ( delta & 4 ) vpdiff += step;
1614 if ( delta & 2 ) vpdiff += step>>1;
1615 if ( delta & 1 ) vpdiff += step>>2;
1616
1617 if ( sign )
1618 valpred -= vpdiff;
1619 else
1620 valpred += vpdiff;
1621
1622 /* Step 5 - clamp output value */
1623 if ( valpred > 32767 )
1624 valpred = 32767;
1625 else if ( valpred < -32768 )
1626 valpred = -32768;
1627
1628 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001629 step = stepsizeTable[index];
Brett Cannon9824e7f2010-05-03 23:42:40 +00001630
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001631 /* Step 6 - Output value */
1632 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1633 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1634 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1635 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001636
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001637 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1638 Py_DECREF(str);
1639 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001640}
1641
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001642static PyMethodDef audioop_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001643 { "max", audioop_max, METH_VARARGS },
1644 { "minmax", audioop_minmax, METH_VARARGS },
1645 { "avg", audioop_avg, METH_VARARGS },
1646 { "maxpp", audioop_maxpp, METH_VARARGS },
1647 { "avgpp", audioop_avgpp, METH_VARARGS },
1648 { "rms", audioop_rms, METH_VARARGS },
1649 { "findfit", audioop_findfit, METH_VARARGS },
1650 { "findmax", audioop_findmax, METH_VARARGS },
1651 { "findfactor", audioop_findfactor, METH_VARARGS },
1652 { "cross", audioop_cross, METH_VARARGS },
1653 { "mul", audioop_mul, METH_VARARGS },
1654 { "add", audioop_add, METH_VARARGS },
1655 { "bias", audioop_bias, METH_VARARGS },
1656 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1657 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1658 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1659 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1660 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1661 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1662 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1663 { "tomono", audioop_tomono, METH_VARARGS },
1664 { "tostereo", audioop_tostereo, METH_VARARGS },
1665 { "getsample", audioop_getsample, METH_VARARGS },
1666 { "reverse", audioop_reverse, METH_VARARGS },
1667 { "ratecv", audioop_ratecv, METH_VARARGS },
1668 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001669};
1670
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001671PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001672initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001673{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001674 PyObject *m, *d;
1675 m = Py_InitModule("audioop", audioop_methods);
1676 if (m == NULL)
1677 return;
1678 d = PyModule_GetDict(m);
1679 if (d == NULL)
1680 return;
1681 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1682 if (AudioopError != NULL)
1683 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001684}