blob: b2fdb9a3c72ec1613862acbfbcdef8c6706381c1 [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);
Christian Heimes217cfd12007-12-02 14:31:20 +0000318 return PyLong_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 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000342 return PyLong_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));
Christian Heimes217cfd12007-12-02 14:31:20 +0000393 return PyLong_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));
Christian Heimes217cfd12007-12-02 14:31:20 +0000420 return PyLong_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
Christian Heimes72b710a2008-05-26 13:28:38 +0000477 as short[]. Due to the definition of PyBytesObject,
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478 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
Georg Brandl86b2fb92008-07-16 03:43:04 +0000578 if ( len2 < 0 || len1 < len2 ) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000579 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
Christian Heimes217cfd12007-12-02 14:31:20 +0000602 return PyLong_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);
Christian Heimes217cfd12007-12-02 14:31:20 +0000659 return PyLong_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 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000712 return PyLong_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 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000739 return PyLong_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
Christian Heimes72b710a2008-05-26 13:28:38 +0000762 rv = PyBytes_FromStringAndSize(NULL, len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000763 if ( rv == 0 )
764 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +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{
Martin v. Löwis423be952008-08-13 15:53:07 +0000786 Py_buffer pcp;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000787 signed char *cp, *ncp;
788 int len, size, val1 = 0, val2 = 0;
789 double fac1, fac2, fval, maxval;
790 PyObject *rv;
791 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000792
Martin v. Löwis423be952008-08-13 15:53:07 +0000793 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
794 &pcp, &size, &fac1, &fac2 ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000795 return 0;
Martin v. Löwis423be952008-08-13 15:53:07 +0000796 cp = pcp.buf;
797 len = pcp.len;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000798
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000799 if ( size == 1 ) maxval = (double) 0x7f;
800 else if ( size == 2 ) maxval = (double) 0x7fff;
801 else if ( size == 4 ) maxval = (double) 0x7fffffff;
802 else {
Martin v. Löwis423be952008-08-13 15:53:07 +0000803 PyBuffer_Release(&pcp);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000804 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
805 return 0;
806 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000807
Christian Heimes72b710a2008-05-26 13:28:38 +0000808 rv = PyBytes_FromStringAndSize(NULL, len/2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000809 if ( rv == 0 )
810 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +0000811 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000812
813
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000814 for ( i=0; i < len; i += size*2 ) {
815 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
816 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
817 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
818 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
819 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
820 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
821 fval = (double)val1*fac1 + (double)val2*fac2;
822 if ( fval > maxval ) fval = maxval;
823 else if ( fval < -maxval ) fval = -maxval;
824 val1 = (int)fval;
825 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
826 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
827 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
828 }
Martin v. Löwis423be952008-08-13 15:53:07 +0000829 PyBuffer_Release(&pcp);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000830 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831}
832
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000833static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000834audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000835{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000836 signed char *cp, *ncp;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000837 int len, new_len, size, val1, val2, val = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000838 double fac1, fac2, fval, maxval;
839 PyObject *rv;
840 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000841
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000842 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
843 &cp, &len, &size, &fac1, &fac2 ) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000844 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000845
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000846 if ( size == 1 ) maxval = (double) 0x7f;
847 else if ( size == 2 ) maxval = (double) 0x7fff;
848 else if ( size == 4 ) maxval = (double) 0x7fffffff;
849 else {
850 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
851 return 0;
852 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000853
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000854 new_len = len*2;
855 if (new_len < 0) {
856 PyErr_SetString(PyExc_MemoryError,
857 "not enough memory for output buffer");
858 return 0;
859 }
860
861 rv = PyBytes_FromStringAndSize(NULL, new_len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000862 if ( rv == 0 )
863 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +0000864 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000865
866
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000867 for ( i=0; i < len; i += size ) {
868 if ( size == 1 ) val = (int)*CHARP(cp, i);
869 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
870 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000871
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000872 fval = (double)val*fac1;
873 if ( fval > maxval ) fval = maxval;
874 else if ( fval < -maxval ) fval = -maxval;
875 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000877 fval = (double)val*fac2;
878 if ( fval > maxval ) fval = maxval;
879 else if ( fval < -maxval ) fval = -maxval;
880 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000881
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000882 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
883 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
884 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000885
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000886 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
887 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
888 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
889 }
890 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000891}
892
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000893static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000894audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000895{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000896 signed char *cp1, *cp2, *ncp;
897 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
898 PyObject *rv;
899 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000900
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000901 if ( !PyArg_ParseTuple(args, "s#s#i:add",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000902 &cp1, &len1, &cp2, &len2, &size ) )
903 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000904
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000905 if ( len1 != len2 ) {
906 PyErr_SetString(AudioopError, "Lengths should be the same");
907 return 0;
908 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000909
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000910 if ( size == 1 ) maxval = 0x7f;
911 else if ( size == 2 ) maxval = 0x7fff;
912 else if ( size == 4 ) maxval = 0x7fffffff;
913 else {
914 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
915 return 0;
916 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000917
Christian Heimes72b710a2008-05-26 13:28:38 +0000918 rv = PyBytes_FromStringAndSize(NULL, len1);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000919 if ( rv == 0 )
920 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +0000921 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000922
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000923 for ( i=0; i < len1; i += size ) {
924 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
925 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
926 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
927
928 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
929 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
930 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000931
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000932 newval = val1 + val2;
933 /* truncate in case of overflow */
934 if (newval > maxval) newval = maxval;
935 else if (newval < -maxval) newval = -maxval;
936 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
937 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000938
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000939 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
940 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
941 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
942 }
943 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000944}
945
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000946static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000947audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000948{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000949 signed char *cp, *ncp;
950 int len, size, val = 0;
951 PyObject *rv;
952 int i;
953 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000954
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000955 if ( !PyArg_ParseTuple(args, "s#ii:bias",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000956 &cp, &len, &size , &bias) )
957 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000958
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000959 if ( size != 1 && size != 2 && size != 4) {
960 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
961 return 0;
962 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000963
Christian Heimes72b710a2008-05-26 13:28:38 +0000964 rv = PyBytes_FromStringAndSize(NULL, len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000965 if ( rv == 0 )
966 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +0000967 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000968
969
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000970 for ( i=0; i < len; i += size ) {
971 if ( size == 1 ) val = (int)*CHARP(cp, i);
972 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
973 else if ( size == 4 ) val = (int)*LONGP(cp, i);
974
975 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
976 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
977 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
978 }
979 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000980}
981
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000982static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000983audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000984{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000985 signed char *cp;
986 unsigned char *ncp;
987 int len, size, val = 0;
988 PyObject *rv;
989 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000990
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000991 if ( !PyArg_ParseTuple(args, "s#i:reverse",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000992 &cp, &len, &size) )
993 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000994
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000995 if ( size != 1 && size != 2 && size != 4 ) {
996 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
997 return 0;
998 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000999
Christian Heimes72b710a2008-05-26 13:28:38 +00001000 rv = PyBytes_FromStringAndSize(NULL, len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001001 if ( rv == 0 )
1002 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001003 ncp = (unsigned char *)PyBytes_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +00001004
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001005 for ( i=0; i < len; i += size ) {
1006 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1007 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1008 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +00001009
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001010 j = len - i - size;
1011
1012 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1013 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1014 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1015 }
1016 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001017}
1018
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001019static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001020audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001021{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001022 signed char *cp;
1023 unsigned char *ncp;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001024 int len, new_len, size, size2, val = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001025 PyObject *rv;
1026 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001027
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001028 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001029 &cp, &len, &size, &size2) )
1030 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001031
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001032 if ( (size != 1 && size != 2 && size != 4) ||
1033 (size2 != 1 && size2 != 2 && size2 != 4)) {
1034 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1035 return 0;
1036 }
Jack Jansena90805f1993-02-17 14:29:28 +00001037
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001038 new_len = (len/size)*size2;
1039 if (new_len < 0) {
1040 PyErr_SetString(PyExc_MemoryError,
1041 "not enough memory for output buffer");
1042 return 0;
1043 }
1044 rv = PyBytes_FromStringAndSize(NULL, new_len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001045 if ( rv == 0 )
1046 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001047 ncp = (unsigned char *)PyBytes_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001048
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001049 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1050 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1051 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1052 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001053
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001054 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1055 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1056 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1057 }
1058 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001059}
1060
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001061static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001062gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001063{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001064 while (b > 0) {
1065 int tmp = a % b;
1066 a = b;
1067 b = tmp;
1068 }
1069 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001070}
1071
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001072static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001073audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001074{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001075 char *cp, *ncp;
1076 int len, size, nchannels, inrate, outrate, weightA, weightB;
1077 int chan, d, *prev_i, *cur_i, cur_o;
1078 PyObject *state, *samps, *str, *rv = NULL;
1079 int bytes_per_frame;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001080 size_t alloc_size;
Guido van Rossum1851a671997-02-14 16:14:03 +00001081
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001082 weightA = 1;
1083 weightB = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001084 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1085 &nchannels, &inrate, &outrate, &state,
1086 &weightA, &weightB))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001087 return NULL;
1088 if (size != 1 && size != 2 && size != 4) {
1089 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1090 return NULL;
1091 }
1092 if (nchannels < 1) {
1093 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1094 return NULL;
1095 }
1096 bytes_per_frame = size * nchannels;
1097 if (bytes_per_frame / nchannels != size) {
1098 /* This overflow test is rigorously correct because
1099 both multiplicands are >= 1. Use the argument names
1100 from the docs for the error msg. */
1101 PyErr_SetString(PyExc_OverflowError,
1102 "width * nchannels too big for a C int");
1103 return NULL;
1104 }
1105 if (weightA < 1 || weightB < 0) {
1106 PyErr_SetString(AudioopError,
1107 "weightA should be >= 1, weightB should be >= 0");
1108 return NULL;
1109 }
1110 if (len % bytes_per_frame != 0) {
1111 PyErr_SetString(AudioopError, "not a whole number of frames");
1112 return NULL;
1113 }
1114 if (inrate <= 0 || outrate <= 0) {
1115 PyErr_SetString(AudioopError, "sampling rate not > 0");
1116 return NULL;
1117 }
1118 /* divide inrate and outrate by their greatest common divisor */
1119 d = gcd(inrate, outrate);
1120 inrate /= d;
1121 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001122
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001123 alloc_size = sizeof(int) * (unsigned)nchannels;
1124 if (alloc_size < nchannels) {
1125 PyErr_SetString(PyExc_MemoryError,
1126 "not enough memory for output buffer");
1127 return 0;
1128 }
1129 prev_i = (int *) malloc(alloc_size);
1130 cur_i = (int *) malloc(alloc_size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001131 if (prev_i == NULL || cur_i == NULL) {
1132 (void) PyErr_NoMemory();
1133 goto exit;
1134 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001135
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001136 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001137
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001138 if (state == Py_None) {
1139 d = -outrate;
1140 for (chan = 0; chan < nchannels; chan++)
1141 prev_i[chan] = cur_i[chan] = 0;
1142 }
1143 else {
1144 if (!PyArg_ParseTuple(state,
1145 "iO!;audioop.ratecv: illegal state argument",
1146 &d, &PyTuple_Type, &samps))
1147 goto exit;
1148 if (PyTuple_Size(samps) != nchannels) {
1149 PyErr_SetString(AudioopError,
1150 "illegal state argument");
1151 goto exit;
1152 }
1153 for (chan = 0; chan < nchannels; chan++) {
1154 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001155 "ii:ratecv", &prev_i[chan],
1156 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001157 goto exit;
1158 }
1159 }
Tim Peters1691bd92001-12-05 06:05:07 +00001160
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001161 /* str <- Space for the output buffer. */
1162 {
1163 /* There are len input frames, so we need (mathematically)
1164 ceiling(len*outrate/inrate) output frames, and each frame
1165 requires bytes_per_frame bytes. Computing this
1166 without spurious overflow is the challenge; we can
1167 settle for a reasonable upper bound, though. */
1168 int ceiling; /* the number of output frames */
1169 int nbytes; /* the number of output bytes needed */
1170 int q = len / inrate;
1171 /* Now len = q * inrate + r exactly (with r = len % inrate),
1172 and this is less than q * inrate + inrate = (q+1)*inrate.
1173 So a reasonable upper bound on len*outrate/inrate is
1174 ((q+1)*inrate)*outrate/inrate =
1175 (q+1)*outrate.
1176 */
1177 ceiling = (q+1) * outrate;
1178 nbytes = ceiling * bytes_per_frame;
1179 /* See whether anything overflowed; if not, get the space. */
1180 if (q+1 < 0 ||
1181 ceiling / outrate != q+1 ||
1182 nbytes / bytes_per_frame != ceiling)
1183 str = NULL;
1184 else
Christian Heimes72b710a2008-05-26 13:28:38 +00001185 str = PyBytes_FromStringAndSize(NULL, nbytes);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001186
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001187 if (str == NULL) {
1188 PyErr_SetString(PyExc_MemoryError,
1189 "not enough memory for output buffer");
1190 goto exit;
1191 }
1192 }
Christian Heimes72b710a2008-05-26 13:28:38 +00001193 ncp = PyBytes_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001194
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001195 for (;;) {
1196 while (d < 0) {
1197 if (len == 0) {
1198 samps = PyTuple_New(nchannels);
1199 if (samps == NULL)
1200 goto exit;
1201 for (chan = 0; chan < nchannels; chan++)
1202 PyTuple_SetItem(samps, chan,
1203 Py_BuildValue("(ii)",
1204 prev_i[chan],
1205 cur_i[chan]));
1206 if (PyErr_Occurred())
1207 goto exit;
1208 /* We have checked before that the length
1209 * of the string fits into int. */
Christian Heimes72b710a2008-05-26 13:28:38 +00001210 len = (int)(ncp - PyBytes_AsString(str));
1211 rv = PyBytes_FromStringAndSize
1212 (PyBytes_AsString(str), len);
Martin v. Löwis3a2e5ce2007-07-20 07:36:26 +00001213 Py_DECREF(str);
1214 str = rv;
1215 if (str == NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001216 goto exit;
1217 rv = Py_BuildValue("(O(iO))", str, d, samps);
1218 Py_DECREF(samps);
1219 Py_DECREF(str);
1220 goto exit; /* return rv */
1221 }
1222 for (chan = 0; chan < nchannels; chan++) {
1223 prev_i[chan] = cur_i[chan];
1224 if (size == 1)
1225 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1226 else if (size == 2)
1227 cur_i[chan] = (int)*SHORTP(cp, 0);
1228 else if (size == 4)
1229 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1230 cp += size;
1231 /* implements a simple digital filter */
1232 cur_i[chan] =
1233 (weightA * cur_i[chan] +
1234 weightB * prev_i[chan]) /
1235 (weightA + weightB);
1236 }
1237 len--;
1238 d += outrate;
1239 }
1240 while (d >= 0) {
1241 for (chan = 0; chan < nchannels; chan++) {
1242 cur_o = (prev_i[chan] * d +
1243 cur_i[chan] * (outrate - d)) /
1244 outrate;
1245 if (size == 1)
1246 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1247 else if (size == 2)
1248 *SHORTP(ncp, 0) = (short)(cur_o);
1249 else if (size == 4)
1250 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1251 ncp += size;
1252 }
1253 d -= inrate;
1254 }
1255 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001256 exit:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001257 if (prev_i != NULL)
1258 free(prev_i);
1259 if (cur_i != NULL)
1260 free(cur_i);
1261 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001262}
Guido van Rossum1851a671997-02-14 16:14:03 +00001263
Roger E. Massec905fff1997-01-17 18:12:04 +00001264static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001265audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001266{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001267 signed char *cp;
1268 unsigned char *ncp;
1269 int len, size, val = 0;
1270 PyObject *rv;
1271 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001272
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001273 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1274 &cp, &len, &size) )
1275 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001276
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001277 if ( size != 1 && size != 2 && size != 4) {
1278 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1279 return 0;
1280 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Christian Heimes72b710a2008-05-26 13:28:38 +00001282 rv = PyBytes_FromStringAndSize(NULL, len/size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001283 if ( rv == 0 )
1284 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001285 ncp = (unsigned char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001286
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001287 for ( i=0; i < len; i += size ) {
1288 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1289 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1290 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001291
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001292 *ncp++ = st_14linear2ulaw(val);
1293 }
1294 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001295}
1296
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001297static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001298audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001299{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001300 unsigned char *cp;
1301 unsigned char cval;
1302 signed char *ncp;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001303 int len, new_len, size, val;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001304 PyObject *rv;
1305 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001306
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001307 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1308 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001309 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001310
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001311 if ( size != 1 && size != 2 && size != 4) {
1312 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1313 return 0;
1314 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001315
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001316 new_len = len*size;
1317 if (new_len < 0) {
1318 PyErr_SetString(PyExc_MemoryError,
1319 "not enough memory for output buffer");
1320 return 0;
1321 }
1322 rv = PyBytes_FromStringAndSize(NULL, new_len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001323 if ( rv == 0 )
1324 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001325 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001326
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001327 for ( i=0; i < new_len; i += size ) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001328 cval = *cp++;
1329 val = st_ulaw2linear16(cval);
1330
1331 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1332 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1333 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1334 }
1335 return rv;
1336}
1337
1338static PyObject *
1339audioop_lin2alaw(PyObject *self, PyObject *args)
1340{
1341 signed char *cp;
1342 unsigned char *ncp;
1343 int len, size, val = 0;
1344 PyObject *rv;
1345 int i;
1346
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1348 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001349 return 0;
1350
1351 if ( size != 1 && size != 2 && size != 4) {
1352 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1353 return 0;
1354 }
1355
Christian Heimes72b710a2008-05-26 13:28:38 +00001356 rv = PyBytes_FromStringAndSize(NULL, len/size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001357 if ( rv == 0 )
1358 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001359 ncp = (unsigned char *)PyBytes_AsString(rv);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001360
1361 for ( i=0; i < len; i += size ) {
1362 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1363 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1364 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1365
1366 *ncp++ = st_linear2alaw(val);
1367 }
1368 return rv;
1369}
1370
1371static PyObject *
1372audioop_alaw2lin(PyObject *self, PyObject *args)
1373{
1374 unsigned char *cp;
1375 unsigned char cval;
1376 signed char *ncp;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001377 int len, new_len, size, val;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001378 PyObject *rv;
1379 int i;
1380
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001381 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1382 &cp, &len, &size) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001383 return 0;
1384
1385 if ( size != 1 && size != 2 && size != 4) {
1386 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1387 return 0;
1388 }
1389
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001390 new_len = len*size;
1391 if (new_len < 0) {
1392 PyErr_SetString(PyExc_MemoryError,
1393 "not enough memory for output buffer");
1394 return 0;
1395 }
1396 rv = PyBytes_FromStringAndSize(NULL, new_len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001397 if ( rv == 0 )
1398 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001399 ncp = (signed char *)PyBytes_AsString(rv);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001400
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001401 for ( i=0; i < new_len; i += size ) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001402 cval = *cp++;
1403 val = st_alaw2linear16(cval);
1404
1405 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1406 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1407 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1408 }
1409 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001410}
1411
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001412static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001413audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001414{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001415 signed char *cp;
1416 signed char *ncp;
1417 int len, size, val = 0, step, valpred, delta,
1418 index, sign, vpdiff, diff;
1419 PyObject *rv, *state, *str;
1420 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001421
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001422 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1423 &cp, &len, &size, &state) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001424 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001425
1426
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001427 if ( size != 1 && size != 2 && size != 4) {
1428 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1429 return 0;
1430 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001431
Christian Heimes72b710a2008-05-26 13:28:38 +00001432 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001433 if ( str == 0 )
1434 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001435 ncp = (signed char *)PyBytes_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001436
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001437 /* Decode state, should have (value, step) */
1438 if ( state == Py_None ) {
1439 /* First time, it seems. Set defaults */
1440 valpred = 0;
1441 step = 7;
1442 index = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001443 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001444 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001445
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001446 step = stepsizeTable[index];
1447 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001448
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001449 for ( i=0; i < len; i += size ) {
1450 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1451 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1452 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001453
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001454 /* Step 1 - compute difference with previous value */
1455 diff = val - valpred;
1456 sign = (diff < 0) ? 8 : 0;
1457 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001458
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001459 /* Step 2 - Divide and clamp */
1460 /* Note:
1461 ** This code *approximately* computes:
1462 ** delta = diff*4/step;
1463 ** vpdiff = (delta+0.5)*step/4;
1464 ** but in shift step bits are dropped. The net result of this
1465 ** is that even if you have fast mul/div hardware you cannot
1466 ** put it to good use since the fixup would be too expensive.
1467 */
1468 delta = 0;
1469 vpdiff = (step >> 3);
1470
1471 if ( diff >= step ) {
1472 delta = 4;
1473 diff -= step;
1474 vpdiff += step;
1475 }
1476 step >>= 1;
1477 if ( diff >= step ) {
1478 delta |= 2;
1479 diff -= step;
1480 vpdiff += step;
1481 }
1482 step >>= 1;
1483 if ( diff >= step ) {
1484 delta |= 1;
1485 vpdiff += step;
1486 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001487
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001488 /* Step 3 - Update previous value */
1489 if ( sign )
1490 valpred -= vpdiff;
1491 else
1492 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001493
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001494 /* Step 4 - Clamp previous value to 16 bits */
1495 if ( valpred > 32767 )
1496 valpred = 32767;
1497 else if ( valpred < -32768 )
1498 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001499
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001500 /* Step 5 - Assemble value, update index and step values */
1501 delta |= sign;
1502
1503 index += indexTable[delta];
1504 if ( index < 0 ) index = 0;
1505 if ( index > 88 ) index = 88;
1506 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001507
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001508 /* Step 6 - Output value */
1509 if ( bufferstep ) {
1510 outputbuffer = (delta << 4) & 0xf0;
1511 } else {
1512 *ncp++ = (delta & 0x0f) | outputbuffer;
1513 }
1514 bufferstep = !bufferstep;
1515 }
1516 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1517 Py_DECREF(str);
1518 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001519}
1520
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001521static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001522audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001523{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001524 signed char *cp;
1525 signed char *ncp;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001526 int len, new_len, size, valpred, step, delta, index, sign, vpdiff;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001527 PyObject *rv, *str, *state;
1528 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001529
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001530 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1531 &cp, &len, &size, &state) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001532 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001533
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001534 if ( size != 1 && size != 2 && size != 4) {
1535 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1536 return 0;
1537 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001538
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001539 /* Decode state, should have (value, step) */
1540 if ( state == Py_None ) {
1541 /* First time, it seems. Set defaults */
1542 valpred = 0;
1543 step = 7;
1544 index = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001545 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001546 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001547
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001548 new_len = len*size*2;
1549 if (new_len < 0) {
1550 PyErr_SetString(PyExc_MemoryError,
1551 "not enough memory for output buffer");
1552 return 0;
1553 }
1554 str = PyBytes_FromStringAndSize(NULL, new_len);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001555 if ( str == 0 )
1556 return 0;
Christian Heimes72b710a2008-05-26 13:28:38 +00001557 ncp = (signed char *)PyBytes_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001558
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001559 step = stepsizeTable[index];
1560 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001561
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001562 for ( i=0; i < new_len; i += size ) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001563 /* Step 1 - get the delta value and compute next index */
1564 if ( bufferstep ) {
1565 delta = inputbuffer & 0xf;
1566 } else {
1567 inputbuffer = *cp++;
1568 delta = (inputbuffer >> 4) & 0xf;
1569 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001570
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001571 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001572
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001573 /* Step 2 - Find new index value (for later) */
1574 index += indexTable[delta];
1575 if ( index < 0 ) index = 0;
1576 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001577
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001578 /* Step 3 - Separate sign and magnitude */
1579 sign = delta & 8;
1580 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001581
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001582 /* Step 4 - Compute difference and new predicted value */
1583 /*
1584 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1585 ** in adpcm_coder.
1586 */
1587 vpdiff = step >> 3;
1588 if ( delta & 4 ) vpdiff += step;
1589 if ( delta & 2 ) vpdiff += step>>1;
1590 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001591
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001592 if ( sign )
1593 valpred -= vpdiff;
1594 else
1595 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001596
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001597 /* Step 5 - clamp output value */
1598 if ( valpred > 32767 )
1599 valpred = 32767;
1600 else if ( valpred < -32768 )
1601 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001602
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001603 /* Step 6 - Update step value */
1604 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001605
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001606 /* Step 6 - Output value */
1607 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1608 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1609 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1610 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001611
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001612 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1613 Py_DECREF(str);
1614 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001615}
1616
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001617static PyMethodDef audioop_methods[] = {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001618 { "max", audioop_max, METH_VARARGS },
1619 { "minmax", audioop_minmax, METH_VARARGS },
1620 { "avg", audioop_avg, METH_VARARGS },
1621 { "maxpp", audioop_maxpp, METH_VARARGS },
1622 { "avgpp", audioop_avgpp, METH_VARARGS },
1623 { "rms", audioop_rms, METH_VARARGS },
1624 { "findfit", audioop_findfit, METH_VARARGS },
1625 { "findmax", audioop_findmax, METH_VARARGS },
1626 { "findfactor", audioop_findfactor, METH_VARARGS },
1627 { "cross", audioop_cross, METH_VARARGS },
1628 { "mul", audioop_mul, METH_VARARGS },
1629 { "add", audioop_add, METH_VARARGS },
1630 { "bias", audioop_bias, METH_VARARGS },
1631 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1632 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1633 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1634 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1635 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1636 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1637 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1638 { "tomono", audioop_tomono, METH_VARARGS },
1639 { "tostereo", audioop_tostereo, METH_VARARGS },
1640 { "getsample", audioop_getsample, METH_VARARGS },
1641 { "reverse", audioop_reverse, METH_VARARGS },
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001642 { "ratecv", audioop_ratecv, METH_VARARGS },
1643 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001644};
1645
Martin v. Löwis1a214512008-06-11 05:26:20 +00001646
1647static struct PyModuleDef audioopmodule = {
1648 PyModuleDef_HEAD_INIT,
1649 "audioop",
1650 NULL,
1651 -1,
1652 audioop_methods,
1653 NULL,
1654 NULL,
1655 NULL,
1656 NULL
1657};
1658
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001659PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001660PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001661{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001662 PyObject *m, *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001663 m = PyModule_Create(&audioopmodule);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001664 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001665 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001666 d = PyModule_GetDict(m);
1667 if (d == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001668 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001669 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1670 if (AudioopError != NULL)
1671 PyDict_SetItemString(d,"error",AudioopError);
Martin v. Löwis1a214512008-06-11 05:26:20 +00001672 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001673}