2 /* audioopmodule - Module to detect peak values in arrays */
8 typedef unsigned int Py_UInt32
;
11 typedef long Py_Int32
;
12 typedef unsigned long Py_UInt32
;
14 #error "No 4-byte integral type"
18 #if defined(__CHAR_UNSIGNED__)
20 /* This module currently does not work on systems where only unsigned
21 characters are available. Take it out of Setup. Sorry. */
25 /* Code shamelessly stolen from sox,
26 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
30 #define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
31 else if ( x > MAXLIN ) x = MAXLIN; \
34 static unsigned char st_linear_to_ulaw(int sample
);
37 ** This macro converts from ulaw to 16 bit linear, faster.
42 ** Input: 8 bit ulaw sample
43 ** Output: signed 16 bit linear sample
45 #define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
47 static int ulaw_table
[256] = {
48 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
49 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
50 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
51 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
52 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
53 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
54 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
55 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
56 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
57 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
58 -876, -844, -812, -780, -748, -716, -684, -652,
59 -620, -588, -556, -524, -492, -460, -428, -396,
60 -372, -356, -340, -324, -308, -292, -276, -260,
61 -244, -228, -212, -196, -180, -164, -148, -132,
62 -120, -112, -104, -96, -88, -80, -72, -64,
63 -56, -48, -40, -32, -24, -16, -8, 0,
64 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
65 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
66 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
67 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
68 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
69 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
70 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
71 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
72 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
73 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
74 876, 844, 812, 780, 748, 716, 684, 652,
75 620, 588, 556, 524, 492, 460, 428, 396,
76 372, 356, 340, 324, 308, 292, 276, 260,
77 244, 228, 212, 196, 180, 164, 148, 132,
78 120, 112, 104, 96, 88, 80, 72, 64,
79 56, 48, 40, 32, 24, 16, 8, 0 };
81 /* #define ZEROTRAP */ /* turn on the trap as per the MIL-STD */
82 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
86 st_linear_to_ulaw(int sample
)
88 static int exp_lut
[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
89 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
90 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
91 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
92 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
93 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
94 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
95 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
96 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
97 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
98 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
99 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
100 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
101 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
102 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
103 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
104 int sign
, exponent
, mantissa
;
105 unsigned char ulawbyte
;
107 /* Get the sample into sign-magnitude. */
108 sign
= (sample
>> 8) & 0x80; /* set aside the sign */
109 if ( sign
!= 0 ) sample
= -sample
; /* get magnitude */
110 if ( sample
> CLIP
) sample
= CLIP
; /* clip the magnitude */
112 /* Convert from 16 bit linear to ulaw. */
113 sample
= sample
+ BIAS
;
114 exponent
= exp_lut
[( sample
>> 7 ) & 0xFF];
115 mantissa
= ( sample
>> ( exponent
+ 3 ) ) & 0x0F;
116 ulawbyte
= ~ ( sign
| ( exponent
<< 4 ) | mantissa
);
118 if ( ulawbyte
== 0 ) ulawbyte
= 0x02; /* optional CCITT trap */
123 /* End of code taken from sox */
125 /* Intel ADPCM step variation table */
126 static int indexTable
[16] = {
127 -1, -1, -1, -1, 2, 4, 6, 8,
128 -1, -1, -1, -1, 2, 4, 6, 8,
131 static int stepsizeTable
[89] = {
132 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
133 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
134 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
135 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
136 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
137 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
138 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
139 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
140 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
143 #define CHARP(cp, i) ((signed char *)(cp+i))
144 #define SHORTP(cp, i) ((short *)(cp+i))
145 #define LONGP(cp, i) ((Py_Int32 *)(cp+i))
149 static PyObject
*AudioopError
;
152 audioop_getsample(PyObject
*self
, PyObject
*args
)
155 int len
, size
, val
= 0;
158 if ( !PyArg_Parse(args
, "(s#ii)", &cp
, &len
, &size
, &i
) )
160 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
161 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
164 if ( i
< 0 || i
>= len
/size
) {
165 PyErr_SetString(AudioopError
, "Index out of range");
168 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
169 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
*2);
170 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
*4);
171 return PyInt_FromLong(val
);
175 audioop_max(PyObject
*self
, PyObject
*args
)
178 int len
, size
, val
= 0;
182 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
184 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
185 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
188 for ( i
=0; i
<len
; i
+= size
) {
189 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
190 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
191 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
192 if ( val
< 0 ) val
= (-val
);
193 if ( val
> max
) max
= val
;
195 return PyInt_FromLong(max
);
199 audioop_minmax(PyObject
*self
, PyObject
*args
)
202 int len
, size
, val
= 0;
204 int min
= 0x7fffffff, max
= -0x7fffffff;
206 if (!PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
))
208 if (size
!= 1 && size
!= 2 && size
!= 4) {
209 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
212 for (i
= 0; i
< len
; i
+= size
) {
213 if (size
== 1) val
= (int) *CHARP(cp
, i
);
214 else if (size
== 2) val
= (int) *SHORTP(cp
, i
);
215 else if (size
== 4) val
= (int) *LONGP(cp
, i
);
216 if (val
> max
) max
= val
;
217 if (val
< min
) min
= val
;
219 return Py_BuildValue("(ii)", min
, max
);
223 audioop_avg(PyObject
*self
, PyObject
*args
)
226 int len
, size
, val
= 0;
230 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
232 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
233 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
236 for ( i
=0; i
<len
; i
+= size
) {
237 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
238 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
239 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
245 val
= (int)(avg
/ (double)(len
/size
));
246 return PyInt_FromLong(val
);
250 audioop_rms(PyObject
*self
, PyObject
*args
)
253 int len
, size
, val
= 0;
255 double sum_squares
= 0.0;
257 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
259 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
260 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
263 for ( i
=0; i
<len
; i
+= size
) {
264 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
265 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
266 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
267 sum_squares
+= (double)val
*(double)val
;
272 val
= (int)sqrt(sum_squares
/ (double)(len
/size
));
273 return PyInt_FromLong(val
);
276 static double _sum2(short *a
, short *b
, int len
)
281 for( i
=0; i
<len
; i
++) {
282 sum
= sum
+ (double)a
[i
]*(double)b
[i
];
288 ** Findfit tries to locate a sample within another sample. Its main use
289 ** is in echo-cancellation (to find the feedback of the output signal in
290 ** the input signal).
291 ** The method used is as follows:
293 ** let R be the reference signal (length n) and A the input signal (length N)
294 ** with N > n, and let all sums be over i from 0 to n-1.
296 ** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
297 ** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
298 ** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
300 ** Next, we compute the relative distance between the original signal and
301 ** the modified signal and minimize that over j:
302 ** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
303 ** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
305 ** In the code variables correspond as follows:
312 ** sum_ri_2 sum(R[i]^2)
313 ** sum_aij_2 sum(A[i+j]^2)
314 ** sum_aij_ri sum(A[i+j]R[i])
316 ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
317 ** is completely recalculated each step.
320 audioop_findfit(PyObject
*self
, PyObject
*args
)
325 double aj_m1
, aj_lm1
;
326 double sum_ri_2
, sum_aij_2
, sum_aij_ri
, result
, best_result
, factor
;
328 if ( !PyArg_Parse(args
, "(s#s#)", &cp1
, &len1
, &cp2
, &len2
) )
330 if ( len1
& 1 || len2
& 1 ) {
331 PyErr_SetString(AudioopError
, "Strings should be even-sized");
338 PyErr_SetString(AudioopError
, "First sample should be longer");
341 sum_ri_2
= _sum2(cp2
, cp2
, len2
);
342 sum_aij_2
= _sum2(cp1
, cp1
, len2
);
343 sum_aij_ri
= _sum2(cp1
, cp2
, len2
);
345 result
= (sum_ri_2
*sum_aij_2
- sum_aij_ri
*sum_aij_ri
) / sum_aij_2
;
347 best_result
= result
;
351 for ( j
=1; j
<=len1
-len2
; j
++) {
352 aj_m1
= (double)cp1
[j
-1];
353 aj_lm1
= (double)cp1
[j
+len2
-1];
355 sum_aij_2
= sum_aij_2
+ aj_lm1
*aj_lm1
- aj_m1
*aj_m1
;
356 sum_aij_ri
= _sum2(cp1
+j
, cp2
, len2
);
358 result
= (sum_ri_2
*sum_aij_2
- sum_aij_ri
*sum_aij_ri
)
361 if ( result
< best_result
) {
362 best_result
= result
;
368 factor
= _sum2(cp1
+best_j
, cp2
, len2
) / sum_ri_2
;
370 return Py_BuildValue("(if)", best_j
, factor
);
374 ** findfactor finds a factor f so that the energy in A-fB is minimal.
375 ** See the comment for findfit for details.
378 audioop_findfactor(PyObject
*self
, PyObject
*args
)
382 double sum_ri_2
, sum_aij_ri
, result
;
384 if ( !PyArg_Parse(args
, "(s#s#)", &cp1
, &len1
, &cp2
, &len2
) )
386 if ( len1
& 1 || len2
& 1 ) {
387 PyErr_SetString(AudioopError
, "Strings should be even-sized");
390 if ( len1
!= len2
) {
391 PyErr_SetString(AudioopError
, "Samples should be same size");
395 sum_ri_2
= _sum2(cp2
, cp2
, len2
);
396 sum_aij_ri
= _sum2(cp1
, cp2
, len2
);
398 result
= sum_aij_ri
/ sum_ri_2
;
400 return PyFloat_FromDouble(result
);
404 ** findmax returns the index of the n-sized segment of the input sample
405 ** that contains the most energy.
408 audioop_findmax(PyObject
*self
, PyObject
*args
)
413 double aj_m1
, aj_lm1
;
414 double result
, best_result
;
416 if ( !PyArg_Parse(args
, "(s#i)", &cp1
, &len1
, &len2
) )
419 PyErr_SetString(AudioopError
, "Strings should be even-sized");
425 PyErr_SetString(AudioopError
, "Input sample should be longer");
429 result
= _sum2(cp1
, cp1
, len2
);
431 best_result
= result
;
435 for ( j
=1; j
<=len1
-len2
; j
++) {
436 aj_m1
= (double)cp1
[j
-1];
437 aj_lm1
= (double)cp1
[j
+len2
-1];
439 result
= result
+ aj_lm1
*aj_lm1
- aj_m1
*aj_m1
;
441 if ( result
> best_result
) {
442 best_result
= result
;
448 return PyInt_FromLong(best_j
);
452 audioop_avgpp(PyObject
*self
, PyObject
*args
)
455 int len
, size
, val
= 0, prevval
= 0, prevextremevalid
= 0,
459 int diff
, prevdiff
, extremediff
, nextreme
= 0;
461 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
463 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
464 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
467 /* Compute first delta value ahead. Also automatically makes us
468 ** skip the first extreme value
470 if ( size
== 1 ) prevval
= (int)*CHARP(cp
, 0);
471 else if ( size
== 2 ) prevval
= (int)*SHORTP(cp
, 0);
472 else if ( size
== 4 ) prevval
= (int)*LONGP(cp
, 0);
473 if ( size
== 1 ) val
= (int)*CHARP(cp
, size
);
474 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, size
);
475 else if ( size
== 4 ) val
= (int)*LONGP(cp
, size
);
476 prevdiff
= val
- prevval
;
478 for ( i
=size
; i
<len
; i
+= size
) {
479 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
480 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
481 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
482 diff
= val
- prevval
;
483 if ( diff
*prevdiff
< 0 ) {
484 /* Derivative changed sign. Compute difference to last
485 ** extreme value and remember.
487 if ( prevextremevalid
) {
488 extremediff
= prevval
- prevextreme
;
489 if ( extremediff
< 0 )
490 extremediff
= -extremediff
;
494 prevextremevalid
= 1;
495 prevextreme
= prevval
;
504 val
= (int)(avg
/ (double)nextreme
);
505 return PyInt_FromLong(val
);
509 audioop_maxpp(PyObject
*self
, PyObject
*args
)
512 int len
, size
, val
= 0, prevval
= 0, prevextremevalid
= 0,
516 int diff
, prevdiff
, extremediff
;
518 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
520 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
521 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
524 /* Compute first delta value ahead. Also automatically makes us
525 ** skip the first extreme value
527 if ( size
== 1 ) prevval
= (int)*CHARP(cp
, 0);
528 else if ( size
== 2 ) prevval
= (int)*SHORTP(cp
, 0);
529 else if ( size
== 4 ) prevval
= (int)*LONGP(cp
, 0);
530 if ( size
== 1 ) val
= (int)*CHARP(cp
, size
);
531 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, size
);
532 else if ( size
== 4 ) val
= (int)*LONGP(cp
, size
);
533 prevdiff
= val
- prevval
;
535 for ( i
=size
; i
<len
; i
+= size
) {
536 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
537 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
538 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
539 diff
= val
- prevval
;
540 if ( diff
*prevdiff
< 0 ) {
541 /* Derivative changed sign. Compute difference to
542 ** last extreme value and remember.
544 if ( prevextremevalid
) {
545 extremediff
= prevval
- prevextreme
;
546 if ( extremediff
< 0 )
547 extremediff
= -extremediff
;
548 if ( extremediff
> max
)
551 prevextremevalid
= 1;
552 prevextreme
= prevval
;
558 return PyInt_FromLong(max
);
562 audioop_cross(PyObject
*self
, PyObject
*args
)
565 int len
, size
, val
= 0;
569 if ( !PyArg_Parse(args
, "(s#i)", &cp
, &len
, &size
) )
571 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
572 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
576 prevval
= 17; /* Anything <> 0,1 */
577 for ( i
=0; i
<len
; i
+= size
) {
578 if ( size
== 1 ) val
= ((int)*CHARP(cp
, i
)) >> 7;
579 else if ( size
== 2 ) val
= ((int)*SHORTP(cp
, i
)) >> 15;
580 else if ( size
== 4 ) val
= ((int)*LONGP(cp
, i
)) >> 31;
582 if ( val
!= prevval
) ncross
++;
585 return PyInt_FromLong(ncross
);
589 audioop_mul(PyObject
*self
, PyObject
*args
)
591 signed char *cp
, *ncp
;
592 int len
, size
, val
= 0;
593 double factor
, fval
, maxval
;
597 if ( !PyArg_Parse(args
, "(s#id)", &cp
, &len
, &size
, &factor
) )
600 if ( size
== 1 ) maxval
= (double) 0x7f;
601 else if ( size
== 2 ) maxval
= (double) 0x7fff;
602 else if ( size
== 4 ) maxval
= (double) 0x7fffffff;
604 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
608 rv
= PyString_FromStringAndSize(NULL
, len
);
611 ncp
= (signed char *)PyString_AsString(rv
);
614 for ( i
=0; i
< len
; i
+= size
) {
615 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
616 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
617 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
618 fval
= (double)val
*factor
;
619 if ( fval
> maxval
) fval
= maxval
;
620 else if ( fval
< -maxval
) fval
= -maxval
;
622 if ( size
== 1 ) *CHARP(ncp
, i
) = (signed char)val
;
623 else if ( size
== 2 ) *SHORTP(ncp
, i
) = (short)val
;
624 else if ( size
== 4 ) *LONGP(ncp
, i
) = (Py_Int32
)val
;
630 audioop_tomono(PyObject
*self
, PyObject
*args
)
632 signed char *cp
, *ncp
;
633 int len
, size
, val1
= 0, val2
= 0;
634 double fac1
, fac2
, fval
, maxval
;
638 if ( !PyArg_Parse(args
, "(s#idd)", &cp
, &len
, &size
, &fac1
, &fac2
) )
641 if ( size
== 1 ) maxval
= (double) 0x7f;
642 else if ( size
== 2 ) maxval
= (double) 0x7fff;
643 else if ( size
== 4 ) maxval
= (double) 0x7fffffff;
645 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
649 rv
= PyString_FromStringAndSize(NULL
, len
/2);
652 ncp
= (signed char *)PyString_AsString(rv
);
655 for ( i
=0; i
< len
; i
+= size
*2 ) {
656 if ( size
== 1 ) val1
= (int)*CHARP(cp
, i
);
657 else if ( size
== 2 ) val1
= (int)*SHORTP(cp
, i
);
658 else if ( size
== 4 ) val1
= (int)*LONGP(cp
, i
);
659 if ( size
== 1 ) val2
= (int)*CHARP(cp
, i
+1);
660 else if ( size
== 2 ) val2
= (int)*SHORTP(cp
, i
+2);
661 else if ( size
== 4 ) val2
= (int)*LONGP(cp
, i
+4);
662 fval
= (double)val1
*fac1
+ (double)val2
*fac2
;
663 if ( fval
> maxval
) fval
= maxval
;
664 else if ( fval
< -maxval
) fval
= -maxval
;
666 if ( size
== 1 ) *CHARP(ncp
, i
/2) = (signed char)val1
;
667 else if ( size
== 2 ) *SHORTP(ncp
, i
/2) = (short)val1
;
668 else if ( size
== 4 ) *LONGP(ncp
, i
/2)= (Py_Int32
)val1
;
674 audioop_tostereo(PyObject
*self
, PyObject
*args
)
676 signed char *cp
, *ncp
;
677 int len
, size
, val1
, val2
, val
= 0;
678 double fac1
, fac2
, fval
, maxval
;
682 if ( !PyArg_Parse(args
, "(s#idd)", &cp
, &len
, &size
, &fac1
, &fac2
) )
685 if ( size
== 1 ) maxval
= (double) 0x7f;
686 else if ( size
== 2 ) maxval
= (double) 0x7fff;
687 else if ( size
== 4 ) maxval
= (double) 0x7fffffff;
689 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
693 rv
= PyString_FromStringAndSize(NULL
, len
*2);
696 ncp
= (signed char *)PyString_AsString(rv
);
699 for ( i
=0; i
< len
; i
+= size
) {
700 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
701 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
702 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
704 fval
= (double)val
*fac1
;
705 if ( fval
> maxval
) fval
= maxval
;
706 else if ( fval
< -maxval
) fval
= -maxval
;
709 fval
= (double)val
*fac2
;
710 if ( fval
> maxval
) fval
= maxval
;
711 else if ( fval
< -maxval
) fval
= -maxval
;
714 if ( size
== 1 ) *CHARP(ncp
, i
*2) = (signed char)val1
;
715 else if ( size
== 2 ) *SHORTP(ncp
, i
*2) = (short)val1
;
716 else if ( size
== 4 ) *LONGP(ncp
, i
*2) = (Py_Int32
)val1
;
718 if ( size
== 1 ) *CHARP(ncp
, i
*2+1) = (signed char)val2
;
719 else if ( size
== 2 ) *SHORTP(ncp
, i
*2+2) = (short)val2
;
720 else if ( size
== 4 ) *LONGP(ncp
, i
*2+4) = (Py_Int32
)val2
;
726 audioop_add(PyObject
*self
, PyObject
*args
)
728 signed char *cp1
, *cp2
, *ncp
;
729 int len1
, len2
, size
, val1
= 0, val2
= 0, maxval
, newval
;
733 if ( !PyArg_Parse(args
, "(s#s#i)",
734 &cp1
, &len1
, &cp2
, &len2
, &size
) )
737 if ( len1
!= len2
) {
738 PyErr_SetString(AudioopError
, "Lengths should be the same");
742 if ( size
== 1 ) maxval
= 0x7f;
743 else if ( size
== 2 ) maxval
= 0x7fff;
744 else if ( size
== 4 ) maxval
= 0x7fffffff;
746 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
750 rv
= PyString_FromStringAndSize(NULL
, len1
);
753 ncp
= (signed char *)PyString_AsString(rv
);
755 for ( i
=0; i
< len1
; i
+= size
) {
756 if ( size
== 1 ) val1
= (int)*CHARP(cp1
, i
);
757 else if ( size
== 2 ) val1
= (int)*SHORTP(cp1
, i
);
758 else if ( size
== 4 ) val1
= (int)*LONGP(cp1
, i
);
760 if ( size
== 1 ) val2
= (int)*CHARP(cp2
, i
);
761 else if ( size
== 2 ) val2
= (int)*SHORTP(cp2
, i
);
762 else if ( size
== 4 ) val2
= (int)*LONGP(cp2
, i
);
764 newval
= val1
+ val2
;
765 /* truncate in case of overflow */
766 if (newval
> maxval
) newval
= maxval
;
767 else if (newval
< -maxval
) newval
= -maxval
;
768 else if (size
== 4 && (newval
^val1
) < 0 && (newval
^val2
) < 0)
769 newval
= val1
> 0 ? maxval
: - maxval
;
771 if ( size
== 1 ) *CHARP(ncp
, i
) = (signed char)newval
;
772 else if ( size
== 2 ) *SHORTP(ncp
, i
) = (short)newval
;
773 else if ( size
== 4 ) *LONGP(ncp
, i
) = (Py_Int32
)newval
;
779 audioop_bias(PyObject
*self
, PyObject
*args
)
781 signed char *cp
, *ncp
;
782 int len
, size
, val
= 0;
787 if ( !PyArg_Parse(args
, "(s#ii)",
788 &cp
, &len
, &size
, &bias
) )
791 if ( size
!= 1 && size
!= 2 && size
!= 4) {
792 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
796 rv
= PyString_FromStringAndSize(NULL
, len
);
799 ncp
= (signed char *)PyString_AsString(rv
);
802 for ( i
=0; i
< len
; i
+= size
) {
803 if ( size
== 1 ) val
= (int)*CHARP(cp
, i
);
804 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
805 else if ( size
== 4 ) val
= (int)*LONGP(cp
, i
);
807 if ( size
== 1 ) *CHARP(ncp
, i
) = (signed char)(val
+bias
);
808 else if ( size
== 2 ) *SHORTP(ncp
, i
) = (short)(val
+bias
);
809 else if ( size
== 4 ) *LONGP(ncp
, i
) = (Py_Int32
)(val
+bias
);
815 audioop_reverse(PyObject
*self
, PyObject
*args
)
819 int len
, size
, val
= 0;
823 if ( !PyArg_Parse(args
, "(s#i)",
827 if ( size
!= 1 && size
!= 2 && size
!= 4 ) {
828 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
832 rv
= PyString_FromStringAndSize(NULL
, len
);
835 ncp
= (unsigned char *)PyString_AsString(rv
);
837 for ( i
=0; i
< len
; i
+= size
) {
838 if ( size
== 1 ) val
= ((int)*CHARP(cp
, i
)) << 8;
839 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
840 else if ( size
== 4 ) val
= ((int)*LONGP(cp
, i
)) >> 16;
844 if ( size
== 1 ) *CHARP(ncp
, j
) = (signed char)(val
>> 8);
845 else if ( size
== 2 ) *SHORTP(ncp
, j
) = (short)(val
);
846 else if ( size
== 4 ) *LONGP(ncp
, j
) = (Py_Int32
)(val
<<16);
852 audioop_lin2lin(PyObject
*self
, PyObject
*args
)
856 int len
, size
, size2
, val
= 0;
860 if ( !PyArg_Parse(args
, "(s#ii)",
861 &cp
, &len
, &size
, &size2
) )
864 if ( (size
!= 1 && size
!= 2 && size
!= 4) ||
865 (size2
!= 1 && size2
!= 2 && size2
!= 4)) {
866 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
870 rv
= PyString_FromStringAndSize(NULL
, (len
/size
)*size2
);
873 ncp
= (unsigned char *)PyString_AsString(rv
);
875 for ( i
=0, j
=0; i
< len
; i
+= size
, j
+= size2
) {
876 if ( size
== 1 ) val
= ((int)*CHARP(cp
, i
)) << 8;
877 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
878 else if ( size
== 4 ) val
= ((int)*LONGP(cp
, i
)) >> 16;
880 if ( size2
== 1 ) *CHARP(ncp
, j
) = (signed char)(val
>> 8);
881 else if ( size2
== 2 ) *SHORTP(ncp
, j
) = (short)(val
);
882 else if ( size2
== 4 ) *LONGP(ncp
, j
) = (Py_Int32
)(val
<<16);
899 audioop_ratecv(PyObject
*self
, PyObject
*args
)
902 int len
, size
, nchannels
, inrate
, outrate
, weightA
, weightB
;
903 int chan
, d
, *prev_i
, *cur_i
, cur_o
;
904 PyObject
*state
, *samps
, *str
, *rv
= NULL
;
908 if (!PyArg_ParseTuple(args
, "s#iiiiO|ii:ratecv", &cp
, &len
, &size
, &nchannels
,
909 &inrate
, &outrate
, &state
, &weightA
, &weightB
))
911 if (size
!= 1 && size
!= 2 && size
!= 4) {
912 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
916 PyErr_SetString(AudioopError
, "# of channels should be >= 1");
919 if (weightA
< 1 || weightB
< 0) {
920 PyErr_SetString(AudioopError
,
921 "weightA should be >= 1, weightB should be >= 0");
924 if (len
% (size
* nchannels
) != 0) {
925 PyErr_SetString(AudioopError
, "not a whole number of frames");
928 if (inrate
<= 0 || outrate
<= 0) {
929 PyErr_SetString(AudioopError
, "sampling rate not > 0");
932 /* divide inrate and outrate by their greatest common divisor */
933 d
= gcd(inrate
, outrate
);
937 prev_i
= (int *) malloc(nchannels
* sizeof(int));
938 cur_i
= (int *) malloc(nchannels
* sizeof(int));
939 len
/= size
* nchannels
; /* # of frames */
940 if (prev_i
== NULL
|| cur_i
== NULL
) {
941 (void) PyErr_NoMemory();
945 if (state
== Py_None
) {
947 for (chan
= 0; chan
< nchannels
; chan
++)
948 prev_i
[chan
] = cur_i
[chan
] = 0;
950 if (!PyArg_ParseTuple(state
,
951 "iO!;audioop.ratecv: illegal state argument",
952 &d
, &PyTuple_Type
, &samps
))
954 if (PyTuple_Size(samps
) != nchannels
) {
955 PyErr_SetString(AudioopError
,
956 "illegal state argument");
959 for (chan
= 0; chan
< nchannels
; chan
++) {
960 if (!PyArg_ParseTuple(PyTuple_GetItem(samps
, chan
),
961 "ii:ratecv",&prev_i
[chan
],&cur_i
[chan
]))
965 str
= PyString_FromStringAndSize(
966 NULL
, size
* nchannels
* (len
* outrate
+ inrate
- 1) / inrate
);
969 ncp
= PyString_AsString(str
);
974 samps
= PyTuple_New(nchannels
);
975 for (chan
= 0; chan
< nchannels
; chan
++)
976 PyTuple_SetItem(samps
, chan
,
977 Py_BuildValue("(ii)",
980 if (PyErr_Occurred())
982 len
= ncp
- PyString_AsString(str
);
984 /*don't want to resize to zero length*/
985 rv
= PyString_FromStringAndSize("", 0);
988 } else if (_PyString_Resize(&str
, len
) < 0)
990 rv
= Py_BuildValue("(O(iO))", str
, d
, samps
);
993 goto exit
; /* return rv */
995 for (chan
= 0; chan
< nchannels
; chan
++) {
996 prev_i
[chan
] = cur_i
[chan
];
998 cur_i
[chan
] = ((int)*CHARP(cp
, 0)) << 8;
1000 cur_i
[chan
] = (int)*SHORTP(cp
, 0);
1002 cur_i
[chan
] = ((int)*LONGP(cp
, 0)) >> 16;
1004 /* implements a simple digital filter */
1006 (weightA
* cur_i
[chan
] +
1007 weightB
* prev_i
[chan
]) /
1008 (weightA
+ weightB
);
1014 for (chan
= 0; chan
< nchannels
; chan
++) {
1015 cur_o
= (prev_i
[chan
] * d
+
1016 cur_i
[chan
] * (outrate
- d
)) /
1019 *CHARP(ncp
, 0) = (signed char)(cur_o
>> 8);
1021 *SHORTP(ncp
, 0) = (short)(cur_o
);
1023 *LONGP(ncp
, 0) = (Py_Int32
)(cur_o
<<16);
1038 audioop_lin2ulaw(PyObject
*self
, PyObject
*args
)
1042 int len
, size
, val
= 0;
1046 if ( !PyArg_Parse(args
, "(s#i)",
1050 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1051 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1055 rv
= PyString_FromStringAndSize(NULL
, len
/size
);
1058 ncp
= (unsigned char *)PyString_AsString(rv
);
1060 for ( i
=0; i
< len
; i
+= size
) {
1061 if ( size
== 1 ) val
= ((int)*CHARP(cp
, i
)) << 8;
1062 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
1063 else if ( size
== 4 ) val
= ((int)*LONGP(cp
, i
)) >> 16;
1065 *ncp
++ = st_linear_to_ulaw(val
);
1071 audioop_ulaw2lin(PyObject
*self
, PyObject
*args
)
1080 if ( !PyArg_Parse(args
, "(s#i)",
1084 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1085 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1089 rv
= PyString_FromStringAndSize(NULL
, len
*size
);
1092 ncp
= (signed char *)PyString_AsString(rv
);
1094 for ( i
=0; i
< len
*size
; i
+= size
) {
1096 val
= st_ulaw_to_linear(cval
);
1098 if ( size
== 1 ) *CHARP(ncp
, i
) = (signed char)(val
>> 8);
1099 else if ( size
== 2 ) *SHORTP(ncp
, i
) = (short)(val
);
1100 else if ( size
== 4 ) *LONGP(ncp
, i
) = (Py_Int32
)(val
<<16);
1106 audioop_lin2adpcm(PyObject
*self
, PyObject
*args
)
1110 int len
, size
, val
= 0, step
, valpred
, delta
,
1111 index
, sign
, vpdiff
, diff
;
1112 PyObject
*rv
, *state
, *str
;
1113 int i
, outputbuffer
= 0, bufferstep
;
1115 if ( !PyArg_Parse(args
, "(s#iO)",
1116 &cp
, &len
, &size
, &state
) )
1120 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1121 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1125 str
= PyString_FromStringAndSize(NULL
, len
/(size
*2));
1128 ncp
= (signed char *)PyString_AsString(str
);
1130 /* Decode state, should have (value, step) */
1131 if ( state
== Py_None
) {
1132 /* First time, it seems. Set defaults */
1136 } else if ( !PyArg_Parse(state
, "(ii)", &valpred
, &index
) )
1139 step
= stepsizeTable
[index
];
1142 for ( i
=0; i
< len
; i
+= size
) {
1143 if ( size
== 1 ) val
= ((int)*CHARP(cp
, i
)) << 8;
1144 else if ( size
== 2 ) val
= (int)*SHORTP(cp
, i
);
1145 else if ( size
== 4 ) val
= ((int)*LONGP(cp
, i
)) >> 16;
1147 /* Step 1 - compute difference with previous value */
1148 diff
= val
- valpred
;
1149 sign
= (diff
< 0) ? 8 : 0;
1150 if ( sign
) diff
= (-diff
);
1152 /* Step 2 - Divide and clamp */
1154 ** This code *approximately* computes:
1155 ** delta = diff*4/step;
1156 ** vpdiff = (delta+0.5)*step/4;
1157 ** but in shift step bits are dropped. The net result of this
1158 ** is that even if you have fast mul/div hardware you cannot
1159 ** put it to good use since the fixup would be too expensive.
1162 vpdiff
= (step
>> 3);
1164 if ( diff
>= step
) {
1170 if ( diff
>= step
) {
1176 if ( diff
>= step
) {
1181 /* Step 3 - Update previous value */
1187 /* Step 4 - Clamp previous value to 16 bits */
1188 if ( valpred
> 32767 )
1190 else if ( valpred
< -32768 )
1193 /* Step 5 - Assemble value, update index and step values */
1196 index
+= indexTable
[delta
];
1197 if ( index
< 0 ) index
= 0;
1198 if ( index
> 88 ) index
= 88;
1199 step
= stepsizeTable
[index
];
1201 /* Step 6 - Output value */
1203 outputbuffer
= (delta
<< 4) & 0xf0;
1205 *ncp
++ = (delta
& 0x0f) | outputbuffer
;
1207 bufferstep
= !bufferstep
;
1209 rv
= Py_BuildValue("(O(ii))", str
, valpred
, index
);
1215 audioop_adpcm2lin(PyObject
*self
, PyObject
*args
)
1219 int len
, size
, valpred
, step
, delta
, index
, sign
, vpdiff
;
1220 PyObject
*rv
, *str
, *state
;
1221 int i
, inputbuffer
= 0, bufferstep
;
1223 if ( !PyArg_Parse(args
, "(s#iO)",
1224 &cp
, &len
, &size
, &state
) )
1227 if ( size
!= 1 && size
!= 2 && size
!= 4) {
1228 PyErr_SetString(AudioopError
, "Size should be 1, 2 or 4");
1232 /* Decode state, should have (value, step) */
1233 if ( state
== Py_None
) {
1234 /* First time, it seems. Set defaults */
1238 } else if ( !PyArg_Parse(state
, "(ii)", &valpred
, &index
) )
1241 str
= PyString_FromStringAndSize(NULL
, len
*size
*2);
1244 ncp
= (signed char *)PyString_AsString(str
);
1246 step
= stepsizeTable
[index
];
1249 for ( i
=0; i
< len
*size
*2; i
+= size
) {
1250 /* Step 1 - get the delta value and compute next index */
1252 delta
= inputbuffer
& 0xf;
1254 inputbuffer
= *cp
++;
1255 delta
= (inputbuffer
>> 4) & 0xf;
1258 bufferstep
= !bufferstep
;
1260 /* Step 2 - Find new index value (for later) */
1261 index
+= indexTable
[delta
];
1262 if ( index
< 0 ) index
= 0;
1263 if ( index
> 88 ) index
= 88;
1265 /* Step 3 - Separate sign and magnitude */
1269 /* Step 4 - Compute difference and new predicted value */
1271 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1275 if ( delta
& 4 ) vpdiff
+= step
;
1276 if ( delta
& 2 ) vpdiff
+= step
>>1;
1277 if ( delta
& 1 ) vpdiff
+= step
>>2;
1284 /* Step 5 - clamp output value */
1285 if ( valpred
> 32767 )
1287 else if ( valpred
< -32768 )
1290 /* Step 6 - Update step value */
1291 step
= stepsizeTable
[index
];
1293 /* Step 6 - Output value */
1294 if ( size
== 1 ) *CHARP(ncp
, i
) = (signed char)(valpred
>> 8);
1295 else if ( size
== 2 ) *SHORTP(ncp
, i
) = (short)(valpred
);
1296 else if ( size
== 4 ) *LONGP(ncp
, i
) = (Py_Int32
)(valpred
<<16);
1299 rv
= Py_BuildValue("(O(ii))", str
, valpred
, index
);
1304 static PyMethodDef audioop_methods
[] = {
1305 { "max", audioop_max
},
1306 { "minmax", audioop_minmax
},
1307 { "avg", audioop_avg
},
1308 { "maxpp", audioop_maxpp
},
1309 { "avgpp", audioop_avgpp
},
1310 { "rms", audioop_rms
},
1311 { "findfit", audioop_findfit
},
1312 { "findmax", audioop_findmax
},
1313 { "findfactor", audioop_findfactor
},
1314 { "cross", audioop_cross
},
1315 { "mul", audioop_mul
},
1316 { "add", audioop_add
},
1317 { "bias", audioop_bias
},
1318 { "ulaw2lin", audioop_ulaw2lin
},
1319 { "lin2ulaw", audioop_lin2ulaw
},
1320 { "lin2lin", audioop_lin2lin
},
1321 { "adpcm2lin", audioop_adpcm2lin
},
1322 { "lin2adpcm", audioop_lin2adpcm
},
1323 { "tomono", audioop_tomono
},
1324 { "tostereo", audioop_tostereo
},
1325 { "getsample", audioop_getsample
},
1326 { "reverse", audioop_reverse
},
1327 { "ratecv", audioop_ratecv
, 1 },
1335 m
= Py_InitModule("audioop", audioop_methods
);
1336 d
= PyModule_GetDict(m
);
1337 AudioopError
= PyErr_NewException("audioop.error", NULL
, NULL
);
1338 if (AudioopError
!= NULL
)
1339 PyDict_SetItemString(d
,"error",AudioopError
);