Bump version to 0.9.1.
[python/dscho.git] / Modules / audioop.c
blob49cd8c95753143f37f6b98aac280ea2e92277225
1 /***********************************************************
2 Copyright (c) 2000, BeOpen.com.
3 Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4 Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5 All rights reserved.
7 See the file "Misc/COPYRIGHT" for information on usage and
8 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 ******************************************************************/
11 /* audioopmodule - Module to detect peak values in arrays */
13 #include "Python.h"
15 #if SIZEOF_INT == 4
16 typedef int Py_Int32;
17 typedef unsigned int Py_UInt32;
18 #else
19 #if SIZEOF_LONG == 4
20 typedef long Py_Int32;
21 typedef unsigned long Py_UInt32;
22 #else
23 #error "No 4-byte integral type"
24 #endif
25 #endif
27 #if defined(__CHAR_UNSIGNED__)
28 #if defined(signed)
29 /* This module currently does not work on systems where only unsigned
30 characters are available. Take it out of Setup. Sorry. */
31 #endif
32 #endif
34 /* Code shamelessly stolen from sox,
35 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
37 #define MINLIN -32768
38 #define MAXLIN 32767
39 #define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
40 else if ( x > MAXLIN ) x = MAXLIN; \
41 } while ( 0 )
43 static unsigned char st_linear_to_ulaw( /* int sample */ );
46 ** This macro converts from ulaw to 16 bit linear, faster.
48 ** Jef Poskanzer
49 ** 23 October 1989
51 ** Input: 8 bit ulaw sample
52 ** Output: signed 16 bit linear sample
54 #define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
56 static int ulaw_table[256] = {
57 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
58 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
59 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
60 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
61 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
62 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
63 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
64 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
65 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
66 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
67 -876, -844, -812, -780, -748, -716, -684, -652,
68 -620, -588, -556, -524, -492, -460, -428, -396,
69 -372, -356, -340, -324, -308, -292, -276, -260,
70 -244, -228, -212, -196, -180, -164, -148, -132,
71 -120, -112, -104, -96, -88, -80, -72, -64,
72 -56, -48, -40, -32, -24, -16, -8, 0,
73 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
74 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
75 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
76 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
77 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
78 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
79 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
80 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
81 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
82 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
83 876, 844, 812, 780, 748, 716, 684, 652,
84 620, 588, 556, 524, 492, 460, 428, 396,
85 372, 356, 340, 324, 308, 292, 276, 260,
86 244, 228, 212, 196, 180, 164, 148, 132,
87 120, 112, 104, 96, 88, 80, 72, 64,
88 56, 48, 40, 32, 24, 16, 8, 0 };
90 /* #define ZEROTRAP */ /* turn on the trap as per the MIL-STD */
91 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
92 #define CLIP 32635
94 static unsigned char
95 st_linear_to_ulaw(int sample)
97 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
98 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
99 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
100 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
101 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
102 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
103 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
104 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
105 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
106 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
107 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
110 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
111 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
112 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
113 int sign, exponent, mantissa;
114 unsigned char ulawbyte;
116 /* Get the sample into sign-magnitude. */
117 sign = (sample >> 8) & 0x80; /* set aside the sign */
118 if ( sign != 0 ) sample = -sample; /* get magnitude */
119 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
121 /* Convert from 16 bit linear to ulaw. */
122 sample = sample + BIAS;
123 exponent = exp_lut[( sample >> 7 ) & 0xFF];
124 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
125 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
126 #ifdef ZEROTRAP
127 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
128 #endif
130 return ulawbyte;
132 /* End of code taken from sox */
134 /* Intel ADPCM step variation table */
135 static int indexTable[16] = {
136 -1, -1, -1, -1, 2, 4, 6, 8,
137 -1, -1, -1, -1, 2, 4, 6, 8,
140 static int stepsizeTable[89] = {
141 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
142 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
143 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
144 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
145 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
146 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
147 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
148 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
149 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
152 #define CHARP(cp, i) ((signed char *)(cp+i))
153 #define SHORTP(cp, i) ((short *)(cp+i))
154 #define LONGP(cp, i) ((Py_Int32 *)(cp+i))
158 static PyObject *AudioopError;
160 static PyObject *
161 audioop_getsample(PyObject *self, PyObject *args)
163 signed char *cp;
164 int len, size, val = 0;
165 int i;
167 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
168 return 0;
169 if ( size != 1 && size != 2 && size != 4 ) {
170 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
171 return 0;
173 if ( i < 0 || i >= len/size ) {
174 PyErr_SetString(AudioopError, "Index out of range");
175 return 0;
177 if ( size == 1 ) val = (int)*CHARP(cp, i);
178 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
179 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
180 return PyInt_FromLong(val);
183 static PyObject *
184 audioop_max(PyObject *self, PyObject *args)
186 signed char *cp;
187 int len, size, val = 0;
188 int i;
189 int max = 0;
191 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
192 return 0;
193 if ( size != 1 && size != 2 && size != 4 ) {
194 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
195 return 0;
197 for ( i=0; i<len; i+= size) {
198 if ( size == 1 ) val = (int)*CHARP(cp, i);
199 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
200 else if ( size == 4 ) val = (int)*LONGP(cp, i);
201 if ( val < 0 ) val = (-val);
202 if ( val > max ) max = val;
204 return PyInt_FromLong(max);
207 static PyObject *
208 audioop_minmax(PyObject *self, PyObject *args)
210 signed char *cp;
211 int len, size, val = 0;
212 int i;
213 int min = 0x7fffffff, max = -0x7fffffff;
215 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
216 return NULL;
217 if (size != 1 && size != 2 && size != 4) {
218 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
219 return NULL;
221 for (i = 0; i < len; i += size) {
222 if (size == 1) val = (int) *CHARP(cp, i);
223 else if (size == 2) val = (int) *SHORTP(cp, i);
224 else if (size == 4) val = (int) *LONGP(cp, i);
225 if (val > max) max = val;
226 if (val < min) min = val;
228 return Py_BuildValue("(ii)", min, max);
231 static PyObject *
232 audioop_avg(PyObject *self, PyObject *args)
234 signed char *cp;
235 int len, size, val = 0;
236 int i;
237 double avg = 0.0;
239 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
240 return 0;
241 if ( size != 1 && size != 2 && size != 4 ) {
242 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
243 return 0;
245 for ( i=0; i<len; i+= size) {
246 if ( size == 1 ) val = (int)*CHARP(cp, i);
247 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
248 else if ( size == 4 ) val = (int)*LONGP(cp, i);
249 avg += val;
251 if ( len == 0 )
252 val = 0;
253 else
254 val = (int)(avg / (double)(len/size));
255 return PyInt_FromLong(val);
258 static PyObject *
259 audioop_rms(PyObject *self, PyObject *args)
261 signed char *cp;
262 int len, size, val = 0;
263 int i;
264 double sum_squares = 0.0;
266 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
267 return 0;
268 if ( size != 1 && size != 2 && size != 4 ) {
269 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
270 return 0;
272 for ( i=0; i<len; i+= size) {
273 if ( size == 1 ) val = (int)*CHARP(cp, i);
274 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
275 else if ( size == 4 ) val = (int)*LONGP(cp, i);
276 sum_squares += (double)val*(double)val;
278 if ( len == 0 )
279 val = 0;
280 else
281 val = (int)sqrt(sum_squares / (double)(len/size));
282 return PyInt_FromLong(val);
285 static double _sum2(short *a, short *b, int len)
287 int i;
288 double sum = 0.0;
290 for( i=0; i<len; i++) {
291 sum = sum + (double)a[i]*(double)b[i];
293 return sum;
297 ** Findfit tries to locate a sample within another sample. Its main use
298 ** is in echo-cancellation (to find the feedback of the output signal in
299 ** the input signal).
300 ** The method used is as follows:
302 ** let R be the reference signal (length n) and A the input signal (length N)
303 ** with N > n, and let all sums be over i from 0 to n-1.
305 ** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
306 ** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
307 ** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
309 ** Next, we compute the relative distance between the original signal and
310 ** the modified signal and minimize that over j:
311 ** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
312 ** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
314 ** In the code variables correspond as follows:
315 ** cp1 A
316 ** cp2 R
317 ** len1 N
318 ** len2 n
319 ** aj_m1 A[j-1]
320 ** aj_lm1 A[j+n-1]
321 ** sum_ri_2 sum(R[i]^2)
322 ** sum_aij_2 sum(A[i+j]^2)
323 ** sum_aij_ri sum(A[i+j]R[i])
325 ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
326 ** is completely recalculated each step.
328 static PyObject *
329 audioop_findfit(PyObject *self, PyObject *args)
331 short *cp1, *cp2;
332 int len1, len2;
333 int j, best_j;
334 double aj_m1, aj_lm1;
335 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
337 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
338 return 0;
339 if ( len1 & 1 || len2 & 1 ) {
340 PyErr_SetString(AudioopError, "Strings should be even-sized");
341 return 0;
343 len1 >>= 1;
344 len2 >>= 1;
346 if ( len1 < len2 ) {
347 PyErr_SetString(AudioopError, "First sample should be longer");
348 return 0;
350 sum_ri_2 = _sum2(cp2, cp2, len2);
351 sum_aij_2 = _sum2(cp1, cp1, len2);
352 sum_aij_ri = _sum2(cp1, cp2, len2);
354 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
356 best_result = result;
357 best_j = 0;
358 j = 0;
360 for ( j=1; j<=len1-len2; j++) {
361 aj_m1 = (double)cp1[j-1];
362 aj_lm1 = (double)cp1[j+len2-1];
364 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
365 sum_aij_ri = _sum2(cp1+j, cp2, len2);
367 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
368 / sum_aij_2;
370 if ( result < best_result ) {
371 best_result = result;
372 best_j = j;
377 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
379 return Py_BuildValue("(if)", best_j, factor);
383 ** findfactor finds a factor f so that the energy in A-fB is minimal.
384 ** See the comment for findfit for details.
386 static PyObject *
387 audioop_findfactor(PyObject *self, PyObject *args)
389 short *cp1, *cp2;
390 int len1, len2;
391 double sum_ri_2, sum_aij_ri, result;
393 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
394 return 0;
395 if ( len1 & 1 || len2 & 1 ) {
396 PyErr_SetString(AudioopError, "Strings should be even-sized");
397 return 0;
399 if ( len1 != len2 ) {
400 PyErr_SetString(AudioopError, "Samples should be same size");
401 return 0;
403 len2 >>= 1;
404 sum_ri_2 = _sum2(cp2, cp2, len2);
405 sum_aij_ri = _sum2(cp1, cp2, len2);
407 result = sum_aij_ri / sum_ri_2;
409 return PyFloat_FromDouble(result);
413 ** findmax returns the index of the n-sized segment of the input sample
414 ** that contains the most energy.
416 static PyObject *
417 audioop_findmax(PyObject *self, PyObject *args)
419 short *cp1;
420 int len1, len2;
421 int j, best_j;
422 double aj_m1, aj_lm1;
423 double result, best_result;
425 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
426 return 0;
427 if ( len1 & 1 ) {
428 PyErr_SetString(AudioopError, "Strings should be even-sized");
429 return 0;
431 len1 >>= 1;
433 if ( len1 < len2 ) {
434 PyErr_SetString(AudioopError, "Input sample should be longer");
435 return 0;
438 result = _sum2(cp1, cp1, len2);
440 best_result = result;
441 best_j = 0;
442 j = 0;
444 for ( j=1; j<=len1-len2; j++) {
445 aj_m1 = (double)cp1[j-1];
446 aj_lm1 = (double)cp1[j+len2-1];
448 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
450 if ( result > best_result ) {
451 best_result = result;
452 best_j = j;
457 return PyInt_FromLong(best_j);
460 static PyObject *
461 audioop_avgpp(PyObject *self, PyObject *args)
463 signed char *cp;
464 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
465 prevextreme = 0;
466 int i;
467 double avg = 0.0;
468 int diff, prevdiff, extremediff, nextreme = 0;
470 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
471 return 0;
472 if ( size != 1 && size != 2 && size != 4 ) {
473 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
474 return 0;
476 /* Compute first delta value ahead. Also automatically makes us
477 ** skip the first extreme value
479 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
480 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
481 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
482 if ( size == 1 ) val = (int)*CHARP(cp, size);
483 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
484 else if ( size == 4 ) val = (int)*LONGP(cp, size);
485 prevdiff = val - prevval;
487 for ( i=size; i<len; i+= size) {
488 if ( size == 1 ) val = (int)*CHARP(cp, i);
489 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
490 else if ( size == 4 ) val = (int)*LONGP(cp, i);
491 diff = val - prevval;
492 if ( diff*prevdiff < 0 ) {
493 /* Derivative changed sign. Compute difference to last
494 ** extreme value and remember.
496 if ( prevextremevalid ) {
497 extremediff = prevval - prevextreme;
498 if ( extremediff < 0 )
499 extremediff = -extremediff;
500 avg += extremediff;
501 nextreme++;
503 prevextremevalid = 1;
504 prevextreme = prevval;
506 prevval = val;
507 if ( diff != 0 )
508 prevdiff = diff;
510 if ( nextreme == 0 )
511 val = 0;
512 else
513 val = (int)(avg / (double)nextreme);
514 return PyInt_FromLong(val);
517 static PyObject *
518 audioop_maxpp(PyObject *self, PyObject *args)
520 signed char *cp;
521 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
522 prevextreme = 0;
523 int i;
524 int max = 0;
525 int diff, prevdiff, extremediff;
527 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
528 return 0;
529 if ( size != 1 && size != 2 && size != 4 ) {
530 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
531 return 0;
533 /* Compute first delta value ahead. Also automatically makes us
534 ** skip the first extreme value
536 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
537 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
538 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
539 if ( size == 1 ) val = (int)*CHARP(cp, size);
540 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
541 else if ( size == 4 ) val = (int)*LONGP(cp, size);
542 prevdiff = val - prevval;
544 for ( i=size; i<len; i+= size) {
545 if ( size == 1 ) val = (int)*CHARP(cp, i);
546 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
547 else if ( size == 4 ) val = (int)*LONGP(cp, i);
548 diff = val - prevval;
549 if ( diff*prevdiff < 0 ) {
550 /* Derivative changed sign. Compute difference to
551 ** last extreme value and remember.
553 if ( prevextremevalid ) {
554 extremediff = prevval - prevextreme;
555 if ( extremediff < 0 )
556 extremediff = -extremediff;
557 if ( extremediff > max )
558 max = extremediff;
560 prevextremevalid = 1;
561 prevextreme = prevval;
563 prevval = val;
564 if ( diff != 0 )
565 prevdiff = diff;
567 return PyInt_FromLong(max);
570 static PyObject *
571 audioop_cross(PyObject *self, PyObject *args)
573 signed char *cp;
574 int len, size, val = 0;
575 int i;
576 int prevval, ncross;
578 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
579 return 0;
580 if ( size != 1 && size != 2 && size != 4 ) {
581 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
582 return 0;
584 ncross = -1;
585 prevval = 17; /* Anything <> 0,1 */
586 for ( i=0; i<len; i+= size) {
587 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
588 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
589 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
590 val = val & 1;
591 if ( val != prevval ) ncross++;
592 prevval = val;
594 return PyInt_FromLong(ncross);
597 static PyObject *
598 audioop_mul(PyObject *self, PyObject *args)
600 signed char *cp, *ncp;
601 int len, size, val = 0;
602 double factor, fval, maxval;
603 PyObject *rv;
604 int i;
606 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
607 return 0;
609 if ( size == 1 ) maxval = (double) 0x7f;
610 else if ( size == 2 ) maxval = (double) 0x7fff;
611 else if ( size == 4 ) maxval = (double) 0x7fffffff;
612 else {
613 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
614 return 0;
617 rv = PyString_FromStringAndSize(NULL, len);
618 if ( rv == 0 )
619 return 0;
620 ncp = (signed char *)PyString_AsString(rv);
623 for ( i=0; i < len; i += size ) {
624 if ( size == 1 ) val = (int)*CHARP(cp, i);
625 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
626 else if ( size == 4 ) val = (int)*LONGP(cp, i);
627 fval = (double)val*factor;
628 if ( fval > maxval ) fval = maxval;
629 else if ( fval < -maxval ) fval = -maxval;
630 val = (int)fval;
631 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
632 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
633 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
635 return rv;
638 static PyObject *
639 audioop_tomono(PyObject *self, PyObject *args)
641 signed char *cp, *ncp;
642 int len, size, val1 = 0, val2 = 0;
643 double fac1, fac2, fval, maxval;
644 PyObject *rv;
645 int i;
647 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
648 return 0;
650 if ( size == 1 ) maxval = (double) 0x7f;
651 else if ( size == 2 ) maxval = (double) 0x7fff;
652 else if ( size == 4 ) maxval = (double) 0x7fffffff;
653 else {
654 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
655 return 0;
658 rv = PyString_FromStringAndSize(NULL, len/2);
659 if ( rv == 0 )
660 return 0;
661 ncp = (signed char *)PyString_AsString(rv);
664 for ( i=0; i < len; i += size*2 ) {
665 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
666 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
667 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
668 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
669 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
670 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
671 fval = (double)val1*fac1 + (double)val2*fac2;
672 if ( fval > maxval ) fval = maxval;
673 else if ( fval < -maxval ) fval = -maxval;
674 val1 = (int)fval;
675 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
676 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
677 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
679 return rv;
682 static PyObject *
683 audioop_tostereo(PyObject *self, PyObject *args)
685 signed char *cp, *ncp;
686 int len, size, val1, val2, val = 0;
687 double fac1, fac2, fval, maxval;
688 PyObject *rv;
689 int i;
691 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
692 return 0;
694 if ( size == 1 ) maxval = (double) 0x7f;
695 else if ( size == 2 ) maxval = (double) 0x7fff;
696 else if ( size == 4 ) maxval = (double) 0x7fffffff;
697 else {
698 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
699 return 0;
702 rv = PyString_FromStringAndSize(NULL, len*2);
703 if ( rv == 0 )
704 return 0;
705 ncp = (signed char *)PyString_AsString(rv);
708 for ( i=0; i < len; i += size ) {
709 if ( size == 1 ) val = (int)*CHARP(cp, i);
710 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
711 else if ( size == 4 ) val = (int)*LONGP(cp, i);
713 fval = (double)val*fac1;
714 if ( fval > maxval ) fval = maxval;
715 else if ( fval < -maxval ) fval = -maxval;
716 val1 = (int)fval;
718 fval = (double)val*fac2;
719 if ( fval > maxval ) fval = maxval;
720 else if ( fval < -maxval ) fval = -maxval;
721 val2 = (int)fval;
723 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
724 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
725 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
727 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
728 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
729 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
731 return rv;
734 static PyObject *
735 audioop_add(PyObject *self, PyObject *args)
737 signed char *cp1, *cp2, *ncp;
738 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
739 PyObject *rv;
740 int i;
742 if ( !PyArg_Parse(args, "(s#s#i)",
743 &cp1, &len1, &cp2, &len2, &size ) )
744 return 0;
746 if ( len1 != len2 ) {
747 PyErr_SetString(AudioopError, "Lengths should be the same");
748 return 0;
751 if ( size == 1 ) maxval = 0x7f;
752 else if ( size == 2 ) maxval = 0x7fff;
753 else if ( size == 4 ) maxval = 0x7fffffff;
754 else {
755 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
756 return 0;
759 rv = PyString_FromStringAndSize(NULL, len1);
760 if ( rv == 0 )
761 return 0;
762 ncp = (signed char *)PyString_AsString(rv);
764 for ( i=0; i < len1; i += size ) {
765 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
766 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
767 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
769 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
770 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
771 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
773 newval = val1 + val2;
774 /* truncate in case of overflow */
775 if (newval > maxval) newval = maxval;
776 else if (newval < -maxval) newval = -maxval;
777 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
778 newval = val1 > 0 ? maxval : - maxval;
780 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
781 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
782 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
784 return rv;
787 static PyObject *
788 audioop_bias(PyObject *self, PyObject *args)
790 signed char *cp, *ncp;
791 int len, size, val = 0;
792 PyObject *rv;
793 int i;
794 int bias;
796 if ( !PyArg_Parse(args, "(s#ii)",
797 &cp, &len, &size , &bias) )
798 return 0;
800 if ( size != 1 && size != 2 && size != 4) {
801 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
802 return 0;
805 rv = PyString_FromStringAndSize(NULL, len);
806 if ( rv == 0 )
807 return 0;
808 ncp = (signed char *)PyString_AsString(rv);
811 for ( i=0; i < len; i += size ) {
812 if ( size == 1 ) val = (int)*CHARP(cp, i);
813 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
814 else if ( size == 4 ) val = (int)*LONGP(cp, i);
816 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
817 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
818 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
820 return rv;
823 static PyObject *
824 audioop_reverse(PyObject *self, PyObject *args)
826 signed char *cp;
827 unsigned char *ncp;
828 int len, size, val = 0;
829 PyObject *rv;
830 int i, j;
832 if ( !PyArg_Parse(args, "(s#i)",
833 &cp, &len, &size) )
834 return 0;
836 if ( size != 1 && size != 2 && size != 4 ) {
837 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
838 return 0;
841 rv = PyString_FromStringAndSize(NULL, len);
842 if ( rv == 0 )
843 return 0;
844 ncp = (unsigned char *)PyString_AsString(rv);
846 for ( i=0; i < len; i += size ) {
847 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
848 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
849 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
851 j = len - i - size;
853 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
854 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
855 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
857 return rv;
860 static PyObject *
861 audioop_lin2lin(PyObject *self, PyObject *args)
863 signed char *cp;
864 unsigned char *ncp;
865 int len, size, size2, val = 0;
866 PyObject *rv;
867 int i, j;
869 if ( !PyArg_Parse(args, "(s#ii)",
870 &cp, &len, &size, &size2) )
871 return 0;
873 if ( (size != 1 && size != 2 && size != 4) ||
874 (size2 != 1 && size2 != 2 && size2 != 4)) {
875 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
876 return 0;
879 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
880 if ( rv == 0 )
881 return 0;
882 ncp = (unsigned char *)PyString_AsString(rv);
884 for ( i=0, j=0; i < len; i += size, j += size2 ) {
885 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
886 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
887 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
889 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
890 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
891 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
893 return rv;
896 static int
897 gcd(int a, int b)
899 while (b > 0) {
900 int tmp = a % b;
901 a = b;
902 b = tmp;
904 return a;
907 static PyObject *
908 audioop_ratecv(PyObject *self, PyObject *args)
910 char *cp, *ncp;
911 int len, size, nchannels, inrate, outrate, weightA, weightB;
912 int chan, d, *prev_i, *cur_i, cur_o;
913 PyObject *state, *samps, *str, *rv = NULL;
915 weightA = 1;
916 weightB = 0;
917 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
918 &inrate, &outrate, &state, &weightA, &weightB))
919 return NULL;
920 if (size != 1 && size != 2 && size != 4) {
921 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
922 return NULL;
924 if (nchannels < 1) {
925 PyErr_SetString(AudioopError, "# of channels should be >= 1");
926 return NULL;
928 if (weightA < 1 || weightB < 0) {
929 PyErr_SetString(AudioopError,
930 "weightA should be >= 1, weightB should be >= 0");
931 return NULL;
933 if (len % (size * nchannels) != 0) {
934 PyErr_SetString(AudioopError, "not a whole number of frames");
935 return NULL;
937 if (inrate <= 0 || outrate <= 0) {
938 PyErr_SetString(AudioopError, "sampling rate not > 0");
939 return NULL;
941 /* divide inrate and outrate by their greatest common divisor */
942 d = gcd(inrate, outrate);
943 inrate /= d;
944 outrate /= d;
946 prev_i = (int *) malloc(nchannels * sizeof(int));
947 cur_i = (int *) malloc(nchannels * sizeof(int));
948 len /= size * nchannels; /* # of frames */
949 if (prev_i == NULL || cur_i == NULL) {
950 (void) PyErr_NoMemory();
951 goto exit;
954 if (state == Py_None) {
955 d = -outrate;
956 for (chan = 0; chan < nchannels; chan++)
957 prev_i[chan] = cur_i[chan] = 0;
958 } else {
959 if (!PyArg_ParseTuple(state,
960 "iO!;audioop.ratecv: illegal state argument",
961 &d, &PyTuple_Type, &samps))
962 goto exit;
963 if (PyTuple_Size(samps) != nchannels) {
964 PyErr_SetString(AudioopError,
965 "illegal state argument");
966 goto exit;
968 for (chan = 0; chan < nchannels; chan++) {
969 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
970 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
971 goto exit;
974 str = PyString_FromStringAndSize(
975 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
976 if (str == NULL)
977 goto exit;
978 ncp = PyString_AsString(str);
980 for (;;) {
981 while (d < 0) {
982 if (len == 0) {
983 samps = PyTuple_New(nchannels);
984 for (chan = 0; chan < nchannels; chan++)
985 PyTuple_SetItem(samps, chan,
986 Py_BuildValue("(ii)",
987 prev_i[chan],
988 cur_i[chan]));
989 if (PyErr_Occurred())
990 goto exit;
991 len = ncp - PyString_AsString(str);
992 if (len == 0) {
993 /*don't want to resize to zero length*/
994 rv = PyString_FromStringAndSize("", 0);
995 Py_DECREF(str);
996 str = rv;
997 } else if (_PyString_Resize(&str, len) < 0)
998 goto exit;
999 rv = Py_BuildValue("(O(iO))", str, d, samps);
1000 Py_DECREF(samps);
1001 Py_DECREF(str);
1002 goto exit; /* return rv */
1004 for (chan = 0; chan < nchannels; chan++) {
1005 prev_i[chan] = cur_i[chan];
1006 if (size == 1)
1007 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1008 else if (size == 2)
1009 cur_i[chan] = (int)*SHORTP(cp, 0);
1010 else if (size == 4)
1011 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1012 cp += size;
1013 /* implements a simple digital filter */
1014 cur_i[chan] =
1015 (weightA * cur_i[chan] +
1016 weightB * prev_i[chan]) /
1017 (weightA + weightB);
1019 len--;
1020 d += outrate;
1022 while (d >= 0) {
1023 for (chan = 0; chan < nchannels; chan++) {
1024 cur_o = (prev_i[chan] * d +
1025 cur_i[chan] * (outrate - d)) /
1026 outrate;
1027 if (size == 1)
1028 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1029 else if (size == 2)
1030 *SHORTP(ncp, 0) = (short)(cur_o);
1031 else if (size == 4)
1032 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1033 ncp += size;
1035 d -= inrate;
1038 exit:
1039 if (prev_i != NULL)
1040 free(prev_i);
1041 if (cur_i != NULL)
1042 free(cur_i);
1043 return rv;
1046 static PyObject *
1047 audioop_lin2ulaw(PyObject *self, PyObject *args)
1049 signed char *cp;
1050 unsigned char *ncp;
1051 int len, size, val = 0;
1052 PyObject *rv;
1053 int i;
1055 if ( !PyArg_Parse(args, "(s#i)",
1056 &cp, &len, &size) )
1057 return 0;
1059 if ( size != 1 && size != 2 && size != 4) {
1060 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1061 return 0;
1064 rv = PyString_FromStringAndSize(NULL, len/size);
1065 if ( rv == 0 )
1066 return 0;
1067 ncp = (unsigned char *)PyString_AsString(rv);
1069 for ( i=0; i < len; i += size ) {
1070 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1071 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1072 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1074 *ncp++ = st_linear_to_ulaw(val);
1076 return rv;
1079 static PyObject *
1080 audioop_ulaw2lin(PyObject *self, PyObject *args)
1082 unsigned char *cp;
1083 unsigned char cval;
1084 signed char *ncp;
1085 int len, size, val;
1086 PyObject *rv;
1087 int i;
1089 if ( !PyArg_Parse(args, "(s#i)",
1090 &cp, &len, &size) )
1091 return 0;
1093 if ( size != 1 && size != 2 && size != 4) {
1094 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1095 return 0;
1098 rv = PyString_FromStringAndSize(NULL, len*size);
1099 if ( rv == 0 )
1100 return 0;
1101 ncp = (signed char *)PyString_AsString(rv);
1103 for ( i=0; i < len*size; i += size ) {
1104 cval = *cp++;
1105 val = st_ulaw_to_linear(cval);
1107 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1108 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1109 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1111 return rv;
1114 static PyObject *
1115 audioop_lin2adpcm(PyObject *self, PyObject *args)
1117 signed char *cp;
1118 signed char *ncp;
1119 int len, size, val = 0, step, valpred, delta,
1120 index, sign, vpdiff, diff;
1121 PyObject *rv, *state, *str;
1122 int i, outputbuffer = 0, bufferstep;
1124 if ( !PyArg_Parse(args, "(s#iO)",
1125 &cp, &len, &size, &state) )
1126 return 0;
1129 if ( size != 1 && size != 2 && size != 4) {
1130 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1131 return 0;
1134 str = PyString_FromStringAndSize(NULL, len/(size*2));
1135 if ( str == 0 )
1136 return 0;
1137 ncp = (signed char *)PyString_AsString(str);
1139 /* Decode state, should have (value, step) */
1140 if ( state == Py_None ) {
1141 /* First time, it seems. Set defaults */
1142 valpred = 0;
1143 step = 7;
1144 index = 0;
1145 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1146 return 0;
1148 step = stepsizeTable[index];
1149 bufferstep = 1;
1151 for ( i=0; i < len; i += size ) {
1152 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1153 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1154 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1156 /* Step 1 - compute difference with previous value */
1157 diff = val - valpred;
1158 sign = (diff < 0) ? 8 : 0;
1159 if ( sign ) diff = (-diff);
1161 /* Step 2 - Divide and clamp */
1162 /* Note:
1163 ** This code *approximately* computes:
1164 ** delta = diff*4/step;
1165 ** vpdiff = (delta+0.5)*step/4;
1166 ** but in shift step bits are dropped. The net result of this
1167 ** is that even if you have fast mul/div hardware you cannot
1168 ** put it to good use since the fixup would be too expensive.
1170 delta = 0;
1171 vpdiff = (step >> 3);
1173 if ( diff >= step ) {
1174 delta = 4;
1175 diff -= step;
1176 vpdiff += step;
1178 step >>= 1;
1179 if ( diff >= step ) {
1180 delta |= 2;
1181 diff -= step;
1182 vpdiff += step;
1184 step >>= 1;
1185 if ( diff >= step ) {
1186 delta |= 1;
1187 vpdiff += step;
1190 /* Step 3 - Update previous value */
1191 if ( sign )
1192 valpred -= vpdiff;
1193 else
1194 valpred += vpdiff;
1196 /* Step 4 - Clamp previous value to 16 bits */
1197 if ( valpred > 32767 )
1198 valpred = 32767;
1199 else if ( valpred < -32768 )
1200 valpred = -32768;
1202 /* Step 5 - Assemble value, update index and step values */
1203 delta |= sign;
1205 index += indexTable[delta];
1206 if ( index < 0 ) index = 0;
1207 if ( index > 88 ) index = 88;
1208 step = stepsizeTable[index];
1210 /* Step 6 - Output value */
1211 if ( bufferstep ) {
1212 outputbuffer = (delta << 4) & 0xf0;
1213 } else {
1214 *ncp++ = (delta & 0x0f) | outputbuffer;
1216 bufferstep = !bufferstep;
1218 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1219 Py_DECREF(str);
1220 return rv;
1223 static PyObject *
1224 audioop_adpcm2lin(PyObject *self, PyObject *args)
1226 signed char *cp;
1227 signed char *ncp;
1228 int len, size, valpred, step, delta, index, sign, vpdiff;
1229 PyObject *rv, *str, *state;
1230 int i, inputbuffer = 0, bufferstep;
1232 if ( !PyArg_Parse(args, "(s#iO)",
1233 &cp, &len, &size, &state) )
1234 return 0;
1236 if ( size != 1 && size != 2 && size != 4) {
1237 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1238 return 0;
1241 /* Decode state, should have (value, step) */
1242 if ( state == Py_None ) {
1243 /* First time, it seems. Set defaults */
1244 valpred = 0;
1245 step = 7;
1246 index = 0;
1247 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1248 return 0;
1250 str = PyString_FromStringAndSize(NULL, len*size*2);
1251 if ( str == 0 )
1252 return 0;
1253 ncp = (signed char *)PyString_AsString(str);
1255 step = stepsizeTable[index];
1256 bufferstep = 0;
1258 for ( i=0; i < len*size*2; i += size ) {
1259 /* Step 1 - get the delta value and compute next index */
1260 if ( bufferstep ) {
1261 delta = inputbuffer & 0xf;
1262 } else {
1263 inputbuffer = *cp++;
1264 delta = (inputbuffer >> 4) & 0xf;
1267 bufferstep = !bufferstep;
1269 /* Step 2 - Find new index value (for later) */
1270 index += indexTable[delta];
1271 if ( index < 0 ) index = 0;
1272 if ( index > 88 ) index = 88;
1274 /* Step 3 - Separate sign and magnitude */
1275 sign = delta & 8;
1276 delta = delta & 7;
1278 /* Step 4 - Compute difference and new predicted value */
1280 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1281 ** in adpcm_coder.
1283 vpdiff = step >> 3;
1284 if ( delta & 4 ) vpdiff += step;
1285 if ( delta & 2 ) vpdiff += step>>1;
1286 if ( delta & 1 ) vpdiff += step>>2;
1288 if ( sign )
1289 valpred -= vpdiff;
1290 else
1291 valpred += vpdiff;
1293 /* Step 5 - clamp output value */
1294 if ( valpred > 32767 )
1295 valpred = 32767;
1296 else if ( valpred < -32768 )
1297 valpred = -32768;
1299 /* Step 6 - Update step value */
1300 step = stepsizeTable[index];
1302 /* Step 6 - Output value */
1303 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1304 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1305 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1308 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1309 Py_DECREF(str);
1310 return rv;
1313 static PyMethodDef audioop_methods[] = {
1314 { "max", audioop_max },
1315 { "minmax", audioop_minmax },
1316 { "avg", audioop_avg },
1317 { "maxpp", audioop_maxpp },
1318 { "avgpp", audioop_avgpp },
1319 { "rms", audioop_rms },
1320 { "findfit", audioop_findfit },
1321 { "findmax", audioop_findmax },
1322 { "findfactor", audioop_findfactor },
1323 { "cross", audioop_cross },
1324 { "mul", audioop_mul },
1325 { "add", audioop_add },
1326 { "bias", audioop_bias },
1327 { "ulaw2lin", audioop_ulaw2lin },
1328 { "lin2ulaw", audioop_lin2ulaw },
1329 { "lin2lin", audioop_lin2lin },
1330 { "adpcm2lin", audioop_adpcm2lin },
1331 { "lin2adpcm", audioop_lin2adpcm },
1332 { "tomono", audioop_tomono },
1333 { "tostereo", audioop_tostereo },
1334 { "getsample", audioop_getsample },
1335 { "reverse", audioop_reverse },
1336 { "ratecv", audioop_ratecv, 1 },
1337 { 0, 0 }
1340 DL_EXPORT(void)
1341 initaudioop(void)
1343 PyObject *m, *d;
1344 m = Py_InitModule("audioop", audioop_methods);
1345 d = PyModule_GetDict(m);
1346 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1347 if (AudioopError != NULL)
1348 PyDict_SetItemString(d,"error",AudioopError);