blob: ad7336c7f9ec8748c2be25e2462fa9aeee152095 [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{
34 if (val > maxval)
35 val = maxval;
36 else if (val < minval + 1)
37 val = minval;
38 return val;
39}
40
41
Anthony Baxterfa869072006-03-20 05:21:58 +000042/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000043** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
44
Anthony Baxterfa869072006-03-20 05:21:58 +000045/* From g711.c:
46 *
47 * December 30, 1994:
48 * Functions linear2alaw, linear2ulaw have been updated to correctly
49 * convert unquantized 16 bit values.
50 * Tables for direct u- to A-law and A- to u-law conversions have been
51 * corrected.
52 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
53 * bli@cpk.auc.dk
54 *
55 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000056#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
57#define CLIP 32635
Martin Panter4f23cab2016-05-08 13:45:55 +000058#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Anthony Baxter17471432006-03-20 05:58:21 +000059#define QUANT_MASK (0xf) /* Quantization field mask. */
60#define SEG_SHIFT (4) /* Left shift for segment number. */
61#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000062
Anthony Baxter17471432006-03-20 05:58:21 +000063static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
64 0x1FF, 0x3FF, 0x7FF, 0xFFF};
65static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
66 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
Anthony Baxterfa869072006-03-20 05:21:58 +000067
Neal Norwitz49c65d02006-03-20 06:34:06 +000068static PyInt16
69search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000070{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000072
Antoine Pitrouc83ea132010-05-09 14:46:46 +000073 for (i = 0; i < size; i++) {
74 if (val <= *table++)
75 return (i);
76 }
77 return (size);
Anthony Baxterfa869072006-03-20 05:21:58 +000078}
79#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
80#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000081
Neal Norwitz49c65d02006-03-20 06:34:06 +000082static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000083 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
84 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
85 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
86 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
87 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
88 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
89 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
90 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
91 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
92 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
93 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
94 -1052, -988, -924, -876, -844, -812, -780,
95 -748, -716, -684, -652, -620, -588, -556,
96 -524, -492, -460, -428, -396, -372, -356,
97 -340, -324, -308, -292, -276, -260, -244,
98 -228, -212, -196, -180, -164, -148, -132,
99 -120, -112, -104, -96, -88, -80, -72,
100 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000101 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21:58 +0000102 27004, 25980, 24956, 23932, 22908, 21884, 20860,
103 19836, 18812, 17788, 16764, 15996, 15484, 14972,
104 14460, 13948, 13436, 12924, 12412, 11900, 11388,
105 10876, 10364, 9852, 9340, 8828, 8316, 7932,
106 7676, 7420, 7164, 6908, 6652, 6396, 6140,
107 5884, 5628, 5372, 5116, 4860, 4604, 4348,
108 4092, 3900, 3772, 3644, 3516, 3388, 3260,
109 3132, 3004, 2876, 2748, 2620, 2492, 2364,
110 2236, 2108, 1980, 1884, 1820, 1756, 1692,
111 1628, 1564, 1500, 1436, 1372, 1308, 1244,
112 1180, 1116, 1052, 988, 924, 876, 844,
113 812, 780, 748, 716, 684, 652, 620,
114 588, 556, 524, 492, 460, 428, 396,
115 372, 356, 340, 324, 308, 292, 276,
116 260, 244, 228, 212, 196, 180, 164,
117 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000118 80, 72, 64, 56, 48, 40, 32,
119 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000120};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000121
Anthony Baxterfa869072006-03-20 05:21:58 +0000122/*
123 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panterb362f752015-11-02 03:37:02 +0000124 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000125 * the data shifted such that it only contains information in the lower
126 * 14-bits.
127 *
128 * In order to simplify the encoding process, the original linear magnitude
129 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
130 * (33 - 8191). The result can be seen in the following encoding table:
131 *
Anthony Baxter17471432006-03-20 05:58:21 +0000132 * Biased Linear Input Code Compressed Code
133 * ------------------------ ---------------
134 * 00000001wxyza 000wxyz
135 * 0000001wxyzab 001wxyz
136 * 000001wxyzabc 010wxyz
137 * 00001wxyzabcd 011wxyz
138 * 0001wxyzabcde 100wxyz
139 * 001wxyzabcdef 101wxyz
140 * 01wxyzabcdefg 110wxyz
141 * 1wxyzabcdefgh 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000142 *
143 * Each biased linear code has a leading 1 which identifies the segment
144 * number. The value of the segment number is equal to 7 minus the number
145 * of leading 0's. The quantization interval is directly available as the
146 * four bits wxyz. * The trailing bits (a - h) are ignored.
147 *
148 * Ordinarily the complement of the resulting code word is used for
149 * transmission, and so the code word is complemented before it is returned.
150 *
151 * For further information see John C. Bellamy's Digital Telephony, 1982,
152 * John Wiley & Sons, pps 98-111 and 472-476.
153 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000154static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000155st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000156{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000157 PyInt16 mask;
158 PyInt16 seg;
159 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000160
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000161 /* The original sox code does this in the calling function, not here */
162 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000163
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000164 /* u-law inverts all bits */
165 /* Get the sign and the magnitude of the value. */
166 if (pcm_val < 0) {
167 pcm_val = -pcm_val;
168 mask = 0x7F;
169 } else {
170 mask = 0xFF;
171 }
172 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
173 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000174
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000175 /* Convert the scaled magnitude to segment number. */
176 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000177
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000178 /*
179 * Combine the sign, segment, quantization bits;
180 * and complement the code word.
181 */
182 if (seg >= 8) /* out of range, return maximum value. */
183 return (unsigned char) (0x7F ^ mask);
184 else {
185 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
186 return (uval ^ mask);
187 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000188
189}
190
Neal Norwitz49c65d02006-03-20 06:34:06 +0000191static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000192 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
193 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
194 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
195 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
196 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
197 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
198 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
199 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
200 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
201 -13568, -344, -328, -376, -360, -280, -264,
202 -312, -296, -472, -456, -504, -488, -408,
203 -392, -440, -424, -88, -72, -120, -104,
204 -24, -8, -56, -40, -216, -200, -248,
205 -232, -152, -136, -184, -168, -1376, -1312,
206 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
207 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
208 -688, -656, -752, -720, -560, -528, -624,
209 -592, -944, -912, -1008, -976, -816, -784,
210 -880, -848, 5504, 5248, 6016, 5760, 4480,
211 4224, 4992, 4736, 7552, 7296, 8064, 7808,
212 6528, 6272, 7040, 6784, 2752, 2624, 3008,
213 2880, 2240, 2112, 2496, 2368, 3776, 3648,
214 4032, 3904, 3264, 3136, 3520, 3392, 22016,
215 20992, 24064, 23040, 17920, 16896, 19968, 18944,
216 30208, 29184, 32256, 31232, 26112, 25088, 28160,
217 27136, 11008, 10496, 12032, 11520, 8960, 8448,
218 9984, 9472, 15104, 14592, 16128, 15616, 13056,
219 12544, 14080, 13568, 344, 328, 376, 360,
220 280, 264, 312, 296, 472, 456, 504,
221 488, 408, 392, 440, 424, 88, 72,
222 120, 104, 24, 8, 56, 40, 216,
223 200, 248, 232, 152, 136, 184, 168,
224 1376, 1312, 1504, 1440, 1120, 1056, 1248,
225 1184, 1888, 1824, 2016, 1952, 1632, 1568,
226 1760, 1696, 688, 656, 752, 720, 560,
227 528, 624, 592, 944, 912, 1008, 976,
228 816, 784, 880, 848
229};
230
231/*
Martin Panter4f23cab2016-05-08 13:45:55 +0000232 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
233 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000234 * the data shifted such that it only contains information in the lower
235 * 13-bits.
236 *
Anthony Baxter17471432006-03-20 05:58:21 +0000237 * Linear Input Code Compressed Code
238 * ------------------------ ---------------
239 * 0000000wxyza 000wxyz
240 * 0000001wxyza 001wxyz
241 * 000001wxyzab 010wxyz
242 * 00001wxyzabc 011wxyz
243 * 0001wxyzabcd 100wxyz
244 * 001wxyzabcde 101wxyz
245 * 01wxyzabcdef 110wxyz
246 * 1wxyzabcdefg 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000247 *
248 * For further information see John C. Bellamy's Digital Telephony, 1982,
249 * John Wiley & Sons, pps 98-111 and 472-476.
250 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000251static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000252st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000253{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000254 PyInt16 mask;
255 short seg;
256 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000257
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000258 /* The original sox code does this in the calling function, not here */
259 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000260
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000261 /* A-law using even bit inversion */
262 if (pcm_val >= 0) {
263 mask = 0xD5; /* sign (7th) bit = 1 */
264 } else {
265 mask = 0x55; /* sign bit = 0 */
266 pcm_val = -pcm_val - 1;
267 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000268
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000269 /* Convert the scaled magnitude to segment number. */
270 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000271
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000273
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000274 if (seg >= 8) /* out of range, return maximum value. */
275 return (unsigned char) (0x7F ^ mask);
276 else {
277 aval = (unsigned char) seg << SEG_SHIFT;
278 if (seg < 2)
279 aval |= (pcm_val >> 1) & QUANT_MASK;
280 else
281 aval |= (pcm_val >> seg) & QUANT_MASK;
282 return (aval ^ mask);
283 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000284}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000285/* End of code taken from sox */
286
Guido van Rossumb64e6351992-07-06 14:21:56 +0000287/* Intel ADPCM step variation table */
288static int indexTable[16] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000289 -1, -1, -1, -1, 2, 4, 6, 8,
290 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000291};
292
293static int stepsizeTable[89] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000294 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
295 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
296 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
297 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
298 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
299 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
300 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
301 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
302 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000303};
Brett Cannon9824e7f2010-05-03 23:42:40 +0000304
Guido van Rossumb66efa01992-06-01 16:01:24 +0000305#define CHARP(cp, i) ((signed char *)(cp+i))
306#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000307#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000308
309
310
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000311static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000312
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000313static int
314audioop_check_size(int size)
315{
316 if (size != 1 && size != 2 && size != 4) {
317 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
318 return 0;
319 }
320 else
321 return 1;
322}
323
324static int
325audioop_check_parameters(int len, int size)
326{
327 if (!audioop_check_size(size))
328 return 0;
329 if (len % size != 0) {
330 PyErr_SetString(AudioopError, "not a whole number of frames");
331 return 0;
332 }
333 return 1;
334}
335
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000336static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000337audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000338{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000339 signed char *cp;
340 int len, size, val = 0;
341 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000342
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000343 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
344 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000345 if (!audioop_check_parameters(len, size))
346 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000347 if ( i < 0 || i >= len/size ) {
348 PyErr_SetString(AudioopError, "Index out of range");
349 return 0;
350 }
351 if ( size == 1 ) val = (int)*CHARP(cp, i);
352 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
353 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
354 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000355}
356
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000357static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000358audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000359{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000360 signed char *cp;
361 int len, size, val = 0;
362 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200363 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000364
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000365 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
366 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000367 if (!audioop_check_parameters(len, size))
368 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000369 for ( i=0; i<len; i+= size) {
370 if ( size == 1 ) val = (int)*CHARP(cp, i);
371 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
372 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200373 if (val < 0) absval = (-val);
374 else absval = val;
375 if (absval > max) max = absval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000376 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200377 if (max <= INT_MAX)
378 return PyInt_FromLong(max);
379 else
380 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000381}
382
383static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000384audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000385{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000386 signed char *cp;
387 int len, size, val = 0;
388 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200389 int min = 0x7fffffff, max = -0x80000000;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000390
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000391 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
392 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000393 if (!audioop_check_parameters(len, size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000394 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000395 for (i = 0; i < len; i += size) {
396 if (size == 1) val = (int) *CHARP(cp, i);
397 else if (size == 2) val = (int) *SHORTP(cp, i);
398 else if (size == 4) val = (int) *LONGP(cp, i);
399 if (val > max) max = val;
400 if (val < min) min = val;
401 }
402 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000403}
404
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000405static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000406audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000407{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000408 signed char *cp;
409 int len, size, val = 0;
410 int i;
411 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000412
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000413 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
414 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000415 if (!audioop_check_parameters(len, size))
416 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000417 for ( i=0; i<len; i+= size) {
418 if ( size == 1 ) val = (int)*CHARP(cp, i);
419 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
420 else if ( size == 4 ) val = (int)*LONGP(cp, i);
421 avg += val;
422 }
423 if ( len == 0 )
424 val = 0;
425 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200426 val = (int)floor(avg / (double)(len/size));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000427 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000428}
429
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000430static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000431audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000432{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000433 signed char *cp;
434 int len, size, val = 0;
435 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200436 unsigned int res;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000437 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000438
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000439 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
440 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000441 if (!audioop_check_parameters(len, size))
442 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000443 for ( i=0; i<len; i+= size) {
444 if ( size == 1 ) val = (int)*CHARP(cp, i);
445 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
446 else if ( size == 4 ) val = (int)*LONGP(cp, i);
447 sum_squares += (double)val*(double)val;
448 }
449 if ( len == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200450 res = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000451 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200452 res = (unsigned int)sqrt(sum_squares / (double)(len/size));
453 if (res <= INT_MAX)
454 return PyInt_FromLong(res);
455 else
456 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000457}
458
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000459static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000460{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000461 int i;
462 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000463
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000464 for( i=0; i<len; i++) {
465 sum = sum + (double)a[i]*(double)b[i];
466 }
467 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000468}
469
470/*
471** Findfit tries to locate a sample within another sample. Its main use
472** is in echo-cancellation (to find the feedback of the output signal in
473** the input signal).
474** The method used is as follows:
475**
476** let R be the reference signal (length n) and A the input signal (length N)
477** with N > n, and let all sums be over i from 0 to n-1.
478**
479** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
480** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
481** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
482**
483** Next, we compute the relative distance between the original signal and
484** the modified signal and minimize that over j:
485** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
486** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
487**
488** In the code variables correspond as follows:
Anthony Baxter17471432006-03-20 05:58:21 +0000489** cp1 A
490** cp2 R
491** len1 N
492** len2 n
493** aj_m1 A[j-1]
494** aj_lm1 A[j+n-1]
495** sum_ri_2 sum(R[i]^2)
496** sum_aij_2 sum(A[i+j]^2)
497** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000498**
499** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
500** is completely recalculated each step.
501*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000503audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000504{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000505 short *cp1, *cp2;
506 int len1, len2;
507 int j, best_j;
508 double aj_m1, aj_lm1;
509 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000510
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000511 /* Passing a short** for an 's' argument is correct only
512 if the string contents is aligned for interpretation
513 as short[]. Due to the definition of PyStringObject,
514 this is currently (Python 2.6) the case. */
515 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
516 (char**)&cp1, &len1, (char**)&cp2, &len2) )
517 return 0;
518 if ( len1 & 1 || len2 & 1 ) {
519 PyErr_SetString(AudioopError, "Strings should be even-sized");
520 return 0;
521 }
522 len1 >>= 1;
523 len2 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000524
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000525 if ( len1 < len2 ) {
526 PyErr_SetString(AudioopError, "First sample should be longer");
527 return 0;
528 }
529 sum_ri_2 = _sum2(cp2, cp2, len2);
530 sum_aij_2 = _sum2(cp1, cp1, len2);
531 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000532
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000533 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000534
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000535 best_result = result;
536 best_j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000537
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000538 for (j=1; j<=len1-len2; j++) {
539 aj_m1 = (double)cp1[j-1];
540 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000541
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000542 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
543 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000544
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000545 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
546 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000547
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000548 if ( result < best_result ) {
549 best_result = result;
550 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000551 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000552
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000553 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000554
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000555 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
556
557 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000558}
559
560/*
561** findfactor finds a factor f so that the energy in A-fB is minimal.
562** See the comment for findfit for details.
563*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000564static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000565audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000566{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000567 short *cp1, *cp2;
568 int len1, len2;
569 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000570
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000571 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
572 (char**)&cp1, &len1, (char**)&cp2, &len2) )
573 return 0;
574 if ( len1 & 1 || len2 & 1 ) {
575 PyErr_SetString(AudioopError, "Strings should be even-sized");
576 return 0;
577 }
578 if ( len1 != len2 ) {
579 PyErr_SetString(AudioopError, "Samples should be same size");
580 return 0;
581 }
582 len2 >>= 1;
583 sum_ri_2 = _sum2(cp2, cp2, len2);
584 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000585
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000586 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000587
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000588 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000589}
590
591/*
592** findmax returns the index of the n-sized segment of the input sample
593** that contains the most energy.
594*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000595static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000596audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000597{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000598 short *cp1;
599 int len1, len2;
600 int j, best_j;
601 double aj_m1, aj_lm1;
602 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000603
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000604 if ( !PyArg_ParseTuple(args, "s#i:findmax",
605 (char**)&cp1, &len1, &len2) )
606 return 0;
607 if ( len1 & 1 ) {
608 PyErr_SetString(AudioopError, "Strings should be even-sized");
609 return 0;
610 }
611 len1 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000612
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000613 if ( len2 < 0 || len1 < len2 ) {
614 PyErr_SetString(AudioopError, "Input sample should be longer");
615 return 0;
616 }
617
618 result = _sum2(cp1, cp1, len2);
619
620 best_result = result;
621 best_j = 0;
622
623 for (j=1; j<=len1-len2; j++) {
624 aj_m1 = (double)cp1[j-1];
625 aj_lm1 = (double)cp1[j+len2-1];
626
627 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
628
629 if ( result > best_result ) {
630 best_result = result;
631 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000632 }
Jack Jansena90805f1993-02-17 14:29:28 +0000633
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000634 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000635
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000636 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000637}
638
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000639static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000640audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000641{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000642 signed char *cp;
643 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
644 prevextreme = 0;
645 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200646 double sum = 0.0;
647 unsigned int avg;
648 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000649
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000650 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
651 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000652 if (!audioop_check_parameters(len, size))
653 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200654 if (len <= size*2)
655 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000656 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
657 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
658 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200659 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 for ( i=size; i<len; i+= size) {
661 if ( size == 1 ) val = (int)*CHARP(cp, i);
662 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
663 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200664 if (val != prevval) {
665 diff = val < prevval;
666 if (prevdiff == !diff) {
667 /* Derivative changed sign. Compute difference to last
668 ** extreme value and remember.
669 */
670 if (prevextremevalid) {
671 sum += fabs((double)prevval - (double)prevextreme);
672 nextreme++;
673 }
674 prevextremevalid = 1;
675 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000676 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200677 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200679 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000680 }
681 if ( nextreme == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200682 avg = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000683 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200684 avg = (unsigned int)(sum / (double)nextreme);
685 if (avg <= INT_MAX)
686 return PyInt_FromLong(avg);
687 else
688 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000689}
690
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000691static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000692audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000693{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000694 signed char *cp;
695 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
696 prevextreme = 0;
697 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200698 unsigned int max = 0, extremediff;
699 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000700
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000701 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
702 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000703 if (!audioop_check_parameters(len, size))
704 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200705 if (len <= size)
706 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000707 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
708 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
709 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200710 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000711 for ( i=size; i<len; i+= size) {
712 if ( size == 1 ) val = (int)*CHARP(cp, i);
713 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
714 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200715 if (val != prevval) {
716 diff = val < prevval;
717 if (prevdiff == !diff) {
718 /* Derivative changed sign. Compute difference to
719 ** last extreme value and remember.
720 */
721 if (prevextremevalid) {
722 if (prevval < prevextreme)
723 extremediff = (unsigned int)prevextreme -
724 (unsigned int)prevval;
725 else
726 extremediff = (unsigned int)prevval -
727 (unsigned int)prevextreme;
728 if ( extremediff > max )
729 max = extremediff;
730 }
731 prevextremevalid = 1;
732 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000733 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200734 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000735 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200736 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000737 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200738 if (max <= INT_MAX)
739 return PyInt_FromLong(max);
740 else
741 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000742}
743
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000744static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000745audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000746{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000747 signed char *cp;
748 int len, size, val = 0;
749 int i;
750 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000751
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000752 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
753 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000754 if (!audioop_check_parameters(len, size))
755 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000756 ncross = -1;
757 prevval = 17; /* Anything <> 0,1 */
758 for ( i=0; i<len; i+= size) {
759 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
760 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
761 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
762 val = val & 1;
763 if ( val != prevval ) ncross++;
764 prevval = val;
765 }
766 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000767}
768
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000769static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000770audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000771{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000772 signed char *cp, *ncp;
773 int len, size, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200774 double factor, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000775 PyObject *rv;
776 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000777
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000778 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
779 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000780 if (!audioop_check_parameters(len, size))
781 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000782
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200783 maxval = (double) maxvals[size];
784 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000785
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000786 rv = PyString_FromStringAndSize(NULL, len);
787 if ( rv == 0 )
788 return 0;
789 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000790
791
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000792 for ( i=0; i < len; i += size ) {
793 if ( size == 1 ) val = (int)*CHARP(cp, i);
794 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
795 else if ( size == 4 ) val = (int)*LONGP(cp, i);
796 fval = (double)val*factor;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200797 val = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000798 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
799 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
800 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
801 }
802 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803}
804
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000805static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000806audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000807{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000808 signed char *cp, *ncp;
809 int len, size, val1 = 0, val2 = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200810 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000811 PyObject *rv;
812 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000813
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000814 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
815 &cp, &len, &size, &fac1, &fac2 ) )
816 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000817 if (!audioop_check_parameters(len, size))
818 return NULL;
819 if (((len / size) & 1) != 0) {
820 PyErr_SetString(AudioopError, "not a whole number of frames");
821 return NULL;
822 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000823
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200824 maxval = (double) maxvals[size];
825 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000826
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000827 rv = PyString_FromStringAndSize(NULL, len/2);
828 if ( rv == 0 )
829 return 0;
830 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000831
832
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000833 for ( i=0; i < len; i += size*2 ) {
834 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
835 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
836 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
837 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
838 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
839 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
840 fval = (double)val1*fac1 + (double)val2*fac2;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200841 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000842 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
843 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
844 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
845 }
846 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000847}
848
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000849static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000850audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000851{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000852 signed char *cp, *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +0000853 int len, size, val1, val2, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200854 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000855 PyObject *rv;
856 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000857
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000858 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
859 &cp, &len, &size, &fac1, &fac2 ) )
860 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000861 if (!audioop_check_parameters(len, size))
862 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000863
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200864 maxval = (double) maxvals[size];
865 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000866
Mark Dickinson932e1622010-05-10 16:07:42 +0000867 if (len > INT_MAX/2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000868 PyErr_SetString(PyExc_MemoryError,
869 "not enough memory for output buffer");
870 return 0;
871 }
Gregory P. Smith9d534572008-06-11 07:41:16 +0000872
Mark Dickinson932e1622010-05-10 16:07:42 +0000873 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000874 if ( rv == 0 )
875 return 0;
876 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000877
878
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000879 for ( i=0; i < len; i += size ) {
880 if ( size == 1 ) val = (int)*CHARP(cp, i);
881 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
882 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000884 fval = (double)val*fac1;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200885 val1 = (int)floor(fbound(fval, minval, maxval));
Guido van Rossumb66efa01992-06-01 16:01:24 +0000886
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000887 fval = (double)val*fac2;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200888 val2 = (int)floor(fbound(fval, minval, maxval));
Guido van Rossumb66efa01992-06-01 16:01:24 +0000889
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000890 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
891 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
892 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000894 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
895 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
896 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
897 }
898 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000899}
900
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000901static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000902audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000903{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000904 signed char *cp1, *cp2, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200905 int len1, len2, size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000906 PyObject *rv;
907 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000908
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000909 if ( !PyArg_ParseTuple(args, "s#s#i:add",
910 &cp1, &len1, &cp2, &len2, &size ) )
911 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000912 if (!audioop_check_parameters(len1, size))
913 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000914 if ( len1 != len2 ) {
915 PyErr_SetString(AudioopError, "Lengths should be the same");
916 return 0;
917 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000918
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200919 maxval = maxvals[size];
920 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000922 rv = PyString_FromStringAndSize(NULL, len1);
923 if ( rv == 0 )
924 return 0;
925 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000926
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000927 for ( i=0; i < len1; i += size ) {
928 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
929 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
930 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000931
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000932 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
933 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
934 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000935
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200936 if (size < 4) {
937 newval = val1 + val2;
938 /* truncate in case of overflow */
939 if (newval > maxval)
940 newval = maxval;
941 else if (newval < minval)
942 newval = minval;
943 }
944 else {
945 double fval = (double)val1 + (double)val2;
946 /* truncate in case of overflow */
947 newval = (int)floor(fbound(fval, minval, maxval));
948 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000949
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000950 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
951 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
952 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
953 }
954 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000955}
956
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000957static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000958audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000959{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000960 signed char *cp, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200961 int len, size;
962 unsigned int val = 0, mask;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000963 PyObject *rv;
964 int i;
965 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000966
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 if ( !PyArg_ParseTuple(args, "s#ii:bias",
968 &cp, &len, &size , &bias) )
969 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000970
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000971 if (!audioop_check_parameters(len, size))
972 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000973
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000974 rv = PyString_FromStringAndSize(NULL, len);
975 if ( rv == 0 )
976 return 0;
977 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000978
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200979 mask = masks[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000980
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000981 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200982 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
983 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
984 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000985
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200986 val += (unsigned int)bias;
987 /* wrap around in case of overflow */
988 val &= mask;
989
990 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
991 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
992 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 }
994 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000995}
996
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000997static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000998audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000999{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001000 signed char *cp;
1001 unsigned char *ncp;
1002 int len, size, val = 0;
1003 PyObject *rv;
1004 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001005
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001006 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1007 &cp, &len, &size) )
1008 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001009
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001010 if (!audioop_check_parameters(len, size))
1011 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001012
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001013 rv = PyString_FromStringAndSize(NULL, len);
1014 if ( rv == 0 )
1015 return 0;
1016 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001017
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001018 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001019 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1020 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1021 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansen337b20e1993-02-23 13:39:57 +00001022
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001023 j = len - i - size;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001024
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001025 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1026 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1027 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001028 }
1029 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001030}
1031
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001032static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001033audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001034{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001035 signed char *cp;
1036 unsigned char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001037 int len, size, size2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001038 PyObject *rv;
1039 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001040
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001041 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1042 &cp, &len, &size, &size2) )
1043 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001044
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001045 if (!audioop_check_parameters(len, size))
1046 return NULL;
1047 if (!audioop_check_size(size2))
1048 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001049
Mark Dickinson932e1622010-05-10 16:07:42 +00001050 if (len/size > INT_MAX/size2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001051 PyErr_SetString(PyExc_MemoryError,
1052 "not enough memory for output buffer");
1053 return 0;
1054 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001055 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001056 if ( rv == 0 )
1057 return 0;
1058 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001059
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001060 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001061 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1062 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1063 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansena90805f1993-02-17 14:29:28 +00001064
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001065 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1066 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1067 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001068 }
1069 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001070}
1071
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001072static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001073gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001074{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001075 while (b > 0) {
1076 int tmp = a % b;
1077 a = b;
1078 b = tmp;
1079 }
1080 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001081}
1082
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001083static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001084audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001085{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001086 char *cp, *ncp;
1087 int len, size, nchannels, inrate, outrate, weightA, weightB;
1088 int chan, d, *prev_i, *cur_i, cur_o;
Oren Milmanbc80fd12017-08-26 21:56:31 +03001089 PyObject *state, *samps, *str, *rv = NULL, *channel;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001090 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001091
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001092 weightA = 1;
1093 weightB = 0;
1094 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1095 &nchannels, &inrate, &outrate, &state,
1096 &weightA, &weightB))
1097 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001098 if (!audioop_check_size(size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001099 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001100 if (nchannels < 1) {
1101 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1102 return NULL;
1103 }
1104 bytes_per_frame = size * nchannels;
1105 if (bytes_per_frame / nchannels != size) {
1106 /* This overflow test is rigorously correct because
1107 both multiplicands are >= 1. Use the argument names
1108 from the docs for the error msg. */
1109 PyErr_SetString(PyExc_OverflowError,
1110 "width * nchannels too big for a C int");
1111 return NULL;
1112 }
1113 if (weightA < 1 || weightB < 0) {
1114 PyErr_SetString(AudioopError,
1115 "weightA should be >= 1, weightB should be >= 0");
1116 return NULL;
1117 }
1118 if (len % bytes_per_frame != 0) {
1119 PyErr_SetString(AudioopError, "not a whole number of frames");
1120 return NULL;
1121 }
1122 if (inrate <= 0 || outrate <= 0) {
1123 PyErr_SetString(AudioopError, "sampling rate not > 0");
1124 return NULL;
1125 }
1126 /* divide inrate and outrate by their greatest common divisor */
1127 d = gcd(inrate, outrate);
1128 inrate /= d;
1129 outrate /= d;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001130 /* divide weightA and weightB by their greatest common divisor */
1131 d = gcd(weightA, weightB);
1132 weightA /= d;
Serhiy Storchaka1e953402015-05-30 00:53:26 +03001133 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001134
Mark Dickinson932e1622010-05-10 16:07:42 +00001135 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001136 PyErr_SetString(PyExc_MemoryError,
1137 "not enough memory for output buffer");
1138 return 0;
1139 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001140 prev_i = (int *) malloc(nchannels * sizeof(int));
1141 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001142 if (prev_i == NULL || cur_i == NULL) {
1143 (void) PyErr_NoMemory();
1144 goto exit;
1145 }
1146
1147 len /= bytes_per_frame; /* # of frames */
1148
1149 if (state == Py_None) {
1150 d = -outrate;
1151 for (chan = 0; chan < nchannels; chan++)
1152 prev_i[chan] = cur_i[chan] = 0;
1153 }
1154 else {
Oren Milmanbc80fd12017-08-26 21:56:31 +03001155 if (!PyTuple_Check(state)) {
1156 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1157 goto exit;
1158 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001159 if (!PyArg_ParseTuple(state,
1160 "iO!;audioop.ratecv: illegal state argument",
1161 &d, &PyTuple_Type, &samps))
1162 goto exit;
1163 if (PyTuple_Size(samps) != nchannels) {
1164 PyErr_SetString(AudioopError,
1165 "illegal state argument");
1166 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001167 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001168 for (chan = 0; chan < nchannels; chan++) {
Oren Milmanbc80fd12017-08-26 21:56:31 +03001169 channel = PyTuple_GetItem(samps, chan);
1170 if (!PyTuple_Check(channel)) {
1171 PyErr_SetString(PyExc_TypeError,
1172 "ratecv(): illegal state argument");
1173 goto exit;
1174 }
1175 if (!PyArg_ParseTuple(channel,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001176 "ii:ratecv", &prev_i[chan],
1177 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001178 goto exit;
1179 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001180 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001181
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001182 /* str <- Space for the output buffer. */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001183 if (len == 0)
1184 str = PyString_FromStringAndSize(NULL, 0);
1185 else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001186 /* There are len input frames, so we need (mathematically)
1187 ceiling(len*outrate/inrate) output frames, and each frame
1188 requires bytes_per_frame bytes. Computing this
1189 without spurious overflow is the challenge; we can
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001190 settle for a reasonable upper bound, though, in this
1191 case ceiling(len/inrate) * outrate. */
1192
1193 /* compute ceiling(len/inrate) without overflow */
1194 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1195 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001196 str = NULL;
1197 else
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001198 str = PyString_FromStringAndSize(NULL,
1199 q * outrate * bytes_per_frame);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001200 }
1201 if (str == NULL) {
1202 PyErr_SetString(PyExc_MemoryError,
1203 "not enough memory for output buffer");
1204 goto exit;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001205 }
1206 ncp = PyString_AsString(str);
1207
1208 for (;;) {
1209 while (d < 0) {
1210 if (len == 0) {
1211 samps = PyTuple_New(nchannels);
1212 if (samps == NULL)
1213 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001214 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001215 PyTuple_SetItem(samps, chan,
1216 Py_BuildValue("(ii)",
1217 prev_i[chan],
1218 cur_i[chan]));
1219 if (PyErr_Occurred())
1220 goto exit;
1221 /* We have checked before that the length
1222 * of the string fits into int. */
1223 len = (int)(ncp - PyString_AsString(str));
1224 if (len == 0) {
1225 /*don't want to resize to zero length*/
1226 rv = PyString_FromStringAndSize("", 0);
1227 Py_DECREF(str);
1228 str = rv;
1229 } else if (_PyString_Resize(&str, len) < 0)
1230 goto exit;
1231 rv = Py_BuildValue("(O(iO))", str, d, samps);
1232 Py_DECREF(samps);
1233 Py_DECREF(str);
1234 goto exit; /* return rv */
1235 }
1236 for (chan = 0; chan < nchannels; chan++) {
1237 prev_i[chan] = cur_i[chan];
1238 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001239 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001240 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001241 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001242 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001243 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001244 cp += size;
1245 /* implements a simple digital filter */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001246 cur_i[chan] = (int)(
1247 ((double)weightA * (double)cur_i[chan] +
1248 (double)weightB * (double)prev_i[chan]) /
1249 ((double)weightA + (double)weightB));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001250 }
1251 len--;
1252 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001253 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001254 while (d >= 0) {
1255 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001256 cur_o = (int)(((double)prev_i[chan] * (double)d +
1257 (double)cur_i[chan] * (double)(outrate - d)) /
1258 (double)outrate);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001259 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001260 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001261 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001262 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001263 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001264 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001265 ncp += size;
1266 }
1267 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001268 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001269 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001270 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001271 if (prev_i != NULL)
1272 free(prev_i);
1273 if (cur_i != NULL)
1274 free(cur_i);
1275 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001276}
Guido van Rossum1851a671997-02-14 16:14:03 +00001277
Roger E. Massec905fff1997-01-17 18:12:04 +00001278static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001279audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001280{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001281 signed char *cp;
1282 unsigned char *ncp;
1283 int len, size, val = 0;
1284 PyObject *rv;
1285 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001286
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001287 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1288 &cp, &len, &size) )
1289 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001290
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001291 if (!audioop_check_parameters(len, size))
1292 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001293
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001294 rv = PyString_FromStringAndSize(NULL, len/size);
1295 if ( rv == 0 )
1296 return 0;
1297 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001298
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001299 for ( i=0; i < len; i += size ) {
1300 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1301 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1302 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001303
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001304 *ncp++ = st_14linear2ulaw(val);
1305 }
1306 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001307}
1308
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001309static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001310audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001311{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001312 unsigned char *cp;
1313 unsigned char cval;
1314 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001315 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001316 PyObject *rv;
1317 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001318
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001319 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1320 &cp, &len, &size) )
1321 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001322
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001323 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001324 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001325
Mark Dickinson932e1622010-05-10 16:07:42 +00001326 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001327 PyErr_SetString(PyExc_MemoryError,
1328 "not enough memory for output buffer");
1329 return 0;
1330 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001331 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001332 if ( rv == 0 )
1333 return 0;
1334 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001335
Mark Dickinson932e1622010-05-10 16:07:42 +00001336 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001337 cval = *cp++;
1338 val = st_ulaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001339
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001340 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1341 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1342 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1343 }
1344 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001345}
1346
1347static PyObject *
1348audioop_lin2alaw(PyObject *self, PyObject *args)
1349{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001350 signed char *cp;
1351 unsigned char *ncp;
1352 int len, size, val = 0;
1353 PyObject *rv;
1354 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001355
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001356 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1357 &cp, &len, &size) )
1358 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001359
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001360 if (!audioop_check_parameters(len, size))
1361 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001362
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 rv = PyString_FromStringAndSize(NULL, len/size);
1364 if ( rv == 0 )
1365 return 0;
1366 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001367
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001368 for ( i=0; i < len; i += size ) {
1369 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1370 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1371 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001372
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001373 *ncp++ = st_linear2alaw(val);
1374 }
1375 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001376}
1377
1378static PyObject *
1379audioop_alaw2lin(PyObject *self, PyObject *args)
1380{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001381 unsigned char *cp;
1382 unsigned char cval;
1383 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001384 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001385 PyObject *rv;
1386 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001387
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001388 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1389 &cp, &len, &size) )
1390 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001391
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001392 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001393 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001394
Mark Dickinson932e1622010-05-10 16:07:42 +00001395 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001396 PyErr_SetString(PyExc_MemoryError,
1397 "not enough memory for output buffer");
1398 return 0;
1399 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001400 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001401 if ( rv == 0 )
1402 return 0;
1403 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001404
Mark Dickinson932e1622010-05-10 16:07:42 +00001405 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001406 cval = *cp++;
1407 val = st_alaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001408
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001409 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1410 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1411 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1412 }
1413 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001414}
1415
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001416static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001417audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001418{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001419 signed char *cp;
1420 signed char *ncp;
1421 int len, size, val = 0, step, valpred, delta,
1422 index, sign, vpdiff, diff;
1423 PyObject *rv, *state, *str;
1424 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001425
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001426 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1427 &cp, &len, &size, &state) )
1428 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001429
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001430 if (!audioop_check_parameters(len, size))
1431 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001432
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001433 /* Decode state, should have (value, step) */
1434 if ( state == Py_None ) {
1435 /* First time, it seems. Set defaults */
1436 valpred = 0;
1437 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001438 }
1439 else if (!PyTuple_Check(state)) {
1440 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1441 return NULL;
1442 }
1443 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1444 return NULL;
1445 }
1446 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1447 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1448 PyErr_SetString(PyExc_ValueError, "bad state");
1449 return NULL;
1450 }
1451
1452 str = PyString_FromStringAndSize(NULL, len/(size*2));
1453 if ( str == 0 )
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001454 return 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001455 ncp = (signed char *)PyString_AsString(str);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001456
1457 step = stepsizeTable[index];
1458 bufferstep = 1;
1459
1460 for ( i=0; i < len; i += size ) {
1461 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1462 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1463 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1464
1465 /* Step 1 - compute difference with previous value */
1466 diff = val - valpred;
1467 sign = (diff < 0) ? 8 : 0;
1468 if ( sign ) diff = (-diff);
1469
1470 /* Step 2 - Divide and clamp */
1471 /* Note:
1472 ** This code *approximately* computes:
1473 ** delta = diff*4/step;
1474 ** vpdiff = (delta+0.5)*step/4;
1475 ** but in shift step bits are dropped. The net result of this
1476 ** is that even if you have fast mul/div hardware you cannot
1477 ** put it to good use since the fixup would be too expensive.
1478 */
1479 delta = 0;
1480 vpdiff = (step >> 3);
1481
1482 if ( diff >= step ) {
1483 delta = 4;
1484 diff -= step;
1485 vpdiff += step;
1486 }
1487 step >>= 1;
1488 if ( diff >= step ) {
1489 delta |= 2;
1490 diff -= step;
1491 vpdiff += step;
1492 }
1493 step >>= 1;
1494 if ( diff >= step ) {
1495 delta |= 1;
1496 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001497 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001498
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001499 /* Step 3 - Update previous value */
1500 if ( sign )
1501 valpred -= vpdiff;
1502 else
1503 valpred += vpdiff;
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001504
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001505 /* Step 4 - Clamp previous value to 16 bits */
1506 if ( valpred > 32767 )
1507 valpred = 32767;
1508 else if ( valpred < -32768 )
1509 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001510
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001511 /* Step 5 - Assemble value, update index and step values */
1512 delta |= sign;
1513
1514 index += indexTable[delta];
1515 if ( index < 0 ) index = 0;
1516 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001517 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001518
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001519 /* Step 6 - Output value */
1520 if ( bufferstep ) {
1521 outputbuffer = (delta << 4) & 0xf0;
1522 } else {
1523 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001524 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001525 bufferstep = !bufferstep;
1526 }
1527 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1528 Py_DECREF(str);
1529 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001530}
1531
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001532static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001533audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001534{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001535 signed char *cp;
1536 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001537 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001538 PyObject *rv, *str, *state;
1539 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001540
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001541 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1542 &cp, &len, &size, &state) )
1543 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001544
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001545 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001546 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001547
1548 /* Decode state, should have (value, step) */
1549 if ( state == Py_None ) {
1550 /* First time, it seems. Set defaults */
1551 valpred = 0;
1552 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001553 }
1554 else if (!PyTuple_Check(state)) {
1555 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1556 return NULL;
1557 }
1558 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1559 return NULL;
1560 }
1561 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1562 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1563 PyErr_SetString(PyExc_ValueError, "bad state");
1564 return NULL;
1565 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001566
Mark Dickinson932e1622010-05-10 16:07:42 +00001567 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001568 PyErr_SetString(PyExc_MemoryError,
1569 "not enough memory for output buffer");
1570 return 0;
1571 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001572 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001573 if ( str == 0 )
1574 return 0;
1575 ncp = (signed char *)PyString_AsString(str);
1576
1577 step = stepsizeTable[index];
1578 bufferstep = 0;
1579
Mark Dickinson932e1622010-05-10 16:07:42 +00001580 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001581 /* Step 1 - get the delta value and compute next index */
1582 if ( bufferstep ) {
1583 delta = inputbuffer & 0xf;
1584 } else {
1585 inputbuffer = *cp++;
1586 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001587 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001588
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001589 bufferstep = !bufferstep;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001590
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001591 /* Step 2 - Find new index value (for later) */
1592 index += indexTable[delta];
1593 if ( index < 0 ) index = 0;
1594 if ( index > 88 ) index = 88;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001595
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001596 /* Step 3 - Separate sign and magnitude */
1597 sign = delta & 8;
1598 delta = delta & 7;
1599
1600 /* Step 4 - Compute difference and new predicted value */
1601 /*
1602 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1603 ** in adpcm_coder.
1604 */
1605 vpdiff = step >> 3;
1606 if ( delta & 4 ) vpdiff += step;
1607 if ( delta & 2 ) vpdiff += step>>1;
1608 if ( delta & 1 ) vpdiff += step>>2;
1609
1610 if ( sign )
1611 valpred -= vpdiff;
1612 else
1613 valpred += vpdiff;
1614
1615 /* Step 5 - clamp output value */
1616 if ( valpred > 32767 )
1617 valpred = 32767;
1618 else if ( valpred < -32768 )
1619 valpred = -32768;
1620
1621 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001622 step = stepsizeTable[index];
Brett Cannon9824e7f2010-05-03 23:42:40 +00001623
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001624 /* Step 6 - Output value */
1625 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1626 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1627 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1628 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001629
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001630 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1631 Py_DECREF(str);
1632 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001633}
1634
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001635static PyMethodDef audioop_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001636 { "max", audioop_max, METH_VARARGS },
1637 { "minmax", audioop_minmax, METH_VARARGS },
1638 { "avg", audioop_avg, METH_VARARGS },
1639 { "maxpp", audioop_maxpp, METH_VARARGS },
1640 { "avgpp", audioop_avgpp, METH_VARARGS },
1641 { "rms", audioop_rms, METH_VARARGS },
1642 { "findfit", audioop_findfit, METH_VARARGS },
1643 { "findmax", audioop_findmax, METH_VARARGS },
1644 { "findfactor", audioop_findfactor, METH_VARARGS },
1645 { "cross", audioop_cross, METH_VARARGS },
1646 { "mul", audioop_mul, METH_VARARGS },
1647 { "add", audioop_add, METH_VARARGS },
1648 { "bias", audioop_bias, METH_VARARGS },
1649 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1650 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1651 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1652 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1653 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1654 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1655 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1656 { "tomono", audioop_tomono, METH_VARARGS },
1657 { "tostereo", audioop_tostereo, METH_VARARGS },
1658 { "getsample", audioop_getsample, METH_VARARGS },
1659 { "reverse", audioop_reverse, METH_VARARGS },
1660 { "ratecv", audioop_ratecv, METH_VARARGS },
1661 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001662};
1663
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001664PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001665initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001666{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001667 PyObject *m, *d;
1668 m = Py_InitModule("audioop", audioop_methods);
1669 if (m == NULL)
1670 return;
1671 d = PyModule_GetDict(m);
1672 if (d == NULL)
1673 return;
1674 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1675 if (AudioopError != NULL)
1676 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001677}