blob: 7175cec7c7613fc86b8bd5a116318be3087278a2 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Mark Dickinson81fece22010-05-11 13:34:35 +00004#define PY_SSIZE_T_CLEAN
5
Roger E. Masseeaa6e111997-01-03 19:26:27 +00006#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00007
Guido van Rossum69011961998-04-23 20:23:00 +00008#if SIZEOF_INT == 4
9typedef int Py_Int32;
10typedef unsigned int Py_UInt32;
11#else
12#if SIZEOF_LONG == 4
13typedef long Py_Int32;
14typedef unsigned long Py_UInt32;
15#else
16#error "No 4-byte integral type"
17#endif
18#endif
19
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000020typedef short PyInt16;
21
Guido van Rossum7b1e9741994-08-29 10:46:42 +000022#if defined(__CHAR_UNSIGNED__)
23#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000024/* This module currently does not work on systems where only unsigned
25 characters are available. Take it out of Setup. Sorry. */
26#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000027#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000028
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020029static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
30static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x80000000};
31static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
32
33static int
34fbound(double val, double minval, double maxval)
35{
36 if (val > maxval)
37 val = maxval;
38 else if (val < minval + 1)
39 val = minval;
Victor Stinnerf2b9a342013-05-07 23:49:15 +020040 return (int)val;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020041}
42
43
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000044/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000045** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
46
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000047/* From g711.c:
48 *
49 * December 30, 1994:
50 * Functions linear2alaw, linear2ulaw have been updated to correctly
51 * convert unquantized 16 bit values.
52 * Tables for direct u- to A-law and A- to u-law conversions have been
53 * corrected.
54 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
55 * bli@cpk.auc.dk
56 *
57 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000058#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
59#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000060#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
61#define QUANT_MASK (0xf) /* Quantization field mask. */
62#define SEG_SHIFT (4) /* Left shift for segment number. */
63#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000064
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000065static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
66 0x1FF, 0x3FF, 0x7FF, 0xFFF};
67static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
68 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
69
70static PyInt16
71search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 for (i = 0; i < size; i++) {
76 if (val <= *table++)
77 return (i);
78 }
79 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000080}
81#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
82#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000083
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000084static PyInt16 _st_ulaw2linear16[256] = {
85 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
86 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
87 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
88 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
89 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
90 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
91 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
92 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
93 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
94 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
95 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
96 -1052, -988, -924, -876, -844, -812, -780,
97 -748, -716, -684, -652, -620, -588, -556,
98 -524, -492, -460, -428, -396, -372, -356,
99 -340, -324, -308, -292, -276, -260, -244,
100 -228, -212, -196, -180, -164, -148, -132,
101 -120, -112, -104, -96, -88, -80, -72,
102 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000104 27004, 25980, 24956, 23932, 22908, 21884, 20860,
105 19836, 18812, 17788, 16764, 15996, 15484, 14972,
106 14460, 13948, 13436, 12924, 12412, 11900, 11388,
107 10876, 10364, 9852, 9340, 8828, 8316, 7932,
108 7676, 7420, 7164, 6908, 6652, 6396, 6140,
109 5884, 5628, 5372, 5116, 4860, 4604, 4348,
110 4092, 3900, 3772, 3644, 3516, 3388, 3260,
111 3132, 3004, 2876, 2748, 2620, 2492, 2364,
112 2236, 2108, 1980, 1884, 1820, 1756, 1692,
113 1628, 1564, 1500, 1436, 1372, 1308, 1244,
114 1180, 1116, 1052, 988, 924, 876, 844,
115 812, 780, 748, 716, 684, 652, 620,
116 588, 556, 524, 492, 460, 428, 396,
117 372, 356, 340, 324, 308, 292, 276,
118 260, 244, 228, 212, 196, 180, 164,
119 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 80, 72, 64, 56, 48, 40, 32,
121 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000122};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000123
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000124/*
125 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
126 * stored in a unsigned char. This function should only be called with
127 * the data shifted such that it only contains information in the lower
128 * 14-bits.
129 *
130 * In order to simplify the encoding process, the original linear magnitude
131 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
132 * (33 - 8191). The result can be seen in the following encoding table:
133 *
134 * Biased Linear Input Code Compressed Code
135 * ------------------------ ---------------
136 * 00000001wxyza 000wxyz
137 * 0000001wxyzab 001wxyz
138 * 000001wxyzabc 010wxyz
139 * 00001wxyzabcd 011wxyz
140 * 0001wxyzabcde 100wxyz
141 * 001wxyzabcdef 101wxyz
142 * 01wxyzabcdefg 110wxyz
143 * 1wxyzabcdefgh 111wxyz
144 *
145 * Each biased linear code has a leading 1 which identifies the segment
146 * number. The value of the segment number is equal to 7 minus the number
147 * of leading 0's. The quantization interval is directly available as the
148 * four bits wxyz. * The trailing bits (a - h) are ignored.
149 *
150 * Ordinarily the complement of the resulting code word is used for
151 * transmission, and so the code word is complemented before it is returned.
152 *
153 * For further information see John C. Bellamy's Digital Telephony, 1982,
154 * John Wiley & Sons, pps 98-111 and 472-476.
155 */
156static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 PyInt16 mask;
160 PyInt16 seg;
161 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 /* The original sox code does this in the calling function, not here */
164 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 /* u-law inverts all bits */
167 /* Get the sign and the magnitude of the value. */
168 if (pcm_val < 0) {
169 pcm_val = -pcm_val;
170 mask = 0x7F;
171 } else {
172 mask = 0xFF;
173 }
174 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
175 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 /* Convert the scaled magnitude to segment number. */
178 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 /*
181 * Combine the sign, segment, quantization bits;
182 * and complement the code word.
183 */
184 if (seg >= 8) /* out of range, return maximum value. */
185 return (unsigned char) (0x7F ^ mask);
186 else {
187 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
188 return (uval ^ mask);
189 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000190
191}
192
193static PyInt16 _st_alaw2linear16[256] = {
194 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
195 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
196 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
197 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
198 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
199 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
200 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
201 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
202 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
203 -13568, -344, -328, -376, -360, -280, -264,
204 -312, -296, -472, -456, -504, -488, -408,
205 -392, -440, -424, -88, -72, -120, -104,
206 -24, -8, -56, -40, -216, -200, -248,
207 -232, -152, -136, -184, -168, -1376, -1312,
208 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
209 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
210 -688, -656, -752, -720, -560, -528, -624,
211 -592, -944, -912, -1008, -976, -816, -784,
212 -880, -848, 5504, 5248, 6016, 5760, 4480,
213 4224, 4992, 4736, 7552, 7296, 8064, 7808,
214 6528, 6272, 7040, 6784, 2752, 2624, 3008,
215 2880, 2240, 2112, 2496, 2368, 3776, 3648,
216 4032, 3904, 3264, 3136, 3520, 3392, 22016,
217 20992, 24064, 23040, 17920, 16896, 19968, 18944,
218 30208, 29184, 32256, 31232, 26112, 25088, 28160,
219 27136, 11008, 10496, 12032, 11520, 8960, 8448,
220 9984, 9472, 15104, 14592, 16128, 15616, 13056,
221 12544, 14080, 13568, 344, 328, 376, 360,
222 280, 264, 312, 296, 472, 456, 504,
223 488, 408, 392, 440, 424, 88, 72,
224 120, 104, 24, 8, 56, 40, 216,
225 200, 248, 232, 152, 136, 184, 168,
226 1376, 1312, 1504, 1440, 1120, 1056, 1248,
227 1184, 1888, 1824, 2016, 1952, 1632, 1568,
228 1760, 1696, 688, 656, 752, 720, 560,
229 528, 624, 592, 944, 912, 1008, 976,
230 816, 784, 880, 848
231};
232
233/*
234 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
235 * stored in a unsigned char. This function should only be called with
236 * the data shifted such that it only contains information in the lower
237 * 13-bits.
238 *
239 * Linear Input Code Compressed Code
240 * ------------------------ ---------------
241 * 0000000wxyza 000wxyz
242 * 0000001wxyza 001wxyz
243 * 000001wxyzab 010wxyz
244 * 00001wxyzabc 011wxyz
245 * 0001wxyzabcd 100wxyz
246 * 001wxyzabcde 101wxyz
247 * 01wxyzabcdef 110wxyz
248 * 1wxyzabcdefg 111wxyz
249 *
250 * For further information see John C. Bellamy's Digital Telephony, 1982,
251 * John Wiley & Sons, pps 98-111 and 472-476.
252 */
253static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 PyInt16 mask;
257 short seg;
258 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 /* The original sox code does this in the calling function, not here */
261 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 /* A-law using even bit inversion */
264 if (pcm_val >= 0) {
265 mask = 0xD5; /* sign (7th) bit = 1 */
266 } else {
267 mask = 0x55; /* sign bit = 0 */
268 pcm_val = -pcm_val - 1;
269 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 /* Convert the scaled magnitude to segment number. */
272 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 if (seg >= 8) /* out of range, return maximum value. */
277 return (unsigned char) (0x7F ^ mask);
278 else {
279 aval = (unsigned char) seg << SEG_SHIFT;
280 if (seg < 2)
281 aval |= (pcm_val >> 1) & QUANT_MASK;
282 else
283 aval |= (pcm_val >> seg) & QUANT_MASK;
284 return (aval ^ mask);
285 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000286}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000287/* End of code taken from sox */
288
Guido van Rossumb64e6351992-07-06 14:21:56 +0000289/* Intel ADPCM step variation table */
290static int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 -1, -1, -1, -1, 2, 4, 6, 8,
292 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000293};
294
295static int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
297 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
298 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
299 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
300 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
301 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
302 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
303 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
304 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000305};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306
Guido van Rossumb66efa01992-06-01 16:01:24 +0000307#define CHARP(cp, i) ((signed char *)(cp+i))
308#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000309#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000310
311
312
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000313static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000314
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000315static int
316audioop_check_size(int size)
317{
318 if (size != 1 && size != 2 && size != 4) {
319 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
320 return 0;
321 }
322 else
323 return 1;
324}
325
326static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000327audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000328{
329 if (!audioop_check_size(size))
330 return 0;
331 if (len % size != 0) {
332 PyErr_SetString(AudioopError, "not a whole number of frames");
333 return 0;
334 }
335 return 1;
336}
337
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000338static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000339audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000342 Py_ssize_t len, i;
343 int size, val = 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000344
Mark Dickinson81fece22010-05-11 13:34:35 +0000345 if ( !PyArg_ParseTuple(args, "s#in:getsample", &cp, &len, &size, &i) )
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000347 if (!audioop_check_parameters(len, size))
348 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 if ( i < 0 || i >= len/size ) {
350 PyErr_SetString(AudioopError, "Index out of range");
351 return 0;
352 }
353 if ( size == 1 ) val = (int)*CHARP(cp, i);
354 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
355 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
356 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000357}
358
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000359static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000360audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000363 Py_ssize_t len, i;
364 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200365 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
368 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000369 if (!audioop_check_parameters(len, size))
370 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 for ( i=0; i<len; i+= size) {
372 if ( size == 1 ) val = (int)*CHARP(cp, i);
373 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
374 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200375 if (val < 0) absval = (-val);
376 else absval = val;
377 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200379 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000380}
381
382static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000383audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000386 Py_ssize_t len, i;
387 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200388 int min = 0x7fffffff, max = -0x80000000;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
391 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000392 if (!audioop_check_parameters(len, size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 for (i = 0; i < len; i += size) {
395 if (size == 1) val = (int) *CHARP(cp, i);
396 else if (size == 2) val = (int) *SHORTP(cp, i);
397 else if (size == 4) val = (int) *LONGP(cp, i);
398 if (val > max) max = val;
399 if (val < min) min = val;
400 }
401 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000402}
403
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000404static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000405audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000406{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000408 Py_ssize_t len, i;
409 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
413 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000414 if (!audioop_check_parameters(len, size))
415 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 for ( i=0; i<len; i+= size) {
417 if ( size == 1 ) val = (int)*CHARP(cp, i);
418 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
419 else if ( size == 4 ) val = (int)*LONGP(cp, i);
420 avg += val;
421 }
422 if ( len == 0 )
423 val = 0;
424 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200425 val = (int)floor(avg / (double)(len/size));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000427}
428
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000429static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000430audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000433 Py_ssize_t len, i;
434 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200435 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
439 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000440 if (!audioop_check_parameters(len, size))
441 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 for ( i=0; i<len; i+= size) {
443 if ( size == 1 ) val = (int)*CHARP(cp, i);
444 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
445 else if ( size == 4 ) val = (int)*LONGP(cp, i);
446 sum_squares += (double)val*(double)val;
447 }
448 if ( len == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200449 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200451 res = (unsigned int)sqrt(sum_squares / (double)(len/size));
452 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000453}
454
Mark Dickinson81fece22010-05-11 13:34:35 +0000455static double _sum2(short *a, short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000456{
Mark Dickinson81fece22010-05-11 13:34:35 +0000457 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 for( i=0; i<len; i++) {
461 sum = sum + (double)a[i]*(double)b[i];
462 }
463 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000464}
465
466/*
467** Findfit tries to locate a sample within another sample. Its main use
468** is in echo-cancellation (to find the feedback of the output signal in
469** the input signal).
470** The method used is as follows:
471**
472** let R be the reference signal (length n) and A the input signal (length N)
473** with N > n, and let all sums be over i from 0 to n-1.
474**
475** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
476** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
477** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
478**
479** Next, we compute the relative distance between the original signal and
480** the modified signal and minimize that over j:
481** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
482** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
483**
484** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000485** cp1 A
486** cp2 R
487** len1 N
488** len2 n
489** aj_m1 A[j-1]
490** aj_lm1 A[j+n-1]
491** sum_ri_2 sum(R[i]^2)
492** sum_aij_2 sum(A[i+j]^2)
493** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000494**
495** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
496** is completely recalculated each step.
497*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000498static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000499audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000502 Py_ssize_t len1, len2;
503 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 double aj_m1, aj_lm1;
505 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 /* Passing a short** for an 's' argument is correct only
508 if the string contents is aligned for interpretation
509 as short[]. Due to the definition of PyBytesObject,
510 this is currently (Python 2.6) the case. */
511 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
512 (char**)&cp1, &len1, (char**)&cp2, &len2) )
513 return 0;
514 if ( len1 & 1 || len2 & 1 ) {
515 PyErr_SetString(AudioopError, "Strings should be even-sized");
516 return 0;
517 }
518 len1 >>= 1;
519 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 if ( len1 < len2 ) {
522 PyErr_SetString(AudioopError, "First sample should be longer");
523 return 0;
524 }
525 sum_ri_2 = _sum2(cp2, cp2, len2);
526 sum_aij_2 = _sum2(cp1, cp1, len2);
527 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 best_result = result;
532 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 for ( j=1; j<=len1-len2; j++) {
535 aj_m1 = (double)cp1[j-1];
536 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
539 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
542 / sum_aij_2;
543
544 if ( result < best_result ) {
545 best_result = result;
546 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000547 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 }
550
551 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
552
Mark Dickinson81fece22010-05-11 13:34:35 +0000553 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000554}
555
556/*
557** findfactor finds a factor f so that the energy in A-fB is minimal.
558** See the comment for findfit for details.
559*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000561audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000564 Py_ssize_t len1, len2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
568 (char**)&cp1, &len1, (char**)&cp2, &len2) )
569 return 0;
570 if ( len1 & 1 || len2 & 1 ) {
571 PyErr_SetString(AudioopError, "Strings should be even-sized");
572 return 0;
573 }
574 if ( len1 != len2 ) {
575 PyErr_SetString(AudioopError, "Samples should be same size");
576 return 0;
577 }
578 len2 >>= 1;
579 sum_ri_2 = _sum2(cp2, cp2, len2);
580 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000585}
586
587/*
588** findmax returns the index of the n-sized segment of the input sample
589** that contains the most energy.
590*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000591static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000592audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 short *cp1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000595 Py_ssize_t len1, len2;
596 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 double aj_m1, aj_lm1;
598 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000599
Mark Dickinson81fece22010-05-11 13:34:35 +0000600 if ( !PyArg_ParseTuple(args, "s#n:findmax",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 (char**)&cp1, &len1, &len2) )
602 return 0;
603 if ( len1 & 1 ) {
604 PyErr_SetString(AudioopError, "Strings should be even-sized");
605 return 0;
606 }
607 len1 >>= 1;
608
609 if ( len2 < 0 || len1 < len2 ) {
610 PyErr_SetString(AudioopError, "Input sample should be longer");
611 return 0;
612 }
613
614 result = _sum2(cp1, cp1, len2);
615
616 best_result = result;
617 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618
619 for ( j=1; j<=len1-len2; j++) {
620 aj_m1 = (double)cp1[j-1];
621 aj_lm1 = (double)cp1[j+len2-1];
622
623 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
624
625 if ( result > best_result ) {
626 best_result = result;
627 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000628 }
Jack Jansena90805f1993-02-17 14:29:28 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000631
Mark Dickinson81fece22010-05-11 13:34:35 +0000632 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000633}
634
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000635static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000636audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000639 Py_ssize_t len, i;
640 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200642 double sum = 0.0;
643 unsigned int avg;
644 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
647 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000648 if (!audioop_check_parameters(len, size))
649 return NULL;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200650 if (len <= size)
651 return PyLong_FromLong(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
653 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
654 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200655 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 for ( i=size; i<len; i+= size) {
657 if ( size == 1 ) val = (int)*CHARP(cp, i);
658 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
659 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200660 if (val != prevval) {
661 diff = val < prevval;
662 if (prevdiff == !diff) {
663 /* Derivative changed sign. Compute difference to last
664 ** extreme value and remember.
665 */
666 if (prevextremevalid) {
667 sum += fabs((double)prevval - (double)prevextreme);
668 nextreme++;
669 }
670 prevextremevalid = 1;
671 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200673 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200675 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 }
677 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200678 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200680 avg = (unsigned int)(sum / (double)nextreme);
681 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000682}
683
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000684static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000685audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000688 Py_ssize_t len, i;
689 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200691 unsigned int max = 0, extremediff;
692 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
695 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000696 if (!audioop_check_parameters(len, size))
697 return NULL;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200698 if (len <= size)
699 return PyLong_FromLong(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
701 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
702 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200703 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 for ( i=size; i<len; i+= size) {
705 if ( size == 1 ) val = (int)*CHARP(cp, i);
706 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
707 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200708 if (val != prevval) {
709 diff = val < prevval;
710 if (prevdiff == !diff) {
711 /* Derivative changed sign. Compute difference to
712 ** last extreme value and remember.
713 */
714 if (prevextremevalid) {
715 if (prevval < prevextreme)
716 extremediff = (unsigned int)prevextreme -
717 (unsigned int)prevval;
718 else
719 extremediff = (unsigned int)prevval -
720 (unsigned int)prevextreme;
721 if ( extremediff > max )
722 max = extremediff;
723 }
724 prevextremevalid = 1;
725 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200727 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200729 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200731 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000732}
733
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000734static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000735audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000738 Py_ssize_t len, i;
739 int size, val = 0;
740 int prevval;
741 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
744 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000745 if (!audioop_check_parameters(len, size))
746 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 ncross = -1;
748 prevval = 17; /* Anything <> 0,1 */
749 for ( i=0; i<len; i+= size) {
750 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
751 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
752 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
753 val = val & 1;
754 if ( val != prevval ) ncross++;
755 prevval = val;
756 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000757 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000758}
759
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000760static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000761audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000764 Py_ssize_t len, i;
765 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200766 double factor, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
770 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000771 if (!audioop_check_parameters(len, size))
772 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200774 maxval = (double) maxvals[size];
775 minval = (double) minvals[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776
777 rv = PyBytes_FromStringAndSize(NULL, len);
778 if ( rv == 0 )
779 return 0;
780 ncp = (signed char *)PyBytes_AsString(rv);
781
782
783 for ( i=0; i < len; i += size ) {
784 if ( size == 1 ) val = (int)*CHARP(cp, i);
785 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
786 else if ( size == 4 ) val = (int)*LONGP(cp, i);
787 fval = (double)val*factor;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200788 val = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
790 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
791 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
792 }
793 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000794}
795
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000796static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000797audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 Py_buffer pcp;
800 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000801 Py_ssize_t len, i;
802 int size, val1 = 0, val2 = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200803 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
807 &pcp, &size, &fac1, &fac2 ) )
808 return 0;
809 cp = pcp.buf;
810 len = pcp.len;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000811 if (!audioop_check_parameters(len, size)) {
812 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000813 return NULL;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000814 }
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000815 if (((len / size) & 1) != 0) {
816 PyErr_SetString(AudioopError, "not a whole number of frames");
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000817 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000818 return NULL;
819 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200821 maxval = (double) maxvals[size];
822 minval = (double) minvals[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823
824 rv = PyBytes_FromStringAndSize(NULL, len/2);
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000825 if ( rv == 0 ) {
826 PyBuffer_Release(&pcp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 return 0;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000828 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 ncp = (signed char *)PyBytes_AsString(rv);
830
831
832 for ( i=0; i < len; i += size*2 ) {
833 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
834 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
835 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
836 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
837 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
838 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
839 fval = (double)val1*fac1 + (double)val2*fac2;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200840 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
842 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
843 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
844 }
845 PyBuffer_Release(&pcp);
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 Pitrouf95a1b32010-05-09 15:52:27 +0000852 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000853 Py_ssize_t len, i;
854 int size, val1, val2, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200855 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
859 &cp, &len, &size, &fac1, &fac2 ) )
860 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000861 if (!audioop_check_parameters(len, size))
862 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000863
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200864 maxval = (double) maxvals[size];
865 minval = (double) minvals[size];
Guido van Rossumb66efa01992-06-01 16:01:24 +0000866
Mark Dickinson81fece22010-05-11 13:34:35 +0000867 if (len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 PyErr_SetString(PyExc_MemoryError,
869 "not enough memory for output buffer");
870 return 0;
871 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000872
Mark Dickinson85eacea2010-05-10 16:27:45 +0000873 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 if ( rv == 0 )
875 return 0;
876 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000877
Guido van Rossumb66efa01992-06-01 16:01:24 +0000878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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);
883
884 fval = (double)val*fac1;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200885 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886
887 fval = (double)val*fac2;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200888 val2 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889
890 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;
893
894 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 Pitrouf95a1b32010-05-09 15:52:27 +0000904 signed char *cp1, *cp2, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000905 Py_ssize_t len1, len2, i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200906 int size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 if ( !PyArg_ParseTuple(args, "s#s#i:add",
910 &cp1, &len1, &cp2, &len2, &size ) )
911 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000912 if (!audioop_check_parameters(len1, size))
913 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 if ( len1 != len2 ) {
915 PyErr_SetString(AudioopError, "Lengths should be the same");
916 return 0;
917 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000918
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200919 maxval = maxvals[size];
920 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 rv = PyBytes_FromStringAndSize(NULL, len1);
923 if ( rv == 0 )
924 return 0;
925 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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);
Guido van Rossum1851a671997-02-14 16:14:03 +0000931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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);
935
Serhiy Storchaka01ad6222013-02-09 11:10:53 +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 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949
950 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 Pitrouf95a1b32010-05-09 15:52:27 +0000960 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000961 Py_ssize_t len, i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200962 int size, bias;
963 unsigned int val = 0, mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 if ( !PyArg_ParseTuple(args, "s#ii:bias",
967 &cp, &len, &size , &bias) )
968 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000969
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000970 if (!audioop_check_parameters(len, size))
971 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972
973 rv = PyBytes_FromStringAndSize(NULL, len);
974 if ( rv == 0 )
975 return 0;
976 ncp = (signed char *)PyBytes_AsString(rv);
977
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200978 mask = masks[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979
980 for ( i=0; i < len; i += size ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200981 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
982 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
983 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200985 val += (unsigned int)bias;
986 /* wrap around in case of overflow */
987 val &= mask;
988
989 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
990 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
991 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 }
993 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000994}
995
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000996static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000997audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 signed char *cp;
1000 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001001 Py_ssize_t len, i, j;
1002 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1006 &cp, &len, &size) )
1007 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001008
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001009 if (!audioop_check_parameters(len, size))
1010 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 rv = PyBytes_FromStringAndSize(NULL, len);
1013 if ( rv == 0 )
1014 return 0;
1015 ncp = (unsigned char *)PyBytes_AsString(rv);
1016
1017 for ( i=0; i < len; i += size ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001018 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1019 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1020 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021
1022 j = len - i - size;
1023
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001024 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1025 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1026 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 }
1028 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001029}
1030
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001031static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001032audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 signed char *cp;
1035 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001036 Py_ssize_t len, i, j;
1037 int size, size2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1041 &cp, &len, &size, &size2) )
1042 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001043
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001044 if (!audioop_check_parameters(len, size))
1045 return NULL;
1046 if (!audioop_check_size(size2))
1047 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001048
Mark Dickinson81fece22010-05-11 13:34:35 +00001049 if (len/size > PY_SSIZE_T_MAX/size2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 PyErr_SetString(PyExc_MemoryError,
1051 "not enough memory for output buffer");
1052 return 0;
1053 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001054 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 if ( rv == 0 )
1056 return 0;
1057 ncp = (unsigned char *)PyBytes_AsString(rv);
1058
1059 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001060 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1061 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1062 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001064 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1065 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1066 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 }
1068 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001069}
1070
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001071static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001072gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 while (b > 0) {
1075 int tmp = a % b;
1076 a = b;
1077 b = tmp;
1078 }
1079 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001080}
1081
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001082static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001083audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001086 Py_ssize_t len;
1087 int size, nchannels, inrate, outrate, weightA, weightB;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 int chan, d, *prev_i, *cur_i, cur_o;
1089 PyObject *state, *samps, *str, *rv = NULL;
1090 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 Stinnerbc5c54b2010-07-03 13:44:22 +00001098 if (!audioop_check_size(size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (nchannels < 1) {
1101 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1102 return NULL;
1103 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001104 if (size > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 /* This overflow test is rigorously correct because
1106 both multiplicands are >= 1. Use the argument names
1107 from the docs for the error msg. */
1108 PyErr_SetString(PyExc_OverflowError,
1109 "width * nchannels too big for a C int");
1110 return NULL;
1111 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001112 bytes_per_frame = size * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 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 Storchaka01ad6222013-02-09 11:10:53 +02001130 /* divide weightA and weightB by their greatest common divisor */
1131 d = gcd(weightA, weightB);
1132 weightA /= d;
1133 weightA /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001134
Mark Dickinson85eacea2010-05-10 16:27:45 +00001135 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 PyErr_SetString(PyExc_MemoryError,
1137 "not enough memory for output buffer");
1138 return 0;
1139 }
Victor Stinnerb6404912013-07-07 16:21:41 +02001140 prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
1141 cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 {
1155 if (!PyArg_ParseTuple(state,
1156 "iO!;audioop.ratecv: illegal state argument",
1157 &d, &PyTuple_Type, &samps))
1158 goto exit;
1159 if (PyTuple_Size(samps) != nchannels) {
1160 PyErr_SetString(AudioopError,
1161 "illegal state argument");
1162 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001163 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 for (chan = 0; chan < nchannels; chan++) {
1165 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1166 "ii:ratecv", &prev_i[chan],
1167 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001168 goto exit;
1169 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001173 if (len == 0)
1174 str = PyBytes_FromStringAndSize(NULL, 0);
1175 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 /* There are len input frames, so we need (mathematically)
1177 ceiling(len*outrate/inrate) output frames, and each frame
1178 requires bytes_per_frame bytes. Computing this
1179 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001180 settle for a reasonable upper bound, though, in this
1181 case ceiling(len/inrate) * outrate. */
1182
1183 /* compute ceiling(len/inrate) without overflow */
Mark Dickinson81fece22010-05-11 13:34:35 +00001184 Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
1185 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 str = NULL;
1187 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001188 str = PyBytes_FromStringAndSize(NULL,
1189 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001190 }
1191 if (str == NULL) {
1192 PyErr_SetString(PyExc_MemoryError,
1193 "not enough memory for output buffer");
1194 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 }
1196 ncp = PyBytes_AsString(str);
1197
1198 for (;;) {
1199 while (d < 0) {
1200 if (len == 0) {
1201 samps = PyTuple_New(nchannels);
1202 if (samps == NULL)
1203 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001204 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 PyTuple_SetItem(samps, chan,
1206 Py_BuildValue("(ii)",
1207 prev_i[chan],
1208 cur_i[chan]));
1209 if (PyErr_Occurred())
1210 goto exit;
1211 /* We have checked before that the length
1212 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001213 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 rv = PyBytes_FromStringAndSize
1215 (PyBytes_AsString(str), len);
1216 Py_DECREF(str);
1217 str = rv;
1218 if (str == NULL)
1219 goto exit;
1220 rv = Py_BuildValue("(O(iO))", str, d, samps);
1221 Py_DECREF(samps);
1222 Py_DECREF(str);
1223 goto exit; /* return rv */
1224 }
1225 for (chan = 0; chan < nchannels; chan++) {
1226 prev_i[chan] = cur_i[chan];
1227 if (size == 1)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001228 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 else if (size == 2)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001230 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 else if (size == 4)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001232 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 cp += size;
1234 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001235 cur_i[chan] = (int)(
1236 ((double)weightA * (double)cur_i[chan] +
1237 (double)weightB * (double)prev_i[chan]) /
1238 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 }
1240 len--;
1241 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001242 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 while (d >= 0) {
1244 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001245 cur_o = (int)(((double)prev_i[chan] * (double)d +
1246 (double)cur_i[chan] * (double)(outrate - d)) /
1247 (double)outrate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 if (size == 1)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001249 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 else if (size == 2)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001251 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 else if (size == 4)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001253 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 ncp += size;
1255 }
1256 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001257 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001259 exit:
Victor Stinnerb6404912013-07-07 16:21:41 +02001260 PyMem_Free(prev_i);
1261 PyMem_Free(cur_i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001263}
Guido van Rossum1851a671997-02-14 16:14:03 +00001264
Roger E. Massec905fff1997-01-17 18:12:04 +00001265static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001266audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 signed char *cp;
1269 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001270 Py_ssize_t len, i;
1271 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1275 &cp, &len, &size) )
1276 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001277
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001278 if (!audioop_check_parameters(len, size))
1279 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 rv = PyBytes_FromStringAndSize(NULL, len/size);
1282 if ( rv == 0 )
1283 return 0;
1284 ncp = (unsigned char *)PyBytes_AsString(rv);
1285
1286 for ( i=0; i < len; i += size ) {
1287 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1288 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1289 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1290
1291 *ncp++ = st_14linear2ulaw(val);
1292 }
1293 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001294}
1295
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001296static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001297audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 unsigned char *cp;
1300 unsigned char cval;
1301 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001302 Py_ssize_t len, i;
1303 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1307 &cp, &len, &size) )
1308 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001309
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001310 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001311 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312
Mark Dickinson81fece22010-05-11 13:34:35 +00001313 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 PyErr_SetString(PyExc_MemoryError,
1315 "not enough memory for output buffer");
1316 return 0;
1317 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001318 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 if ( rv == 0 )
1320 return 0;
1321 ncp = (signed char *)PyBytes_AsString(rv);
1322
Mark Dickinson85eacea2010-05-10 16:27:45 +00001323 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 cval = *cp++;
1325 val = st_ulaw2linear16(cval);
1326
1327 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1328 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1329 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1330 }
1331 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001332}
1333
1334static PyObject *
1335audioop_lin2alaw(PyObject *self, PyObject *args)
1336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 signed char *cp;
1338 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001339 Py_ssize_t len, i;
1340 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1344 &cp, &len, &size) )
1345 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001346
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001347 if (!audioop_check_parameters(len, size))
1348 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 rv = PyBytes_FromStringAndSize(NULL, len/size);
1351 if ( rv == 0 )
1352 return 0;
1353 ncp = (unsigned char *)PyBytes_AsString(rv);
1354
1355 for ( i=0; i < len; i += size ) {
1356 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1357 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1358 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1359
1360 *ncp++ = st_linear2alaw(val);
1361 }
1362 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001363}
1364
1365static PyObject *
1366audioop_alaw2lin(PyObject *self, PyObject *args)
1367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 unsigned char *cp;
1369 unsigned char cval;
1370 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001371 Py_ssize_t len, i;
1372 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1376 &cp, &len, &size) )
1377 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001378
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001379 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001380 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381
Mark Dickinson81fece22010-05-11 13:34:35 +00001382 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 PyErr_SetString(PyExc_MemoryError,
1384 "not enough memory for output buffer");
1385 return 0;
1386 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001387 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 if ( rv == 0 )
1389 return 0;
1390 ncp = (signed char *)PyBytes_AsString(rv);
1391
Mark Dickinson85eacea2010-05-10 16:27:45 +00001392 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 cval = *cp++;
1394 val = st_alaw2linear16(cval);
1395
1396 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1397 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1398 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1399 }
1400 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001401}
1402
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001403static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001404audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 signed char *cp;
1407 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001408 Py_ssize_t len, i;
1409 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 index, sign, vpdiff, diff;
1411 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001412 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1415 &cp, &len, &size, &state) )
1416 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001417
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001418 if (!audioop_check_parameters(len, size))
1419 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420
1421 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1422 if ( str == 0 )
1423 return 0;
1424 ncp = (signed char *)PyBytes_AsString(str);
1425
1426 /* Decode state, should have (value, step) */
1427 if ( state == Py_None ) {
1428 /* First time, it seems. Set defaults */
1429 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 index = 0;
1431 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1432 return 0;
1433
1434 step = stepsizeTable[index];
1435 bufferstep = 1;
1436
1437 for ( i=0; i < len; i += size ) {
1438 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1439 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1440 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1441
1442 /* Step 1 - compute difference with previous value */
1443 diff = val - valpred;
1444 sign = (diff < 0) ? 8 : 0;
1445 if ( sign ) diff = (-diff);
1446
1447 /* Step 2 - Divide and clamp */
1448 /* Note:
1449 ** This code *approximately* computes:
1450 ** delta = diff*4/step;
1451 ** vpdiff = (delta+0.5)*step/4;
1452 ** but in shift step bits are dropped. The net result of this
1453 ** is that even if you have fast mul/div hardware you cannot
1454 ** put it to good use since the fixup would be too expensive.
1455 */
1456 delta = 0;
1457 vpdiff = (step >> 3);
1458
1459 if ( diff >= step ) {
1460 delta = 4;
1461 diff -= step;
1462 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001463 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 step >>= 1;
1465 if ( diff >= step ) {
1466 delta |= 2;
1467 diff -= step;
1468 vpdiff += step;
1469 }
1470 step >>= 1;
1471 if ( diff >= step ) {
1472 delta |= 1;
1473 vpdiff += step;
1474 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 /* Step 3 - Update previous value */
1477 if ( sign )
1478 valpred -= vpdiff;
1479 else
1480 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 /* Step 4 - Clamp previous value to 16 bits */
1483 if ( valpred > 32767 )
1484 valpred = 32767;
1485 else if ( valpred < -32768 )
1486 valpred = -32768;
1487
1488 /* Step 5 - Assemble value, update index and step values */
1489 delta |= sign;
1490
1491 index += indexTable[delta];
1492 if ( index < 0 ) index = 0;
1493 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001494 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 /* Step 6 - Output value */
1497 if ( bufferstep ) {
1498 outputbuffer = (delta << 4) & 0xf0;
1499 } else {
1500 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001501 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 bufferstep = !bufferstep;
1503 }
1504 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1505 Py_DECREF(str);
1506 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001507}
1508
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001509static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001510audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 signed char *cp;
1513 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001514 Py_ssize_t len, i;
1515 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001517 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1520 &cp, &len, &size, &state) )
1521 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001522
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001523 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001524 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525
1526 /* Decode state, should have (value, step) */
1527 if ( state == Py_None ) {
1528 /* First time, it seems. Set defaults */
1529 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 index = 0;
1531 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1532 return 0;
1533
Mark Dickinson81fece22010-05-11 13:34:35 +00001534 if (len > (PY_SSIZE_T_MAX/2)/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 PyErr_SetString(PyExc_MemoryError,
1536 "not enough memory for output buffer");
1537 return 0;
1538 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001539 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 if ( str == 0 )
1541 return 0;
1542 ncp = (signed char *)PyBytes_AsString(str);
1543
1544 step = stepsizeTable[index];
1545 bufferstep = 0;
1546
Mark Dickinson85eacea2010-05-10 16:27:45 +00001547 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 /* Step 1 - get the delta value and compute next index */
1549 if ( bufferstep ) {
1550 delta = inputbuffer & 0xf;
1551 } else {
1552 inputbuffer = *cp++;
1553 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001554 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 bufferstep = !bufferstep;
1557
1558 /* Step 2 - Find new index value (for later) */
1559 index += indexTable[delta];
1560 if ( index < 0 ) index = 0;
1561 if ( index > 88 ) index = 88;
1562
1563 /* Step 3 - Separate sign and magnitude */
1564 sign = delta & 8;
1565 delta = delta & 7;
1566
1567 /* Step 4 - Compute difference and new predicted value */
1568 /*
1569 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1570 ** in adpcm_coder.
1571 */
1572 vpdiff = step >> 3;
1573 if ( delta & 4 ) vpdiff += step;
1574 if ( delta & 2 ) vpdiff += step>>1;
1575 if ( delta & 1 ) vpdiff += step>>2;
1576
1577 if ( sign )
1578 valpred -= vpdiff;
1579 else
1580 valpred += vpdiff;
1581
1582 /* Step 5 - clamp output value */
1583 if ( valpred > 32767 )
1584 valpred = 32767;
1585 else if ( valpred < -32768 )
1586 valpred = -32768;
1587
1588 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001589 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 /* Step 6 - Output value */
1592 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1593 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1594 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1595 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1598 Py_DECREF(str);
1599 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001600}
1601
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001602static PyMethodDef audioop_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 { "max", audioop_max, METH_VARARGS },
1604 { "minmax", audioop_minmax, METH_VARARGS },
1605 { "avg", audioop_avg, METH_VARARGS },
1606 { "maxpp", audioop_maxpp, METH_VARARGS },
1607 { "avgpp", audioop_avgpp, METH_VARARGS },
1608 { "rms", audioop_rms, METH_VARARGS },
1609 { "findfit", audioop_findfit, METH_VARARGS },
1610 { "findmax", audioop_findmax, METH_VARARGS },
1611 { "findfactor", audioop_findfactor, METH_VARARGS },
1612 { "cross", audioop_cross, METH_VARARGS },
1613 { "mul", audioop_mul, METH_VARARGS },
1614 { "add", audioop_add, METH_VARARGS },
1615 { "bias", audioop_bias, METH_VARARGS },
1616 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1617 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1618 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1619 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1620 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1621 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1622 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1623 { "tomono", audioop_tomono, METH_VARARGS },
1624 { "tostereo", audioop_tostereo, METH_VARARGS },
1625 { "getsample", audioop_getsample, METH_VARARGS },
1626 { "reverse", audioop_reverse, METH_VARARGS },
1627 { "ratecv", audioop_ratecv, METH_VARARGS },
1628 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001629};
1630
Martin v. Löwis1a214512008-06-11 05:26:20 +00001631
1632static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 PyModuleDef_HEAD_INIT,
1634 "audioop",
1635 NULL,
1636 -1,
1637 audioop_methods,
1638 NULL,
1639 NULL,
1640 NULL,
1641 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001642};
1643
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001644PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001645PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 PyObject *m, *d;
1648 m = PyModule_Create(&audioopmodule);
1649 if (m == NULL)
1650 return NULL;
1651 d = PyModule_GetDict(m);
1652 if (d == NULL)
1653 return NULL;
1654 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1655 if (AudioopError != NULL)
1656 PyDict_SetItemString(d,"error",AudioopError);
1657 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001658}