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.
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 */
17 typedef unsigned int Py_UInt32
;
20 typedef long Py_Int32
;
21 typedef unsigned long Py_UInt32
;
23 #error "No 4-byte integral type"
27 #if defined(__CHAR_UNSIGNED__)
29 /* This module currently does not work on systems where only unsigned
30 characters are available. Take it out of Setup. Sorry. */
34 /* Code shamelessly stolen from sox,
35 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
39 #define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
40 else if ( x > MAXLIN ) x = MAXLIN; \
43 static unsigned char st_linear_to_ulaw( /* int sample */ );
46 ** This macro converts from ulaw to 16 bit linear, faster.
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 */
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
);
127 if ( ulawbyte
== 0 ) ulawbyte
= 0x02; /* optional CCITT trap */
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
;
161 audioop_getsample(PyObject
*self
, PyObject
*args
)
164 int len
, size
, val
= 0;
167 if ( !PyArg_Parse(args
, "(s#ii)", &cp
, &len
, &size
, &i
) )
169 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
170 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
173 if ( i
< 0 || i
>= len
/size
) {
174 PyErr_SetString(AudioopError
, "Index out of range");
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
);
184 audioop_max(PyObject
*self
, PyObject
*args
)
187 int len
, size
, val
= 0;
191 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
193 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
194 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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
);
208 audioop_minmax(PyObject
*self
, PyObject
*args
)
211 int len
, size
, val
= 0;
213 int min
= 0x7fffffff, max
= -0x7fffffff;
215 if (!PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
))
217 if (size
!= 1 && size
!= 2 && size
!= 4) {
218 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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
);
232 audioop_avg(PyObject
*self
, PyObject
*args
)
235 int len
, size
, val
= 0;
239 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
241 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
242 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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
);
254 val
= (int)(avg
/ (double)(len
/size
));
255 return PyInt_FromLong(val
);
259 audioop_rms(PyObject
*self
, PyObject
*args
)
262 int len
, size
, val
= 0;
264 double sum_squares
= 0.0;
266 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
268 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
269 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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
;
281 val
= (int)sqrt(sum_squares
/ (double)(len
/size
));
282 return PyInt_FromLong(val
);
285 static double _sum2(short *a
, short *b
, int len
)
290 for( i
=0; i
<len
; i
++) {
291 sum
= sum
+ (double)a
[i
]*(double)b
[i
];
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:
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.
329 audioop_findfit(PyObject
*self
, PyObject
*args
)
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
) )
339 if ( len1
& 1 || len2
& 1 ) {
340 PyErr_SetString(AudioopError
, "Strings should be even-sized");
347 PyErr_SetString(AudioopError
, "First sample should be longer");
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
;
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
)
370 if ( result
< best_result
) {
371 best_result
= result
;
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.
387 audioop_findfactor(PyObject
*self
, PyObject
*args
)
391 double sum_ri_2
, sum_aij_ri
, result
;
393 if ( !PyArg_Parse(args
, "(s#s#)", &cp1
, &len1
, &cp2
, &len2
) )
395 if ( len1
& 1 || len2
& 1 ) {
396 PyErr_SetString(AudioopError
, "Strings should be even-sized");
399 if ( len1
!= len2
) {
400 PyErr_SetString(AudioopError
, "Samples should be same size");
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.
417 audioop_findmax(PyObject
*self
, PyObject
*args
)
422 double aj_m1
, aj_lm1
;
423 double result
, best_result
;
425 if ( !PyArg_Parse(args
, "(s#i)", &cp1
, &len1
, &len2
) )
428 PyErr_SetString(AudioopError
, "Strings should be even-sized");
434 PyErr_SetString(AudioopError
, "Input sample should be longer");
438 result
= _sum2(cp1
, cp1
, len2
);
440 best_result
= result
;
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
;
457 return PyInt_FromLong(best_j
);
461 audioop_avgpp(PyObject
*self
, PyObject
*args
)
464 int len
, size
, val
= 0, prevval
= 0, prevextremevalid
= 0,
468 int diff
, prevdiff
, extremediff
, nextreme
= 0;
470 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
472 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
473 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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
;
503 prevextremevalid
= 1;
504 prevextreme
= prevval
;
513 val
= (int)(avg
/ (double)nextreme
);
514 return PyInt_FromLong(val
);
518 audioop_maxpp(PyObject
*self
, PyObject
*args
)
521 int len
, size
, val
= 0, prevval
= 0, prevextremevalid
= 0,
525 int diff
, prevdiff
, extremediff
;
527 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
529 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
530 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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
)
560 prevextremevalid
= 1;
561 prevextreme
= prevval
;
567 return PyInt_FromLong(max
);
571 audioop_cross(PyObject
*self
, PyObject
*args
)
574 int len
, size
, val
= 0;
578 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
580 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
581 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
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;
591 if ( val
!= prevval
) ncross
++;
594 return PyInt_FromLong(ncross
);
598 audioop_mul(PyObject
*self
, PyObject
*args
)
600 signed char *cp
, *ncp
;
601 int len
, size
, val
= 0;
602 double factor
, fval
, maxval
;
606 if ( !PyArg_Parse(args
, "(s#id)", &cp
, &len
, &size
, &factor
) )
609 if ( size
== 1 ) maxval
= (double) 0x7f;
610 else if ( size
== 2 ) maxval
= (double) 0x7fff;
611 else if ( size
== 4 ) maxval
= (double) 0x7fffffff;
613 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
617 rv
= PyString_FromStringAndSize(NULL
, len
);
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
;
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
;
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
;
647 if ( !PyArg_Parse(args
, "(s#idd)", &cp
, &len
, &size
, &fac1
, &fac2
) )
650 if ( size
== 1 ) maxval
= (double) 0x7f;
651 else if ( size
== 2 ) maxval
= (double) 0x7fff;
652 else if ( size
== 4 ) maxval
= (double) 0x7fffffff;
654 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
658 rv
= PyString_FromStringAndSize(NULL
, len
/2);
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
;
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
;
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
;
691 if ( !PyArg_Parse(args
, "(s#idd)", &cp
, &len
, &size
, &fac1
, &fac2
) )
694 if ( size
== 1 ) maxval
= (double) 0x7f;
695 else if ( size
== 2 ) maxval
= (double) 0x7fff;
696 else if ( size
== 4 ) maxval
= (double) 0x7fffffff;
698 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
702 rv
= PyString_FromStringAndSize(NULL
, len
*2);
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
;
718 fval
= (double)val
*fac2
;
719 if ( fval
> maxval
) fval
= maxval
;
720 else if ( fval
< -maxval
) fval
= -maxval
;
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
;
735 audioop_add(PyObject
*self
, PyObject
*args
)
737 signed char *cp1
, *cp2
, *ncp
;
738 int len1
, len2
, size
, val1
= 0, val2
= 0, maxval
, newval
;
742 if ( !PyArg_Parse(args
, "(s#s#i)",
743 &cp1
, &len1
, &cp2
, &len2
, &size
) )
746 if ( len1
!= len2
) {
747 PyErr_SetString(AudioopError
, "Lengths should be the same");
751 if ( size
== 1 ) maxval
= 0x7f;
752 else if ( size
== 2 ) maxval
= 0x7fff;
753 else if ( size
== 4 ) maxval
= 0x7fffffff;
755 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
759 rv
= PyString_FromStringAndSize(NULL
, len1
);
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
;
788 audioop_bias(PyObject
*self
, PyObject
*args
)
790 signed char *cp
, *ncp
;
791 int len
, size
, val
= 0;
796 if ( !PyArg_Parse(args
, "(s#ii)",
797 &cp
, &len
, &size
, &bias
) )
800 if ( size
!= 1 && size
!= 2 && size
!= 4) {
801 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
805 rv
= PyString_FromStringAndSize(NULL
, len
);
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
);
824 audioop_reverse(PyObject
*self
, PyObject
*args
)
828 int len
, size
, val
= 0;
832 if ( !PyArg_Parse(args
, "(s#i)",
836 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
837 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
841 rv
= PyString_FromStringAndSize(NULL
, len
);
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;
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);
861 audioop_lin2lin(PyObject
*self
, PyObject
*args
)
865 int len
, size
, size2
, val
= 0;
869 if ( !PyArg_Parse(args
, "(s#ii)",
870 &cp
, &len
, &size
, &size2
) )
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");
879 rv
= PyString_FromStringAndSize(NULL
, (len
/size
)*size2
);
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);
908 audioop_ratecv(PyObject
*self
, PyObject
*args
)
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
;
917 if (!PyArg_ParseTuple(args
, "s#iiiiO|ii:ratecv", &cp
, &len
, &size
, &nchannels
,
918 &inrate
, &outrate
, &state
, &weightA
, &weightB
))
920 if (size
!= 1 && size
!= 2 && size
!= 4) {
921 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
925 PyErr_SetString(AudioopError
, "# of channels should be >= 1");
928 if (weightA
< 1 || weightB
< 0) {
929 PyErr_SetString(AudioopError
,
930 "weightA should be >= 1, weightB should be >= 0");
933 if (len
% (size
* nchannels
) != 0) {
934 PyErr_SetString(AudioopError
, "not a whole number of frames");
937 if (inrate
<= 0 || outrate
<= 0) {
938 PyErr_SetString(AudioopError
, "sampling rate not > 0");
941 /* divide inrate and outrate by their greatest common divisor */
942 d
= gcd(inrate
, outrate
);
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();
954 if (state
== Py_None
) {
956 for (chan
= 0; chan
< nchannels
; chan
++)
957 prev_i
[chan
] = cur_i
[chan
] = 0;
959 if (!PyArg_ParseTuple(state
,
960 "iO!;audioop.ratecv: illegal state argument",
961 &d
, &PyTuple_Type
, &samps
))
963 if (PyTuple_Size(samps
) != nchannels
) {
964 PyErr_SetString(AudioopError
,
965 "illegal state argument");
968 for (chan
= 0; chan
< nchannels
; chan
++) {
969 if (!PyArg_ParseTuple(PyTuple_GetItem(samps
, chan
),
970 "ii:ratecv",&prev_i
[chan
],&cur_i
[chan
]))
974 str
= PyString_FromStringAndSize(
975 NULL
, size
* nchannels
* (len
* outrate
+ inrate
- 1) / inrate
);
978 ncp
= PyString_AsString(str
);
983 samps
= PyTuple_New(nchannels
);
984 for (chan
= 0; chan
< nchannels
; chan
++)
985 PyTuple_SetItem(samps
, chan
,
986 Py_BuildValue("(ii)",
989 if (PyErr_Occurred())
991 len
= ncp
- PyString_AsString(str
);
993 /*don't want to resize to zero length*/
994 rv
= PyString_FromStringAndSize("", 0);
997 } else if (_PyString_Resize(&str
, len
) < 0)
999 rv
= Py_BuildValue("(O(iO))", str
, d
, samps
);
1002 goto exit
; /* return rv */
1004 for (chan
= 0; chan
< nchannels
; chan
++) {
1005 prev_i
[chan
] = cur_i
[chan
];
1007 cur_i
[chan
] = ((int)*CHARP(cp
, 0)) << 8;
1009 cur_i
[chan
] = (int)*SHORTP(cp
, 0);
1011 cur_i
[chan
] = ((int)*LONGP(cp
, 0)) >> 16;
1013 /* implements a simple digital filter */
1015 (weightA
* cur_i
[chan
] +
1016 weightB
* prev_i
[chan
]) /
1017 (weightA
+ weightB
);
1023 for (chan
= 0; chan
< nchannels
; chan
++) {
1024 cur_o
= (prev_i
[chan
] * d
+
1025 cur_i
[chan
] * (outrate
- d
)) /
1028 *CHARP(ncp
, 0) = (signed char)(cur_o
>> 8);
1030 *SHORTP(ncp
, 0) = (short)(cur_o
);
1032 *LONGP(ncp
, 0) = (Py_Int32
)(cur_o
<<16);
1047 audioop_lin2ulaw(PyObject
*self
, PyObject
*args
)
1051 int len
, size
, val
= 0;
1055 if ( !PyArg_Parse(args
, "(s#i)",
1059 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1060 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1064 rv
= PyString_FromStringAndSize(NULL
, len
/size
);
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
);
1080 audioop_ulaw2lin(PyObject
*self
, PyObject
*args
)
1089 if ( !PyArg_Parse(args
, "(s#i)",
1093 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1094 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1098 rv
= PyString_FromStringAndSize(NULL
, len
*size
);
1101 ncp
= (signed char *)PyString_AsString(rv
);
1103 for ( i
=0; i
< len
*size
; i
+= size
) {
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);
1115 audioop_lin2adpcm(PyObject
*self
, PyObject
*args
)
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
) )
1129 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1130 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1134 str
= PyString_FromStringAndSize(NULL
, len
/(size
*2));
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 */
1145 } else if ( !PyArg_Parse(state
, "(ii)", &valpred
, &index
) )
1148 step
= stepsizeTable
[index
];
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 */
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.
1171 vpdiff
= (step
>> 3);
1173 if ( diff
>= step
) {
1179 if ( diff
>= step
) {
1185 if ( diff
>= step
) {
1190 /* Step 3 - Update previous value */
1196 /* Step 4 - Clamp previous value to 16 bits */
1197 if ( valpred
> 32767 )
1199 else if ( valpred
< -32768 )
1202 /* Step 5 - Assemble value, update index and step values */
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 */
1212 outputbuffer
= (delta
<< 4) & 0xf0;
1214 *ncp
++ = (delta
& 0x0f) | outputbuffer
;
1216 bufferstep
= !bufferstep
;
1218 rv
= Py_BuildValue("(O(ii))", str
, valpred
, index
);
1224 audioop_adpcm2lin(PyObject
*self
, PyObject
*args
)
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
) )
1236 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1237 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1241 /* Decode state, should have (value, step) */
1242 if ( state
== Py_None
) {
1243 /* First time, it seems. Set defaults */
1247 } else if ( !PyArg_Parse(state
, "(ii)", &valpred
, &index
) )
1250 str
= PyString_FromStringAndSize(NULL
, len
*size
*2);
1253 ncp
= (signed char *)PyString_AsString(str
);
1255 step
= stepsizeTable
[index
];
1258 for ( i
=0; i
< len
*size
*2; i
+= size
) {
1259 /* Step 1 - get the delta value and compute next index */
1261 delta
= inputbuffer
& 0xf;
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 */
1278 /* Step 4 - Compute difference and new predicted value */
1280 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1284 if ( delta
& 4 ) vpdiff
+= step
;
1285 if ( delta
& 2 ) vpdiff
+= step
>>1;
1286 if ( delta
& 1 ) vpdiff
+= step
>>2;
1293 /* Step 5 - clamp output value */
1294 if ( valpred
> 32767 )
1296 else if ( 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
);
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 },
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
);