blob: bdee4687ed8448cbfff49c67f397a9ab4815a864 [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{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000058 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
61 }
62 return (size);
63}
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,
86 -8, 0, 32124, 31100, 30076, 29052, 28028,
87 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,
103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
105};
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
140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
141{
142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
145
146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
148
149 /* 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);
159
160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
162
163 /*
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 }
173
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
237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
238{
239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
242
243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
245
246 /* 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 }
253
254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
256
257 /* Combine the sign, segment, and quantization bits. */
258
259 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] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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] = {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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};
289
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
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000298static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000299audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000300{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000301 signed char *cp;
302 int len, size, val = 0;
303 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000304
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000305 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000306 return 0;
307 if ( size != 1 && size != 2 && size != 4 ) {
308 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
309 return 0;
310 }
311 if ( i < 0 || i >= len/size ) {
312 PyErr_SetString(AudioopError, "Index out of range");
313 return 0;
314 }
315 if ( size == 1 ) val = (int)*CHARP(cp, i);
316 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
317 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
318 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000319}
320
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000321static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000322audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
327 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000329 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000330 return 0;
331 if ( size != 1 && size != 2 && size != 4 ) {
332 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
333 return 0;
334 }
335 for ( i=0; i<len; i+= size) {
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i);
339 if ( val < 0 ) val = (-val);
340 if ( val > max ) max = val;
341 }
342 return PyInt_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000343}
344
345static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000346audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000347{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000348 signed char *cp;
349 int len, size, val = 0;
350 int i;
351 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000352
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000353 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000354 return NULL;
355 if (size != 1 && size != 2 && size != 4) {
356 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
357 return NULL;
358 }
359 for (i = 0; i < len; i += size) {
360 if (size == 1) val = (int) *CHARP(cp, i);
361 else if (size == 2) val = (int) *SHORTP(cp, i);
362 else if (size == 4) val = (int) *LONGP(cp, i);
363 if (val > max) max = val;
364 if (val < min) min = val;
365 }
366 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000367}
368
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000369static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000370audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000371{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000372 signed char *cp;
373 int len, size, val = 0;
374 int i;
375 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000376
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000377 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000378 return 0;
379 if ( size != 1 && size != 2 && size != 4 ) {
380 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
381 return 0;
382 }
383 for ( i=0; i<len; i+= size) {
384 if ( size == 1 ) val = (int)*CHARP(cp, i);
385 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
386 else if ( size == 4 ) val = (int)*LONGP(cp, i);
387 avg += val;
388 }
389 if ( len == 0 )
390 val = 0;
391 else
392 val = (int)(avg / (double)(len/size));
393 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000394}
395
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000396static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000397audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000398{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000399 signed char *cp;
400 int len, size, val = 0;
401 int i;
402 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000403
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000404 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000405 return 0;
406 if ( size != 1 && size != 2 && size != 4 ) {
407 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
408 return 0;
409 }
410 for ( i=0; i<len; i+= size) {
411 if ( size == 1 ) val = (int)*CHARP(cp, i);
412 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
413 else if ( size == 4 ) val = (int)*LONGP(cp, i);
414 sum_squares += (double)val*(double)val;
415 }
416 if ( len == 0 )
417 val = 0;
418 else
419 val = (int)sqrt(sum_squares / (double)(len/size));
420 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000421}
422
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000423static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000424{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000425 int i;
426 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000427
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000428 for( i=0; i<len; i++) {
429 sum = sum + (double)a[i]*(double)b[i];
430 }
431 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000432}
433
434/*
435** Findfit tries to locate a sample within another sample. Its main use
436** is in echo-cancellation (to find the feedback of the output signal in
437** the input signal).
438** The method used is as follows:
439**
440** let R be the reference signal (length n) and A the input signal (length N)
441** with N > n, and let all sums be over i from 0 to n-1.
442**
443** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
444** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
445** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
446**
447** Next, we compute the relative distance between the original signal and
448** the modified signal and minimize that over j:
449** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
450** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
451**
452** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000453** cp1 A
454** cp2 R
455** len1 N
456** len2 n
457** aj_m1 A[j-1]
458** aj_lm1 A[j+n-1]
459** sum_ri_2 sum(R[i]^2)
460** sum_aij_2 sum(A[i+j]^2)
461** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000462**
463** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
464** is completely recalculated each step.
465*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000466static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000467audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000468{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000469 short *cp1, *cp2;
470 int len1, len2;
471 int j, best_j;
472 double aj_m1, aj_lm1;
473 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000474
Thomas Wouters89f507f2006-12-13 04:49:30 +0000475 /* Passing a short** for an 's' argument is correct only
476 if the string contents is aligned for interpretation
477 as short[]. Due to the definition of PyStringObject,
478 this is currently (Python 2.6) the case. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000479 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
Thomas Wouters89f507f2006-12-13 04:49:30 +0000480 (char**)&cp1, &len1, (char**)&cp2, &len2) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481 return 0;
482 if ( len1 & 1 || len2 & 1 ) {
483 PyErr_SetString(AudioopError, "Strings should be even-sized");
484 return 0;
485 }
486 len1 >>= 1;
487 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000488
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000489 if ( len1 < len2 ) {
490 PyErr_SetString(AudioopError, "First sample should be longer");
491 return 0;
492 }
493 sum_ri_2 = _sum2(cp2, cp2, len2);
494 sum_aij_2 = _sum2(cp1, cp1, len2);
495 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000496
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000497 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000498
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000499 best_result = result;
500 best_j = 0;
501 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000502
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000503 for ( j=1; j<=len1-len2; j++) {
504 aj_m1 = (double)cp1[j-1];
505 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000506
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000507 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
508 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000509
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
511 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000512
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000513 if ( result < best_result ) {
514 best_result = result;
515 best_j = j;
516 }
517
518 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000520 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000521
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000522 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000523}
524
525/*
526** findfactor finds a factor f so that the energy in A-fB is minimal.
527** See the comment for findfit for details.
528*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000529static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000530audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000531{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000532 short *cp1, *cp2;
533 int len1, len2;
534 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000535
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000536 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
Thomas Wouters89f507f2006-12-13 04:49:30 +0000537 (char**)&cp1, &len1, (char**)&cp2, &len2) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000538 return 0;
539 if ( len1 & 1 || len2 & 1 ) {
540 PyErr_SetString(AudioopError, "Strings should be even-sized");
541 return 0;
542 }
543 if ( len1 != len2 ) {
544 PyErr_SetString(AudioopError, "Samples should be same size");
545 return 0;
546 }
547 len2 >>= 1;
548 sum_ri_2 = _sum2(cp2, cp2, len2);
549 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000550
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000552
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000553 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000554}
555
556/*
557** findmax returns the index of the n-sized segment of the input sample
558** that contains the most energy.
559*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000561audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000562{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000563 short *cp1;
564 int len1, len2;
565 int j, best_j;
566 double aj_m1, aj_lm1;
567 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000568
Thomas Wouters89f507f2006-12-13 04:49:30 +0000569 if ( !PyArg_ParseTuple(args, "s#i:findmax",
570 (char**)&cp1, &len1, &len2) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000571 return 0;
572 if ( len1 & 1 ) {
573 PyErr_SetString(AudioopError, "Strings should be even-sized");
574 return 0;
575 }
576 len1 >>= 1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000577
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000578 if ( len1 < len2 ) {
579 PyErr_SetString(AudioopError, "Input sample should be longer");
580 return 0;
581 }
Jack Jansena90805f1993-02-17 14:29:28 +0000582
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000583 result = _sum2(cp1, cp1, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000584
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000585 best_result = result;
586 best_j = 0;
587 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000588
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000589 for ( j=1; j<=len1-len2; j++) {
590 aj_m1 = (double)cp1[j-1];
591 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000592
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000593 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000594
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000595 if ( result > best_result ) {
596 best_result = result;
597 best_j = j;
598 }
599
600 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000601
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000602 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000603}
604
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000606audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000607{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000608 signed char *cp;
609 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
610 prevextreme = 0;
611 int i;
612 double avg = 0.0;
613 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000614
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000615 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000616 return 0;
617 if ( size != 1 && size != 2 && size != 4 ) {
618 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
619 return 0;
620 }
621 /* Compute first delta value ahead. Also automatically makes us
622 ** skip the first extreme value
623 */
624 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
625 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
626 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
627 if ( size == 1 ) val = (int)*CHARP(cp, size);
628 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
629 else if ( size == 4 ) val = (int)*LONGP(cp, size);
630 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000631
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000632 for ( i=size; i<len; i+= size) {
633 if ( size == 1 ) val = (int)*CHARP(cp, i);
634 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
635 else if ( size == 4 ) val = (int)*LONGP(cp, i);
636 diff = val - prevval;
637 if ( diff*prevdiff < 0 ) {
638 /* Derivative changed sign. Compute difference to last
639 ** extreme value and remember.
640 */
641 if ( prevextremevalid ) {
642 extremediff = prevval - prevextreme;
643 if ( extremediff < 0 )
644 extremediff = -extremediff;
645 avg += extremediff;
646 nextreme++;
647 }
648 prevextremevalid = 1;
649 prevextreme = prevval;
650 }
651 prevval = val;
652 if ( diff != 0 )
653 prevdiff = diff;
654 }
655 if ( nextreme == 0 )
656 val = 0;
657 else
658 val = (int)(avg / (double)nextreme);
659 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000660}
661
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000662static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000663audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000664{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000665 signed char *cp;
666 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
667 prevextreme = 0;
668 int i;
669 int max = 0;
670 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000671
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000672 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000673 return 0;
674 if ( size != 1 && size != 2 && size != 4 ) {
675 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
676 return 0;
677 }
678 /* Compute first delta value ahead. Also automatically makes us
679 ** skip the first extreme value
680 */
681 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
682 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
683 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
684 if ( size == 1 ) val = (int)*CHARP(cp, size);
685 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
686 else if ( size == 4 ) val = (int)*LONGP(cp, size);
687 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000688
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000689 for ( i=size; i<len; i+= size) {
690 if ( size == 1 ) val = (int)*CHARP(cp, i);
691 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
692 else if ( size == 4 ) val = (int)*LONGP(cp, i);
693 diff = val - prevval;
694 if ( diff*prevdiff < 0 ) {
695 /* Derivative changed sign. Compute difference to
696 ** last extreme value and remember.
697 */
698 if ( prevextremevalid ) {
699 extremediff = prevval - prevextreme;
700 if ( extremediff < 0 )
701 extremediff = -extremediff;
702 if ( extremediff > max )
703 max = extremediff;
704 }
705 prevextremevalid = 1;
706 prevextreme = prevval;
707 }
708 prevval = val;
709 if ( diff != 0 )
710 prevdiff = diff;
711 }
712 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000713}
714
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000715static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000716audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000718 signed char *cp;
719 int len, size, val = 0;
720 int i;
721 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000723 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000724 return 0;
725 if ( size != 1 && size != 2 && size != 4 ) {
726 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
727 return 0;
728 }
729 ncross = -1;
730 prevval = 17; /* Anything <> 0,1 */
731 for ( i=0; i<len; i+= size) {
732 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
733 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
734 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
735 val = val & 1;
736 if ( val != prevval ) ncross++;
737 prevval = val;
738 }
739 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000740}
741
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000742static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000743audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000744{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000745 signed char *cp, *ncp;
746 int len, size, val = 0;
747 double factor, fval, maxval;
748 PyObject *rv;
749 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000751 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000753
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000754 if ( size == 1 ) maxval = (double) 0x7f;
755 else if ( size == 2 ) maxval = (double) 0x7fff;
756 else if ( size == 4 ) maxval = (double) 0x7fffffff;
757 else {
758 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
759 return 0;
760 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000762 rv = PyBytes_FromStringAndSize(NULL, len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000763 if ( rv == 0 )
764 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000765 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000766
767
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000768 for ( i=0; i < len; i += size ) {
769 if ( size == 1 ) val = (int)*CHARP(cp, i);
770 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
771 else if ( size == 4 ) val = (int)*LONGP(cp, i);
772 fval = (double)val*factor;
773 if ( fval > maxval ) fval = maxval;
774 else if ( fval < -maxval ) fval = -maxval;
775 val = (int)fval;
776 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
777 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
778 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
779 }
780 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000781}
782
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000784audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000785{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000786 signed char *cp, *ncp;
787 int len, size, val1 = 0, val2 = 0;
788 double fac1, fac2, fval, maxval;
789 PyObject *rv;
790 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000792 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
793 &cp, &len, &size, &fac1, &fac2 ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000794 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000796 if ( size == 1 ) maxval = (double) 0x7f;
797 else if ( size == 2 ) maxval = (double) 0x7fff;
798 else if ( size == 4 ) maxval = (double) 0x7fffffff;
799 else {
800 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
801 return 0;
802 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000804 rv = PyBytes_FromStringAndSize(NULL, len/2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000805 if ( rv == 0 )
806 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000807 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000808
809
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000810 for ( i=0; i < len; i += size*2 ) {
811 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
812 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
813 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
814 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
815 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
816 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
817 fval = (double)val1*fac1 + (double)val2*fac2;
818 if ( fval > maxval ) fval = maxval;
819 else if ( fval < -maxval ) fval = -maxval;
820 val1 = (int)fval;
821 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
822 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
823 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
824 }
825 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000826}
827
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000828static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000829audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000830{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000831 signed char *cp, *ncp;
832 int len, size, val1, val2, val = 0;
833 double fac1, fac2, fval, maxval;
834 PyObject *rv;
835 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000836
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000837 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
838 &cp, &len, &size, &fac1, &fac2 ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000839 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000840
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000841 if ( size == 1 ) maxval = (double) 0x7f;
842 else if ( size == 2 ) maxval = (double) 0x7fff;
843 else if ( size == 4 ) maxval = (double) 0x7fffffff;
844 else {
845 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
846 return 0;
847 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000848
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000849 rv = PyBytes_FromStringAndSize(NULL, len*2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000850 if ( rv == 0 )
851 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000852 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000853
854
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000855 for ( i=0; i < len; i += size ) {
856 if ( size == 1 ) val = (int)*CHARP(cp, i);
857 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
858 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000859
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000860 fval = (double)val*fac1;
861 if ( fval > maxval ) fval = maxval;
862 else if ( fval < -maxval ) fval = -maxval;
863 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000864
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000865 fval = (double)val*fac2;
866 if ( fval > maxval ) fval = maxval;
867 else if ( fval < -maxval ) fval = -maxval;
868 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000869
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000870 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
871 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
872 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000873
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000874 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
875 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
876 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
877 }
878 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000879}
880
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000881static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000882audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000884 signed char *cp1, *cp2, *ncp;
885 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
886 PyObject *rv;
887 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000888
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000889 if ( !PyArg_ParseTuple(args, "s#s#i:add",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000890 &cp1, &len1, &cp2, &len2, &size ) )
891 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000892
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000893 if ( len1 != len2 ) {
894 PyErr_SetString(AudioopError, "Lengths should be the same");
895 return 0;
896 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000897
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000898 if ( size == 1 ) maxval = 0x7f;
899 else if ( size == 2 ) maxval = 0x7fff;
900 else if ( size == 4 ) maxval = 0x7fffffff;
901 else {
902 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
903 return 0;
904 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000905
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000906 rv = PyBytes_FromStringAndSize(NULL, len1);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000907 if ( rv == 0 )
908 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000909 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000910
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000911 for ( i=0; i < len1; i += size ) {
912 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
913 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
914 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
915
916 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
917 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
918 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000919
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000920 newval = val1 + val2;
921 /* truncate in case of overflow */
922 if (newval > maxval) newval = maxval;
923 else if (newval < -maxval) newval = -maxval;
924 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
925 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000926
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000927 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
928 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
929 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
930 }
931 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000932}
933
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000934static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000935audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000936{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000937 signed char *cp, *ncp;
938 int len, size, val = 0;
939 PyObject *rv;
940 int i;
941 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000942
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000943 if ( !PyArg_ParseTuple(args, "s#ii:bias",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000944 &cp, &len, &size , &bias) )
945 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000946
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000947 if ( size != 1 && size != 2 && size != 4) {
948 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
949 return 0;
950 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000951
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000952 rv = PyBytes_FromStringAndSize(NULL, len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000953 if ( rv == 0 )
954 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000955 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000956
957
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000958 for ( i=0; i < len; i += size ) {
959 if ( size == 1 ) val = (int)*CHARP(cp, i);
960 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
961 else if ( size == 4 ) val = (int)*LONGP(cp, i);
962
963 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
964 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
965 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
966 }
967 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000968}
969
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000970static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000971audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000972{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000973 signed char *cp;
974 unsigned char *ncp;
975 int len, size, val = 0;
976 PyObject *rv;
977 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000978
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000979 if ( !PyArg_ParseTuple(args, "s#i:reverse",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000980 &cp, &len, &size) )
981 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000982
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000983 if ( size != 1 && size != 2 && size != 4 ) {
984 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
985 return 0;
986 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000987
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000988 rv = PyBytes_FromStringAndSize(NULL, len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000989 if ( rv == 0 )
990 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +0000991 ncp = (unsigned char *)PyBytes_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000992
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000993 for ( i=0; i < len; i += size ) {
994 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
995 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
996 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000997
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000998 j = len - i - size;
999
1000 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1001 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1002 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1003 }
1004 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001005}
1006
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001007static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001008audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001009{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001010 signed char *cp;
1011 unsigned char *ncp;
1012 int len, size, size2, val = 0;
1013 PyObject *rv;
1014 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001015
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001016 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001017 &cp, &len, &size, &size2) )
1018 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001019
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001020 if ( (size != 1 && size != 2 && size != 4) ||
1021 (size2 != 1 && size2 != 2 && size2 != 4)) {
1022 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1023 return 0;
1024 }
Jack Jansena90805f1993-02-17 14:29:28 +00001025
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001026 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001027 if ( rv == 0 )
1028 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001029 ncp = (unsigned char *)PyBytes_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001030
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001031 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1032 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1033 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1034 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001035
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001036 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1037 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1038 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1039 }
1040 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001041}
1042
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001043static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001044gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001045{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001046 while (b > 0) {
1047 int tmp = a % b;
1048 a = b;
1049 b = tmp;
1050 }
1051 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001052}
1053
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001054static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001055audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001056{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001057 char *cp, *ncp;
1058 int len, size, nchannels, inrate, outrate, weightA, weightB;
1059 int chan, d, *prev_i, *cur_i, cur_o;
1060 PyObject *state, *samps, *str, *rv = NULL;
1061 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001062
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001063 weightA = 1;
1064 weightB = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001065 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1066 &nchannels, &inrate, &outrate, &state,
1067 &weightA, &weightB))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001068 return NULL;
1069 if (size != 1 && size != 2 && size != 4) {
1070 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1071 return NULL;
1072 }
1073 if (nchannels < 1) {
1074 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1075 return NULL;
1076 }
1077 bytes_per_frame = size * nchannels;
1078 if (bytes_per_frame / nchannels != size) {
1079 /* This overflow test is rigorously correct because
1080 both multiplicands are >= 1. Use the argument names
1081 from the docs for the error msg. */
1082 PyErr_SetString(PyExc_OverflowError,
1083 "width * nchannels too big for a C int");
1084 return NULL;
1085 }
1086 if (weightA < 1 || weightB < 0) {
1087 PyErr_SetString(AudioopError,
1088 "weightA should be >= 1, weightB should be >= 0");
1089 return NULL;
1090 }
1091 if (len % bytes_per_frame != 0) {
1092 PyErr_SetString(AudioopError, "not a whole number of frames");
1093 return NULL;
1094 }
1095 if (inrate <= 0 || outrate <= 0) {
1096 PyErr_SetString(AudioopError, "sampling rate not > 0");
1097 return NULL;
1098 }
1099 /* divide inrate and outrate by their greatest common divisor */
1100 d = gcd(inrate, outrate);
1101 inrate /= d;
1102 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001103
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001104 prev_i = (int *) malloc(nchannels * sizeof(int));
1105 cur_i = (int *) malloc(nchannels * sizeof(int));
1106 if (prev_i == NULL || cur_i == NULL) {
1107 (void) PyErr_NoMemory();
1108 goto exit;
1109 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001110
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001111 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001112
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001113 if (state == Py_None) {
1114 d = -outrate;
1115 for (chan = 0; chan < nchannels; chan++)
1116 prev_i[chan] = cur_i[chan] = 0;
1117 }
1118 else {
1119 if (!PyArg_ParseTuple(state,
1120 "iO!;audioop.ratecv: illegal state argument",
1121 &d, &PyTuple_Type, &samps))
1122 goto exit;
1123 if (PyTuple_Size(samps) != nchannels) {
1124 PyErr_SetString(AudioopError,
1125 "illegal state argument");
1126 goto exit;
1127 }
1128 for (chan = 0; chan < nchannels; chan++) {
1129 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001130 "ii:ratecv", &prev_i[chan],
1131 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001132 goto exit;
1133 }
1134 }
Tim Peters1691bd92001-12-05 06:05:07 +00001135
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001136 /* str <- Space for the output buffer. */
1137 {
1138 /* There are len input frames, so we need (mathematically)
1139 ceiling(len*outrate/inrate) output frames, and each frame
1140 requires bytes_per_frame bytes. Computing this
1141 without spurious overflow is the challenge; we can
1142 settle for a reasonable upper bound, though. */
1143 int ceiling; /* the number of output frames */
1144 int nbytes; /* the number of output bytes needed */
1145 int q = len / inrate;
1146 /* Now len = q * inrate + r exactly (with r = len % inrate),
1147 and this is less than q * inrate + inrate = (q+1)*inrate.
1148 So a reasonable upper bound on len*outrate/inrate is
1149 ((q+1)*inrate)*outrate/inrate =
1150 (q+1)*outrate.
1151 */
1152 ceiling = (q+1) * outrate;
1153 nbytes = ceiling * bytes_per_frame;
1154 /* See whether anything overflowed; if not, get the space. */
1155 if (q+1 < 0 ||
1156 ceiling / outrate != q+1 ||
1157 nbytes / bytes_per_frame != ceiling)
1158 str = NULL;
1159 else
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001160 str = PyBytes_FromStringAndSize(NULL, nbytes);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001161
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001162 if (str == NULL) {
1163 PyErr_SetString(PyExc_MemoryError,
1164 "not enough memory for output buffer");
1165 goto exit;
1166 }
1167 }
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001168 ncp = PyBytes_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001169
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001170 for (;;) {
1171 while (d < 0) {
1172 if (len == 0) {
1173 samps = PyTuple_New(nchannels);
1174 if (samps == NULL)
1175 goto exit;
1176 for (chan = 0; chan < nchannels; chan++)
1177 PyTuple_SetItem(samps, chan,
1178 Py_BuildValue("(ii)",
1179 prev_i[chan],
1180 cur_i[chan]));
1181 if (PyErr_Occurred())
1182 goto exit;
1183 /* We have checked before that the length
1184 * of the string fits into int. */
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001185 len = (int)(ncp - PyBytes_AsString(str));
1186 rv = PyBytes_FromStringAndSize
1187 (PyBytes_AsString(str), len);
1188 Py_DECREF(str);
1189 str = rv;
1190 if (str == NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001191 goto exit;
1192 rv = Py_BuildValue("(O(iO))", str, d, samps);
1193 Py_DECREF(samps);
1194 Py_DECREF(str);
1195 goto exit; /* return rv */
1196 }
1197 for (chan = 0; chan < nchannels; chan++) {
1198 prev_i[chan] = cur_i[chan];
1199 if (size == 1)
1200 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1201 else if (size == 2)
1202 cur_i[chan] = (int)*SHORTP(cp, 0);
1203 else if (size == 4)
1204 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1205 cp += size;
1206 /* implements a simple digital filter */
1207 cur_i[chan] =
1208 (weightA * cur_i[chan] +
1209 weightB * prev_i[chan]) /
1210 (weightA + weightB);
1211 }
1212 len--;
1213 d += outrate;
1214 }
1215 while (d >= 0) {
1216 for (chan = 0; chan < nchannels; chan++) {
1217 cur_o = (prev_i[chan] * d +
1218 cur_i[chan] * (outrate - d)) /
1219 outrate;
1220 if (size == 1)
1221 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1222 else if (size == 2)
1223 *SHORTP(ncp, 0) = (short)(cur_o);
1224 else if (size == 4)
1225 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1226 ncp += size;
1227 }
1228 d -= inrate;
1229 }
1230 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001231 exit:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001232 if (prev_i != NULL)
1233 free(prev_i);
1234 if (cur_i != NULL)
1235 free(cur_i);
1236 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001237}
Guido van Rossum1851a671997-02-14 16:14:03 +00001238
Roger E. Massec905fff1997-01-17 18:12:04 +00001239static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001240audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001241{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001242 signed char *cp;
1243 unsigned char *ncp;
1244 int len, size, val = 0;
1245 PyObject *rv;
1246 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001247
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001248 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1249 &cp, &len, &size) )
1250 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001251
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001252 if ( size != 1 && size != 2 && size != 4) {
1253 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1254 return 0;
1255 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001256
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001257 rv = PyBytes_FromStringAndSize(NULL, len/size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001258 if ( rv == 0 )
1259 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001260 ncp = (unsigned char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001261
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001262 for ( i=0; i < len; i += size ) {
1263 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1264 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1265 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001266
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001267 *ncp++ = st_14linear2ulaw(val);
1268 }
1269 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001270}
1271
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001272static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001273audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001274{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001275 unsigned char *cp;
1276 unsigned char cval;
1277 signed char *ncp;
1278 int len, size, val;
1279 PyObject *rv;
1280 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001282 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1283 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001284 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001285
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001286 if ( size != 1 && size != 2 && size != 4) {
1287 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1288 return 0;
1289 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001290
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001291 rv = PyBytes_FromStringAndSize(NULL, len*size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001292 if ( rv == 0 )
1293 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001294 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001295
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001296 for ( i=0; i < len*size; i += size ) {
1297 cval = *cp++;
1298 val = st_ulaw2linear16(cval);
1299
1300 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1301 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1302 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1303 }
1304 return rv;
1305}
1306
1307static PyObject *
1308audioop_lin2alaw(PyObject *self, PyObject *args)
1309{
1310 signed char *cp;
1311 unsigned char *ncp;
1312 int len, size, val = 0;
1313 PyObject *rv;
1314 int i;
1315
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001316 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1317 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001318 return 0;
1319
1320 if ( size != 1 && size != 2 && size != 4) {
1321 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1322 return 0;
1323 }
1324
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001325 rv = PyBytes_FromStringAndSize(NULL, len/size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001326 if ( rv == 0 )
1327 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001328 ncp = (unsigned char *)PyBytes_AsString(rv);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001329
1330 for ( i=0; i < len; i += size ) {
1331 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1332 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1333 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1334
1335 *ncp++ = st_linear2alaw(val);
1336 }
1337 return rv;
1338}
1339
1340static PyObject *
1341audioop_alaw2lin(PyObject *self, PyObject *args)
1342{
1343 unsigned char *cp;
1344 unsigned char cval;
1345 signed char *ncp;
1346 int len, size, val;
1347 PyObject *rv;
1348 int i;
1349
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001350 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1351 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001352 return 0;
1353
1354 if ( size != 1 && size != 2 && size != 4) {
1355 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1356 return 0;
1357 }
1358
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001359 rv = PyBytes_FromStringAndSize(NULL, len*size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001360 if ( rv == 0 )
1361 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001362 ncp = (signed char *)PyBytes_AsString(rv);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001363
1364 for ( i=0; i < len*size; i += size ) {
1365 cval = *cp++;
1366 val = st_alaw2linear16(cval);
1367
1368 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1369 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1370 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1371 }
1372 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001373}
1374
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001375static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001376audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001377{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001378 signed char *cp;
1379 signed char *ncp;
1380 int len, size, val = 0, step, valpred, delta,
1381 index, sign, vpdiff, diff;
1382 PyObject *rv, *state, *str;
1383 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001384
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001385 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1386 &cp, &len, &size, &state) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001387 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001388
1389
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001390 if ( size != 1 && size != 2 && size != 4) {
1391 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1392 return 0;
1393 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001394
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001395 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001396 if ( str == 0 )
1397 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001398 ncp = (signed char *)PyBytes_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001399
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001400 /* Decode state, should have (value, step) */
1401 if ( state == Py_None ) {
1402 /* First time, it seems. Set defaults */
1403 valpred = 0;
1404 step = 7;
1405 index = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001406 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001407 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001408
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001409 step = stepsizeTable[index];
1410 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001411
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001412 for ( i=0; i < len; i += size ) {
1413 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1414 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1415 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001416
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001417 /* Step 1 - compute difference with previous value */
1418 diff = val - valpred;
1419 sign = (diff < 0) ? 8 : 0;
1420 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001421
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001422 /* Step 2 - Divide and clamp */
1423 /* Note:
1424 ** This code *approximately* computes:
1425 ** delta = diff*4/step;
1426 ** vpdiff = (delta+0.5)*step/4;
1427 ** but in shift step bits are dropped. The net result of this
1428 ** is that even if you have fast mul/div hardware you cannot
1429 ** put it to good use since the fixup would be too expensive.
1430 */
1431 delta = 0;
1432 vpdiff = (step >> 3);
1433
1434 if ( diff >= step ) {
1435 delta = 4;
1436 diff -= step;
1437 vpdiff += step;
1438 }
1439 step >>= 1;
1440 if ( diff >= step ) {
1441 delta |= 2;
1442 diff -= step;
1443 vpdiff += step;
1444 }
1445 step >>= 1;
1446 if ( diff >= step ) {
1447 delta |= 1;
1448 vpdiff += step;
1449 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001450
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001451 /* Step 3 - Update previous value */
1452 if ( sign )
1453 valpred -= vpdiff;
1454 else
1455 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001456
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001457 /* Step 4 - Clamp previous value to 16 bits */
1458 if ( valpred > 32767 )
1459 valpred = 32767;
1460 else if ( valpred < -32768 )
1461 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001462
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001463 /* Step 5 - Assemble value, update index and step values */
1464 delta |= sign;
1465
1466 index += indexTable[delta];
1467 if ( index < 0 ) index = 0;
1468 if ( index > 88 ) index = 88;
1469 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001470
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001471 /* Step 6 - Output value */
1472 if ( bufferstep ) {
1473 outputbuffer = (delta << 4) & 0xf0;
1474 } else {
1475 *ncp++ = (delta & 0x0f) | outputbuffer;
1476 }
1477 bufferstep = !bufferstep;
1478 }
1479 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1480 Py_DECREF(str);
1481 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001482}
1483
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001484static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001485audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001486{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001487 signed char *cp;
1488 signed char *ncp;
1489 int len, size, valpred, step, delta, index, sign, vpdiff;
1490 PyObject *rv, *str, *state;
1491 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001492
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001493 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1494 &cp, &len, &size, &state) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001495 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001496
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001497 if ( size != 1 && size != 2 && size != 4) {
1498 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1499 return 0;
1500 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001501
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001502 /* Decode state, should have (value, step) */
1503 if ( state == Py_None ) {
1504 /* First time, it seems. Set defaults */
1505 valpred = 0;
1506 step = 7;
1507 index = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001508 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001509 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001510
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001511 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001512 if ( str == 0 )
1513 return 0;
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001514 ncp = (signed char *)PyBytes_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001515
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001516 step = stepsizeTable[index];
1517 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001518
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001519 for ( i=0; i < len*size*2; i += size ) {
1520 /* Step 1 - get the delta value and compute next index */
1521 if ( bufferstep ) {
1522 delta = inputbuffer & 0xf;
1523 } else {
1524 inputbuffer = *cp++;
1525 delta = (inputbuffer >> 4) & 0xf;
1526 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001527
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001528 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001529
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001530 /* Step 2 - Find new index value (for later) */
1531 index += indexTable[delta];
1532 if ( index < 0 ) index = 0;
1533 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001534
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001535 /* Step 3 - Separate sign and magnitude */
1536 sign = delta & 8;
1537 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001538
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001539 /* Step 4 - Compute difference and new predicted value */
1540 /*
1541 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1542 ** in adpcm_coder.
1543 */
1544 vpdiff = step >> 3;
1545 if ( delta & 4 ) vpdiff += step;
1546 if ( delta & 2 ) vpdiff += step>>1;
1547 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001548
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001549 if ( sign )
1550 valpred -= vpdiff;
1551 else
1552 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001553
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001554 /* Step 5 - clamp output value */
1555 if ( valpred > 32767 )
1556 valpred = 32767;
1557 else if ( valpred < -32768 )
1558 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001559
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001560 /* Step 6 - Update step value */
1561 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001562
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001563 /* Step 6 - Output value */
1564 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1565 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1566 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1567 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001568
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001569 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1570 Py_DECREF(str);
1571 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001572}
1573
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001574static PyMethodDef audioop_methods[] = {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001575 { "max", audioop_max, METH_VARARGS },
1576 { "minmax", audioop_minmax, METH_VARARGS },
1577 { "avg", audioop_avg, METH_VARARGS },
1578 { "maxpp", audioop_maxpp, METH_VARARGS },
1579 { "avgpp", audioop_avgpp, METH_VARARGS },
1580 { "rms", audioop_rms, METH_VARARGS },
1581 { "findfit", audioop_findfit, METH_VARARGS },
1582 { "findmax", audioop_findmax, METH_VARARGS },
1583 { "findfactor", audioop_findfactor, METH_VARARGS },
1584 { "cross", audioop_cross, METH_VARARGS },
1585 { "mul", audioop_mul, METH_VARARGS },
1586 { "add", audioop_add, METH_VARARGS },
1587 { "bias", audioop_bias, METH_VARARGS },
1588 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1589 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1590 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1591 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1592 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1593 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1594 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1595 { "tomono", audioop_tomono, METH_VARARGS },
1596 { "tostereo", audioop_tostereo, METH_VARARGS },
1597 { "getsample", audioop_getsample, METH_VARARGS },
1598 { "reverse", audioop_reverse, METH_VARARGS },
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001599 { "ratecv", audioop_ratecv, METH_VARARGS },
1600 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001601};
1602
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001603PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001604initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001605{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001606 PyObject *m, *d;
1607 m = Py_InitModule("audioop", audioop_methods);
1608 if (m == NULL)
1609 return;
1610 d = PyModule_GetDict(m);
1611 if (d == NULL)
1612 return;
1613 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1614 if (AudioopError != NULL)
1615 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001616}