blob: 4f2b25f33a06fe68b662578cde74a31d53662230 [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 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001140 prev_i = (int *) malloc(nchannels * sizeof(int));
1141 cur_i = (int *) 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:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (prev_i != NULL)
1261 free(prev_i);
1262 if (cur_i != NULL)
1263 free(cur_i);
1264 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001265}
Guido van Rossum1851a671997-02-14 16:14:03 +00001266
Roger E. Massec905fff1997-01-17 18:12:04 +00001267static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001268audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 signed char *cp;
1271 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001272 Py_ssize_t len, i;
1273 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1277 &cp, &len, &size) )
1278 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001279
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001280 if (!audioop_check_parameters(len, size))
1281 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 rv = PyBytes_FromStringAndSize(NULL, len/size);
1284 if ( rv == 0 )
1285 return 0;
1286 ncp = (unsigned char *)PyBytes_AsString(rv);
1287
1288 for ( i=0; i < len; i += size ) {
1289 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1290 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1291 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1292
1293 *ncp++ = st_14linear2ulaw(val);
1294 }
1295 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001296}
1297
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001298static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001299audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 unsigned char *cp;
1302 unsigned char cval;
1303 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001304 Py_ssize_t len, i;
1305 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1309 &cp, &len, &size) )
1310 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001311
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001312 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001313 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314
Mark Dickinson81fece22010-05-11 13:34:35 +00001315 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 PyErr_SetString(PyExc_MemoryError,
1317 "not enough memory for output buffer");
1318 return 0;
1319 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001320 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 if ( rv == 0 )
1322 return 0;
1323 ncp = (signed char *)PyBytes_AsString(rv);
1324
Mark Dickinson85eacea2010-05-10 16:27:45 +00001325 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 cval = *cp++;
1327 val = st_ulaw2linear16(cval);
1328
1329 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1330 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1331 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1332 }
1333 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001334}
1335
1336static PyObject *
1337audioop_lin2alaw(PyObject *self, PyObject *args)
1338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 signed char *cp;
1340 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001341 Py_ssize_t len, i;
1342 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1346 &cp, &len, &size) )
1347 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001348
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001349 if (!audioop_check_parameters(len, size))
1350 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 rv = PyBytes_FromStringAndSize(NULL, len/size);
1353 if ( rv == 0 )
1354 return 0;
1355 ncp = (unsigned char *)PyBytes_AsString(rv);
1356
1357 for ( i=0; i < len; i += size ) {
1358 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1359 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1360 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1361
1362 *ncp++ = st_linear2alaw(val);
1363 }
1364 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001365}
1366
1367static PyObject *
1368audioop_alaw2lin(PyObject *self, PyObject *args)
1369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 unsigned char *cp;
1371 unsigned char cval;
1372 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001373 Py_ssize_t len, i;
1374 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1378 &cp, &len, &size) )
1379 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001380
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001381 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001382 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383
Mark Dickinson81fece22010-05-11 13:34:35 +00001384 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 PyErr_SetString(PyExc_MemoryError,
1386 "not enough memory for output buffer");
1387 return 0;
1388 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001389 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 if ( rv == 0 )
1391 return 0;
1392 ncp = (signed char *)PyBytes_AsString(rv);
1393
Mark Dickinson85eacea2010-05-10 16:27:45 +00001394 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 cval = *cp++;
1396 val = st_alaw2linear16(cval);
1397
1398 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1399 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1400 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1401 }
1402 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001403}
1404
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001405static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001406audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 signed char *cp;
1409 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001410 Py_ssize_t len, i;
1411 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 index, sign, vpdiff, diff;
1413 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001414 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1417 &cp, &len, &size, &state) )
1418 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001419
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001420 if (!audioop_check_parameters(len, size))
1421 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422
1423 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1424 if ( str == 0 )
1425 return 0;
1426 ncp = (signed char *)PyBytes_AsString(str);
1427
1428 /* Decode state, should have (value, step) */
1429 if ( state == Py_None ) {
1430 /* First time, it seems. Set defaults */
1431 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 index = 0;
1433 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1434 return 0;
1435
1436 step = stepsizeTable[index];
1437 bufferstep = 1;
1438
1439 for ( i=0; i < len; i += size ) {
1440 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1441 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1442 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1443
1444 /* Step 1 - compute difference with previous value */
1445 diff = val - valpred;
1446 sign = (diff < 0) ? 8 : 0;
1447 if ( sign ) diff = (-diff);
1448
1449 /* Step 2 - Divide and clamp */
1450 /* Note:
1451 ** This code *approximately* computes:
1452 ** delta = diff*4/step;
1453 ** vpdiff = (delta+0.5)*step/4;
1454 ** but in shift step bits are dropped. The net result of this
1455 ** is that even if you have fast mul/div hardware you cannot
1456 ** put it to good use since the fixup would be too expensive.
1457 */
1458 delta = 0;
1459 vpdiff = (step >> 3);
1460
1461 if ( diff >= step ) {
1462 delta = 4;
1463 diff -= step;
1464 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 step >>= 1;
1467 if ( diff >= step ) {
1468 delta |= 2;
1469 diff -= step;
1470 vpdiff += step;
1471 }
1472 step >>= 1;
1473 if ( diff >= step ) {
1474 delta |= 1;
1475 vpdiff += step;
1476 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 /* Step 3 - Update previous value */
1479 if ( sign )
1480 valpred -= vpdiff;
1481 else
1482 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 /* Step 4 - Clamp previous value to 16 bits */
1485 if ( valpred > 32767 )
1486 valpred = 32767;
1487 else if ( valpred < -32768 )
1488 valpred = -32768;
1489
1490 /* Step 5 - Assemble value, update index and step values */
1491 delta |= sign;
1492
1493 index += indexTable[delta];
1494 if ( index < 0 ) index = 0;
1495 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001496 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 /* Step 6 - Output value */
1499 if ( bufferstep ) {
1500 outputbuffer = (delta << 4) & 0xf0;
1501 } else {
1502 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001503 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 bufferstep = !bufferstep;
1505 }
1506 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1507 Py_DECREF(str);
1508 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001509}
1510
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001511static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001512audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 signed char *cp;
1515 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001516 Py_ssize_t len, i;
1517 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001519 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1522 &cp, &len, &size, &state) )
1523 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001524
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001525 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001526 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527
1528 /* Decode state, should have (value, step) */
1529 if ( state == Py_None ) {
1530 /* First time, it seems. Set defaults */
1531 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 index = 0;
1533 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1534 return 0;
1535
Mark Dickinson81fece22010-05-11 13:34:35 +00001536 if (len > (PY_SSIZE_T_MAX/2)/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 PyErr_SetString(PyExc_MemoryError,
1538 "not enough memory for output buffer");
1539 return 0;
1540 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001541 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 if ( str == 0 )
1543 return 0;
1544 ncp = (signed char *)PyBytes_AsString(str);
1545
1546 step = stepsizeTable[index];
1547 bufferstep = 0;
1548
Mark Dickinson85eacea2010-05-10 16:27:45 +00001549 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 /* Step 1 - get the delta value and compute next index */
1551 if ( bufferstep ) {
1552 delta = inputbuffer & 0xf;
1553 } else {
1554 inputbuffer = *cp++;
1555 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001556 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 bufferstep = !bufferstep;
1559
1560 /* Step 2 - Find new index value (for later) */
1561 index += indexTable[delta];
1562 if ( index < 0 ) index = 0;
1563 if ( index > 88 ) index = 88;
1564
1565 /* Step 3 - Separate sign and magnitude */
1566 sign = delta & 8;
1567 delta = delta & 7;
1568
1569 /* Step 4 - Compute difference and new predicted value */
1570 /*
1571 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1572 ** in adpcm_coder.
1573 */
1574 vpdiff = step >> 3;
1575 if ( delta & 4 ) vpdiff += step;
1576 if ( delta & 2 ) vpdiff += step>>1;
1577 if ( delta & 1 ) vpdiff += step>>2;
1578
1579 if ( sign )
1580 valpred -= vpdiff;
1581 else
1582 valpred += vpdiff;
1583
1584 /* Step 5 - clamp output value */
1585 if ( valpred > 32767 )
1586 valpred = 32767;
1587 else if ( valpred < -32768 )
1588 valpred = -32768;
1589
1590 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001591 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 /* Step 6 - Output value */
1594 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1595 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1596 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1597 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1600 Py_DECREF(str);
1601 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001602}
1603
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001604static PyMethodDef audioop_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 { "max", audioop_max, METH_VARARGS },
1606 { "minmax", audioop_minmax, METH_VARARGS },
1607 { "avg", audioop_avg, METH_VARARGS },
1608 { "maxpp", audioop_maxpp, METH_VARARGS },
1609 { "avgpp", audioop_avgpp, METH_VARARGS },
1610 { "rms", audioop_rms, METH_VARARGS },
1611 { "findfit", audioop_findfit, METH_VARARGS },
1612 { "findmax", audioop_findmax, METH_VARARGS },
1613 { "findfactor", audioop_findfactor, METH_VARARGS },
1614 { "cross", audioop_cross, METH_VARARGS },
1615 { "mul", audioop_mul, METH_VARARGS },
1616 { "add", audioop_add, METH_VARARGS },
1617 { "bias", audioop_bias, METH_VARARGS },
1618 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1619 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1620 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1621 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1622 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1623 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1624 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1625 { "tomono", audioop_tomono, METH_VARARGS },
1626 { "tostereo", audioop_tostereo, METH_VARARGS },
1627 { "getsample", audioop_getsample, METH_VARARGS },
1628 { "reverse", audioop_reverse, METH_VARARGS },
1629 { "ratecv", audioop_ratecv, METH_VARARGS },
1630 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001631};
1632
Martin v. Löwis1a214512008-06-11 05:26:20 +00001633
1634static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 PyModuleDef_HEAD_INIT,
1636 "audioop",
1637 NULL,
1638 -1,
1639 audioop_methods,
1640 NULL,
1641 NULL,
1642 NULL,
1643 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001644};
1645
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001646PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001647PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 PyObject *m, *d;
1650 m = PyModule_Create(&audioopmodule);
1651 if (m == NULL)
1652 return NULL;
1653 d = PyModule_GetDict(m);
1654 if (d == NULL)
1655 return NULL;
1656 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1657 if (AudioopError != NULL)
1658 PyDict_SetItemString(d,"error",AudioopError);
1659 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001660}