blob: 5c6925870d9d3304095ff61b109166d9765c959f [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;
40 return val;
41}
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;
533 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 for ( j=1; j<=len1-len2; j++) {
536 aj_m1 = (double)cp1[j-1];
537 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
540 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
543 / sum_aij_2;
544
545 if ( result < best_result ) {
546 best_result = result;
547 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000548 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 }
551
552 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
553
Mark Dickinson81fece22010-05-11 13:34:35 +0000554 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000555}
556
557/*
558** findfactor finds a factor f so that the energy in A-fB is minimal.
559** See the comment for findfit for details.
560*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000561static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000562audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000563{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000565 Py_ssize_t len1, len2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
569 (char**)&cp1, &len1, (char**)&cp2, &len2) )
570 return 0;
571 if ( len1 & 1 || len2 & 1 ) {
572 PyErr_SetString(AudioopError, "Strings should be even-sized");
573 return 0;
574 }
575 if ( len1 != len2 ) {
576 PyErr_SetString(AudioopError, "Samples should be same size");
577 return 0;
578 }
579 len2 >>= 1;
580 sum_ri_2 = _sum2(cp2, cp2, len2);
581 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000586}
587
588/*
589** findmax returns the index of the n-sized segment of the input sample
590** that contains the most energy.
591*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000592static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000593audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 short *cp1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000596 Py_ssize_t len1, len2;
597 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 double aj_m1, aj_lm1;
599 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000600
Mark Dickinson81fece22010-05-11 13:34:35 +0000601 if ( !PyArg_ParseTuple(args, "s#n:findmax",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 (char**)&cp1, &len1, &len2) )
603 return 0;
604 if ( len1 & 1 ) {
605 PyErr_SetString(AudioopError, "Strings should be even-sized");
606 return 0;
607 }
608 len1 >>= 1;
609
610 if ( len2 < 0 || len1 < len2 ) {
611 PyErr_SetString(AudioopError, "Input sample should be longer");
612 return 0;
613 }
614
615 result = _sum2(cp1, cp1, len2);
616
617 best_result = result;
618 best_j = 0;
619 j = 0;
620
621 for ( j=1; j<=len1-len2; j++) {
622 aj_m1 = (double)cp1[j-1];
623 aj_lm1 = (double)cp1[j+len2-1];
624
625 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
626
627 if ( result > best_result ) {
628 best_result = result;
629 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000630 }
Jack Jansena90805f1993-02-17 14:29:28 +0000631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000633
Mark Dickinson81fece22010-05-11 13:34:35 +0000634 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000635}
636
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000638audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000639{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000641 Py_ssize_t len, i;
642 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200644 double sum = 0.0;
645 unsigned int avg;
646 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
649 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000650 if (!audioop_check_parameters(len, size))
651 return NULL;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200652 if (len <= size)
653 return PyLong_FromLong(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
655 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
656 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200657 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 for ( i=size; i<len; i+= size) {
659 if ( size == 1 ) val = (int)*CHARP(cp, i);
660 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
661 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200662 if (val != prevval) {
663 diff = val < prevval;
664 if (prevdiff == !diff) {
665 /* Derivative changed sign. Compute difference to last
666 ** extreme value and remember.
667 */
668 if (prevextremevalid) {
669 sum += fabs((double)prevval - (double)prevextreme);
670 nextreme++;
671 }
672 prevextremevalid = 1;
673 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200675 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200677 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 }
679 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200680 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200682 avg = (unsigned int)(sum / (double)nextreme);
683 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000684}
685
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000686static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000687audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000690 Py_ssize_t len, i;
691 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200693 unsigned int max = 0, extremediff;
694 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
697 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000698 if (!audioop_check_parameters(len, size))
699 return NULL;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200700 if (len <= size)
701 return PyLong_FromLong(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
703 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
704 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200705 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 for ( i=size; i<len; i+= size) {
707 if ( size == 1 ) val = (int)*CHARP(cp, i);
708 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
709 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200710 if (val != prevval) {
711 diff = val < prevval;
712 if (prevdiff == !diff) {
713 /* Derivative changed sign. Compute difference to
714 ** last extreme value and remember.
715 */
716 if (prevextremevalid) {
717 if (prevval < prevextreme)
718 extremediff = (unsigned int)prevextreme -
719 (unsigned int)prevval;
720 else
721 extremediff = (unsigned int)prevval -
722 (unsigned int)prevextreme;
723 if ( extremediff > max )
724 max = extremediff;
725 }
726 prevextremevalid = 1;
727 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200729 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200731 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200733 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000734}
735
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000736static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000737audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000740 Py_ssize_t len, i;
741 int size, val = 0;
742 int prevval;
743 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
746 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000747 if (!audioop_check_parameters(len, size))
748 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 ncross = -1;
750 prevval = 17; /* Anything <> 0,1 */
751 for ( i=0; i<len; i+= size) {
752 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
753 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
754 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
755 val = val & 1;
756 if ( val != prevval ) ncross++;
757 prevval = val;
758 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000759 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000760}
761
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000762static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000763audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000766 Py_ssize_t len, i;
767 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200768 double factor, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
772 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000773 if (!audioop_check_parameters(len, size))
774 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200776 maxval = (double) maxvals[size];
777 minval = (double) minvals[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778
779 rv = PyBytes_FromStringAndSize(NULL, len);
780 if ( rv == 0 )
781 return 0;
782 ncp = (signed char *)PyBytes_AsString(rv);
783
784
785 for ( i=0; i < len; i += size ) {
786 if ( size == 1 ) val = (int)*CHARP(cp, i);
787 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
788 else if ( size == 4 ) val = (int)*LONGP(cp, i);
789 fval = (double)val*factor;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200790 val = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
792 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
793 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
794 }
795 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000796}
797
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000798static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000799audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 Py_buffer pcp;
802 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000803 Py_ssize_t len, i;
804 int size, val1 = 0, val2 = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200805 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
809 &pcp, &size, &fac1, &fac2 ) )
810 return 0;
811 cp = pcp.buf;
812 len = pcp.len;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000813 if (!audioop_check_parameters(len, size)) {
814 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000815 return NULL;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000816 }
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000817 if (((len / size) & 1) != 0) {
818 PyErr_SetString(AudioopError, "not a whole number of frames");
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000819 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000820 return NULL;
821 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200823 maxval = (double) maxvals[size];
824 minval = (double) minvals[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825
826 rv = PyBytes_FromStringAndSize(NULL, len/2);
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000827 if ( rv == 0 ) {
828 PyBuffer_Release(&pcp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 return 0;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000830 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 ncp = (signed char *)PyBytes_AsString(rv);
832
833
834 for ( i=0; i < len; i += size*2 ) {
835 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
836 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
837 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
838 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
839 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
840 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
841 fval = (double)val1*fac1 + (double)val2*fac2;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200842 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
844 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
845 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
846 }
847 PyBuffer_Release(&pcp);
848 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000849}
850
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000851static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000852audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000855 Py_ssize_t len, i;
856 int size, val1, val2, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200857 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
861 &cp, &len, &size, &fac1, &fac2 ) )
862 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000863 if (!audioop_check_parameters(len, size))
864 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000865
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200866 maxval = (double) maxvals[size];
867 minval = (double) minvals[size];
Guido van Rossumb66efa01992-06-01 16:01:24 +0000868
Mark Dickinson81fece22010-05-11 13:34:35 +0000869 if (len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 PyErr_SetString(PyExc_MemoryError,
871 "not enough memory for output buffer");
872 return 0;
873 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000874
Mark Dickinson85eacea2010-05-10 16:27:45 +0000875 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 if ( rv == 0 )
877 return 0;
878 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000879
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 for ( i=0; i < len; i += size ) {
882 if ( size == 1 ) val = (int)*CHARP(cp, i);
883 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
884 else if ( size == 4 ) val = (int)*LONGP(cp, i);
885
886 fval = (double)val*fac1;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200887 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888
889 fval = (double)val*fac2;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200890 val2 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891
892 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
893 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
894 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
895
896 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
897 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
898 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
899 }
900 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000901}
902
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000904audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 signed char *cp1, *cp2, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000907 Py_ssize_t len1, len2, i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200908 int size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 if ( !PyArg_ParseTuple(args, "s#s#i:add",
912 &cp1, &len1, &cp2, &len2, &size ) )
913 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000914 if (!audioop_check_parameters(len1, size))
915 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 if ( len1 != len2 ) {
917 PyErr_SetString(AudioopError, "Lengths should be the same");
918 return 0;
919 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000920
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200921 maxval = maxvals[size];
922 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 rv = PyBytes_FromStringAndSize(NULL, len1);
925 if ( rv == 0 )
926 return 0;
927 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 for ( i=0; i < len1; i += size ) {
930 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
931 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
932 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
935 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
936 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
937
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200938 if (size < 4) {
939 newval = val1 + val2;
940 /* truncate in case of overflow */
941 if (newval > maxval)
942 newval = maxval;
943 else if (newval < minval)
944 newval = minval;
945 }
946 else {
947 double fval = (double)val1 + (double)val2;
948 /* truncate in case of overflow */
949 newval = (int)floor(fbound(fval, minval, maxval));
950 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951
952 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
953 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
954 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
955 }
956 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000957}
958
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000959static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000960audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000963 Py_ssize_t len, i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200964 int size, bias;
965 unsigned int val = 0, mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 if ( !PyArg_ParseTuple(args, "s#ii:bias",
969 &cp, &len, &size , &bias) )
970 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000971
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000972 if (!audioop_check_parameters(len, size))
973 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974
975 rv = PyBytes_FromStringAndSize(NULL, len);
976 if ( rv == 0 )
977 return 0;
978 ncp = (signed char *)PyBytes_AsString(rv);
979
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200980 mask = masks[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981
982 for ( i=0; i < len; i += size ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200983 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
984 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
985 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200987 val += (unsigned int)bias;
988 /* wrap around in case of overflow */
989 val &= mask;
990
991 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
992 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
993 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 }
995 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000996}
997
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000998static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000999audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 signed char *cp;
1002 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001003 Py_ssize_t len, i, j;
1004 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1008 &cp, &len, &size) )
1009 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001010
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001011 if (!audioop_check_parameters(len, size))
1012 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 rv = PyBytes_FromStringAndSize(NULL, len);
1015 if ( rv == 0 )
1016 return 0;
1017 ncp = (unsigned char *)PyBytes_AsString(rv);
1018
1019 for ( i=0; i < len; i += size ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001020 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1021 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1022 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023
1024 j = len - i - size;
1025
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001026 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1027 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1028 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 }
1030 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001031}
1032
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001033static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001034audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 signed char *cp;
1037 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001038 Py_ssize_t len, i, j;
1039 int size, size2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1043 &cp, &len, &size, &size2) )
1044 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001045
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001046 if (!audioop_check_parameters(len, size))
1047 return NULL;
1048 if (!audioop_check_size(size2))
1049 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001050
Mark Dickinson81fece22010-05-11 13:34:35 +00001051 if (len/size > PY_SSIZE_T_MAX/size2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 PyErr_SetString(PyExc_MemoryError,
1053 "not enough memory for output buffer");
1054 return 0;
1055 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001056 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 if ( rv == 0 )
1058 return 0;
1059 ncp = (unsigned char *)PyBytes_AsString(rv);
1060
1061 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001062 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1063 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1064 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001066 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1067 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1068 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 }
1070 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001071}
1072
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001073static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001074gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 while (b > 0) {
1077 int tmp = a % b;
1078 a = b;
1079 b = tmp;
1080 }
1081 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001082}
1083
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001084static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001085audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001088 Py_ssize_t len;
1089 int size, nchannels, inrate, outrate, weightA, weightB;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 int chan, d, *prev_i, *cur_i, cur_o;
1091 PyObject *state, *samps, *str, *rv = NULL;
1092 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 weightA = 1;
1095 weightB = 0;
1096 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1097 &nchannels, &inrate, &outrate, &state,
1098 &weightA, &weightB))
1099 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001100 if (!audioop_check_size(size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 if (nchannels < 1) {
1103 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1104 return NULL;
1105 }
1106 bytes_per_frame = size * nchannels;
1107 if (bytes_per_frame / nchannels != size) {
1108 /* This overflow test is rigorously correct because
1109 both multiplicands are >= 1. Use the argument names
1110 from the docs for the error msg. */
1111 PyErr_SetString(PyExc_OverflowError,
1112 "width * nchannels too big for a C int");
1113 return NULL;
1114 }
1115 if (weightA < 1 || weightB < 0) {
1116 PyErr_SetString(AudioopError,
1117 "weightA should be >= 1, weightB should be >= 0");
1118 return NULL;
1119 }
1120 if (len % bytes_per_frame != 0) {
1121 PyErr_SetString(AudioopError, "not a whole number of frames");
1122 return NULL;
1123 }
1124 if (inrate <= 0 || outrate <= 0) {
1125 PyErr_SetString(AudioopError, "sampling rate not > 0");
1126 return NULL;
1127 }
1128 /* divide inrate and outrate by their greatest common divisor */
1129 d = gcd(inrate, outrate);
1130 inrate /= d;
1131 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001132 /* divide weightA and weightB by their greatest common divisor */
1133 d = gcd(weightA, weightB);
1134 weightA /= d;
1135 weightA /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001136
Mark Dickinson85eacea2010-05-10 16:27:45 +00001137 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 PyErr_SetString(PyExc_MemoryError,
1139 "not enough memory for output buffer");
1140 return 0;
1141 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001142 prev_i = (int *) malloc(nchannels * sizeof(int));
1143 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 if (prev_i == NULL || cur_i == NULL) {
1145 (void) PyErr_NoMemory();
1146 goto exit;
1147 }
1148
1149 len /= bytes_per_frame; /* # of frames */
1150
1151 if (state == Py_None) {
1152 d = -outrate;
1153 for (chan = 0; chan < nchannels; chan++)
1154 prev_i[chan] = cur_i[chan] = 0;
1155 }
1156 else {
1157 if (!PyArg_ParseTuple(state,
1158 "iO!;audioop.ratecv: illegal state argument",
1159 &d, &PyTuple_Type, &samps))
1160 goto exit;
1161 if (PyTuple_Size(samps) != nchannels) {
1162 PyErr_SetString(AudioopError,
1163 "illegal state argument");
1164 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001165 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 for (chan = 0; chan < nchannels; chan++) {
1167 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1168 "ii:ratecv", &prev_i[chan],
1169 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001170 goto exit;
1171 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 /* str <- Space for the output buffer. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001175 if (len == 0)
1176 str = PyBytes_FromStringAndSize(NULL, 0);
1177 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 /* There are len input frames, so we need (mathematically)
1179 ceiling(len*outrate/inrate) output frames, and each frame
1180 requires bytes_per_frame bytes. Computing this
1181 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001182 settle for a reasonable upper bound, though, in this
1183 case ceiling(len/inrate) * outrate. */
1184
1185 /* compute ceiling(len/inrate) without overflow */
Mark Dickinson81fece22010-05-11 13:34:35 +00001186 Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
1187 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 str = NULL;
1189 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001190 str = PyBytes_FromStringAndSize(NULL,
1191 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001192 }
1193 if (str == NULL) {
1194 PyErr_SetString(PyExc_MemoryError,
1195 "not enough memory for output buffer");
1196 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 }
1198 ncp = PyBytes_AsString(str);
1199
1200 for (;;) {
1201 while (d < 0) {
1202 if (len == 0) {
1203 samps = PyTuple_New(nchannels);
1204 if (samps == NULL)
1205 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001206 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 PyTuple_SetItem(samps, chan,
1208 Py_BuildValue("(ii)",
1209 prev_i[chan],
1210 cur_i[chan]));
1211 if (PyErr_Occurred())
1212 goto exit;
1213 /* We have checked before that the length
1214 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001215 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 rv = PyBytes_FromStringAndSize
1217 (PyBytes_AsString(str), len);
1218 Py_DECREF(str);
1219 str = rv;
1220 if (str == NULL)
1221 goto exit;
1222 rv = Py_BuildValue("(O(iO))", str, d, samps);
1223 Py_DECREF(samps);
1224 Py_DECREF(str);
1225 goto exit; /* return rv */
1226 }
1227 for (chan = 0; chan < nchannels; chan++) {
1228 prev_i[chan] = cur_i[chan];
1229 if (size == 1)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001230 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 else if (size == 2)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001232 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 else if (size == 4)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001234 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 cp += size;
1236 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001237 cur_i[chan] = (int)(
1238 ((double)weightA * (double)cur_i[chan] +
1239 (double)weightB * (double)prev_i[chan]) /
1240 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 }
1242 len--;
1243 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001244 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 while (d >= 0) {
1246 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001247 cur_o = (int)(((double)prev_i[chan] * (double)d +
1248 (double)cur_i[chan] * (double)(outrate - d)) /
1249 (double)outrate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 if (size == 1)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001251 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 else if (size == 2)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001253 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 else if (size == 4)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001255 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 ncp += size;
1257 }
1258 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001259 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001261 exit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 if (prev_i != NULL)
1263 free(prev_i);
1264 if (cur_i != NULL)
1265 free(cur_i);
1266 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001267}
Guido van Rossum1851a671997-02-14 16:14:03 +00001268
Roger E. Massec905fff1997-01-17 18:12:04 +00001269static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001270audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 signed char *cp;
1273 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001274 Py_ssize_t len, i;
1275 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1279 &cp, &len, &size) )
1280 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001282 if (!audioop_check_parameters(len, size))
1283 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 rv = PyBytes_FromStringAndSize(NULL, len/size);
1286 if ( rv == 0 )
1287 return 0;
1288 ncp = (unsigned char *)PyBytes_AsString(rv);
1289
1290 for ( i=0; i < len; i += size ) {
1291 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1292 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1293 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1294
1295 *ncp++ = st_14linear2ulaw(val);
1296 }
1297 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001298}
1299
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001300static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001301audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 unsigned char *cp;
1304 unsigned char cval;
1305 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001306 Py_ssize_t len, i;
1307 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1311 &cp, &len, &size) )
1312 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001313
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001314 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001315 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316
Mark Dickinson81fece22010-05-11 13:34:35 +00001317 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 PyErr_SetString(PyExc_MemoryError,
1319 "not enough memory for output buffer");
1320 return 0;
1321 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001322 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if ( rv == 0 )
1324 return 0;
1325 ncp = (signed char *)PyBytes_AsString(rv);
1326
Mark Dickinson85eacea2010-05-10 16:27:45 +00001327 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 cval = *cp++;
1329 val = st_ulaw2linear16(cval);
1330
1331 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1332 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1333 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1334 }
1335 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001336}
1337
1338static PyObject *
1339audioop_lin2alaw(PyObject *self, PyObject *args)
1340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 signed char *cp;
1342 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001343 Py_ssize_t len, i;
1344 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1348 &cp, &len, &size) )
1349 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001350
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001351 if (!audioop_check_parameters(len, size))
1352 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 rv = PyBytes_FromStringAndSize(NULL, len/size);
1355 if ( rv == 0 )
1356 return 0;
1357 ncp = (unsigned char *)PyBytes_AsString(rv);
1358
1359 for ( i=0; i < len; i += size ) {
1360 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1361 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1362 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1363
1364 *ncp++ = st_linear2alaw(val);
1365 }
1366 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001367}
1368
1369static PyObject *
1370audioop_alaw2lin(PyObject *self, PyObject *args)
1371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 unsigned char *cp;
1373 unsigned char cval;
1374 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001375 Py_ssize_t len, i;
1376 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1380 &cp, &len, &size) )
1381 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001382
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001383 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001384 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385
Mark Dickinson81fece22010-05-11 13:34:35 +00001386 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyErr_SetString(PyExc_MemoryError,
1388 "not enough memory for output buffer");
1389 return 0;
1390 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001391 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 if ( rv == 0 )
1393 return 0;
1394 ncp = (signed char *)PyBytes_AsString(rv);
1395
Mark Dickinson85eacea2010-05-10 16:27:45 +00001396 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 cval = *cp++;
1398 val = st_alaw2linear16(cval);
1399
1400 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1401 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1402 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1403 }
1404 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001405}
1406
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001407static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001408audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 signed char *cp;
1411 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001412 Py_ssize_t len, i;
1413 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 index, sign, vpdiff, diff;
1415 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001416 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1419 &cp, &len, &size, &state) )
1420 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001421
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001422 if (!audioop_check_parameters(len, size))
1423 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424
1425 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1426 if ( str == 0 )
1427 return 0;
1428 ncp = (signed char *)PyBytes_AsString(str);
1429
1430 /* Decode state, should have (value, step) */
1431 if ( state == Py_None ) {
1432 /* First time, it seems. Set defaults */
1433 valpred = 0;
1434 step = 7;
1435 index = 0;
1436 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1437 return 0;
1438
1439 step = stepsizeTable[index];
1440 bufferstep = 1;
1441
1442 for ( i=0; i < len; i += size ) {
1443 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1444 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1445 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1446
1447 /* Step 1 - compute difference with previous value */
1448 diff = val - valpred;
1449 sign = (diff < 0) ? 8 : 0;
1450 if ( sign ) diff = (-diff);
1451
1452 /* Step 2 - Divide and clamp */
1453 /* Note:
1454 ** This code *approximately* computes:
1455 ** delta = diff*4/step;
1456 ** vpdiff = (delta+0.5)*step/4;
1457 ** but in shift step bits are dropped. The net result of this
1458 ** is that even if you have fast mul/div hardware you cannot
1459 ** put it to good use since the fixup would be too expensive.
1460 */
1461 delta = 0;
1462 vpdiff = (step >> 3);
1463
1464 if ( diff >= step ) {
1465 delta = 4;
1466 diff -= step;
1467 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001468 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 step >>= 1;
1470 if ( diff >= step ) {
1471 delta |= 2;
1472 diff -= step;
1473 vpdiff += step;
1474 }
1475 step >>= 1;
1476 if ( diff >= step ) {
1477 delta |= 1;
1478 vpdiff += step;
1479 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 /* Step 3 - Update previous value */
1482 if ( sign )
1483 valpred -= vpdiff;
1484 else
1485 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 /* Step 4 - Clamp previous value to 16 bits */
1488 if ( valpred > 32767 )
1489 valpred = 32767;
1490 else if ( valpred < -32768 )
1491 valpred = -32768;
1492
1493 /* Step 5 - Assemble value, update index and step values */
1494 delta |= sign;
1495
1496 index += indexTable[delta];
1497 if ( index < 0 ) index = 0;
1498 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001499 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 /* Step 6 - Output value */
1502 if ( bufferstep ) {
1503 outputbuffer = (delta << 4) & 0xf0;
1504 } else {
1505 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001506 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 bufferstep = !bufferstep;
1508 }
1509 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1510 Py_DECREF(str);
1511 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001512}
1513
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001514static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001515audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 signed char *cp;
1518 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001519 Py_ssize_t len, i;
1520 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001522 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1525 &cp, &len, &size, &state) )
1526 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001527
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001528 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001529 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530
1531 /* Decode state, should have (value, step) */
1532 if ( state == Py_None ) {
1533 /* First time, it seems. Set defaults */
1534 valpred = 0;
1535 step = 7;
1536 index = 0;
1537 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1538 return 0;
1539
Mark Dickinson81fece22010-05-11 13:34:35 +00001540 if (len > (PY_SSIZE_T_MAX/2)/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 PyErr_SetString(PyExc_MemoryError,
1542 "not enough memory for output buffer");
1543 return 0;
1544 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001545 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 if ( str == 0 )
1547 return 0;
1548 ncp = (signed char *)PyBytes_AsString(str);
1549
1550 step = stepsizeTable[index];
1551 bufferstep = 0;
1552
Mark Dickinson85eacea2010-05-10 16:27:45 +00001553 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 /* Step 1 - get the delta value and compute next index */
1555 if ( bufferstep ) {
1556 delta = inputbuffer & 0xf;
1557 } else {
1558 inputbuffer = *cp++;
1559 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001560 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 bufferstep = !bufferstep;
1563
1564 /* Step 2 - Find new index value (for later) */
1565 index += indexTable[delta];
1566 if ( index < 0 ) index = 0;
1567 if ( index > 88 ) index = 88;
1568
1569 /* Step 3 - Separate sign and magnitude */
1570 sign = delta & 8;
1571 delta = delta & 7;
1572
1573 /* Step 4 - Compute difference and new predicted value */
1574 /*
1575 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1576 ** in adpcm_coder.
1577 */
1578 vpdiff = step >> 3;
1579 if ( delta & 4 ) vpdiff += step;
1580 if ( delta & 2 ) vpdiff += step>>1;
1581 if ( delta & 1 ) vpdiff += step>>2;
1582
1583 if ( sign )
1584 valpred -= vpdiff;
1585 else
1586 valpred += vpdiff;
1587
1588 /* Step 5 - clamp output value */
1589 if ( valpred > 32767 )
1590 valpred = 32767;
1591 else if ( valpred < -32768 )
1592 valpred = -32768;
1593
1594 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001595 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 /* Step 6 - Output value */
1598 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1599 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1600 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1601 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1604 Py_DECREF(str);
1605 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001606}
1607
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001608static PyMethodDef audioop_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 { "max", audioop_max, METH_VARARGS },
1610 { "minmax", audioop_minmax, METH_VARARGS },
1611 { "avg", audioop_avg, METH_VARARGS },
1612 { "maxpp", audioop_maxpp, METH_VARARGS },
1613 { "avgpp", audioop_avgpp, METH_VARARGS },
1614 { "rms", audioop_rms, METH_VARARGS },
1615 { "findfit", audioop_findfit, METH_VARARGS },
1616 { "findmax", audioop_findmax, METH_VARARGS },
1617 { "findfactor", audioop_findfactor, METH_VARARGS },
1618 { "cross", audioop_cross, METH_VARARGS },
1619 { "mul", audioop_mul, METH_VARARGS },
1620 { "add", audioop_add, METH_VARARGS },
1621 { "bias", audioop_bias, METH_VARARGS },
1622 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1623 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1624 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1625 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1626 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1627 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1628 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1629 { "tomono", audioop_tomono, METH_VARARGS },
1630 { "tostereo", audioop_tostereo, METH_VARARGS },
1631 { "getsample", audioop_getsample, METH_VARARGS },
1632 { "reverse", audioop_reverse, METH_VARARGS },
1633 { "ratecv", audioop_ratecv, METH_VARARGS },
1634 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001635};
1636
Martin v. Löwis1a214512008-06-11 05:26:20 +00001637
1638static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 PyModuleDef_HEAD_INIT,
1640 "audioop",
1641 NULL,
1642 -1,
1643 audioop_methods,
1644 NULL,
1645 NULL,
1646 NULL,
1647 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001648};
1649
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001650PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001651PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 PyObject *m, *d;
1654 m = PyModule_Create(&audioopmodule);
1655 if (m == NULL)
1656 return NULL;
1657 d = PyModule_GetDict(m);
1658 if (d == NULL)
1659 return NULL;
1660 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1661 if (AudioopError != NULL)
1662 PyDict_SetItemString(d,"error",AudioopError);
1663 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001664}