blob: ce3fce36ab652efafeab44c363aad0c3914def22 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000018typedef short PyInt16;
19
Guido van Rossum7b1e9741994-08-29 10:46:42 +000020#if defined(__CHAR_UNSIGNED__)
21#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000022/* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000026
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000027/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000028** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
29
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030/* From g711.c:
31 *
32 * December 30, 1994:
33 * Functions linear2alaw, linear2ulaw have been updated to correctly
34 * convert unquantized 16 bit values.
35 * Tables for direct u- to A-law and A- to u-law conversions have been
36 * corrected.
37 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
38 * bli@cpk.auc.dk
39 *
40 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000041#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
42#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
44#define QUANT_MASK (0xf) /* Quantization field mask. */
45#define SEG_SHIFT (4) /* Left shift for segment number. */
46#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000047
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
49 0x1FF, 0x3FF, 0x7FF, 0xFFF};
50static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
51 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
52
53static PyInt16
54search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000055{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000058 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
61 }
62 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000063}
64#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
65#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000066
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000067static PyInt16 _st_ulaw2linear16[256] = {
68 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
69 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
70 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
71 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
72 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
73 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
74 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
75 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
76 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
77 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
78 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
79 -1052, -988, -924, -876, -844, -812, -780,
80 -748, -716, -684, -652, -620, -588, -556,
81 -524, -492, -460, -428, -396, -372, -356,
82 -340, -324, -308, -292, -276, -260, -244,
83 -228, -212, -196, -180, -164, -148, -132,
84 -120, -112, -104, -96, -88, -80, -72,
85 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000086 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000087 27004, 25980, 24956, 23932, 22908, 21884, 20860,
88 19836, 18812, 17788, 16764, 15996, 15484, 14972,
89 14460, 13948, 13436, 12924, 12412, 11900, 11388,
90 10876, 10364, 9852, 9340, 8828, 8316, 7932,
91 7676, 7420, 7164, 6908, 6652, 6396, 6140,
92 5884, 5628, 5372, 5116, 4860, 4604, 4348,
93 4092, 3900, 3772, 3644, 3516, 3388, 3260,
94 3132, 3004, 2876, 2748, 2620, 2492, 2364,
95 2236, 2108, 1980, 1884, 1820, 1756, 1692,
96 1628, 1564, 1500, 1436, 1372, 1308, 1244,
97 1180, 1116, 1052, 988, 924, 876, 844,
98 812, 780, 748, 716, 684, 652, 620,
99 588, 556, 524, 492, 460, 428, 396,
100 372, 356, 340, 324, 308, 292, 276,
101 260, 244, 228, 212, 196, 180, 164,
102 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000105};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107/*
108 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
109 * stored in a unsigned char. This function should only be called with
110 * the data shifted such that it only contains information in the lower
111 * 14-bits.
112 *
113 * In order to simplify the encoding process, the original linear magnitude
114 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
115 * (33 - 8191). The result can be seen in the following encoding table:
116 *
117 * Biased Linear Input Code Compressed Code
118 * ------------------------ ---------------
119 * 00000001wxyza 000wxyz
120 * 0000001wxyzab 001wxyz
121 * 000001wxyzabc 010wxyz
122 * 00001wxyzabcd 011wxyz
123 * 0001wxyzabcde 100wxyz
124 * 001wxyzabcdef 101wxyz
125 * 01wxyzabcdefg 110wxyz
126 * 1wxyzabcdefgh 111wxyz
127 *
128 * Each biased linear code has a leading 1 which identifies the segment
129 * number. The value of the segment number is equal to 7 minus the number
130 * of leading 0's. The quantization interval is directly available as the
131 * four bits wxyz. * The trailing bits (a - h) are ignored.
132 *
133 * Ordinarily the complement of the resulting code word is used for
134 * transmission, and so the code word is complemented before it is returned.
135 *
136 * For further information see John C. Bellamy's Digital Telephony, 1982,
137 * John Wiley & Sons, pps 98-111 and 472-476.
138 */
139static unsigned char
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000141{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000145
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000148
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000149 /* u-law inverts all bits */
150 /* Get the sign and the magnitude of the value. */
151 if (pcm_val < 0) {
152 pcm_val = -pcm_val;
153 mask = 0x7F;
154 } else {
155 mask = 0xFF;
156 }
157 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
158 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000159
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000163 /*
164 * Combine the sign, segment, quantization bits;
165 * and complement the code word.
166 */
167 if (seg >= 8) /* out of range, return maximum value. */
168 return (unsigned char) (0x7F ^ mask);
169 else {
170 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
171 return (uval ^ mask);
172 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000173
174}
175
176static PyInt16 _st_alaw2linear16[256] = {
177 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
178 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
179 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
180 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
181 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
182 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
183 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
184 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
185 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
186 -13568, -344, -328, -376, -360, -280, -264,
187 -312, -296, -472, -456, -504, -488, -408,
188 -392, -440, -424, -88, -72, -120, -104,
189 -24, -8, -56, -40, -216, -200, -248,
190 -232, -152, -136, -184, -168, -1376, -1312,
191 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
192 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
193 -688, -656, -752, -720, -560, -528, -624,
194 -592, -944, -912, -1008, -976, -816, -784,
195 -880, -848, 5504, 5248, 6016, 5760, 4480,
196 4224, 4992, 4736, 7552, 7296, 8064, 7808,
197 6528, 6272, 7040, 6784, 2752, 2624, 3008,
198 2880, 2240, 2112, 2496, 2368, 3776, 3648,
199 4032, 3904, 3264, 3136, 3520, 3392, 22016,
200 20992, 24064, 23040, 17920, 16896, 19968, 18944,
201 30208, 29184, 32256, 31232, 26112, 25088, 28160,
202 27136, 11008, 10496, 12032, 11520, 8960, 8448,
203 9984, 9472, 15104, 14592, 16128, 15616, 13056,
204 12544, 14080, 13568, 344, 328, 376, 360,
205 280, 264, 312, 296, 472, 456, 504,
206 488, 408, 392, 440, 424, 88, 72,
207 120, 104, 24, 8, 56, 40, 216,
208 200, 248, 232, 152, 136, 184, 168,
209 1376, 1312, 1504, 1440, 1120, 1056, 1248,
210 1184, 1888, 1824, 2016, 1952, 1632, 1568,
211 1760, 1696, 688, 656, 752, 720, 560,
212 528, 624, 592, 944, 912, 1008, 976,
213 816, 784, 880, 848
214};
215
216/*
217 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
218 * stored in a unsigned char. This function should only be called with
219 * the data shifted such that it only contains information in the lower
220 * 13-bits.
221 *
222 * Linear Input Code Compressed Code
223 * ------------------------ ---------------
224 * 0000000wxyza 000wxyz
225 * 0000001wxyza 001wxyz
226 * 000001wxyzab 010wxyz
227 * 00001wxyzabc 011wxyz
228 * 0001wxyzabcd 100wxyz
229 * 001wxyzabcde 101wxyz
230 * 01wxyzabcdef 110wxyz
231 * 1wxyzabcdefg 111wxyz
232 *
233 * For further information see John C. Bellamy's Digital Telephony, 1982,
234 * John Wiley & Sons, pps 98-111 and 472-476.
235 */
236static unsigned char
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000238{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000242
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000245
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
252 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000257 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
273static int indexTable[16] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
278static int stepsizeTable[89] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000289
Guido van Rossumb66efa01992-06-01 16:01:24 +0000290#define CHARP(cp, i) ((signed char *)(cp+i))
291#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000292#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000293
294
295
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000296static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000297
Victor Stinner8e42fb72010-07-03 13:46:01 +0000298static int
299audioop_check_size(int size)
300{
301 if (size != 1 && size != 2 && size != 4) {
302 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
303 return 0;
304 }
305 else
306 return 1;
307}
308
309static int
310audioop_check_parameters(int len, int size)
311{
312 if (!audioop_check_size(size))
313 return 0;
314 if (len % size != 0) {
315 PyErr_SetString(AudioopError, "not a whole number of frames");
316 return 0;
317 }
318 return 1;
319}
320
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000321static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000322audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000323{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000327
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000328 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
329 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000330 if (!audioop_check_parameters(len, size))
331 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000332 if ( i < 0 || i >= len/size ) {
333 PyErr_SetString(AudioopError, "Index out of range");
334 return 0;
335 }
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
339 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000340}
341
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000342static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000343audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000344{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000345 signed char *cp;
346 int len, size, val = 0;
347 int i;
348 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000349
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000350 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
351 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000352 if (!audioop_check_parameters(len, size))
353 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000354 for ( i=0; i<len; i+= size) {
355 if ( size == 1 ) val = (int)*CHARP(cp, i);
356 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
357 else if ( size == 4 ) val = (int)*LONGP(cp, i);
358 if ( val < 0 ) val = (-val);
359 if ( val > max ) max = val;
360 }
361 return PyLong_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000362}
363
364static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000365audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000366{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000367 signed char *cp;
368 int len, size, val = 0;
369 int i;
370 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000371
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000372 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
373 return NULL;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000374 if (!audioop_check_parameters(len, size))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000375 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000376 for (i = 0; i < len; i += size) {
377 if (size == 1) val = (int) *CHARP(cp, i);
378 else if (size == 2) val = (int) *SHORTP(cp, i);
379 else if (size == 4) val = (int) *LONGP(cp, i);
380 if (val > max) max = val;
381 if (val < min) min = val;
382 }
383 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000384}
385
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000386static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000387audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000388{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000389 signed char *cp;
390 int len, size, val = 0;
391 int i;
392 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000393
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000394 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
395 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000396 if (!audioop_check_parameters(len, size))
397 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000398 for ( i=0; i<len; i+= size) {
399 if ( size == 1 ) val = (int)*CHARP(cp, i);
400 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
401 else if ( size == 4 ) val = (int)*LONGP(cp, i);
402 avg += val;
403 }
404 if ( len == 0 )
405 val = 0;
406 else
407 val = (int)(avg / (double)(len/size));
408 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000409}
410
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000412audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000413{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000414 signed char *cp;
415 int len, size, val = 0;
416 int i;
417 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000418
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000419 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
420 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000421 if (!audioop_check_parameters(len, size))
422 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000423 for ( i=0; i<len; i+= size) {
424 if ( size == 1 ) val = (int)*CHARP(cp, i);
425 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
426 else if ( size == 4 ) val = (int)*LONGP(cp, i);
427 sum_squares += (double)val*(double)val;
428 }
429 if ( len == 0 )
430 val = 0;
431 else
432 val = (int)sqrt(sum_squares / (double)(len/size));
433 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000434}
435
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000436static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000437{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000438 int i;
439 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000440
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000441 for( i=0; i<len; i++) {
442 sum = sum + (double)a[i]*(double)b[i];
443 }
444 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000445}
446
447/*
448** Findfit tries to locate a sample within another sample. Its main use
449** is in echo-cancellation (to find the feedback of the output signal in
450** the input signal).
451** The method used is as follows:
452**
453** let R be the reference signal (length n) and A the input signal (length N)
454** with N > n, and let all sums be over i from 0 to n-1.
455**
456** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
457** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
458** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
459**
460** Next, we compute the relative distance between the original signal and
461** the modified signal and minimize that over j:
462** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
463** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
464**
465** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466** cp1 A
467** cp2 R
468** len1 N
469** len2 n
470** aj_m1 A[j-1]
471** aj_lm1 A[j+n-1]
472** sum_ri_2 sum(R[i]^2)
473** sum_aij_2 sum(A[i+j]^2)
474** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000475**
476** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
477** is completely recalculated each step.
478*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000479static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000480audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000481{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000482 short *cp1, *cp2;
483 int len1, len2;
484 int j, best_j;
485 double aj_m1, aj_lm1;
486 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000487
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000488 /* Passing a short** for an 's' argument is correct only
489 if the string contents is aligned for interpretation
490 as short[]. Due to the definition of PyBytesObject,
491 this is currently (Python 2.6) the case. */
492 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
493 (char**)&cp1, &len1, (char**)&cp2, &len2) )
494 return 0;
495 if ( len1 & 1 || len2 & 1 ) {
496 PyErr_SetString(AudioopError, "Strings should be even-sized");
497 return 0;
498 }
499 len1 >>= 1;
500 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000501
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000502 if ( len1 < len2 ) {
503 PyErr_SetString(AudioopError, "First sample should be longer");
504 return 0;
505 }
506 sum_ri_2 = _sum2(cp2, cp2, len2);
507 sum_aij_2 = _sum2(cp1, cp1, len2);
508 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000509
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000511
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000512 best_result = result;
513 best_j = 0;
514 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000515
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000516 for ( j=1; j<=len1-len2; j++) {
517 aj_m1 = (double)cp1[j-1];
518 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000520 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
521 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000522
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000523 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
524 / sum_aij_2;
525
526 if ( result < best_result ) {
527 best_result = result;
528 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000529 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000530
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000531 }
532
533 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
534
535 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000536}
537
538/*
539** findfactor finds a factor f so that the energy in A-fB is minimal.
540** See the comment for findfit for details.
541*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000542static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000543audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000544{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000545 short *cp1, *cp2;
546 int len1, len2;
547 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000548
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000549 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
550 (char**)&cp1, &len1, (char**)&cp2, &len2) )
551 return 0;
552 if ( len1 & 1 || len2 & 1 ) {
553 PyErr_SetString(AudioopError, "Strings should be even-sized");
554 return 0;
555 }
556 if ( len1 != len2 ) {
557 PyErr_SetString(AudioopError, "Samples should be same size");
558 return 0;
559 }
560 len2 >>= 1;
561 sum_ri_2 = _sum2(cp2, cp2, len2);
562 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000563
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000564 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000565
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000566 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000567}
568
569/*
570** findmax returns the index of the n-sized segment of the input sample
571** that contains the most energy.
572*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000573static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000574audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000575{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000576 short *cp1;
577 int len1, len2;
578 int j, best_j;
579 double aj_m1, aj_lm1;
580 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000581
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000582 if ( !PyArg_ParseTuple(args, "s#i:findmax",
583 (char**)&cp1, &len1, &len2) )
584 return 0;
585 if ( len1 & 1 ) {
586 PyErr_SetString(AudioopError, "Strings should be even-sized");
587 return 0;
588 }
589 len1 >>= 1;
590
591 if ( len2 < 0 || len1 < len2 ) {
592 PyErr_SetString(AudioopError, "Input sample should be longer");
593 return 0;
594 }
595
596 result = _sum2(cp1, cp1, len2);
597
598 best_result = result;
599 best_j = 0;
600 j = 0;
601
602 for ( j=1; j<=len1-len2; j++) {
603 aj_m1 = (double)cp1[j-1];
604 aj_lm1 = (double)cp1[j+len2-1];
605
606 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
607
608 if ( result > best_result ) {
609 best_result = result;
610 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000611 }
Jack Jansena90805f1993-02-17 14:29:28 +0000612
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000613 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000615 return PyLong_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000616}
617
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000618static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000619audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000620{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000621 signed char *cp;
622 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
623 prevextreme = 0;
624 int i;
625 double avg = 0.0;
626 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000627
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000628 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
629 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000630 if (!audioop_check_parameters(len, size))
631 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000632 /* Compute first delta value ahead. Also automatically makes us
633 ** skip the first extreme value
634 */
635 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
636 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
637 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
638 if ( size == 1 ) val = (int)*CHARP(cp, size);
639 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
640 else if ( size == 4 ) val = (int)*LONGP(cp, size);
641 prevdiff = val - prevval;
642
643 for ( i=size; i<len; i+= size) {
644 if ( size == 1 ) val = (int)*CHARP(cp, i);
645 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
646 else if ( size == 4 ) val = (int)*LONGP(cp, i);
647 diff = val - prevval;
648 if ( diff*prevdiff < 0 ) {
649 /* Derivative changed sign. Compute difference to last
650 ** extreme value and remember.
651 */
652 if ( prevextremevalid ) {
653 extremediff = prevval - prevextreme;
654 if ( extremediff < 0 )
655 extremediff = -extremediff;
656 avg += extremediff;
657 nextreme++;
658 }
659 prevextremevalid = 1;
660 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000662 prevval = val;
663 if ( diff != 0 )
664 prevdiff = diff;
665 }
666 if ( nextreme == 0 )
667 val = 0;
668 else
669 val = (int)(avg / (double)nextreme);
670 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000671}
672
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000673static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000674audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000675{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000676 signed char *cp;
677 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
678 prevextreme = 0;
679 int i;
680 int max = 0;
681 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000682
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000683 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
684 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000685 if (!audioop_check_parameters(len, size))
686 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000687 /* Compute first delta value ahead. Also automatically makes us
688 ** skip the first extreme value
689 */
690 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
691 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
692 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
693 if ( size == 1 ) val = (int)*CHARP(cp, size);
694 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
695 else if ( size == 4 ) val = (int)*LONGP(cp, size);
696 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000697
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000698 for ( i=size; i<len; i+= size) {
699 if ( size == 1 ) val = (int)*CHARP(cp, i);
700 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
701 else if ( size == 4 ) val = (int)*LONGP(cp, i);
702 diff = val - prevval;
703 if ( diff*prevdiff < 0 ) {
704 /* Derivative changed sign. Compute difference to
705 ** last extreme value and remember.
706 */
707 if ( prevextremevalid ) {
708 extremediff = prevval - prevextreme;
709 if ( extremediff < 0 )
710 extremediff = -extremediff;
711 if ( extremediff > max )
712 max = extremediff;
713 }
714 prevextremevalid = 1;
715 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000716 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000717 prevval = val;
718 if ( diff != 0 )
719 prevdiff = diff;
720 }
721 return PyLong_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000722}
723
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000724static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000725audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000726{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000727 signed char *cp;
728 int len, size, val = 0;
729 int i;
730 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000731
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000732 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
733 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000734 if (!audioop_check_parameters(len, size))
735 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000736 ncross = -1;
737 prevval = 17; /* Anything <> 0,1 */
738 for ( i=0; i<len; i+= size) {
739 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
740 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
741 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
742 val = val & 1;
743 if ( val != prevval ) ncross++;
744 prevval = val;
745 }
746 return PyLong_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000747}
748
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000749static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000750audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000751{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000752 signed char *cp, *ncp;
753 int len, size, val = 0;
754 double factor, fval, maxval;
755 PyObject *rv;
756 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000757
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000758 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
759 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000760 if (!audioop_check_parameters(len, size))
761 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000762
763 if ( size == 1 ) maxval = (double) 0x7f;
764 else if ( size == 2 ) maxval = (double) 0x7fff;
765 else if ( size == 4 ) maxval = (double) 0x7fffffff;
766 else {
767 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
768 return 0;
769 }
770
771 rv = PyBytes_FromStringAndSize(NULL, len);
772 if ( rv == 0 )
773 return 0;
774 ncp = (signed char *)PyBytes_AsString(rv);
775
776
777 for ( i=0; i < len; i += size ) {
778 if ( size == 1 ) val = (int)*CHARP(cp, i);
779 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
780 else if ( size == 4 ) val = (int)*LONGP(cp, i);
781 fval = (double)val*factor;
782 if ( fval > maxval ) fval = maxval;
783 else if ( fval < -maxval ) fval = -maxval;
784 val = (int)fval;
785 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
786 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
787 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
788 }
789 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790}
791
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000793audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000794{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000795 Py_buffer pcp;
796 signed char *cp, *ncp;
797 int len, size, val1 = 0, val2 = 0;
798 double fac1, fac2, fval, maxval;
799 PyObject *rv;
800 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000801
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000802 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
803 &pcp, &size, &fac1, &fac2 ) )
804 return 0;
805 cp = pcp.buf;
806 len = pcp.len;
Mark Dickinson874135b2010-07-04 10:15:59 +0000807 if (!audioop_check_parameters(len, size)) {
808 PyBuffer_Release(&pcp);
Victor Stinner8e42fb72010-07-03 13:46:01 +0000809 return NULL;
Mark Dickinson874135b2010-07-04 10:15:59 +0000810 }
Victor Stinner8e42fb72010-07-03 13:46:01 +0000811 if (((len / size) & 1) != 0) {
812 PyErr_SetString(AudioopError, "not a whole number of frames");
Mark Dickinson874135b2010-07-04 10:15:59 +0000813 PyBuffer_Release(&pcp);
Victor Stinner8e42fb72010-07-03 13:46:01 +0000814 return NULL;
815 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000816
817 if ( size == 1 ) maxval = (double) 0x7f;
818 else if ( size == 2 ) maxval = (double) 0x7fff;
819 else if ( size == 4 ) maxval = (double) 0x7fffffff;
820 else {
821 PyBuffer_Release(&pcp);
822 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
823 return 0;
824 }
825
826 rv = PyBytes_FromStringAndSize(NULL, len/2);
Mark Dickinson874135b2010-07-04 10:15:59 +0000827 if ( rv == 0 ) {
828 PyBuffer_Release(&pcp);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000829 return 0;
Mark Dickinson874135b2010-07-04 10:15:59 +0000830 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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;
842 if ( fval > maxval ) fval = maxval;
843 else if ( fval < -maxval ) fval = -maxval;
844 val1 = (int)fval;
845 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
846 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
847 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
848 }
849 PyBuffer_Release(&pcp);
850 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000851}
852
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000853static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000854audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000855{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000856 signed char *cp, *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +0000857 int len, size, val1, val2, val = 0;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000858 double fac1, fac2, fval, maxval;
859 PyObject *rv;
860 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000861
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000862 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
863 &cp, &len, &size, &fac1, &fac2 ) )
864 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000865 if (!audioop_check_parameters(len, size))
866 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000867
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000868 if ( size == 1 ) maxval = (double) 0x7f;
869 else if ( size == 2 ) maxval = (double) 0x7fff;
870 else if ( size == 4 ) maxval = (double) 0x7fffffff;
871 else {
872 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
873 return 0;
874 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000875
Mark Dickinson587cb1a2010-05-10 16:39:55 +0000876 if (len > INT_MAX/2) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000877 PyErr_SetString(PyExc_MemoryError,
878 "not enough memory for output buffer");
879 return 0;
880 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000881
Mark Dickinson587cb1a2010-05-10 16:39:55 +0000882 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000883 if ( rv == 0 )
884 return 0;
885 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000886
Guido van Rossumb66efa01992-06-01 16:01:24 +0000887
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000888 for ( i=0; i < len; i += size ) {
889 if ( size == 1 ) val = (int)*CHARP(cp, i);
890 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
891 else if ( size == 4 ) val = (int)*LONGP(cp, i);
892
893 fval = (double)val*fac1;
894 if ( fval > maxval ) fval = maxval;
895 else if ( fval < -maxval ) fval = -maxval;
896 val1 = (int)fval;
897
898 fval = (double)val*fac2;
899 if ( fval > maxval ) fval = maxval;
900 else if ( fval < -maxval ) fval = -maxval;
901 val2 = (int)fval;
902
903 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
904 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
905 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
906
907 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
908 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
909 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
910 }
911 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000912}
913
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000914static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000915audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000916{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000917 signed char *cp1, *cp2, *ncp;
918 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
919 PyObject *rv;
920 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000921
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000922 if ( !PyArg_ParseTuple(args, "s#s#i:add",
923 &cp1, &len1, &cp2, &len2, &size ) )
924 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000925 if (!audioop_check_parameters(len1, size))
926 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000927 if ( len1 != len2 ) {
928 PyErr_SetString(AudioopError, "Lengths should be the same");
929 return 0;
930 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000931
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000932 if ( size == 1 ) maxval = 0x7f;
933 else if ( size == 2 ) maxval = 0x7fff;
934 else if ( size == 4 ) maxval = 0x7fffffff;
935 else {
936 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
937 return 0;
938 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000939
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000940 rv = PyBytes_FromStringAndSize(NULL, len1);
941 if ( rv == 0 )
942 return 0;
943 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000944
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000945 for ( i=0; i < len1; i += size ) {
946 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
947 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
948 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000949
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000950 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
951 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
952 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
953
954 newval = val1 + val2;
955 /* truncate in case of overflow */
956 if (newval > maxval) newval = maxval;
957 else if (newval < -maxval) newval = -maxval;
958 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
959 newval = val1 > 0 ? maxval : - maxval;
960
961 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
962 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
963 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
964 }
965 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000966}
967
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000968static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000969audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000970{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000971 signed char *cp, *ncp;
972 int len, size, val = 0;
973 PyObject *rv;
974 int i;
975 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000976
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000977 if ( !PyArg_ParseTuple(args, "s#ii:bias",
978 &cp, &len, &size , &bias) )
979 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000980
Victor Stinner8e42fb72010-07-03 13:46:01 +0000981 if (!audioop_check_parameters(len, size))
982 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000983
984 rv = PyBytes_FromStringAndSize(NULL, len);
985 if ( rv == 0 )
986 return 0;
987 ncp = (signed char *)PyBytes_AsString(rv);
988
989
990 for ( i=0; i < len; i += size ) {
991 if ( size == 1 ) val = (int)*CHARP(cp, i);
992 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
993 else if ( size == 4 ) val = (int)*LONGP(cp, i);
994
995 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
996 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
997 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
998 }
999 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001000}
1001
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001002static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001003audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001004{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001005 signed char *cp;
1006 unsigned char *ncp;
1007 int len, size, val = 0;
1008 PyObject *rv;
1009 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001010
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001011 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1012 &cp, &len, &size) )
1013 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001014
Victor Stinner8e42fb72010-07-03 13:46:01 +00001015 if (!audioop_check_parameters(len, size))
1016 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001017
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001018 rv = PyBytes_FromStringAndSize(NULL, len);
1019 if ( rv == 0 )
1020 return 0;
1021 ncp = (unsigned char *)PyBytes_AsString(rv);
1022
1023 for ( i=0; i < len; i += size ) {
1024 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1025 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1026 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1027
1028 j = len - i - size;
1029
1030 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1031 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1032 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1033 }
1034 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001035}
1036
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001037static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001038audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001039{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001040 signed char *cp;
1041 unsigned char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001042 int len, size, size2, val = 0;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001043 PyObject *rv;
1044 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001045
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001046 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1047 &cp, &len, &size, &size2) )
1048 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001049
Victor Stinner8e42fb72010-07-03 13:46:01 +00001050 if (!audioop_check_parameters(len, size))
1051 return NULL;
1052 if (!audioop_check_size(size2))
1053 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001054
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001055 if (len/size > INT_MAX/size2) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001056 PyErr_SetString(PyExc_MemoryError,
1057 "not enough memory for output buffer");
1058 return 0;
1059 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001060 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001061 if ( rv == 0 )
1062 return 0;
1063 ncp = (unsigned char *)PyBytes_AsString(rv);
1064
1065 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1066 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1067 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1068 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1069
1070 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1071 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1072 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1073 }
1074 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001075}
1076
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001077static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001078gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001079{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001080 while (b > 0) {
1081 int tmp = a % b;
1082 a = b;
1083 b = tmp;
1084 }
1085 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001086}
1087
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001088static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001089audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001090{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001091 char *cp, *ncp;
1092 int len, size, nchannels, inrate, outrate, weightA, weightB;
1093 int chan, d, *prev_i, *cur_i, cur_o;
1094 PyObject *state, *samps, *str, *rv = NULL;
1095 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001096
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001097 weightA = 1;
1098 weightB = 0;
1099 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1100 &nchannels, &inrate, &outrate, &state,
1101 &weightA, &weightB))
1102 return NULL;
Victor Stinner8e42fb72010-07-03 13:46:01 +00001103 if (!audioop_check_size(size))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001104 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001105 if (nchannels < 1) {
1106 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1107 return NULL;
1108 }
1109 bytes_per_frame = size * nchannels;
1110 if (bytes_per_frame / nchannels != size) {
1111 /* This overflow test is rigorously correct because
1112 both multiplicands are >= 1. Use the argument names
1113 from the docs for the error msg. */
1114 PyErr_SetString(PyExc_OverflowError,
1115 "width * nchannels too big for a C int");
1116 return NULL;
1117 }
1118 if (weightA < 1 || weightB < 0) {
1119 PyErr_SetString(AudioopError,
1120 "weightA should be >= 1, weightB should be >= 0");
1121 return NULL;
1122 }
1123 if (len % bytes_per_frame != 0) {
1124 PyErr_SetString(AudioopError, "not a whole number of frames");
1125 return NULL;
1126 }
1127 if (inrate <= 0 || outrate <= 0) {
1128 PyErr_SetString(AudioopError, "sampling rate not > 0");
1129 return NULL;
1130 }
1131 /* divide inrate and outrate by their greatest common divisor */
1132 d = gcd(inrate, outrate);
1133 inrate /= d;
1134 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001135
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001136 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001137 PyErr_SetString(PyExc_MemoryError,
1138 "not enough memory for output buffer");
1139 return 0;
1140 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001141 prev_i = (int *) malloc(nchannels * sizeof(int));
1142 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001143 if (prev_i == NULL || cur_i == NULL) {
1144 (void) PyErr_NoMemory();
1145 goto exit;
1146 }
1147
1148 len /= bytes_per_frame; /* # of frames */
1149
1150 if (state == Py_None) {
1151 d = -outrate;
1152 for (chan = 0; chan < nchannels; chan++)
1153 prev_i[chan] = cur_i[chan] = 0;
1154 }
1155 else {
1156 if (!PyArg_ParseTuple(state,
1157 "iO!;audioop.ratecv: illegal state argument",
1158 &d, &PyTuple_Type, &samps))
1159 goto exit;
1160 if (PyTuple_Size(samps) != nchannels) {
1161 PyErr_SetString(AudioopError,
1162 "illegal state argument");
1163 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001164 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001165 for (chan = 0; chan < nchannels; chan++) {
1166 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1167 "ii:ratecv", &prev_i[chan],
1168 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001169 goto exit;
1170 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001171 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001172
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001173 /* str <- Space for the output buffer. */
1174 {
1175 /* There are len input frames, so we need (mathematically)
1176 ceiling(len*outrate/inrate) output frames, and each frame
1177 requires bytes_per_frame bytes. Computing this
1178 without spurious overflow is the challenge; we can
Mark Dickinsonee289e62010-05-11 13:11:12 +00001179 settle for a reasonable upper bound, though, in this
1180 case ceiling(len/inrate) * outrate. */
1181
1182 /* compute ceiling(len/inrate) without overflow */
1183 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1184 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001185 str = NULL;
1186 else
Mark Dickinsonee289e62010-05-11 13:11:12 +00001187 str = PyBytes_FromStringAndSize(NULL,
1188 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001189
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001190 if (str == NULL) {
1191 PyErr_SetString(PyExc_MemoryError,
1192 "not enough memory for output buffer");
1193 goto exit;
1194 }
1195 }
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 Pitrou7f14f0d2010-05-09 16:14:21 +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. */
1213 len = (int)(ncp - PyBytes_AsString(str));
1214 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)
1228 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1229 else if (size == 2)
1230 cur_i[chan] = (int)*SHORTP(cp, 0);
1231 else if (size == 4)
1232 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1233 cp += size;
1234 /* implements a simple digital filter */
1235 cur_i[chan] =
1236 (weightA * cur_i[chan] +
1237 weightB * prev_i[chan]) /
1238 (weightA + weightB);
1239 }
1240 len--;
1241 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001242 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001243 while (d >= 0) {
1244 for (chan = 0; chan < nchannels; chan++) {
1245 cur_o = (prev_i[chan] * d +
1246 cur_i[chan] * (outrate - d)) /
1247 outrate;
1248 if (size == 1)
1249 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1250 else if (size == 2)
1251 *SHORTP(ncp, 0) = (short)(cur_o);
1252 else if (size == 4)
1253 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1254 ncp += size;
1255 }
1256 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001257 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001258 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001259 exit:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +00001270 signed char *cp;
1271 unsigned char *ncp;
1272 int len, size, val = 0;
1273 PyObject *rv;
1274 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001275
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Stinner8e42fb72010-07-03 13:46:01 +00001280 if (!audioop_check_parameters(len, size))
1281 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001282
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +00001301 unsigned char *cp;
1302 unsigned char cval;
1303 signed char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001304 int len, size, val;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001305 PyObject *rv;
1306 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001307
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001308 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1309 &cp, &len, &size) )
1310 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001311
Victor Stinner8e42fb72010-07-03 13:46:01 +00001312 if (!audioop_check_parameters(len, size))
1313 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001314
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001315 if (len > INT_MAX/size) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001316 PyErr_SetString(PyExc_MemoryError,
1317 "not enough memory for output buffer");
1318 return 0;
1319 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001320 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001321 if ( rv == 0 )
1322 return 0;
1323 ncp = (signed char *)PyBytes_AsString(rv);
1324
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001325 for ( i=0; i < len*size; i += size ) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +00001339 signed char *cp;
1340 unsigned char *ncp;
1341 int len, size, val = 0;
1342 PyObject *rv;
1343 int i;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001344
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001345 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1346 &cp, &len, &size) )
1347 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001348
Victor Stinner8e42fb72010-07-03 13:46:01 +00001349 if (!audioop_check_parameters(len, size))
1350 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001351
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +00001370 unsigned char *cp;
1371 unsigned char cval;
1372 signed char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001373 int len, size, val;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001374 PyObject *rv;
1375 int i;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001376
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001377 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1378 &cp, &len, &size) )
1379 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001380
Victor Stinner8e42fb72010-07-03 13:46:01 +00001381 if (!audioop_check_parameters(len, size))
1382 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001383
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001384 if (len > INT_MAX/size) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001385 PyErr_SetString(PyExc_MemoryError,
1386 "not enough memory for output buffer");
1387 return 0;
1388 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001389 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001390 if ( rv == 0 )
1391 return 0;
1392 ncp = (signed char *)PyBytes_AsString(rv);
1393
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001394 for ( i=0; i < len*size; i += size ) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +00001408 signed char *cp;
1409 signed char *ncp;
1410 int len, size, val = 0, step, valpred, delta,
1411 index, sign, vpdiff, diff;
1412 PyObject *rv, *state, *str;
1413 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001414
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001415 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1416 &cp, &len, &size, &state) )
1417 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001418
Victor Stinner8e42fb72010-07-03 13:46:01 +00001419 if (!audioop_check_parameters(len, size))
1420 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001421
1422 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1423 if ( str == 0 )
1424 return 0;
1425 ncp = (signed char *)PyBytes_AsString(str);
1426
1427 /* Decode state, should have (value, step) */
1428 if ( state == Py_None ) {
1429 /* First time, it seems. Set defaults */
1430 valpred = 0;
1431 step = 7;
1432 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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +00001514 signed char *cp;
1515 signed char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001516 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001517 PyObject *rv, *str, *state;
1518 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001519
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001520 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1521 &cp, &len, &size, &state) )
1522 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001523
Victor Stinner8e42fb72010-07-03 13:46:01 +00001524 if (!audioop_check_parameters(len, size))
1525 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001526
1527 /* Decode state, should have (value, step) */
1528 if ( state == Py_None ) {
1529 /* First time, it seems. Set defaults */
1530 valpred = 0;
1531 step = 7;
1532 index = 0;
1533 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1534 return 0;
1535
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001536 if (len > (INT_MAX/2)/size) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001537 PyErr_SetString(PyExc_MemoryError,
1538 "not enough memory for output buffer");
1539 return 0;
1540 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001541 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001542 if ( str == 0 )
1543 return 0;
1544 ncp = (signed char *)PyBytes_AsString(str);
1545
1546 step = stepsizeTable[index];
1547 bufferstep = 0;
1548
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001549 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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}