blob: 8f5d30c80585d90ceeb633bbb0117c7f86f5fcc4 [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 Wouters4d70c3d2006-06-08 14:42:34 +0000475 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
476 &cp1, &len1, &cp2, &len2) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000477 return 0;
478 if ( len1 & 1 || len2 & 1 ) {
479 PyErr_SetString(AudioopError, "Strings should be even-sized");
480 return 0;
481 }
482 len1 >>= 1;
483 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000484
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000485 if ( len1 < len2 ) {
486 PyErr_SetString(AudioopError, "First sample should be longer");
487 return 0;
488 }
489 sum_ri_2 = _sum2(cp2, cp2, len2);
490 sum_aij_2 = _sum2(cp1, cp1, len2);
491 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000492
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000493 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000494
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000495 best_result = result;
496 best_j = 0;
497 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000498
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000499 for ( j=1; j<=len1-len2; j++) {
500 aj_m1 = (double)cp1[j-1];
501 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000503 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
504 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000505
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000506 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
507 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000508
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000509 if ( result < best_result ) {
510 best_result = result;
511 best_j = j;
512 }
513
514 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000515
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000516 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000517
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000518 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000519}
520
521/*
522** findfactor finds a factor f so that the energy in A-fB is minimal.
523** See the comment for findfit for details.
524*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000525static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000526audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000527{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000528 short *cp1, *cp2;
529 int len1, len2;
530 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000531
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000532 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
533 &cp1, &len1, &cp2, &len2) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000534 return 0;
535 if ( len1 & 1 || len2 & 1 ) {
536 PyErr_SetString(AudioopError, "Strings should be even-sized");
537 return 0;
538 }
539 if ( len1 != len2 ) {
540 PyErr_SetString(AudioopError, "Samples should be same size");
541 return 0;
542 }
543 len2 >>= 1;
544 sum_ri_2 = _sum2(cp2, cp2, len2);
545 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000546
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000547 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000548
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000549 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000550}
551
552/*
553** findmax returns the index of the n-sized segment of the input sample
554** that contains the most energy.
555*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000556static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000557audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000558{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000559 short *cp1;
560 int len1, len2;
561 int j, best_j;
562 double aj_m1, aj_lm1;
563 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000564
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000565 if ( !PyArg_ParseTuple(args, "s#i:findmax", &cp1, &len1, &len2) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000566 return 0;
567 if ( len1 & 1 ) {
568 PyErr_SetString(AudioopError, "Strings should be even-sized");
569 return 0;
570 }
571 len1 >>= 1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000572
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000573 if ( len1 < len2 ) {
574 PyErr_SetString(AudioopError, "Input sample should be longer");
575 return 0;
576 }
Jack Jansena90805f1993-02-17 14:29:28 +0000577
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000578 result = _sum2(cp1, cp1, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000579
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000580 best_result = result;
581 best_j = 0;
582 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000583
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000584 for ( j=1; j<=len1-len2; j++) {
585 aj_m1 = (double)cp1[j-1];
586 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000587
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000588 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000589
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000590 if ( result > best_result ) {
591 best_result = result;
592 best_j = j;
593 }
594
595 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000596
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000597 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000598}
599
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000601audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000602{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000603 signed char *cp;
604 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
605 prevextreme = 0;
606 int i;
607 double avg = 0.0;
608 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000609
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000610 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000611 return 0;
612 if ( size != 1 && size != 2 && size != 4 ) {
613 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
614 return 0;
615 }
616 /* Compute first delta value ahead. Also automatically makes us
617 ** skip the first extreme value
618 */
619 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
620 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
621 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
622 if ( size == 1 ) val = (int)*CHARP(cp, size);
623 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
624 else if ( size == 4 ) val = (int)*LONGP(cp, size);
625 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000626
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000627 for ( i=size; i<len; i+= size) {
628 if ( size == 1 ) val = (int)*CHARP(cp, i);
629 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
630 else if ( size == 4 ) val = (int)*LONGP(cp, i);
631 diff = val - prevval;
632 if ( diff*prevdiff < 0 ) {
633 /* Derivative changed sign. Compute difference to last
634 ** extreme value and remember.
635 */
636 if ( prevextremevalid ) {
637 extremediff = prevval - prevextreme;
638 if ( extremediff < 0 )
639 extremediff = -extremediff;
640 avg += extremediff;
641 nextreme++;
642 }
643 prevextremevalid = 1;
644 prevextreme = prevval;
645 }
646 prevval = val;
647 if ( diff != 0 )
648 prevdiff = diff;
649 }
650 if ( nextreme == 0 )
651 val = 0;
652 else
653 val = (int)(avg / (double)nextreme);
654 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000655}
656
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000657static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000658audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000659{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000660 signed char *cp;
661 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
662 prevextreme = 0;
663 int i;
664 int max = 0;
665 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000666
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000667 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000668 return 0;
669 if ( size != 1 && size != 2 && size != 4 ) {
670 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
671 return 0;
672 }
673 /* Compute first delta value ahead. Also automatically makes us
674 ** skip the first extreme value
675 */
676 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
677 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
678 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
679 if ( size == 1 ) val = (int)*CHARP(cp, size);
680 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
681 else if ( size == 4 ) val = (int)*LONGP(cp, size);
682 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000684 for ( i=size; i<len; i+= size) {
685 if ( size == 1 ) val = (int)*CHARP(cp, i);
686 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
687 else if ( size == 4 ) val = (int)*LONGP(cp, i);
688 diff = val - prevval;
689 if ( diff*prevdiff < 0 ) {
690 /* Derivative changed sign. Compute difference to
691 ** last extreme value and remember.
692 */
693 if ( prevextremevalid ) {
694 extremediff = prevval - prevextreme;
695 if ( extremediff < 0 )
696 extremediff = -extremediff;
697 if ( extremediff > max )
698 max = extremediff;
699 }
700 prevextremevalid = 1;
701 prevextreme = prevval;
702 }
703 prevval = val;
704 if ( diff != 0 )
705 prevdiff = diff;
706 }
707 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000708}
709
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000710static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000711audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000712{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000713 signed char *cp;
714 int len, size, val = 0;
715 int i;
716 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000718 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000719 return 0;
720 if ( size != 1 && size != 2 && size != 4 ) {
721 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
722 return 0;
723 }
724 ncross = -1;
725 prevval = 17; /* Anything <> 0,1 */
726 for ( i=0; i<len; i+= size) {
727 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
728 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
729 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
730 val = val & 1;
731 if ( val != prevval ) ncross++;
732 prevval = val;
733 }
734 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000735}
736
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000738audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000739{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000740 signed char *cp, *ncp;
741 int len, size, val = 0;
742 double factor, fval, maxval;
743 PyObject *rv;
744 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000746 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000747 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000748
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000749 if ( size == 1 ) maxval = (double) 0x7f;
750 else if ( size == 2 ) maxval = (double) 0x7fff;
751 else if ( size == 4 ) maxval = (double) 0x7fffffff;
752 else {
753 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
754 return 0;
755 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000756
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000757 rv = PyString_FromStringAndSize(NULL, len);
758 if ( rv == 0 )
759 return 0;
760 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
762
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000763 for ( i=0; i < len; i += size ) {
764 if ( size == 1 ) val = (int)*CHARP(cp, i);
765 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
766 else if ( size == 4 ) val = (int)*LONGP(cp, i);
767 fval = (double)val*factor;
768 if ( fval > maxval ) fval = maxval;
769 else if ( fval < -maxval ) fval = -maxval;
770 val = (int)fval;
771 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
772 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
773 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
774 }
775 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000776}
777
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000778static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000779audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000780{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000781 signed char *cp, *ncp;
782 int len, size, val1 = 0, val2 = 0;
783 double fac1, fac2, fval, maxval;
784 PyObject *rv;
785 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000786
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000787 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
788 &cp, &len, &size, &fac1, &fac2 ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000789 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000791 if ( size == 1 ) maxval = (double) 0x7f;
792 else if ( size == 2 ) maxval = (double) 0x7fff;
793 else if ( size == 4 ) maxval = (double) 0x7fffffff;
794 else {
795 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
796 return 0;
797 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000798
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000799 rv = PyString_FromStringAndSize(NULL, len/2);
800 if ( rv == 0 )
801 return 0;
802 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803
804
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000805 for ( i=0; i < len; i += size*2 ) {
806 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
807 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
808 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
809 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
810 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
811 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
812 fval = (double)val1*fac1 + (double)val2*fac2;
813 if ( fval > maxval ) fval = maxval;
814 else if ( fval < -maxval ) fval = -maxval;
815 val1 = (int)fval;
816 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
817 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
818 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
819 }
820 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000821}
822
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000823static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000824audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000825{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000826 signed char *cp, *ncp;
827 int len, size, val1, val2, val = 0;
828 double fac1, fac2, fval, maxval;
829 PyObject *rv;
830 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000832 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
833 &cp, &len, &size, &fac1, &fac2 ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000834 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000835
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000836 if ( size == 1 ) maxval = (double) 0x7f;
837 else if ( size == 2 ) maxval = (double) 0x7fff;
838 else if ( size == 4 ) maxval = (double) 0x7fffffff;
839 else {
840 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
841 return 0;
842 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000844 rv = PyString_FromStringAndSize(NULL, len*2);
845 if ( rv == 0 )
846 return 0;
847 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000848
849
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000850 for ( i=0; i < len; i += size ) {
851 if ( size == 1 ) val = (int)*CHARP(cp, i);
852 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
853 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000855 fval = (double)val*fac1;
856 if ( fval > maxval ) fval = maxval;
857 else if ( fval < -maxval ) fval = -maxval;
858 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000859
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000860 fval = (double)val*fac2;
861 if ( fval > maxval ) fval = maxval;
862 else if ( fval < -maxval ) fval = -maxval;
863 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000864
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000865 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
866 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
867 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000869 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
870 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
871 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
872 }
873 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000874}
875
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000876static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000877audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000878{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000879 signed char *cp1, *cp2, *ncp;
880 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
881 PyObject *rv;
882 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000884 if ( !PyArg_ParseTuple(args, "s#s#i:add",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000885 &cp1, &len1, &cp2, &len2, &size ) )
886 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000887
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000888 if ( len1 != len2 ) {
889 PyErr_SetString(AudioopError, "Lengths should be the same");
890 return 0;
891 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000892
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000893 if ( size == 1 ) maxval = 0x7f;
894 else if ( size == 2 ) maxval = 0x7fff;
895 else if ( size == 4 ) maxval = 0x7fffffff;
896 else {
897 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
898 return 0;
899 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000900
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000901 rv = PyString_FromStringAndSize(NULL, len1);
902 if ( rv == 0 )
903 return 0;
904 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000905
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000906 for ( i=0; i < len1; i += size ) {
907 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
908 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
909 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
910
911 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
912 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
913 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000914
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000915 newval = val1 + val2;
916 /* truncate in case of overflow */
917 if (newval > maxval) newval = maxval;
918 else if (newval < -maxval) newval = -maxval;
919 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
920 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000922 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
923 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
924 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
925 }
926 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000927}
928
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000929static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000930audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000931{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000932 signed char *cp, *ncp;
933 int len, size, val = 0;
934 PyObject *rv;
935 int i;
936 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000937
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000938 if ( !PyArg_ParseTuple(args, "s#ii:bias",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000939 &cp, &len, &size , &bias) )
940 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000941
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000942 if ( size != 1 && size != 2 && size != 4) {
943 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
944 return 0;
945 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000946
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000947 rv = PyString_FromStringAndSize(NULL, len);
948 if ( rv == 0 )
949 return 0;
950 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000951
952
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000953 for ( i=0; i < len; i += size ) {
954 if ( size == 1 ) val = (int)*CHARP(cp, i);
955 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
956 else if ( size == 4 ) val = (int)*LONGP(cp, i);
957
958 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
959 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
960 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
961 }
962 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000963}
964
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000965static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000966audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000967{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000968 signed char *cp;
969 unsigned char *ncp;
970 int len, size, val = 0;
971 PyObject *rv;
972 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000973
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000974 if ( !PyArg_ParseTuple(args, "s#i:reverse",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000975 &cp, &len, &size) )
976 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000977
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000978 if ( size != 1 && size != 2 && size != 4 ) {
979 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
980 return 0;
981 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000982
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000983 rv = PyString_FromStringAndSize(NULL, len);
984 if ( rv == 0 )
985 return 0;
986 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000987
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000988 for ( i=0; i < len; i += size ) {
989 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
990 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
991 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000992
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000993 j = len - i - size;
994
995 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
996 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
997 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
998 }
999 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001000}
1001
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001002static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001003audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001004{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001005 signed char *cp;
1006 unsigned char *ncp;
1007 int len, size, size2, val = 0;
1008 PyObject *rv;
1009 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001010
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001011 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001012 &cp, &len, &size, &size2) )
1013 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001014
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001015 if ( (size != 1 && size != 2 && size != 4) ||
1016 (size2 != 1 && size2 != 2 && size2 != 4)) {
1017 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1018 return 0;
1019 }
Jack Jansena90805f1993-02-17 14:29:28 +00001020
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001021 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
1022 if ( rv == 0 )
1023 return 0;
1024 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001025
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001026 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1027 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1028 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1029 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001030
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001031 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1032 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1033 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1034 }
1035 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001036}
1037
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001038static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001039gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001040{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001041 while (b > 0) {
1042 int tmp = a % b;
1043 a = b;
1044 b = tmp;
1045 }
1046 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001047}
1048
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001049static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001050audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001051{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001052 char *cp, *ncp;
1053 int len, size, nchannels, inrate, outrate, weightA, weightB;
1054 int chan, d, *prev_i, *cur_i, cur_o;
1055 PyObject *state, *samps, *str, *rv = NULL;
1056 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001057
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001058 weightA = 1;
1059 weightB = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001060 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1061 &nchannels, &inrate, &outrate, &state,
1062 &weightA, &weightB))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001063 return NULL;
1064 if (size != 1 && size != 2 && size != 4) {
1065 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1066 return NULL;
1067 }
1068 if (nchannels < 1) {
1069 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1070 return NULL;
1071 }
1072 bytes_per_frame = size * nchannels;
1073 if (bytes_per_frame / nchannels != size) {
1074 /* This overflow test is rigorously correct because
1075 both multiplicands are >= 1. Use the argument names
1076 from the docs for the error msg. */
1077 PyErr_SetString(PyExc_OverflowError,
1078 "width * nchannels too big for a C int");
1079 return NULL;
1080 }
1081 if (weightA < 1 || weightB < 0) {
1082 PyErr_SetString(AudioopError,
1083 "weightA should be >= 1, weightB should be >= 0");
1084 return NULL;
1085 }
1086 if (len % bytes_per_frame != 0) {
1087 PyErr_SetString(AudioopError, "not a whole number of frames");
1088 return NULL;
1089 }
1090 if (inrate <= 0 || outrate <= 0) {
1091 PyErr_SetString(AudioopError, "sampling rate not > 0");
1092 return NULL;
1093 }
1094 /* divide inrate and outrate by their greatest common divisor */
1095 d = gcd(inrate, outrate);
1096 inrate /= d;
1097 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001098
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001099 prev_i = (int *) malloc(nchannels * sizeof(int));
1100 cur_i = (int *) malloc(nchannels * sizeof(int));
1101 if (prev_i == NULL || cur_i == NULL) {
1102 (void) PyErr_NoMemory();
1103 goto exit;
1104 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001105
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001106 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001107
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001108 if (state == Py_None) {
1109 d = -outrate;
1110 for (chan = 0; chan < nchannels; chan++)
1111 prev_i[chan] = cur_i[chan] = 0;
1112 }
1113 else {
1114 if (!PyArg_ParseTuple(state,
1115 "iO!;audioop.ratecv: illegal state argument",
1116 &d, &PyTuple_Type, &samps))
1117 goto exit;
1118 if (PyTuple_Size(samps) != nchannels) {
1119 PyErr_SetString(AudioopError,
1120 "illegal state argument");
1121 goto exit;
1122 }
1123 for (chan = 0; chan < nchannels; chan++) {
1124 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001125 "ii:ratecv", &prev_i[chan],
1126 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001127 goto exit;
1128 }
1129 }
Tim Peters1691bd92001-12-05 06:05:07 +00001130
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001131 /* str <- Space for the output buffer. */
1132 {
1133 /* There are len input frames, so we need (mathematically)
1134 ceiling(len*outrate/inrate) output frames, and each frame
1135 requires bytes_per_frame bytes. Computing this
1136 without spurious overflow is the challenge; we can
1137 settle for a reasonable upper bound, though. */
1138 int ceiling; /* the number of output frames */
1139 int nbytes; /* the number of output bytes needed */
1140 int q = len / inrate;
1141 /* Now len = q * inrate + r exactly (with r = len % inrate),
1142 and this is less than q * inrate + inrate = (q+1)*inrate.
1143 So a reasonable upper bound on len*outrate/inrate is
1144 ((q+1)*inrate)*outrate/inrate =
1145 (q+1)*outrate.
1146 */
1147 ceiling = (q+1) * outrate;
1148 nbytes = ceiling * bytes_per_frame;
1149 /* See whether anything overflowed; if not, get the space. */
1150 if (q+1 < 0 ||
1151 ceiling / outrate != q+1 ||
1152 nbytes / bytes_per_frame != ceiling)
1153 str = NULL;
1154 else
1155 str = PyString_FromStringAndSize(NULL, nbytes);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001156
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001157 if (str == NULL) {
1158 PyErr_SetString(PyExc_MemoryError,
1159 "not enough memory for output buffer");
1160 goto exit;
1161 }
1162 }
1163 ncp = PyString_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001164
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001165 for (;;) {
1166 while (d < 0) {
1167 if (len == 0) {
1168 samps = PyTuple_New(nchannels);
1169 if (samps == NULL)
1170 goto exit;
1171 for (chan = 0; chan < nchannels; chan++)
1172 PyTuple_SetItem(samps, chan,
1173 Py_BuildValue("(ii)",
1174 prev_i[chan],
1175 cur_i[chan]));
1176 if (PyErr_Occurred())
1177 goto exit;
1178 /* We have checked before that the length
1179 * of the string fits into int. */
1180 len = (int)(ncp - PyString_AsString(str));
1181 if (len == 0) {
1182 /*don't want to resize to zero length*/
1183 rv = PyString_FromStringAndSize("", 0);
1184 Py_DECREF(str);
1185 str = rv;
1186 } else if (_PyString_Resize(&str, len) < 0)
1187 goto exit;
1188 rv = Py_BuildValue("(O(iO))", str, d, samps);
1189 Py_DECREF(samps);
1190 Py_DECREF(str);
1191 goto exit; /* return rv */
1192 }
1193 for (chan = 0; chan < nchannels; chan++) {
1194 prev_i[chan] = cur_i[chan];
1195 if (size == 1)
1196 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1197 else if (size == 2)
1198 cur_i[chan] = (int)*SHORTP(cp, 0);
1199 else if (size == 4)
1200 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1201 cp += size;
1202 /* implements a simple digital filter */
1203 cur_i[chan] =
1204 (weightA * cur_i[chan] +
1205 weightB * prev_i[chan]) /
1206 (weightA + weightB);
1207 }
1208 len--;
1209 d += outrate;
1210 }
1211 while (d >= 0) {
1212 for (chan = 0; chan < nchannels; chan++) {
1213 cur_o = (prev_i[chan] * d +
1214 cur_i[chan] * (outrate - d)) /
1215 outrate;
1216 if (size == 1)
1217 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1218 else if (size == 2)
1219 *SHORTP(ncp, 0) = (short)(cur_o);
1220 else if (size == 4)
1221 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1222 ncp += size;
1223 }
1224 d -= inrate;
1225 }
1226 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001227 exit:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001228 if (prev_i != NULL)
1229 free(prev_i);
1230 if (cur_i != NULL)
1231 free(cur_i);
1232 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001233}
Guido van Rossum1851a671997-02-14 16:14:03 +00001234
Roger E. Massec905fff1997-01-17 18:12:04 +00001235static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001236audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001237{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001238 signed char *cp;
1239 unsigned char *ncp;
1240 int len, size, val = 0;
1241 PyObject *rv;
1242 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001243
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001244 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1245 &cp, &len, &size) )
1246 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001247
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001248 if ( size != 1 && size != 2 && size != 4) {
1249 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1250 return 0;
1251 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001252
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001253 rv = PyString_FromStringAndSize(NULL, len/size);
1254 if ( rv == 0 )
1255 return 0;
1256 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001257
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001258 for ( i=0; i < len; i += size ) {
1259 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1260 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1261 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001262
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001263 *ncp++ = st_14linear2ulaw(val);
1264 }
1265 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001266}
1267
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001268static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001269audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001270{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001271 unsigned char *cp;
1272 unsigned char cval;
1273 signed char *ncp;
1274 int len, size, val;
1275 PyObject *rv;
1276 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001277
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001278 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1279 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001280 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001282 if ( size != 1 && size != 2 && size != 4) {
1283 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1284 return 0;
1285 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001286
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001287 rv = PyString_FromStringAndSize(NULL, len*size);
1288 if ( rv == 0 )
1289 return 0;
1290 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001291
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001292 for ( i=0; i < len*size; i += size ) {
1293 cval = *cp++;
1294 val = st_ulaw2linear16(cval);
1295
1296 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1297 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1298 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1299 }
1300 return rv;
1301}
1302
1303static PyObject *
1304audioop_lin2alaw(PyObject *self, PyObject *args)
1305{
1306 signed char *cp;
1307 unsigned char *ncp;
1308 int len, size, val = 0;
1309 PyObject *rv;
1310 int i;
1311
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001312 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1313 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001314 return 0;
1315
1316 if ( size != 1 && size != 2 && size != 4) {
1317 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1318 return 0;
1319 }
1320
1321 rv = PyString_FromStringAndSize(NULL, len/size);
1322 if ( rv == 0 )
1323 return 0;
1324 ncp = (unsigned char *)PyString_AsString(rv);
1325
1326 for ( i=0; i < len; i += size ) {
1327 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1328 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1329 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1330
1331 *ncp++ = st_linear2alaw(val);
1332 }
1333 return rv;
1334}
1335
1336static PyObject *
1337audioop_alaw2lin(PyObject *self, PyObject *args)
1338{
1339 unsigned char *cp;
1340 unsigned char cval;
1341 signed char *ncp;
1342 int len, size, val;
1343 PyObject *rv;
1344 int i;
1345
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001346 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1347 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001348 return 0;
1349
1350 if ( size != 1 && size != 2 && size != 4) {
1351 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1352 return 0;
1353 }
1354
1355 rv = PyString_FromStringAndSize(NULL, len*size);
1356 if ( rv == 0 )
1357 return 0;
1358 ncp = (signed char *)PyString_AsString(rv);
1359
1360 for ( i=0; i < len*size; i += size ) {
1361 cval = *cp++;
1362 val = st_alaw2linear16(cval);
1363
1364 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1365 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1366 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1367 }
1368 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001369}
1370
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001371static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001372audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001373{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001374 signed char *cp;
1375 signed char *ncp;
1376 int len, size, val = 0, step, valpred, delta,
1377 index, sign, vpdiff, diff;
1378 PyObject *rv, *state, *str;
1379 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001380
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001381 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1382 &cp, &len, &size, &state) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001383 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001384
1385
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001386 if ( size != 1 && size != 2 && size != 4) {
1387 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1388 return 0;
1389 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001390
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001391 str = PyString_FromStringAndSize(NULL, len/(size*2));
1392 if ( str == 0 )
1393 return 0;
1394 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001395
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001396 /* Decode state, should have (value, step) */
1397 if ( state == Py_None ) {
1398 /* First time, it seems. Set defaults */
1399 valpred = 0;
1400 step = 7;
1401 index = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001402 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001403 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001404
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001405 step = stepsizeTable[index];
1406 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001407
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001408 for ( i=0; i < len; i += size ) {
1409 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1410 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1411 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001412
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001413 /* Step 1 - compute difference with previous value */
1414 diff = val - valpred;
1415 sign = (diff < 0) ? 8 : 0;
1416 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001417
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001418 /* Step 2 - Divide and clamp */
1419 /* Note:
1420 ** This code *approximately* computes:
1421 ** delta = diff*4/step;
1422 ** vpdiff = (delta+0.5)*step/4;
1423 ** but in shift step bits are dropped. The net result of this
1424 ** is that even if you have fast mul/div hardware you cannot
1425 ** put it to good use since the fixup would be too expensive.
1426 */
1427 delta = 0;
1428 vpdiff = (step >> 3);
1429
1430 if ( diff >= step ) {
1431 delta = 4;
1432 diff -= step;
1433 vpdiff += step;
1434 }
1435 step >>= 1;
1436 if ( diff >= step ) {
1437 delta |= 2;
1438 diff -= step;
1439 vpdiff += step;
1440 }
1441 step >>= 1;
1442 if ( diff >= step ) {
1443 delta |= 1;
1444 vpdiff += step;
1445 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001446
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001447 /* Step 3 - Update previous value */
1448 if ( sign )
1449 valpred -= vpdiff;
1450 else
1451 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001452
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001453 /* Step 4 - Clamp previous value to 16 bits */
1454 if ( valpred > 32767 )
1455 valpred = 32767;
1456 else if ( valpred < -32768 )
1457 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001458
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001459 /* Step 5 - Assemble value, update index and step values */
1460 delta |= sign;
1461
1462 index += indexTable[delta];
1463 if ( index < 0 ) index = 0;
1464 if ( index > 88 ) index = 88;
1465 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001466
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001467 /* Step 6 - Output value */
1468 if ( bufferstep ) {
1469 outputbuffer = (delta << 4) & 0xf0;
1470 } else {
1471 *ncp++ = (delta & 0x0f) | outputbuffer;
1472 }
1473 bufferstep = !bufferstep;
1474 }
1475 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1476 Py_DECREF(str);
1477 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001478}
1479
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001480static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001481audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001482{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001483 signed char *cp;
1484 signed char *ncp;
1485 int len, size, valpred, step, delta, index, sign, vpdiff;
1486 PyObject *rv, *str, *state;
1487 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001488
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001489 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1490 &cp, &len, &size, &state) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001491 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001492
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001493 if ( size != 1 && size != 2 && size != 4) {
1494 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1495 return 0;
1496 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001497
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001498 /* Decode state, should have (value, step) */
1499 if ( state == Py_None ) {
1500 /* First time, it seems. Set defaults */
1501 valpred = 0;
1502 step = 7;
1503 index = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001504 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001505 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001506
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001507 str = PyString_FromStringAndSize(NULL, len*size*2);
1508 if ( str == 0 )
1509 return 0;
1510 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001511
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001512 step = stepsizeTable[index];
1513 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001514
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001515 for ( i=0; i < len*size*2; i += size ) {
1516 /* Step 1 - get the delta value and compute next index */
1517 if ( bufferstep ) {
1518 delta = inputbuffer & 0xf;
1519 } else {
1520 inputbuffer = *cp++;
1521 delta = (inputbuffer >> 4) & 0xf;
1522 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001523
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001524 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001525
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001526 /* Step 2 - Find new index value (for later) */
1527 index += indexTable[delta];
1528 if ( index < 0 ) index = 0;
1529 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001530
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001531 /* Step 3 - Separate sign and magnitude */
1532 sign = delta & 8;
1533 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001534
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001535 /* Step 4 - Compute difference and new predicted value */
1536 /*
1537 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1538 ** in adpcm_coder.
1539 */
1540 vpdiff = step >> 3;
1541 if ( delta & 4 ) vpdiff += step;
1542 if ( delta & 2 ) vpdiff += step>>1;
1543 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001544
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001545 if ( sign )
1546 valpred -= vpdiff;
1547 else
1548 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001549
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001550 /* Step 5 - clamp output value */
1551 if ( valpred > 32767 )
1552 valpred = 32767;
1553 else if ( valpred < -32768 )
1554 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001555
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001556 /* Step 6 - Update step value */
1557 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001558
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001559 /* Step 6 - Output value */
1560 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1561 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1562 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1563 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001564
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001565 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1566 Py_DECREF(str);
1567 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001568}
1569
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001570static PyMethodDef audioop_methods[] = {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001571 { "max", audioop_max, METH_VARARGS },
1572 { "minmax", audioop_minmax, METH_VARARGS },
1573 { "avg", audioop_avg, METH_VARARGS },
1574 { "maxpp", audioop_maxpp, METH_VARARGS },
1575 { "avgpp", audioop_avgpp, METH_VARARGS },
1576 { "rms", audioop_rms, METH_VARARGS },
1577 { "findfit", audioop_findfit, METH_VARARGS },
1578 { "findmax", audioop_findmax, METH_VARARGS },
1579 { "findfactor", audioop_findfactor, METH_VARARGS },
1580 { "cross", audioop_cross, METH_VARARGS },
1581 { "mul", audioop_mul, METH_VARARGS },
1582 { "add", audioop_add, METH_VARARGS },
1583 { "bias", audioop_bias, METH_VARARGS },
1584 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1585 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1586 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1587 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1588 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1589 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1590 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1591 { "tomono", audioop_tomono, METH_VARARGS },
1592 { "tostereo", audioop_tostereo, METH_VARARGS },
1593 { "getsample", audioop_getsample, METH_VARARGS },
1594 { "reverse", audioop_reverse, METH_VARARGS },
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001595 { "ratecv", audioop_ratecv, METH_VARARGS },
1596 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001597};
1598
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001599PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001600initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001601{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001602 PyObject *m, *d;
1603 m = Py_InitModule("audioop", audioop_methods);
1604 if (m == NULL)
1605 return;
1606 d = PyModule_GetDict(m);
1607 if (d == NULL)
1608 return;
1609 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1610 if (AudioopError != NULL)
1611 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001612}