blob: cfb97f2904e96872827732d61d56f7a170800ec5 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum34679b71993-01-26 13:33:44 +00003Amsterdam, The Netherlands.
Guido van Rossumb66efa01992-06-01 16:01:24 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossumb6775db1994-08-01 11:34:53 +000025/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +000026
Guido van Rossumb66efa01992-06-01 16:01:24 +000027#include "allobjects.h"
28#include "modsupport.h"
29
Guido van Rossumb6775db1994-08-01 11:34:53 +000030#if defined(__CHAR_UNSIGNED__) && defined(signed)
31!ERROR!; READ THE SOURCE FILE!;
32/* This module currently does not work on systems where only unsigned
33 characters are available. Take it out of Setup. Sorry. */
34#endif
35
36#include <math.h>
37
Jack Jansena90805f1993-02-17 14:29:28 +000038/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000039** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
40
41#define MINLIN -32768
42#define MAXLIN 32767
43#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; else if ( x > MAXLIN ) x = MAXLIN; } while ( 0 )
44
45unsigned char st_linear_to_ulaw( /* int sample */ );
46
47/*
48** This macro converts from ulaw to 16 bit linear, faster.
49**
50** Jef Poskanzer
51** 23 October 1989
52**
53** Input: 8 bit ulaw sample
54** Output: signed 16 bit linear sample
55*/
56#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
57
58static int ulaw_table[256] = {
59 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
60 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
61 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
62 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
63 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
64 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
65 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
66 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
67 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
68 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
69 -876, -844, -812, -780, -748, -716, -684, -652,
70 -620, -588, -556, -524, -492, -460, -428, -396,
71 -372, -356, -340, -324, -308, -292, -276, -260,
72 -244, -228, -212, -196, -180, -164, -148, -132,
73 -120, -112, -104, -96, -88, -80, -72, -64,
74 -56, -48, -40, -32, -24, -16, -8, 0,
75 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
76 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
77 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
78 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
79 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
80 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
81 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
82 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
83 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
84 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
85 876, 844, 812, 780, 748, 716, 684, 652,
86 620, 588, 556, 524, 492, 460, 428, 396,
87 372, 356, 340, 324, 308, 292, 276, 260,
88 244, 228, 212, 196, 180, 164, 148, 132,
89 120, 112, 104, 96, 88, 80, 72, 64,
90 56, 48, 40, 32, 24, 16, 8, 0 };
91
92#define ZEROTRAP /* turn on the trap as per the MIL-STD */
93#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
94#define CLIP 32635
95
96unsigned char
97st_linear_to_ulaw( sample )
98int sample;
99 {
100 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
101 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
102 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
103 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
104 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
105 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
106 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
107 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
114 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
115 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
116 int sign, exponent, mantissa;
117 unsigned char ulawbyte;
118
119 /* Get the sample into sign-magnitude. */
120 sign = (sample >> 8) & 0x80; /* set aside the sign */
121 if ( sign != 0 ) sample = -sample; /* get magnitude */
122 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
123
124 /* Convert from 16 bit linear to ulaw. */
125 sample = sample + BIAS;
126 exponent = exp_lut[( sample >> 7 ) & 0xFF];
127 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
128 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
129#ifdef ZEROTRAP
130 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
131#endif
132
133 return ulawbyte;
134 }
135/* End of code taken from sox */
136
Guido van Rossumb64e6351992-07-06 14:21:56 +0000137/* ADPCM-3 step variation table */
Guido van Rossum8e7a0f01992-06-23 15:23:57 +0000138static float newstep[5] = { 0.8, 0.9, 1.0, 1.75, 1.75 };
139
Guido van Rossumb64e6351992-07-06 14:21:56 +0000140/* Intel ADPCM step variation table */
141static int indexTable[16] = {
142 -1, -1, -1, -1, 2, 4, 6, 8,
143 -1, -1, -1, -1, 2, 4, 6, 8,
144};
145
146static int stepsizeTable[89] = {
147 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
148 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
149 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
150 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
151 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
152 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
153 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
154 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
155 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
156};
157
Guido van Rossumb66efa01992-06-01 16:01:24 +0000158#define CHARP(cp, i) ((signed char *)(cp+i))
159#define SHORTP(cp, i) ((short *)(cp+i))
160#define LONGP(cp, i) ((long *)(cp+i))
161
162
163
164static object *AudioopError;
165
166static object *
167audioop_getsample(self, args)
168 object *self;
169 object *args;
170{
171 signed char *cp;
172 int len, size, val;
173 int i;
174
175 if ( !getargs(args, "(s#ii)", &cp, &len, &size, &i) )
176 return 0;
177 if ( size != 1 && size != 2 && size != 4 ) {
178 err_setstr(AudioopError, "Size should be 1, 2 or 4");
179 return 0;
180 }
181 if ( i < 0 || i >= len/size ) {
182 err_setstr(AudioopError, "Index out of range");
183 return 0;
184 }
185 if ( size == 1 ) val = (int)*CHARP(cp, i);
186 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
187 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
188 return newintobject(val);
189}
190
191static object *
192audioop_max(self, args)
193 object *self;
194 object *args;
195{
196 signed char *cp;
197 int len, size, val;
198 int i;
199 int max = 0;
200
201 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
202 return 0;
203 if ( size != 1 && size != 2 && size != 4 ) {
204 err_setstr(AudioopError, "Size should be 1, 2 or 4");
205 return 0;
206 }
207 for ( i=0; i<len; i+= size) {
208 if ( size == 1 ) val = (int)*CHARP(cp, i);
209 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
210 else if ( size == 4 ) val = (int)*LONGP(cp, i);
211 if ( val < 0 ) val = (-val);
212 if ( val > max ) max = val;
213 }
214 return newintobject(max);
215}
216
217static object *
218audioop_avg(self, args)
219 object *self;
220 object *args;
221{
222 signed char *cp;
223 int len, size, val;
224 int i;
225 float avg = 0.0;
226
227 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
228 return 0;
229 if ( size != 1 && size != 2 && size != 4 ) {
230 err_setstr(AudioopError, "Size should be 1, 2 or 4");
231 return 0;
232 }
233 for ( i=0; i<len; i+= size) {
234 if ( size == 1 ) val = (int)*CHARP(cp, i);
235 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
236 else if ( size == 4 ) val = (int)*LONGP(cp, i);
237 avg += val;
238 }
239 if ( len == 0 )
240 val = 0;
241 else
242 val = (int)(avg / (float)(len/size));
243 return newintobject(val);
244}
245
246static object *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000247audioop_rms(self, args)
248 object *self;
249 object *args;
250{
251 signed char *cp;
252 int len, size, val;
253 int i;
254 float sum_squares = 0.0;
255
256 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
257 return 0;
258 if ( size != 1 && size != 2 && size != 4 ) {
259 err_setstr(AudioopError, "Size should be 1, 2 or 4");
260 return 0;
261 }
262 for ( i=0; i<len; i+= size) {
263 if ( size == 1 ) val = (int)*CHARP(cp, i);
264 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
265 else if ( size == 4 ) val = (int)*LONGP(cp, i);
266 sum_squares += (float)val*(float)val;
267 }
268 if ( len == 0 )
269 val = 0;
270 else
271 val = (int)sqrt(sum_squares / (float)(len/size));
272 return newintobject(val);
273}
274
Jack Jansena90805f1993-02-17 14:29:28 +0000275double _sum2(a, b, len)
276 short *a;
277 short *b;
278 int len;
279{
280 int i;
281 double sum = 0.0;
282
283 for( i=0; i<len; i++) {
284 sum = sum + (double)a[i]*(double)b[i];
285 }
286 return sum;
287}
288
289/*
290** Findfit tries to locate a sample within another sample. Its main use
291** is in echo-cancellation (to find the feedback of the output signal in
292** the input signal).
293** The method used is as follows:
294**
295** let R be the reference signal (length n) and A the input signal (length N)
296** with N > n, and let all sums be over i from 0 to n-1.
297**
298** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
299** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
300** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
301**
302** Next, we compute the relative distance between the original signal and
303** the modified signal and minimize that over j:
304** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
305** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
306**
307** In the code variables correspond as follows:
308** cp1 A
309** cp2 R
310** len1 N
311** len2 n
312** aj_m1 A[j-1]
313** aj_lm1 A[j+n-1]
314** sum_ri_2 sum(R[i]^2)
315** sum_aij_2 sum(A[i+j]^2)
316** sum_aij_ri sum(A[i+j]R[i])
317**
318** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
319** is completely recalculated each step.
320*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000321static object *
Jack Jansena90805f1993-02-17 14:29:28 +0000322audioop_findfit(self, args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000323 object *self;
324 object *args;
325{
Jack Jansena90805f1993-02-17 14:29:28 +0000326 short *cp1, *cp2;
327 int len1, len2;
328 int j, best_j;
329 double aj_m1, aj_lm1;
330 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000331
Jack Jansena90805f1993-02-17 14:29:28 +0000332 if ( !getargs(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000333 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000334 if ( len1 & 1 || len2 & 1 ) {
335 err_setstr(AudioopError, "Strings should be even-sized");
336 return 0;
337 }
338 len1 >>= 1;
339 len2 >>= 1;
340
341 if ( len1 < len2 ) {
342 err_setstr(AudioopError, "First sample should be longer");
343 return 0;
344 }
345 sum_ri_2 = _sum2(cp2, cp2, len2);
346 sum_aij_2 = _sum2(cp1, cp1, len2);
347 sum_aij_ri = _sum2(cp1, cp2, len2);
348
349 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
350
351 best_result = result;
352 best_j = 0;
353 j = 0;
354
355 for ( j=1; j<=len1-len2; j++) {
356 aj_m1 = (double)cp1[j-1];
357 aj_lm1 = (double)cp1[j+len2-1];
358
359 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
360 sum_aij_ri = _sum2(cp1+j, cp2, len2);
361
362 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
363
364 if ( result < best_result ) {
365 best_result = result;
366 best_j = j;
367 }
368
369 }
370
371 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
372
373 return mkvalue("(if)", best_j, factor);
374}
375
376/*
377** findfactor finds a factor f so that the energy in A-fB is minimal.
378** See the comment for findfit for details.
379*/
380static object *
381audioop_findfactor(self, args)
382 object *self;
383 object *args;
384{
385 short *cp1, *cp2;
386 int len1, len2;
387 double sum_ri_2, sum_aij_ri, result;
388
389 if ( !getargs(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
390 return 0;
391 if ( len1 & 1 || len2 & 1 ) {
392 err_setstr(AudioopError, "Strings should be even-sized");
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000393 return 0;
394 }
395 if ( len1 != len2 ) {
396 err_setstr(AudioopError, "Samples should be same size");
397 return 0;
398 }
Jack Jansena90805f1993-02-17 14:29:28 +0000399 len2 >>= 1;
400 sum_ri_2 = _sum2(cp2, cp2, len2);
401 sum_aij_ri = _sum2(cp1, cp2, len2);
402
403 result = sum_aij_ri / sum_ri_2;
404
405 return newfloatobject(result);
406}
407
408/*
409** findmax returns the index of the n-sized segment of the input sample
410** that contains the most energy.
411*/
412static object *
413audioop_findmax(self, args)
414 object *self;
415 object *args;
416{
417 short *cp1;
418 int len1, len2;
419 int j, best_j;
420 double aj_m1, aj_lm1;
421 double result, best_result;
422
423 if ( !getargs(args, "(s#i)", &cp1, &len1, &len2) )
424 return 0;
425 if ( len1 & 1 ) {
426 err_setstr(AudioopError, "Strings should be even-sized");
427 return 0;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000428 }
Jack Jansena90805f1993-02-17 14:29:28 +0000429 len1 >>= 1;
430
431 if ( len1 < len2 ) {
432 err_setstr(AudioopError, "Input sample should be longer");
433 return 0;
434 }
435
436 result = _sum2(cp1, cp1, len2);
437
438 best_result = result;
439 best_j = 0;
440 j = 0;
441
442 for ( j=1; j<=len1-len2; j++) {
443 aj_m1 = (double)cp1[j-1];
444 aj_lm1 = (double)cp1[j+len2-1];
445
446 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
447
448 if ( result > best_result ) {
449 best_result = result;
450 best_j = j;
451 }
452
453 }
454
455 return newintobject(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000456}
457
458static object *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000459audioop_avgpp(self, args)
460 object *self;
461 object *args;
462{
463 signed char *cp;
464 int len, size, val, prevval, prevextremevalid = 0, prevextreme;
465 int i;
466 float avg = 0.0;
467 int diff, prevdiff, extremediff, nextreme = 0;
468
469 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
470 return 0;
471 if ( size != 1 && size != 2 && size != 4 ) {
472 err_setstr(AudioopError, "Size should be 1, 2 or 4");
473 return 0;
474 }
475 /* Compute first delta value ahead. Also automatically makes us
476 ** skip the first extreme value
477 */
478 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
479 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
480 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
481 if ( size == 1 ) val = (int)*CHARP(cp, size);
482 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
483 else if ( size == 4 ) val = (int)*LONGP(cp, size);
484 prevdiff = val - prevval;
485
486 for ( i=size; i<len; i+= size) {
487 if ( size == 1 ) val = (int)*CHARP(cp, i);
488 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
489 else if ( size == 4 ) val = (int)*LONGP(cp, i);
490 diff = val - prevval;
491 if ( diff*prevdiff < 0 ) {
492 /* Derivative changed sign. Compute difference to last extreme
493 ** value and remember.
494 */
495 if ( prevextremevalid ) {
496 extremediff = prevval - prevextreme;
497 if ( extremediff < 0 )
498 extremediff = -extremediff;
499 avg += extremediff;
500 nextreme++;
501 }
502 prevextremevalid = 1;
503 prevextreme = prevval;
504 }
505 prevval = val;
506 if ( diff != 0 )
507 prevdiff = diff;
508 }
509 if ( nextreme == 0 )
510 val = 0;
511 else
512 val = (int)(avg / (float)nextreme);
513 return newintobject(val);
514}
515
516static object *
517audioop_maxpp(self, args)
518 object *self;
519 object *args;
520{
521 signed char *cp;
522 int len, size, val, prevval, prevextremevalid = 0, prevextreme;
523 int i;
524 int max = 0;
525 int diff, prevdiff, extremediff;
526
527 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
528 return 0;
529 if ( size != 1 && size != 2 && size != 4 ) {
530 err_setstr(AudioopError, "Size should be 1, 2 or 4");
531 return 0;
532 }
533 /* Compute first delta value ahead. Also automatically makes us
534 ** skip the first extreme value
535 */
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;
543
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 last extreme
551 ** value and remember.
552 */
553 if ( prevextremevalid ) {
554 extremediff = prevval - prevextreme;
555 if ( extremediff < 0 )
556 extremediff = -extremediff;
557 if ( extremediff > max )
558 max = extremediff;
559 }
560 prevextremevalid = 1;
561 prevextreme = prevval;
562 }
563 prevval = val;
564 if ( diff != 0 )
565 prevdiff = diff;
566 }
567 return newintobject(max);
568}
569
570static object *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000571audioop_cross(self, args)
572 object *self;
573 object *args;
574{
575 signed char *cp;
576 int len, size, val;
577 int i;
578 int cross, prevval, ncross;
579
580 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
581 return 0;
582 if ( size != 1 && size != 2 && size != 4 ) {
583 err_setstr(AudioopError, "Size should be 1, 2 or 4");
584 return 0;
585 }
586 ncross = -1;
587 prevval = 17; /* Anything <> 0,1 */
588 for ( i=0; i<len; i+= size) {
589 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
590 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
591 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
592 val = val & 1;
593 if ( val != prevval ) ncross++;
594 prevval = val;
595 }
596 return newintobject(ncross);
597}
598
599static object *
600audioop_mul(self, args)
601 object *self;
602 object *args;
603{
604 signed char *cp, *ncp;
605 int len, size, val;
606 double factor, fval, maxval;
607 object *rv;
608 int i;
609
610 if ( !getargs(args, "(s#id)", &cp, &len, &size, &factor ) )
611 return 0;
612
613 if ( size == 1 ) maxval = (double) 0x7f;
614 else if ( size == 2 ) maxval = (double) 0x7fff;
615 else if ( size == 4 ) maxval = (double) 0x7fffffff;
616 else {
617 err_setstr(AudioopError, "Size should be 1, 2 or 4");
618 return 0;
619 }
620
621 rv = newsizedstringobject(NULL, len);
622 if ( rv == 0 )
623 return 0;
624 ncp = (signed char *)getstringvalue(rv);
625
626
627 for ( i=0; i < len; i += size ) {
628 if ( size == 1 ) val = (int)*CHARP(cp, i);
629 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
630 else if ( size == 4 ) val = (int)*LONGP(cp, i);
631 fval = (double)val*factor;
632 if ( fval > maxval ) fval = maxval;
633 else if ( fval < -maxval ) fval = -maxval;
634 val = (int)fval;
635 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
636 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
637 else if ( size == 4 ) *LONGP(ncp, i) = (long)val;
638 }
639 return rv;
640}
641
642static object *
643audioop_tomono(self, args)
644 object *self;
645 object *args;
646{
647 signed char *cp, *ncp;
648 int len, size, val1, val2;
649 double fac1, fac2, fval, maxval;
650 object *rv;
651 int i;
652
653 if ( !getargs(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
654 return 0;
655
656 if ( size == 1 ) maxval = (double) 0x7f;
657 else if ( size == 2 ) maxval = (double) 0x7fff;
658 else if ( size == 4 ) maxval = (double) 0x7fffffff;
659 else {
660 err_setstr(AudioopError, "Size should be 1, 2 or 4");
661 return 0;
662 }
663
664 rv = newsizedstringobject(NULL, len/2);
665 if ( rv == 0 )
666 return 0;
667 ncp = (signed char *)getstringvalue(rv);
668
669
670 for ( i=0; i < len; i += size*2 ) {
671 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
672 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
673 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
674 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
675 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
676 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
677 fval = (double)val1*fac1 + (double)val2*fac2;
678 if ( fval > maxval ) fval = maxval;
679 else if ( fval < -maxval ) fval = -maxval;
680 val1 = (int)fval;
681 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
682 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
683 else if ( size == 4 ) *LONGP(ncp, i/2)= (long)val1;
684 }
685 return rv;
686}
687
688static object *
689audioop_tostereo(self, args)
690 object *self;
691 object *args;
692{
693 signed char *cp, *ncp;
694 int len, size, val1, val2, val;
695 double fac1, fac2, fval, maxval;
696 object *rv;
697 int i;
698
699 if ( !getargs(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
700 return 0;
701
702 if ( size == 1 ) maxval = (double) 0x7f;
703 else if ( size == 2 ) maxval = (double) 0x7fff;
704 else if ( size == 4 ) maxval = (double) 0x7fffffff;
705 else {
706 err_setstr(AudioopError, "Size should be 1, 2 or 4");
707 return 0;
708 }
709
710 rv = newsizedstringobject(NULL, len*2);
711 if ( rv == 0 )
712 return 0;
713 ncp = (signed char *)getstringvalue(rv);
714
715
716 for ( i=0; i < len; i += size ) {
717 if ( size == 1 ) val = (int)*CHARP(cp, i);
718 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
719 else if ( size == 4 ) val = (int)*LONGP(cp, i);
720
721 fval = (double)val*fac1;
722 if ( fval > maxval ) fval = maxval;
723 else if ( fval < -maxval ) fval = -maxval;
724 val1 = (int)fval;
725
726 fval = (double)val*fac2;
727 if ( fval > maxval ) fval = maxval;
728 else if ( fval < -maxval ) fval = -maxval;
729 val2 = (int)fval;
730
731 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
732 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
733 else if ( size == 4 ) *LONGP(ncp, i*2) = (long)val1;
734
735 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
736 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
737 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (long)val2;
738 }
739 return rv;
740}
741
742static object *
743audioop_add(self, args)
744 object *self;
745 object *args;
746{
747 signed char *cp1, *cp2, *ncp;
748 int len1, len2, size, val1, val2;
749 object *rv;
750 int i;
751
752 if ( !getargs(args, "(s#s#i)",
753 &cp1, &len1, &cp2, &len2, &size ) )
754 return 0;
755
756 if ( len1 != len2 ) {
757 err_setstr(AudioopError, "Lengths should be the same");
758 return 0;
759 }
760
761 if ( size != 1 && size != 2 && size != 4) {
762 err_setstr(AudioopError, "Size should be 1, 2 or 4");
763 return 0;
764 }
765
766 rv = newsizedstringobject(NULL, len1);
767 if ( rv == 0 )
768 return 0;
769 ncp = (signed char *)getstringvalue(rv);
770
771
772 for ( i=0; i < len1; i += size ) {
773 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
774 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
775 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
776
777 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
778 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
779 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
780
781 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val1+val2);
782 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val1+val2);
783 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val1+val2);
784 }
785 return rv;
786}
787
788static object *
789audioop_bias(self, args)
790 object *self;
791 object *args;
792{
793 signed char *cp, *ncp;
794 int len, size, val;
795 object *rv;
796 int i;
797 int bias;
798
799 if ( !getargs(args, "(s#ii)",
800 &cp, &len, &size , &bias) )
801 return 0;
802
803 if ( size != 1 && size != 2 && size != 4) {
804 err_setstr(AudioopError, "Size should be 1, 2 or 4");
805 return 0;
806 }
807
808 rv = newsizedstringobject(NULL, len);
809 if ( rv == 0 )
810 return 0;
811 ncp = (signed char *)getstringvalue(rv);
812
813
814 for ( i=0; i < len; i += size ) {
815 if ( size == 1 ) val = (int)*CHARP(cp, i);
816 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
817 else if ( size == 4 ) val = (int)*LONGP(cp, i);
818
819 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
820 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
821 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val+bias);
822 }
823 return rv;
824}
825
826static object *
Jack Jansen337b20e1993-02-23 13:39:57 +0000827audioop_reverse(self, args)
828 object *self;
829 object *args;
830{
831 signed char *cp;
832 unsigned char *ncp;
833 int len, size, val;
834 object *rv;
835 int i, j;
836
837 if ( !getargs(args, "(s#i)",
838 &cp, &len, &size) )
839 return 0;
840
841 if ( size != 1 && size != 2 && size != 4 ) {
842 err_setstr(AudioopError, "Size should be 1, 2 or 4");
843 return 0;
844 }
845
846 rv = newsizedstringobject(NULL, len);
847 if ( rv == 0 )
848 return 0;
849 ncp = (unsigned char *)getstringvalue(rv);
850
851 for ( i=0; i < len; i += size ) {
852 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
853 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
854 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
855
856 j = len - i - size;
857
858 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
859 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
860 else if ( size == 4 ) *LONGP(ncp, j) = (long)(val<<16);
861 }
862 return rv;
863}
864
865static object *
Jack Jansena90805f1993-02-17 14:29:28 +0000866audioop_lin2lin(self, args)
867 object *self;
868 object *args;
869{
870 signed char *cp;
871 unsigned char *ncp;
872 int len, size, size2, val;
873 object *rv;
874 int i, j;
875
876 if ( !getargs(args, "(s#ii)",
877 &cp, &len, &size, &size2) )
878 return 0;
879
880 if ( (size != 1 && size != 2 && size != 4) ||
881 (size2 != 1 && size2 != 2 && size2 != 4)) {
882 err_setstr(AudioopError, "Size should be 1, 2 or 4");
883 return 0;
884 }
885
886 rv = newsizedstringobject(NULL, (len/size)*size2);
887 if ( rv == 0 )
888 return 0;
889 ncp = (unsigned char *)getstringvalue(rv);
890
891 for ( i=0, j=0; i < len; i += size, j += size2 ) {
892 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
893 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
894 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
895
896 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
897 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
898 else if ( size2 == 4 ) *LONGP(ncp, j) = (long)(val<<16);
899 }
900 return rv;
901}
902
903static object *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000904audioop_lin2ulaw(self, args)
905 object *self;
906 object *args;
907{
908 signed char *cp;
909 unsigned char *ncp;
910 int len, size, val;
911 object *rv;
912 int i;
913
914 if ( !getargs(args, "(s#i)",
915 &cp, &len, &size) )
916 return 0;
917
918 if ( size != 1 && size != 2 && size != 4) {
919 err_setstr(AudioopError, "Size should be 1, 2 or 4");
920 return 0;
921 }
922
923 rv = newsizedstringobject(NULL, len/size);
924 if ( rv == 0 )
925 return 0;
926 ncp = (unsigned char *)getstringvalue(rv);
927
928 for ( i=0; i < len; i += size ) {
929 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
930 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
931 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
932
933 *ncp++ = st_linear_to_ulaw(val);
934 }
935 return rv;
936}
937
938static object *
939audioop_ulaw2lin(self, args)
940 object *self;
941 object *args;
942{
943 unsigned char *cp;
944 unsigned char cval;
945 signed char *ncp;
946 int len, size, val;
947 object *rv;
948 int i;
949
950 if ( !getargs(args, "(s#i)",
951 &cp, &len, &size) )
952 return 0;
953
954 if ( size != 1 && size != 2 && size != 4) {
955 err_setstr(AudioopError, "Size should be 1, 2 or 4");
956 return 0;
957 }
958
959 rv = newsizedstringobject(NULL, len*size);
960 if ( rv == 0 )
961 return 0;
962 ncp = (signed char *)getstringvalue(rv);
963
964 for ( i=0; i < len*size; i += size ) {
965 cval = *cp++;
966 val = st_ulaw_to_linear(cval);
967
968 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
969 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossumaad53441992-06-05 15:11:56 +0000970 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val<<16);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000971 }
972 return rv;
973}
974
Guido van Rossum8e7a0f01992-06-23 15:23:57 +0000975static object *
Guido van Rossumb64e6351992-07-06 14:21:56 +0000976audioop_lin2adpcm(self, args)
977 object *self;
978 object *args;
979{
980 signed char *cp;
981 signed char *ncp;
Jack Jansend513f0b1993-01-08 14:40:53 +0000982 int len, size, val, step, valpred, delta, index, sign, vpdiff, diff;
Guido van Rossumb64e6351992-07-06 14:21:56 +0000983 object *rv, *state, *str;
984 int i, outputbuffer, bufferstep;
985
986 if ( !getargs(args, "(s#iO)",
987 &cp, &len, &size, &state) )
988 return 0;
989
990
991 if ( size != 1 && size != 2 && size != 4) {
992 err_setstr(AudioopError, "Size should be 1, 2 or 4");
993 return 0;
994 }
995
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000996 str = newsizedstringobject(NULL, len/(size*2));
997 if ( str == 0 )
998 return 0;
999 ncp = (signed char *)getstringvalue(str);
1000
Guido van Rossumb64e6351992-07-06 14:21:56 +00001001 /* Decode state, should have (value, step) */
1002 if ( state == None ) {
1003 /* First time, it seems. Set defaults */
Jack Jansend513f0b1993-01-08 14:40:53 +00001004 valpred = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001005 step = 7;
1006 index = 0;
Jack Jansen55cea471993-02-10 13:21:59 +00001007 } else if ( !getargs(state, "(ii)", &valpred, &index) )
Guido van Rossumb64e6351992-07-06 14:21:56 +00001008 return 0;
1009
Jack Jansen55cea471993-02-10 13:21:59 +00001010 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001011 bufferstep = 1;
1012
1013 for ( i=0; i < len; i += size ) {
1014 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1015 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1016 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1017
1018 /* Step 1 - compute difference with previous value */
Jack Jansend513f0b1993-01-08 14:40:53 +00001019 diff = val - valpred;
1020 sign = (diff < 0) ? 8 : 0;
1021 if ( sign ) diff = (-diff);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001022
1023 /* Step 2 - Divide and clamp */
Jack Jansend513f0b1993-01-08 14:40:53 +00001024 /* Note:
1025 ** This code *approximately* computes:
1026 ** delta = diff*4/step;
1027 ** vpdiff = (delta+0.5)*step/4;
1028 ** but in shift step bits are dropped. The net result of this is
1029 ** that even if you have fast mul/div hardware you cannot put it to
1030 ** good use since the fixup would be too expensive.
1031 */
1032 delta = 0;
1033 vpdiff = (step >> 3);
1034
1035 if ( diff >= step ) {
1036 delta = 4;
1037 diff -= step;
1038 vpdiff += step;
1039 }
1040 step >>= 1;
1041 if ( diff >= step ) {
1042 delta |= 2;
1043 diff -= step;
1044 vpdiff += step;
1045 }
1046 step >>= 1;
1047 if ( diff >= step ) {
1048 delta |= 1;
1049 vpdiff += step;
1050 }
1051
Guido van Rossumb64e6351992-07-06 14:21:56 +00001052 /* Step 3 - Update previous value */
1053 if ( sign )
Jack Jansend513f0b1993-01-08 14:40:53 +00001054 valpred -= vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001055 else
Jack Jansend513f0b1993-01-08 14:40:53 +00001056 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001057
1058 /* Step 4 - Clamp previous value to 16 bits */
Jack Jansend513f0b1993-01-08 14:40:53 +00001059 if ( valpred > 32767 )
1060 valpred = 32767;
1061 else if ( valpred < -32768 )
1062 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001063
1064 /* Step 5 - Assemble value, update index and step values */
1065 delta |= sign;
1066
1067 index += indexTable[delta];
1068 if ( index < 0 ) index = 0;
1069 if ( index > 88 ) index = 88;
1070 step = stepsizeTable[index];
1071
Jack Jansend513f0b1993-01-08 14:40:53 +00001072 /* Step 6 - Output value */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001073 if ( bufferstep ) {
Jack Jansend513f0b1993-01-08 14:40:53 +00001074 outputbuffer = (delta << 4) & 0xf0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001075 } else {
Jack Jansend513f0b1993-01-08 14:40:53 +00001076 *ncp++ = (delta & 0x0f) | outputbuffer;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001077 }
1078 bufferstep = !bufferstep;
1079 }
Jack Jansen55cea471993-02-10 13:21:59 +00001080 rv = mkvalue("(O(ii))", str, valpred, index);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001081 DECREF(str);
1082 return rv;
1083}
1084
1085static object *
1086audioop_adpcm2lin(self, args)
1087 object *self;
1088 object *args;
1089{
1090 signed char *cp;
1091 signed char *ncp;
Jack Jansend513f0b1993-01-08 14:40:53 +00001092 int len, size, val, valpred, step, delta, index, sign, vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001093 object *rv, *str, *state;
1094 int i, inputbuffer, bufferstep;
1095
1096 if ( !getargs(args, "(s#iO)",
1097 &cp, &len, &size, &state) )
1098 return 0;
1099
1100 if ( size != 1 && size != 2 && size != 4) {
1101 err_setstr(AudioopError, "Size should be 1, 2 or 4");
1102 return 0;
1103 }
1104
1105 /* Decode state, should have (value, step) */
1106 if ( state == None ) {
1107 /* First time, it seems. Set defaults */
Jack Jansend513f0b1993-01-08 14:40:53 +00001108 valpred = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001109 step = 7;
1110 index = 0;
Jack Jansen55cea471993-02-10 13:21:59 +00001111 } else if ( !getargs(state, "(ii)", &valpred, &index) )
Guido van Rossumb64e6351992-07-06 14:21:56 +00001112 return 0;
1113
1114 str = newsizedstringobject(NULL, len*size*2);
1115 if ( str == 0 )
1116 return 0;
1117 ncp = (signed char *)getstringvalue(str);
1118
Jack Jansen55cea471993-02-10 13:21:59 +00001119 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001120 bufferstep = 0;
1121
1122 for ( i=0; i < len*size*2; i += size ) {
1123 /* Step 1 - get the delta value and compute next index */
1124 if ( bufferstep ) {
1125 delta = inputbuffer & 0xf;
1126 } else {
1127 inputbuffer = *cp++;
1128 delta = (inputbuffer >> 4) & 0xf;
1129 }
1130
1131 bufferstep = !bufferstep;
1132
Jack Jansend513f0b1993-01-08 14:40:53 +00001133 /* Step 2 - Find new index value (for later) */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001134 index += indexTable[delta];
1135 if ( index < 0 ) index = 0;
1136 if ( index > 88 ) index = 88;
1137
Jack Jansend513f0b1993-01-08 14:40:53 +00001138 /* Step 3 - Separate sign and magnitude */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001139 sign = delta & 8;
1140 delta = delta & 7;
1141
Jack Jansend513f0b1993-01-08 14:40:53 +00001142 /* Step 4 - Compute difference and new predicted value */
1143 /*
1144 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1145 ** in adpcm_coder.
1146 */
1147 vpdiff = step >> 3;
1148 if ( delta & 4 ) vpdiff += step;
1149 if ( delta & 2 ) vpdiff += step>>1;
1150 if ( delta & 1 ) vpdiff += step>>2;
1151
Guido van Rossumb64e6351992-07-06 14:21:56 +00001152 if ( sign )
Jack Jansend513f0b1993-01-08 14:40:53 +00001153 valpred -= vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001154 else
Jack Jansend513f0b1993-01-08 14:40:53 +00001155 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001156
Jack Jansend513f0b1993-01-08 14:40:53 +00001157 /* Step 5 - clamp output value */
1158 if ( valpred > 32767 )
1159 valpred = 32767;
1160 else if ( valpred < -32768 )
1161 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001162
Jack Jansend513f0b1993-01-08 14:40:53 +00001163 /* Step 6 - Update step value */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001164 step = stepsizeTable[index];
1165
1166 /* Step 6 - Output value */
Jack Jansend513f0b1993-01-08 14:40:53 +00001167 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1168 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1169 else if ( size == 4 ) *LONGP(ncp, i) = (long)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001170 }
1171
Jack Jansen55cea471993-02-10 13:21:59 +00001172 rv = mkvalue("(O(ii))", str, valpred, index);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001173 DECREF(str);
1174 return rv;
1175}
1176
Guido van Rossumb66efa01992-06-01 16:01:24 +00001177static struct methodlist audioop_methods[] = {
1178 { "max", audioop_max },
1179 { "avg", audioop_avg },
Jack Jansene1b4d7c1992-08-24 14:36:31 +00001180 { "maxpp", audioop_maxpp },
1181 { "avgpp", audioop_avgpp },
1182 { "rms", audioop_rms },
Jack Jansena90805f1993-02-17 14:29:28 +00001183 { "findfit", audioop_findfit },
1184 { "findmax", audioop_findmax },
1185 { "findfactor", audioop_findfactor },
Guido van Rossumb66efa01992-06-01 16:01:24 +00001186 { "cross", audioop_cross },
1187 { "mul", audioop_mul },
1188 { "add", audioop_add },
1189 { "bias", audioop_bias },
1190 { "ulaw2lin", audioop_ulaw2lin },
1191 { "lin2ulaw", audioop_lin2ulaw },
Jack Jansena90805f1993-02-17 14:29:28 +00001192 { "lin2lin", audioop_lin2lin },
Guido van Rossum8e7a0f01992-06-23 15:23:57 +00001193 { "adpcm2lin", audioop_adpcm2lin },
1194 { "lin2adpcm", audioop_lin2adpcm },
Guido van Rossumb66efa01992-06-01 16:01:24 +00001195 { "tomono", audioop_tomono },
1196 { "tostereo", audioop_tostereo },
1197 { "getsample", audioop_getsample },
Jack Jansen337b20e1993-02-23 13:39:57 +00001198 { "reverse", audioop_reverse },
Guido van Rossumb66efa01992-06-01 16:01:24 +00001199 { 0, 0 }
1200};
1201
1202
1203void
1204initaudioop()
1205{
1206 object *m, *d;
1207 m = initmodule("audioop", audioop_methods);
1208 d = getmoduledict(m);
1209 AudioopError = newstringobject("audioop.error");
1210 if ( AudioopError == NULL || dictinsert(d,"error",AudioopError) )
1211 fatal("can't define audioop.error");
1212}