blob: d4e020b7f2d38955f09bd7d012492186820a409b [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 Rossum7b1e9741994-08-29 10:46:42 +000030#if defined(__CHAR_UNSIGNED__)
31#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000032!ERROR!; READ THE SOURCE FILE!;
33/* This module currently does not work on systems where only unsigned
34 characters are available. Take it out of Setup. Sorry. */
35#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000036#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000037
38#include <math.h>
39
Jack Jansena90805f1993-02-17 14:29:28 +000040/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000041** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
42
43#define MINLIN -32768
44#define MAXLIN 32767
45#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; else if ( x > MAXLIN ) x = MAXLIN; } while ( 0 )
46
47unsigned char st_linear_to_ulaw( /* int sample */ );
48
49/*
50** This macro converts from ulaw to 16 bit linear, faster.
51**
52** Jef Poskanzer
53** 23 October 1989
54**
55** Input: 8 bit ulaw sample
56** Output: signed 16 bit linear sample
57*/
58#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
59
60static int ulaw_table[256] = {
61 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
62 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
63 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
64 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
65 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
66 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
67 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
68 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
69 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
70 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
71 -876, -844, -812, -780, -748, -716, -684, -652,
72 -620, -588, -556, -524, -492, -460, -428, -396,
73 -372, -356, -340, -324, -308, -292, -276, -260,
74 -244, -228, -212, -196, -180, -164, -148, -132,
75 -120, -112, -104, -96, -88, -80, -72, -64,
76 -56, -48, -40, -32, -24, -16, -8, 0,
77 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
78 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
79 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
80 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
81 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
82 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
83 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
84 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
85 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
86 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
87 876, 844, 812, 780, 748, 716, 684, 652,
88 620, 588, 556, 524, 492, 460, 428, 396,
89 372, 356, 340, 324, 308, 292, 276, 260,
90 244, 228, 212, 196, 180, 164, 148, 132,
91 120, 112, 104, 96, 88, 80, 72, 64,
92 56, 48, 40, 32, 24, 16, 8, 0 };
93
94#define ZEROTRAP /* turn on the trap as per the MIL-STD */
95#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
96#define CLIP 32635
97
98unsigned char
99st_linear_to_ulaw( sample )
100int sample;
101 {
102 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
103 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
104 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
105 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
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 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
109 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
117 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
118 int sign, exponent, mantissa;
119 unsigned char ulawbyte;
120
121 /* Get the sample into sign-magnitude. */
122 sign = (sample >> 8) & 0x80; /* set aside the sign */
123 if ( sign != 0 ) sample = -sample; /* get magnitude */
124 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
125
126 /* Convert from 16 bit linear to ulaw. */
127 sample = sample + BIAS;
128 exponent = exp_lut[( sample >> 7 ) & 0xFF];
129 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
130 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
131#ifdef ZEROTRAP
132 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
133#endif
134
135 return ulawbyte;
136 }
137/* End of code taken from sox */
138
Guido van Rossumb64e6351992-07-06 14:21:56 +0000139/* ADPCM-3 step variation table */
Guido van Rossum8e7a0f01992-06-23 15:23:57 +0000140static float newstep[5] = { 0.8, 0.9, 1.0, 1.75, 1.75 };
141
Guido van Rossumb64e6351992-07-06 14:21:56 +0000142/* Intel ADPCM step variation table */
143static int indexTable[16] = {
144 -1, -1, -1, -1, 2, 4, 6, 8,
145 -1, -1, -1, -1, 2, 4, 6, 8,
146};
147
148static int stepsizeTable[89] = {
149 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
150 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
151 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
152 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
153 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
154 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
155 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
156 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
157 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
158};
159
Guido van Rossumb66efa01992-06-01 16:01:24 +0000160#define CHARP(cp, i) ((signed char *)(cp+i))
161#define SHORTP(cp, i) ((short *)(cp+i))
162#define LONGP(cp, i) ((long *)(cp+i))
163
164
165
166static object *AudioopError;
167
168static object *
169audioop_getsample(self, args)
170 object *self;
171 object *args;
172{
173 signed char *cp;
174 int len, size, val;
175 int i;
176
177 if ( !getargs(args, "(s#ii)", &cp, &len, &size, &i) )
178 return 0;
179 if ( size != 1 && size != 2 && size != 4 ) {
180 err_setstr(AudioopError, "Size should be 1, 2 or 4");
181 return 0;
182 }
183 if ( i < 0 || i >= len/size ) {
184 err_setstr(AudioopError, "Index out of range");
185 return 0;
186 }
187 if ( size == 1 ) val = (int)*CHARP(cp, i);
188 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
189 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
190 return newintobject(val);
191}
192
193static object *
194audioop_max(self, args)
195 object *self;
196 object *args;
197{
198 signed char *cp;
199 int len, size, val;
200 int i;
201 int max = 0;
202
203 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
204 return 0;
205 if ( size != 1 && size != 2 && size != 4 ) {
206 err_setstr(AudioopError, "Size should be 1, 2 or 4");
207 return 0;
208 }
209 for ( i=0; i<len; i+= size) {
210 if ( size == 1 ) val = (int)*CHARP(cp, i);
211 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
212 else if ( size == 4 ) val = (int)*LONGP(cp, i);
213 if ( val < 0 ) val = (-val);
214 if ( val > max ) max = val;
215 }
216 return newintobject(max);
217}
218
219static object *
220audioop_avg(self, args)
221 object *self;
222 object *args;
223{
224 signed char *cp;
225 int len, size, val;
226 int i;
227 float avg = 0.0;
228
229 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
230 return 0;
231 if ( size != 1 && size != 2 && size != 4 ) {
232 err_setstr(AudioopError, "Size should be 1, 2 or 4");
233 return 0;
234 }
235 for ( i=0; i<len; i+= size) {
236 if ( size == 1 ) val = (int)*CHARP(cp, i);
237 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
238 else if ( size == 4 ) val = (int)*LONGP(cp, i);
239 avg += val;
240 }
241 if ( len == 0 )
242 val = 0;
243 else
244 val = (int)(avg / (float)(len/size));
245 return newintobject(val);
246}
247
248static object *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000249audioop_rms(self, args)
250 object *self;
251 object *args;
252{
253 signed char *cp;
254 int len, size, val;
255 int i;
256 float sum_squares = 0.0;
257
258 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
259 return 0;
260 if ( size != 1 && size != 2 && size != 4 ) {
261 err_setstr(AudioopError, "Size should be 1, 2 or 4");
262 return 0;
263 }
264 for ( i=0; i<len; i+= size) {
265 if ( size == 1 ) val = (int)*CHARP(cp, i);
266 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
267 else if ( size == 4 ) val = (int)*LONGP(cp, i);
268 sum_squares += (float)val*(float)val;
269 }
270 if ( len == 0 )
271 val = 0;
272 else
273 val = (int)sqrt(sum_squares / (float)(len/size));
274 return newintobject(val);
275}
276
Jack Jansena90805f1993-02-17 14:29:28 +0000277double _sum2(a, b, len)
278 short *a;
279 short *b;
280 int len;
281{
282 int i;
283 double sum = 0.0;
284
285 for( i=0; i<len; i++) {
286 sum = sum + (double)a[i]*(double)b[i];
287 }
288 return sum;
289}
290
291/*
292** Findfit tries to locate a sample within another sample. Its main use
293** is in echo-cancellation (to find the feedback of the output signal in
294** the input signal).
295** The method used is as follows:
296**
297** let R be the reference signal (length n) and A the input signal (length N)
298** with N > n, and let all sums be over i from 0 to n-1.
299**
300** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
301** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
302** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
303**
304** Next, we compute the relative distance between the original signal and
305** the modified signal and minimize that over j:
306** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
307** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
308**
309** In the code variables correspond as follows:
310** cp1 A
311** cp2 R
312** len1 N
313** len2 n
314** aj_m1 A[j-1]
315** aj_lm1 A[j+n-1]
316** sum_ri_2 sum(R[i]^2)
317** sum_aij_2 sum(A[i+j]^2)
318** sum_aij_ri sum(A[i+j]R[i])
319**
320** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
321** is completely recalculated each step.
322*/
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000323static object *
Jack Jansena90805f1993-02-17 14:29:28 +0000324audioop_findfit(self, args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000325 object *self;
326 object *args;
327{
Jack Jansena90805f1993-02-17 14:29:28 +0000328 short *cp1, *cp2;
329 int len1, len2;
330 int j, best_j;
331 double aj_m1, aj_lm1;
332 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000333
Jack Jansena90805f1993-02-17 14:29:28 +0000334 if ( !getargs(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000335 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000336 if ( len1 & 1 || len2 & 1 ) {
337 err_setstr(AudioopError, "Strings should be even-sized");
338 return 0;
339 }
340 len1 >>= 1;
341 len2 >>= 1;
342
343 if ( len1 < len2 ) {
344 err_setstr(AudioopError, "First sample should be longer");
345 return 0;
346 }
347 sum_ri_2 = _sum2(cp2, cp2, len2);
348 sum_aij_2 = _sum2(cp1, cp1, len2);
349 sum_aij_ri = _sum2(cp1, cp2, len2);
350
351 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
352
353 best_result = result;
354 best_j = 0;
355 j = 0;
356
357 for ( j=1; j<=len1-len2; j++) {
358 aj_m1 = (double)cp1[j-1];
359 aj_lm1 = (double)cp1[j+len2-1];
360
361 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
362 sum_aij_ri = _sum2(cp1+j, cp2, len2);
363
364 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
365
366 if ( result < best_result ) {
367 best_result = result;
368 best_j = j;
369 }
370
371 }
372
373 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
374
375 return mkvalue("(if)", best_j, factor);
376}
377
378/*
379** findfactor finds a factor f so that the energy in A-fB is minimal.
380** See the comment for findfit for details.
381*/
382static object *
383audioop_findfactor(self, args)
384 object *self;
385 object *args;
386{
387 short *cp1, *cp2;
388 int len1, len2;
389 double sum_ri_2, sum_aij_ri, result;
390
391 if ( !getargs(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
392 return 0;
393 if ( len1 & 1 || len2 & 1 ) {
394 err_setstr(AudioopError, "Strings should be even-sized");
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000395 return 0;
396 }
397 if ( len1 != len2 ) {
398 err_setstr(AudioopError, "Samples should be same size");
399 return 0;
400 }
Jack Jansena90805f1993-02-17 14:29:28 +0000401 len2 >>= 1;
402 sum_ri_2 = _sum2(cp2, cp2, len2);
403 sum_aij_ri = _sum2(cp1, cp2, len2);
404
405 result = sum_aij_ri / sum_ri_2;
406
407 return newfloatobject(result);
408}
409
410/*
411** findmax returns the index of the n-sized segment of the input sample
412** that contains the most energy.
413*/
414static object *
415audioop_findmax(self, args)
416 object *self;
417 object *args;
418{
419 short *cp1;
420 int len1, len2;
421 int j, best_j;
422 double aj_m1, aj_lm1;
423 double result, best_result;
424
425 if ( !getargs(args, "(s#i)", &cp1, &len1, &len2) )
426 return 0;
427 if ( len1 & 1 ) {
428 err_setstr(AudioopError, "Strings should be even-sized");
429 return 0;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000430 }
Jack Jansena90805f1993-02-17 14:29:28 +0000431 len1 >>= 1;
432
433 if ( len1 < len2 ) {
434 err_setstr(AudioopError, "Input sample should be longer");
435 return 0;
436 }
437
438 result = _sum2(cp1, cp1, len2);
439
440 best_result = result;
441 best_j = 0;
442 j = 0;
443
444 for ( j=1; j<=len1-len2; j++) {
445 aj_m1 = (double)cp1[j-1];
446 aj_lm1 = (double)cp1[j+len2-1];
447
448 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
449
450 if ( result > best_result ) {
451 best_result = result;
452 best_j = j;
453 }
454
455 }
456
457 return newintobject(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000458}
459
460static object *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000461audioop_avgpp(self, args)
462 object *self;
463 object *args;
464{
465 signed char *cp;
466 int len, size, val, prevval, prevextremevalid = 0, prevextreme;
467 int i;
468 float avg = 0.0;
469 int diff, prevdiff, extremediff, nextreme = 0;
470
471 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
472 return 0;
473 if ( size != 1 && size != 2 && size != 4 ) {
474 err_setstr(AudioopError, "Size should be 1, 2 or 4");
475 return 0;
476 }
477 /* Compute first delta value ahead. Also automatically makes us
478 ** skip the first extreme value
479 */
480 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
481 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
482 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
483 if ( size == 1 ) val = (int)*CHARP(cp, size);
484 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
485 else if ( size == 4 ) val = (int)*LONGP(cp, size);
486 prevdiff = val - prevval;
487
488 for ( i=size; i<len; i+= size) {
489 if ( size == 1 ) val = (int)*CHARP(cp, i);
490 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
491 else if ( size == 4 ) val = (int)*LONGP(cp, i);
492 diff = val - prevval;
493 if ( diff*prevdiff < 0 ) {
494 /* Derivative changed sign. Compute difference to last extreme
495 ** value and remember.
496 */
497 if ( prevextremevalid ) {
498 extremediff = prevval - prevextreme;
499 if ( extremediff < 0 )
500 extremediff = -extremediff;
501 avg += extremediff;
502 nextreme++;
503 }
504 prevextremevalid = 1;
505 prevextreme = prevval;
506 }
507 prevval = val;
508 if ( diff != 0 )
509 prevdiff = diff;
510 }
511 if ( nextreme == 0 )
512 val = 0;
513 else
514 val = (int)(avg / (float)nextreme);
515 return newintobject(val);
516}
517
518static object *
519audioop_maxpp(self, args)
520 object *self;
521 object *args;
522{
523 signed char *cp;
524 int len, size, val, prevval, prevextremevalid = 0, prevextreme;
525 int i;
526 int max = 0;
527 int diff, prevdiff, extremediff;
528
529 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
530 return 0;
531 if ( size != 1 && size != 2 && size != 4 ) {
532 err_setstr(AudioopError, "Size should be 1, 2 or 4");
533 return 0;
534 }
535 /* Compute first delta value ahead. Also automatically makes us
536 ** skip the first extreme value
537 */
538 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
539 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
540 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
541 if ( size == 1 ) val = (int)*CHARP(cp, size);
542 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
543 else if ( size == 4 ) val = (int)*LONGP(cp, size);
544 prevdiff = val - prevval;
545
546 for ( i=size; i<len; i+= size) {
547 if ( size == 1 ) val = (int)*CHARP(cp, i);
548 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
549 else if ( size == 4 ) val = (int)*LONGP(cp, i);
550 diff = val - prevval;
551 if ( diff*prevdiff < 0 ) {
552 /* Derivative changed sign. Compute difference to last extreme
553 ** value and remember.
554 */
555 if ( prevextremevalid ) {
556 extremediff = prevval - prevextreme;
557 if ( extremediff < 0 )
558 extremediff = -extremediff;
559 if ( extremediff > max )
560 max = extremediff;
561 }
562 prevextremevalid = 1;
563 prevextreme = prevval;
564 }
565 prevval = val;
566 if ( diff != 0 )
567 prevdiff = diff;
568 }
569 return newintobject(max);
570}
571
572static object *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000573audioop_cross(self, args)
574 object *self;
575 object *args;
576{
577 signed char *cp;
578 int len, size, val;
579 int i;
580 int cross, prevval, ncross;
581
582 if ( !getargs(args, "(s#i)", &cp, &len, &size) )
583 return 0;
584 if ( size != 1 && size != 2 && size != 4 ) {
585 err_setstr(AudioopError, "Size should be 1, 2 or 4");
586 return 0;
587 }
588 ncross = -1;
589 prevval = 17; /* Anything <> 0,1 */
590 for ( i=0; i<len; i+= size) {
591 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
592 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
593 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
594 val = val & 1;
595 if ( val != prevval ) ncross++;
596 prevval = val;
597 }
598 return newintobject(ncross);
599}
600
601static object *
602audioop_mul(self, args)
603 object *self;
604 object *args;
605{
606 signed char *cp, *ncp;
607 int len, size, val;
608 double factor, fval, maxval;
609 object *rv;
610 int i;
611
612 if ( !getargs(args, "(s#id)", &cp, &len, &size, &factor ) )
613 return 0;
614
615 if ( size == 1 ) maxval = (double) 0x7f;
616 else if ( size == 2 ) maxval = (double) 0x7fff;
617 else if ( size == 4 ) maxval = (double) 0x7fffffff;
618 else {
619 err_setstr(AudioopError, "Size should be 1, 2 or 4");
620 return 0;
621 }
622
623 rv = newsizedstringobject(NULL, len);
624 if ( rv == 0 )
625 return 0;
626 ncp = (signed char *)getstringvalue(rv);
627
628
629 for ( i=0; i < len; i += size ) {
630 if ( size == 1 ) val = (int)*CHARP(cp, i);
631 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
632 else if ( size == 4 ) val = (int)*LONGP(cp, i);
633 fval = (double)val*factor;
634 if ( fval > maxval ) fval = maxval;
635 else if ( fval < -maxval ) fval = -maxval;
636 val = (int)fval;
637 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
638 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
639 else if ( size == 4 ) *LONGP(ncp, i) = (long)val;
640 }
641 return rv;
642}
643
644static object *
645audioop_tomono(self, args)
646 object *self;
647 object *args;
648{
649 signed char *cp, *ncp;
650 int len, size, val1, val2;
651 double fac1, fac2, fval, maxval;
652 object *rv;
653 int i;
654
655 if ( !getargs(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
656 return 0;
657
658 if ( size == 1 ) maxval = (double) 0x7f;
659 else if ( size == 2 ) maxval = (double) 0x7fff;
660 else if ( size == 4 ) maxval = (double) 0x7fffffff;
661 else {
662 err_setstr(AudioopError, "Size should be 1, 2 or 4");
663 return 0;
664 }
665
666 rv = newsizedstringobject(NULL, len/2);
667 if ( rv == 0 )
668 return 0;
669 ncp = (signed char *)getstringvalue(rv);
670
671
672 for ( i=0; i < len; i += size*2 ) {
673 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
674 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
675 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
676 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
677 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
678 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
679 fval = (double)val1*fac1 + (double)val2*fac2;
680 if ( fval > maxval ) fval = maxval;
681 else if ( fval < -maxval ) fval = -maxval;
682 val1 = (int)fval;
683 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
684 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
685 else if ( size == 4 ) *LONGP(ncp, i/2)= (long)val1;
686 }
687 return rv;
688}
689
690static object *
691audioop_tostereo(self, args)
692 object *self;
693 object *args;
694{
695 signed char *cp, *ncp;
696 int len, size, val1, val2, val;
697 double fac1, fac2, fval, maxval;
698 object *rv;
699 int i;
700
701 if ( !getargs(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
702 return 0;
703
704 if ( size == 1 ) maxval = (double) 0x7f;
705 else if ( size == 2 ) maxval = (double) 0x7fff;
706 else if ( size == 4 ) maxval = (double) 0x7fffffff;
707 else {
708 err_setstr(AudioopError, "Size should be 1, 2 or 4");
709 return 0;
710 }
711
712 rv = newsizedstringobject(NULL, len*2);
713 if ( rv == 0 )
714 return 0;
715 ncp = (signed char *)getstringvalue(rv);
716
717
718 for ( i=0; i < len; i += size ) {
719 if ( size == 1 ) val = (int)*CHARP(cp, i);
720 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
721 else if ( size == 4 ) val = (int)*LONGP(cp, i);
722
723 fval = (double)val*fac1;
724 if ( fval > maxval ) fval = maxval;
725 else if ( fval < -maxval ) fval = -maxval;
726 val1 = (int)fval;
727
728 fval = (double)val*fac2;
729 if ( fval > maxval ) fval = maxval;
730 else if ( fval < -maxval ) fval = -maxval;
731 val2 = (int)fval;
732
733 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
734 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
735 else if ( size == 4 ) *LONGP(ncp, i*2) = (long)val1;
736
737 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
738 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
739 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (long)val2;
740 }
741 return rv;
742}
743
744static object *
745audioop_add(self, args)
746 object *self;
747 object *args;
748{
749 signed char *cp1, *cp2, *ncp;
750 int len1, len2, size, val1, val2;
751 object *rv;
752 int i;
753
754 if ( !getargs(args, "(s#s#i)",
755 &cp1, &len1, &cp2, &len2, &size ) )
756 return 0;
757
758 if ( len1 != len2 ) {
759 err_setstr(AudioopError, "Lengths should be the same");
760 return 0;
761 }
762
763 if ( size != 1 && size != 2 && size != 4) {
764 err_setstr(AudioopError, "Size should be 1, 2 or 4");
765 return 0;
766 }
767
768 rv = newsizedstringobject(NULL, len1);
769 if ( rv == 0 )
770 return 0;
771 ncp = (signed char *)getstringvalue(rv);
772
773
774 for ( i=0; i < len1; i += size ) {
775 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
776 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
777 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
778
779 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
780 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
781 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
782
783 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val1+val2);
784 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val1+val2);
785 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val1+val2);
786 }
787 return rv;
788}
789
790static object *
791audioop_bias(self, args)
792 object *self;
793 object *args;
794{
795 signed char *cp, *ncp;
796 int len, size, val;
797 object *rv;
798 int i;
799 int bias;
800
801 if ( !getargs(args, "(s#ii)",
802 &cp, &len, &size , &bias) )
803 return 0;
804
805 if ( size != 1 && size != 2 && size != 4) {
806 err_setstr(AudioopError, "Size should be 1, 2 or 4");
807 return 0;
808 }
809
810 rv = newsizedstringobject(NULL, len);
811 if ( rv == 0 )
812 return 0;
813 ncp = (signed char *)getstringvalue(rv);
814
815
816 for ( i=0; i < len; i += size ) {
817 if ( size == 1 ) val = (int)*CHARP(cp, i);
818 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
819 else if ( size == 4 ) val = (int)*LONGP(cp, i);
820
821 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
822 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
823 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val+bias);
824 }
825 return rv;
826}
827
828static object *
Jack Jansen337b20e1993-02-23 13:39:57 +0000829audioop_reverse(self, args)
830 object *self;
831 object *args;
832{
833 signed char *cp;
834 unsigned char *ncp;
835 int len, size, val;
836 object *rv;
837 int i, j;
838
839 if ( !getargs(args, "(s#i)",
840 &cp, &len, &size) )
841 return 0;
842
843 if ( size != 1 && size != 2 && size != 4 ) {
844 err_setstr(AudioopError, "Size should be 1, 2 or 4");
845 return 0;
846 }
847
848 rv = newsizedstringobject(NULL, len);
849 if ( rv == 0 )
850 return 0;
851 ncp = (unsigned char *)getstringvalue(rv);
852
853 for ( i=0; i < len; i += size ) {
854 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
855 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
856 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
857
858 j = len - i - size;
859
860 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
861 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
862 else if ( size == 4 ) *LONGP(ncp, j) = (long)(val<<16);
863 }
864 return rv;
865}
866
867static object *
Jack Jansena90805f1993-02-17 14:29:28 +0000868audioop_lin2lin(self, args)
869 object *self;
870 object *args;
871{
872 signed char *cp;
873 unsigned char *ncp;
874 int len, size, size2, val;
875 object *rv;
876 int i, j;
877
878 if ( !getargs(args, "(s#ii)",
879 &cp, &len, &size, &size2) )
880 return 0;
881
882 if ( (size != 1 && size != 2 && size != 4) ||
883 (size2 != 1 && size2 != 2 && size2 != 4)) {
884 err_setstr(AudioopError, "Size should be 1, 2 or 4");
885 return 0;
886 }
887
888 rv = newsizedstringobject(NULL, (len/size)*size2);
889 if ( rv == 0 )
890 return 0;
891 ncp = (unsigned char *)getstringvalue(rv);
892
893 for ( i=0, j=0; i < len; i += size, j += size2 ) {
894 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
895 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
896 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
897
898 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
899 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
900 else if ( size2 == 4 ) *LONGP(ncp, j) = (long)(val<<16);
901 }
902 return rv;
903}
904
905static object *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906audioop_lin2ulaw(self, args)
907 object *self;
908 object *args;
909{
910 signed char *cp;
911 unsigned char *ncp;
912 int len, size, val;
913 object *rv;
914 int i;
915
916 if ( !getargs(args, "(s#i)",
917 &cp, &len, &size) )
918 return 0;
919
920 if ( size != 1 && size != 2 && size != 4) {
921 err_setstr(AudioopError, "Size should be 1, 2 or 4");
922 return 0;
923 }
924
925 rv = newsizedstringobject(NULL, len/size);
926 if ( rv == 0 )
927 return 0;
928 ncp = (unsigned char *)getstringvalue(rv);
929
930 for ( i=0; i < len; i += size ) {
931 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
932 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
933 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
934
935 *ncp++ = st_linear_to_ulaw(val);
936 }
937 return rv;
938}
939
940static object *
941audioop_ulaw2lin(self, args)
942 object *self;
943 object *args;
944{
945 unsigned char *cp;
946 unsigned char cval;
947 signed char *ncp;
948 int len, size, val;
949 object *rv;
950 int i;
951
952 if ( !getargs(args, "(s#i)",
953 &cp, &len, &size) )
954 return 0;
955
956 if ( size != 1 && size != 2 && size != 4) {
957 err_setstr(AudioopError, "Size should be 1, 2 or 4");
958 return 0;
959 }
960
961 rv = newsizedstringobject(NULL, len*size);
962 if ( rv == 0 )
963 return 0;
964 ncp = (signed char *)getstringvalue(rv);
965
966 for ( i=0; i < len*size; i += size ) {
967 cval = *cp++;
968 val = st_ulaw_to_linear(cval);
969
970 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
971 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossumaad53441992-06-05 15:11:56 +0000972 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val<<16);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000973 }
974 return rv;
975}
976
Guido van Rossum8e7a0f01992-06-23 15:23:57 +0000977static object *
Guido van Rossumb64e6351992-07-06 14:21:56 +0000978audioop_lin2adpcm(self, args)
979 object *self;
980 object *args;
981{
982 signed char *cp;
983 signed char *ncp;
Jack Jansend513f0b1993-01-08 14:40:53 +0000984 int len, size, val, step, valpred, delta, index, sign, vpdiff, diff;
Guido van Rossumb64e6351992-07-06 14:21:56 +0000985 object *rv, *state, *str;
986 int i, outputbuffer, bufferstep;
987
988 if ( !getargs(args, "(s#iO)",
989 &cp, &len, &size, &state) )
990 return 0;
991
992
993 if ( size != 1 && size != 2 && size != 4) {
994 err_setstr(AudioopError, "Size should be 1, 2 or 4");
995 return 0;
996 }
997
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000998 str = newsizedstringobject(NULL, len/(size*2));
999 if ( str == 0 )
1000 return 0;
1001 ncp = (signed char *)getstringvalue(str);
1002
Guido van Rossumb64e6351992-07-06 14:21:56 +00001003 /* Decode state, should have (value, step) */
1004 if ( state == None ) {
1005 /* First time, it seems. Set defaults */
Jack Jansend513f0b1993-01-08 14:40:53 +00001006 valpred = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001007 step = 7;
1008 index = 0;
Jack Jansen55cea471993-02-10 13:21:59 +00001009 } else if ( !getargs(state, "(ii)", &valpred, &index) )
Guido van Rossumb64e6351992-07-06 14:21:56 +00001010 return 0;
1011
Jack Jansen55cea471993-02-10 13:21:59 +00001012 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001013 bufferstep = 1;
1014
1015 for ( i=0; i < len; i += size ) {
1016 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1017 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1018 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1019
1020 /* Step 1 - compute difference with previous value */
Jack Jansend513f0b1993-01-08 14:40:53 +00001021 diff = val - valpred;
1022 sign = (diff < 0) ? 8 : 0;
1023 if ( sign ) diff = (-diff);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001024
1025 /* Step 2 - Divide and clamp */
Jack Jansend513f0b1993-01-08 14:40:53 +00001026 /* Note:
1027 ** This code *approximately* computes:
1028 ** delta = diff*4/step;
1029 ** vpdiff = (delta+0.5)*step/4;
1030 ** but in shift step bits are dropped. The net result of this is
1031 ** that even if you have fast mul/div hardware you cannot put it to
1032 ** good use since the fixup would be too expensive.
1033 */
1034 delta = 0;
1035 vpdiff = (step >> 3);
1036
1037 if ( diff >= step ) {
1038 delta = 4;
1039 diff -= step;
1040 vpdiff += step;
1041 }
1042 step >>= 1;
1043 if ( diff >= step ) {
1044 delta |= 2;
1045 diff -= step;
1046 vpdiff += step;
1047 }
1048 step >>= 1;
1049 if ( diff >= step ) {
1050 delta |= 1;
1051 vpdiff += step;
1052 }
1053
Guido van Rossumb64e6351992-07-06 14:21:56 +00001054 /* Step 3 - Update previous value */
1055 if ( sign )
Jack Jansend513f0b1993-01-08 14:40:53 +00001056 valpred -= vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001057 else
Jack Jansend513f0b1993-01-08 14:40:53 +00001058 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001059
1060 /* Step 4 - Clamp previous value to 16 bits */
Jack Jansend513f0b1993-01-08 14:40:53 +00001061 if ( valpred > 32767 )
1062 valpred = 32767;
1063 else if ( valpred < -32768 )
1064 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001065
1066 /* Step 5 - Assemble value, update index and step values */
1067 delta |= sign;
1068
1069 index += indexTable[delta];
1070 if ( index < 0 ) index = 0;
1071 if ( index > 88 ) index = 88;
1072 step = stepsizeTable[index];
1073
Jack Jansend513f0b1993-01-08 14:40:53 +00001074 /* Step 6 - Output value */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001075 if ( bufferstep ) {
Jack Jansend513f0b1993-01-08 14:40:53 +00001076 outputbuffer = (delta << 4) & 0xf0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001077 } else {
Jack Jansend513f0b1993-01-08 14:40:53 +00001078 *ncp++ = (delta & 0x0f) | outputbuffer;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001079 }
1080 bufferstep = !bufferstep;
1081 }
Jack Jansen55cea471993-02-10 13:21:59 +00001082 rv = mkvalue("(O(ii))", str, valpred, index);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001083 DECREF(str);
1084 return rv;
1085}
1086
1087static object *
1088audioop_adpcm2lin(self, args)
1089 object *self;
1090 object *args;
1091{
1092 signed char *cp;
1093 signed char *ncp;
Jack Jansend513f0b1993-01-08 14:40:53 +00001094 int len, size, val, valpred, step, delta, index, sign, vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001095 object *rv, *str, *state;
1096 int i, inputbuffer, bufferstep;
1097
1098 if ( !getargs(args, "(s#iO)",
1099 &cp, &len, &size, &state) )
1100 return 0;
1101
1102 if ( size != 1 && size != 2 && size != 4) {
1103 err_setstr(AudioopError, "Size should be 1, 2 or 4");
1104 return 0;
1105 }
1106
1107 /* Decode state, should have (value, step) */
1108 if ( state == None ) {
1109 /* First time, it seems. Set defaults */
Jack Jansend513f0b1993-01-08 14:40:53 +00001110 valpred = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001111 step = 7;
1112 index = 0;
Jack Jansen55cea471993-02-10 13:21:59 +00001113 } else if ( !getargs(state, "(ii)", &valpred, &index) )
Guido van Rossumb64e6351992-07-06 14:21:56 +00001114 return 0;
1115
1116 str = newsizedstringobject(NULL, len*size*2);
1117 if ( str == 0 )
1118 return 0;
1119 ncp = (signed char *)getstringvalue(str);
1120
Jack Jansen55cea471993-02-10 13:21:59 +00001121 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001122 bufferstep = 0;
1123
1124 for ( i=0; i < len*size*2; i += size ) {
1125 /* Step 1 - get the delta value and compute next index */
1126 if ( bufferstep ) {
1127 delta = inputbuffer & 0xf;
1128 } else {
1129 inputbuffer = *cp++;
1130 delta = (inputbuffer >> 4) & 0xf;
1131 }
1132
1133 bufferstep = !bufferstep;
1134
Jack Jansend513f0b1993-01-08 14:40:53 +00001135 /* Step 2 - Find new index value (for later) */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001136 index += indexTable[delta];
1137 if ( index < 0 ) index = 0;
1138 if ( index > 88 ) index = 88;
1139
Jack Jansend513f0b1993-01-08 14:40:53 +00001140 /* Step 3 - Separate sign and magnitude */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001141 sign = delta & 8;
1142 delta = delta & 7;
1143
Jack Jansend513f0b1993-01-08 14:40:53 +00001144 /* Step 4 - Compute difference and new predicted value */
1145 /*
1146 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1147 ** in adpcm_coder.
1148 */
1149 vpdiff = step >> 3;
1150 if ( delta & 4 ) vpdiff += step;
1151 if ( delta & 2 ) vpdiff += step>>1;
1152 if ( delta & 1 ) vpdiff += step>>2;
1153
Guido van Rossumb64e6351992-07-06 14:21:56 +00001154 if ( sign )
Jack Jansend513f0b1993-01-08 14:40:53 +00001155 valpred -= vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001156 else
Jack Jansend513f0b1993-01-08 14:40:53 +00001157 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001158
Jack Jansend513f0b1993-01-08 14:40:53 +00001159 /* Step 5 - clamp output value */
1160 if ( valpred > 32767 )
1161 valpred = 32767;
1162 else if ( valpred < -32768 )
1163 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001164
Jack Jansend513f0b1993-01-08 14:40:53 +00001165 /* Step 6 - Update step value */
Guido van Rossumb64e6351992-07-06 14:21:56 +00001166 step = stepsizeTable[index];
1167
1168 /* Step 6 - Output value */
Jack Jansend513f0b1993-01-08 14:40:53 +00001169 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1170 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1171 else if ( size == 4 ) *LONGP(ncp, i) = (long)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001172 }
1173
Jack Jansen55cea471993-02-10 13:21:59 +00001174 rv = mkvalue("(O(ii))", str, valpred, index);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001175 DECREF(str);
1176 return rv;
1177}
1178
Guido van Rossumb66efa01992-06-01 16:01:24 +00001179static struct methodlist audioop_methods[] = {
1180 { "max", audioop_max },
1181 { "avg", audioop_avg },
Jack Jansene1b4d7c1992-08-24 14:36:31 +00001182 { "maxpp", audioop_maxpp },
1183 { "avgpp", audioop_avgpp },
1184 { "rms", audioop_rms },
Jack Jansena90805f1993-02-17 14:29:28 +00001185 { "findfit", audioop_findfit },
1186 { "findmax", audioop_findmax },
1187 { "findfactor", audioop_findfactor },
Guido van Rossumb66efa01992-06-01 16:01:24 +00001188 { "cross", audioop_cross },
1189 { "mul", audioop_mul },
1190 { "add", audioop_add },
1191 { "bias", audioop_bias },
1192 { "ulaw2lin", audioop_ulaw2lin },
1193 { "lin2ulaw", audioop_lin2ulaw },
Jack Jansena90805f1993-02-17 14:29:28 +00001194 { "lin2lin", audioop_lin2lin },
Guido van Rossum8e7a0f01992-06-23 15:23:57 +00001195 { "adpcm2lin", audioop_adpcm2lin },
1196 { "lin2adpcm", audioop_lin2adpcm },
Guido van Rossumb66efa01992-06-01 16:01:24 +00001197 { "tomono", audioop_tomono },
1198 { "tostereo", audioop_tostereo },
1199 { "getsample", audioop_getsample },
Jack Jansen337b20e1993-02-23 13:39:57 +00001200 { "reverse", audioop_reverse },
Guido van Rossumb66efa01992-06-01 16:01:24 +00001201 { 0, 0 }
1202};
1203
1204
1205void
1206initaudioop()
1207{
1208 object *m, *d;
1209 m = initmodule("audioop", audioop_methods);
1210 d = getmoduledict(m);
1211 AudioopError = newstringobject("audioop.error");
1212 if ( AudioopError == NULL || dictinsert(d,"error",AudioopError) )
1213 fatal("can't define audioop.error");
1214}