Speed-up isinstance() for one easy case.
[python.git] / Modules / audioop.c
blobce009758dee4e64787c03aa3a3a52ecbfb98461e
2 /* audioopmodule - Module to detect peak values in arrays */
4 #include "Python.h"
6 #if SIZEOF_INT == 4
7 typedef int Py_Int32;
8 typedef unsigned int Py_UInt32;
9 #else
10 #if SIZEOF_LONG == 4
11 typedef long Py_Int32;
12 typedef unsigned long Py_UInt32;
13 #else
14 #error "No 4-byte integral type"
15 #endif
16 #endif
18 typedef short PyInt16;
20 #if defined(__CHAR_UNSIGNED__)
21 #if defined(signed)
22 /* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24 #endif
25 #endif
27 /* Code shamelessly stolen from sox, 12.17.7, g711.c
28 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
30 /* From g711.c:
32 * December 30, 1994:
33 * Functions linear2alaw, linear2ulaw have been updated to correctly
34 * convert unquantized 16 bit values.
35 * Tables for direct u- to A-law and A- to u-law conversions have been
36 * corrected.
37 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
38 * bli@cpk.auc.dk
41 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
42 #define CLIP 32635
43 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
44 #define QUANT_MASK (0xf) /* Quantization field mask. */
45 #define SEG_SHIFT (4) /* Left shift for segment number. */
46 #define SEG_MASK (0x70) /* Segment field mask. */
48 static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
49 0x1FF, 0x3FF, 0x7FF, 0xFFF};
50 static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
51 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
53 static PyInt16
54 search(PyInt16 val, PyInt16 *table, int size)
56 int i;
58 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
62 return (size);
64 #define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
65 #define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
67 static PyInt16 _st_ulaw2linear16[256] = {
68 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
69 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
70 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
71 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
72 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
73 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
74 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
75 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
76 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
77 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
78 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
79 -1052, -988, -924, -876, -844, -812, -780,
80 -748, -716, -684, -652, -620, -588, -556,
81 -524, -492, -460, -428, -396, -372, -356,
82 -340, -324, -308, -292, -276, -260, -244,
83 -228, -212, -196, -180, -164, -148, -132,
84 -120, -112, -104, -96, -88, -80, -72,
85 -64, -56, -48, -40, -32, -24, -16,
86 -8, 0, 32124, 31100, 30076, 29052, 28028,
87 27004, 25980, 24956, 23932, 22908, 21884, 20860,
88 19836, 18812, 17788, 16764, 15996, 15484, 14972,
89 14460, 13948, 13436, 12924, 12412, 11900, 11388,
90 10876, 10364, 9852, 9340, 8828, 8316, 7932,
91 7676, 7420, 7164, 6908, 6652, 6396, 6140,
92 5884, 5628, 5372, 5116, 4860, 4604, 4348,
93 4092, 3900, 3772, 3644, 3516, 3388, 3260,
94 3132, 3004, 2876, 2748, 2620, 2492, 2364,
95 2236, 2108, 1980, 1884, 1820, 1756, 1692,
96 1628, 1564, 1500, 1436, 1372, 1308, 1244,
97 1180, 1116, 1052, 988, 924, 876, 844,
98 812, 780, 748, 716, 684, 652, 620,
99 588, 556, 524, 492, 460, 428, 396,
100 372, 356, 340, 324, 308, 292, 276,
101 260, 244, 228, 212, 196, 180, 164,
102 148, 132, 120, 112, 104, 96, 88,
103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
108 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
109 * stored in a unsigned char. This function should only be called with
110 * the data shifted such that it only contains information in the lower
111 * 14-bits.
113 * In order to simplify the encoding process, the original linear magnitude
114 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
115 * (33 - 8191). The result can be seen in the following encoding table:
117 * Biased Linear Input Code Compressed Code
118 * ------------------------ ---------------
119 * 00000001wxyza 000wxyz
120 * 0000001wxyzab 001wxyz
121 * 000001wxyzabc 010wxyz
122 * 00001wxyzabcd 011wxyz
123 * 0001wxyzabcde 100wxyz
124 * 001wxyzabcdef 101wxyz
125 * 01wxyzabcdefg 110wxyz
126 * 1wxyzabcdefgh 111wxyz
128 * Each biased linear code has a leading 1 which identifies the segment
129 * number. The value of the segment number is equal to 7 minus the number
130 * of leading 0's. The quantization interval is directly available as the
131 * four bits wxyz. * The trailing bits (a - h) are ignored.
133 * Ordinarily the complement of the resulting code word is used for
134 * transmission, and so the code word is complemented before it is returned.
136 * For further information see John C. Bellamy's Digital Telephony, 1982,
137 * John Wiley & Sons, pps 98-111 and 472-476.
139 static unsigned char
140 st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
149 /* u-law inverts all bits */
150 /* Get the sign and the magnitude of the value. */
151 if (pcm_val < 0) {
152 pcm_val = -pcm_val;
153 mask = 0x7F;
154 } else {
155 mask = 0xFF;
157 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
158 pcm_val += (BIAS >> 2);
160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
164 * Combine the sign, segment, quantization bits;
165 * and complement the code word.
167 if (seg >= 8) /* out of range, return maximum value. */
168 return (unsigned char) (0x7F ^ mask);
169 else {
170 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
171 return (uval ^ mask);
176 static PyInt16 _st_alaw2linear16[256] = {
177 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
178 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
179 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
180 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
181 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
182 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
183 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
184 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
185 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
186 -13568, -344, -328, -376, -360, -280, -264,
187 -312, -296, -472, -456, -504, -488, -408,
188 -392, -440, -424, -88, -72, -120, -104,
189 -24, -8, -56, -40, -216, -200, -248,
190 -232, -152, -136, -184, -168, -1376, -1312,
191 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
192 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
193 -688, -656, -752, -720, -560, -528, -624,
194 -592, -944, -912, -1008, -976, -816, -784,
195 -880, -848, 5504, 5248, 6016, 5760, 4480,
196 4224, 4992, 4736, 7552, 7296, 8064, 7808,
197 6528, 6272, 7040, 6784, 2752, 2624, 3008,
198 2880, 2240, 2112, 2496, 2368, 3776, 3648,
199 4032, 3904, 3264, 3136, 3520, 3392, 22016,
200 20992, 24064, 23040, 17920, 16896, 19968, 18944,
201 30208, 29184, 32256, 31232, 26112, 25088, 28160,
202 27136, 11008, 10496, 12032, 11520, 8960, 8448,
203 9984, 9472, 15104, 14592, 16128, 15616, 13056,
204 12544, 14080, 13568, 344, 328, 376, 360,
205 280, 264, 312, 296, 472, 456, 504,
206 488, 408, 392, 440, 424, 88, 72,
207 120, 104, 24, 8, 56, 40, 216,
208 200, 248, 232, 152, 136, 184, 168,
209 1376, 1312, 1504, 1440, 1120, 1056, 1248,
210 1184, 1888, 1824, 2016, 1952, 1632, 1568,
211 1760, 1696, 688, 656, 752, 720, 560,
212 528, 624, 592, 944, 912, 1008, 976,
213 816, 784, 880, 848
217 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
218 * stored in a unsigned char. This function should only be called with
219 * the data shifted such that it only contains information in the lower
220 * 13-bits.
222 * Linear Input Code Compressed Code
223 * ------------------------ ---------------
224 * 0000000wxyza 000wxyz
225 * 0000001wxyza 001wxyz
226 * 000001wxyzab 010wxyz
227 * 00001wxyzabc 011wxyz
228 * 0001wxyzabcd 100wxyz
229 * 001wxyzabcde 101wxyz
230 * 01wxyzabcdef 110wxyz
231 * 1wxyzabcdefg 111wxyz
233 * For further information see John C. Bellamy's Digital Telephony, 1982,
234 * John Wiley & Sons, pps 98-111 and 472-476.
236 static unsigned char
237 st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
257 /* Combine the sign, segment, and quantization bits. */
259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
270 /* End of code taken from sox */
272 /* Intel ADPCM step variation table */
273 static int indexTable[16] = {
274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
278 static int stepsizeTable[89] = {
279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
290 #define CHARP(cp, i) ((signed char *)(cp+i))
291 #define SHORTP(cp, i) ((short *)(cp+i))
292 #define LONGP(cp, i) ((Py_Int32 *)(cp+i))
296 static PyObject *AudioopError;
298 static PyObject *
299 audioop_getsample(PyObject *self, PyObject *args)
301 signed char *cp;
302 int len, size, val = 0;
303 int i;
305 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
306 return 0;
307 if ( size != 1 && size != 2 && size != 4 ) {
308 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
309 return 0;
311 if ( i < 0 || i >= len/size ) {
312 PyErr_SetString(AudioopError, "Index out of range");
313 return 0;
315 if ( size == 1 ) val = (int)*CHARP(cp, i);
316 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
317 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
318 return PyInt_FromLong(val);
321 static PyObject *
322 audioop_max(PyObject *self, PyObject *args)
324 signed char *cp;
325 int len, size, val = 0;
326 int i;
327 int max = 0;
329 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
330 return 0;
331 if ( size != 1 && size != 2 && size != 4 ) {
332 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
333 return 0;
335 for ( i=0; i<len; i+= size) {
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i);
339 if ( val < 0 ) val = (-val);
340 if ( val > max ) max = val;
342 return PyInt_FromLong(max);
345 static PyObject *
346 audioop_minmax(PyObject *self, PyObject *args)
348 signed char *cp;
349 int len, size, val = 0;
350 int i;
351 int min = 0x7fffffff, max = -0x7fffffff;
353 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
354 return NULL;
355 if (size != 1 && size != 2 && size != 4) {
356 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
357 return NULL;
359 for (i = 0; i < len; i += size) {
360 if (size == 1) val = (int) *CHARP(cp, i);
361 else if (size == 2) val = (int) *SHORTP(cp, i);
362 else if (size == 4) val = (int) *LONGP(cp, i);
363 if (val > max) max = val;
364 if (val < min) min = val;
366 return Py_BuildValue("(ii)", min, max);
369 static PyObject *
370 audioop_avg(PyObject *self, PyObject *args)
372 signed char *cp;
373 int len, size, val = 0;
374 int i;
375 double avg = 0.0;
377 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
378 return 0;
379 if ( size != 1 && size != 2 && size != 4 ) {
380 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
381 return 0;
383 for ( i=0; i<len; i+= size) {
384 if ( size == 1 ) val = (int)*CHARP(cp, i);
385 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
386 else if ( size == 4 ) val = (int)*LONGP(cp, i);
387 avg += val;
389 if ( len == 0 )
390 val = 0;
391 else
392 val = (int)(avg / (double)(len/size));
393 return PyInt_FromLong(val);
396 static PyObject *
397 audioop_rms(PyObject *self, PyObject *args)
399 signed char *cp;
400 int len, size, val = 0;
401 int i;
402 double sum_squares = 0.0;
404 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
405 return 0;
406 if ( size != 1 && size != 2 && size != 4 ) {
407 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
408 return 0;
410 for ( i=0; i<len; i+= size) {
411 if ( size == 1 ) val = (int)*CHARP(cp, i);
412 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
413 else if ( size == 4 ) val = (int)*LONGP(cp, i);
414 sum_squares += (double)val*(double)val;
416 if ( len == 0 )
417 val = 0;
418 else
419 val = (int)sqrt(sum_squares / (double)(len/size));
420 return PyInt_FromLong(val);
423 static double _sum2(short *a, short *b, int len)
425 int i;
426 double sum = 0.0;
428 for( i=0; i<len; i++) {
429 sum = sum + (double)a[i]*(double)b[i];
431 return sum;
435 ** Findfit tries to locate a sample within another sample. Its main use
436 ** is in echo-cancellation (to find the feedback of the output signal in
437 ** the input signal).
438 ** The method used is as follows:
440 ** let R be the reference signal (length n) and A the input signal (length N)
441 ** with N > n, and let all sums be over i from 0 to n-1.
443 ** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
444 ** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
445 ** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
447 ** Next, we compute the relative distance between the original signal and
448 ** the modified signal and minimize that over j:
449 ** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
450 ** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
452 ** In the code variables correspond as follows:
453 ** cp1 A
454 ** cp2 R
455 ** len1 N
456 ** len2 n
457 ** aj_m1 A[j-1]
458 ** aj_lm1 A[j+n-1]
459 ** sum_ri_2 sum(R[i]^2)
460 ** sum_aij_2 sum(A[i+j]^2)
461 ** sum_aij_ri sum(A[i+j]R[i])
463 ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
464 ** is completely recalculated each step.
466 static PyObject *
467 audioop_findfit(PyObject *self, PyObject *args)
469 short *cp1, *cp2;
470 int len1, len2;
471 int j, best_j;
472 double aj_m1, aj_lm1;
473 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
475 /* Passing a short** for an 's' argument is correct only
476 if the string contents is aligned for interpretation
477 as short[]. Due to the definition of PyStringObject,
478 this is currently (Python 2.6) the case. */
479 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
480 (char**)&cp1, &len1, (char**)&cp2, &len2) )
481 return 0;
482 if ( len1 & 1 || len2 & 1 ) {
483 PyErr_SetString(AudioopError, "Strings should be even-sized");
484 return 0;
486 len1 >>= 1;
487 len2 >>= 1;
489 if ( len1 < len2 ) {
490 PyErr_SetString(AudioopError, "First sample should be longer");
491 return 0;
493 sum_ri_2 = _sum2(cp2, cp2, len2);
494 sum_aij_2 = _sum2(cp1, cp1, len2);
495 sum_aij_ri = _sum2(cp1, cp2, len2);
497 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
499 best_result = result;
500 best_j = 0;
501 j = 0;
503 for ( j=1; j<=len1-len2; j++) {
504 aj_m1 = (double)cp1[j-1];
505 aj_lm1 = (double)cp1[j+len2-1];
507 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
508 sum_aij_ri = _sum2(cp1+j, cp2, len2);
510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
511 / sum_aij_2;
513 if ( result < best_result ) {
514 best_result = result;
515 best_j = j;
520 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
522 return Py_BuildValue("(if)", best_j, factor);
526 ** findfactor finds a factor f so that the energy in A-fB is minimal.
527 ** See the comment for findfit for details.
529 static PyObject *
530 audioop_findfactor(PyObject *self, PyObject *args)
532 short *cp1, *cp2;
533 int len1, len2;
534 double sum_ri_2, sum_aij_ri, result;
536 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
537 (char**)&cp1, &len1, (char**)&cp2, &len2) )
538 return 0;
539 if ( len1 & 1 || len2 & 1 ) {
540 PyErr_SetString(AudioopError, "Strings should be even-sized");
541 return 0;
543 if ( len1 != len2 ) {
544 PyErr_SetString(AudioopError, "Samples should be same size");
545 return 0;
547 len2 >>= 1;
548 sum_ri_2 = _sum2(cp2, cp2, len2);
549 sum_aij_ri = _sum2(cp1, cp2, len2);
551 result = sum_aij_ri / sum_ri_2;
553 return PyFloat_FromDouble(result);
557 ** findmax returns the index of the n-sized segment of the input sample
558 ** that contains the most energy.
560 static PyObject *
561 audioop_findmax(PyObject *self, PyObject *args)
563 short *cp1;
564 int len1, len2;
565 int j, best_j;
566 double aj_m1, aj_lm1;
567 double result, best_result;
569 if ( !PyArg_ParseTuple(args, "s#i:findmax",
570 (char**)&cp1, &len1, &len2) )
571 return 0;
572 if ( len1 & 1 ) {
573 PyErr_SetString(AudioopError, "Strings should be even-sized");
574 return 0;
576 len1 >>= 1;
578 if ( len1 < len2 ) {
579 PyErr_SetString(AudioopError, "Input sample should be longer");
580 return 0;
583 result = _sum2(cp1, cp1, len2);
585 best_result = result;
586 best_j = 0;
587 j = 0;
589 for ( j=1; j<=len1-len2; j++) {
590 aj_m1 = (double)cp1[j-1];
591 aj_lm1 = (double)cp1[j+len2-1];
593 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
595 if ( result > best_result ) {
596 best_result = result;
597 best_j = j;
602 return PyInt_FromLong(best_j);
605 static PyObject *
606 audioop_avgpp(PyObject *self, PyObject *args)
608 signed char *cp;
609 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
610 prevextreme = 0;
611 int i;
612 double avg = 0.0;
613 int diff, prevdiff, extremediff, nextreme = 0;
615 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
616 return 0;
617 if ( size != 1 && size != 2 && size != 4 ) {
618 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
619 return 0;
621 /* Compute first delta value ahead. Also automatically makes us
622 ** skip the first extreme value
624 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
625 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
626 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
627 if ( size == 1 ) val = (int)*CHARP(cp, size);
628 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
629 else if ( size == 4 ) val = (int)*LONGP(cp, size);
630 prevdiff = val - prevval;
632 for ( i=size; i<len; i+= size) {
633 if ( size == 1 ) val = (int)*CHARP(cp, i);
634 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
635 else if ( size == 4 ) val = (int)*LONGP(cp, i);
636 diff = val - prevval;
637 if ( diff*prevdiff < 0 ) {
638 /* Derivative changed sign. Compute difference to last
639 ** extreme value and remember.
641 if ( prevextremevalid ) {
642 extremediff = prevval - prevextreme;
643 if ( extremediff < 0 )
644 extremediff = -extremediff;
645 avg += extremediff;
646 nextreme++;
648 prevextremevalid = 1;
649 prevextreme = prevval;
651 prevval = val;
652 if ( diff != 0 )
653 prevdiff = diff;
655 if ( nextreme == 0 )
656 val = 0;
657 else
658 val = (int)(avg / (double)nextreme);
659 return PyInt_FromLong(val);
662 static PyObject *
663 audioop_maxpp(PyObject *self, PyObject *args)
665 signed char *cp;
666 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
667 prevextreme = 0;
668 int i;
669 int max = 0;
670 int diff, prevdiff, extremediff;
672 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
673 return 0;
674 if ( size != 1 && size != 2 && size != 4 ) {
675 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
676 return 0;
678 /* Compute first delta value ahead. Also automatically makes us
679 ** skip the first extreme value
681 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
682 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
683 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
684 if ( size == 1 ) val = (int)*CHARP(cp, size);
685 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
686 else if ( size == 4 ) val = (int)*LONGP(cp, size);
687 prevdiff = val - prevval;
689 for ( i=size; i<len; i+= size) {
690 if ( size == 1 ) val = (int)*CHARP(cp, i);
691 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
692 else if ( size == 4 ) val = (int)*LONGP(cp, i);
693 diff = val - prevval;
694 if ( diff*prevdiff < 0 ) {
695 /* Derivative changed sign. Compute difference to
696 ** last extreme value and remember.
698 if ( prevextremevalid ) {
699 extremediff = prevval - prevextreme;
700 if ( extremediff < 0 )
701 extremediff = -extremediff;
702 if ( extremediff > max )
703 max = extremediff;
705 prevextremevalid = 1;
706 prevextreme = prevval;
708 prevval = val;
709 if ( diff != 0 )
710 prevdiff = diff;
712 return PyInt_FromLong(max);
715 static PyObject *
716 audioop_cross(PyObject *self, PyObject *args)
718 signed char *cp;
719 int len, size, val = 0;
720 int i;
721 int prevval, ncross;
723 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
724 return 0;
725 if ( size != 1 && size != 2 && size != 4 ) {
726 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
727 return 0;
729 ncross = -1;
730 prevval = 17; /* Anything <> 0,1 */
731 for ( i=0; i<len; i+= size) {
732 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
733 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
734 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
735 val = val & 1;
736 if ( val != prevval ) ncross++;
737 prevval = val;
739 return PyInt_FromLong(ncross);
742 static PyObject *
743 audioop_mul(PyObject *self, PyObject *args)
745 signed char *cp, *ncp;
746 int len, size, val = 0;
747 double factor, fval, maxval;
748 PyObject *rv;
749 int i;
751 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
752 return 0;
754 if ( size == 1 ) maxval = (double) 0x7f;
755 else if ( size == 2 ) maxval = (double) 0x7fff;
756 else if ( size == 4 ) maxval = (double) 0x7fffffff;
757 else {
758 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
759 return 0;
762 rv = PyString_FromStringAndSize(NULL, len);
763 if ( rv == 0 )
764 return 0;
765 ncp = (signed char *)PyString_AsString(rv);
768 for ( i=0; i < len; i += size ) {
769 if ( size == 1 ) val = (int)*CHARP(cp, i);
770 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
771 else if ( size == 4 ) val = (int)*LONGP(cp, i);
772 fval = (double)val*factor;
773 if ( fval > maxval ) fval = maxval;
774 else if ( fval < -maxval ) fval = -maxval;
775 val = (int)fval;
776 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
777 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
778 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
780 return rv;
783 static PyObject *
784 audioop_tomono(PyObject *self, PyObject *args)
786 signed char *cp, *ncp;
787 int len, size, val1 = 0, val2 = 0;
788 double fac1, fac2, fval, maxval;
789 PyObject *rv;
790 int i;
792 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
793 &cp, &len, &size, &fac1, &fac2 ) )
794 return 0;
796 if ( size == 1 ) maxval = (double) 0x7f;
797 else if ( size == 2 ) maxval = (double) 0x7fff;
798 else if ( size == 4 ) maxval = (double) 0x7fffffff;
799 else {
800 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
801 return 0;
804 rv = PyString_FromStringAndSize(NULL, len/2);
805 if ( rv == 0 )
806 return 0;
807 ncp = (signed char *)PyString_AsString(rv);
810 for ( i=0; i < len; i += size*2 ) {
811 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
812 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
813 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
814 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
815 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
816 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
817 fval = (double)val1*fac1 + (double)val2*fac2;
818 if ( fval > maxval ) fval = maxval;
819 else if ( fval < -maxval ) fval = -maxval;
820 val1 = (int)fval;
821 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
822 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
823 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
825 return rv;
828 static PyObject *
829 audioop_tostereo(PyObject *self, PyObject *args)
831 signed char *cp, *ncp;
832 int len, size, val1, val2, val = 0;
833 double fac1, fac2, fval, maxval;
834 PyObject *rv;
835 int i;
837 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
838 &cp, &len, &size, &fac1, &fac2 ) )
839 return 0;
841 if ( size == 1 ) maxval = (double) 0x7f;
842 else if ( size == 2 ) maxval = (double) 0x7fff;
843 else if ( size == 4 ) maxval = (double) 0x7fffffff;
844 else {
845 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
846 return 0;
849 rv = PyString_FromStringAndSize(NULL, len*2);
850 if ( rv == 0 )
851 return 0;
852 ncp = (signed char *)PyString_AsString(rv);
855 for ( i=0; i < len; i += size ) {
856 if ( size == 1 ) val = (int)*CHARP(cp, i);
857 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
858 else if ( size == 4 ) val = (int)*LONGP(cp, i);
860 fval = (double)val*fac1;
861 if ( fval > maxval ) fval = maxval;
862 else if ( fval < -maxval ) fval = -maxval;
863 val1 = (int)fval;
865 fval = (double)val*fac2;
866 if ( fval > maxval ) fval = maxval;
867 else if ( fval < -maxval ) fval = -maxval;
868 val2 = (int)fval;
870 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
871 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
872 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
874 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
875 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
876 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
878 return rv;
881 static PyObject *
882 audioop_add(PyObject *self, PyObject *args)
884 signed char *cp1, *cp2, *ncp;
885 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
886 PyObject *rv;
887 int i;
889 if ( !PyArg_ParseTuple(args, "s#s#i:add",
890 &cp1, &len1, &cp2, &len2, &size ) )
891 return 0;
893 if ( len1 != len2 ) {
894 PyErr_SetString(AudioopError, "Lengths should be the same");
895 return 0;
898 if ( size == 1 ) maxval = 0x7f;
899 else if ( size == 2 ) maxval = 0x7fff;
900 else if ( size == 4 ) maxval = 0x7fffffff;
901 else {
902 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
903 return 0;
906 rv = PyString_FromStringAndSize(NULL, len1);
907 if ( rv == 0 )
908 return 0;
909 ncp = (signed char *)PyString_AsString(rv);
911 for ( i=0; i < len1; i += size ) {
912 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
913 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
914 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
916 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
917 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
918 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
920 newval = val1 + val2;
921 /* truncate in case of overflow */
922 if (newval > maxval) newval = maxval;
923 else if (newval < -maxval) newval = -maxval;
924 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
925 newval = val1 > 0 ? maxval : - maxval;
927 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
928 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
929 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
931 return rv;
934 static PyObject *
935 audioop_bias(PyObject *self, PyObject *args)
937 signed char *cp, *ncp;
938 int len, size, val = 0;
939 PyObject *rv;
940 int i;
941 int bias;
943 if ( !PyArg_ParseTuple(args, "s#ii:bias",
944 &cp, &len, &size , &bias) )
945 return 0;
947 if ( size != 1 && size != 2 && size != 4) {
948 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
949 return 0;
952 rv = PyString_FromStringAndSize(NULL, len);
953 if ( rv == 0 )
954 return 0;
955 ncp = (signed char *)PyString_AsString(rv);
958 for ( i=0; i < len; i += size ) {
959 if ( size == 1 ) val = (int)*CHARP(cp, i);
960 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
961 else if ( size == 4 ) val = (int)*LONGP(cp, i);
963 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
964 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
965 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
967 return rv;
970 static PyObject *
971 audioop_reverse(PyObject *self, PyObject *args)
973 signed char *cp;
974 unsigned char *ncp;
975 int len, size, val = 0;
976 PyObject *rv;
977 int i, j;
979 if ( !PyArg_ParseTuple(args, "s#i:reverse",
980 &cp, &len, &size) )
981 return 0;
983 if ( size != 1 && size != 2 && size != 4 ) {
984 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
985 return 0;
988 rv = PyString_FromStringAndSize(NULL, len);
989 if ( rv == 0 )
990 return 0;
991 ncp = (unsigned char *)PyString_AsString(rv);
993 for ( i=0; i < len; i += size ) {
994 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
995 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
996 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
998 j = len - i - size;
1000 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1001 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1002 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1004 return rv;
1007 static PyObject *
1008 audioop_lin2lin(PyObject *self, PyObject *args)
1010 signed char *cp;
1011 unsigned char *ncp;
1012 int len, size, size2, val = 0;
1013 PyObject *rv;
1014 int i, j;
1016 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1017 &cp, &len, &size, &size2) )
1018 return 0;
1020 if ( (size != 1 && size != 2 && size != 4) ||
1021 (size2 != 1 && size2 != 2 && size2 != 4)) {
1022 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1023 return 0;
1026 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
1027 if ( rv == 0 )
1028 return 0;
1029 ncp = (unsigned char *)PyString_AsString(rv);
1031 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1032 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1033 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1034 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1036 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1037 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1038 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1040 return rv;
1043 static int
1044 gcd(int a, int b)
1046 while (b > 0) {
1047 int tmp = a % b;
1048 a = b;
1049 b = tmp;
1051 return a;
1054 static PyObject *
1055 audioop_ratecv(PyObject *self, PyObject *args)
1057 char *cp, *ncp;
1058 int len, size, nchannels, inrate, outrate, weightA, weightB;
1059 int chan, d, *prev_i, *cur_i, cur_o;
1060 PyObject *state, *samps, *str, *rv = NULL;
1061 int bytes_per_frame;
1063 weightA = 1;
1064 weightB = 0;
1065 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1066 &nchannels, &inrate, &outrate, &state,
1067 &weightA, &weightB))
1068 return NULL;
1069 if (size != 1 && size != 2 && size != 4) {
1070 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1071 return NULL;
1073 if (nchannels < 1) {
1074 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1075 return NULL;
1077 bytes_per_frame = size * nchannels;
1078 if (bytes_per_frame / nchannels != size) {
1079 /* This overflow test is rigorously correct because
1080 both multiplicands are >= 1. Use the argument names
1081 from the docs for the error msg. */
1082 PyErr_SetString(PyExc_OverflowError,
1083 "width * nchannels too big for a C int");
1084 return NULL;
1086 if (weightA < 1 || weightB < 0) {
1087 PyErr_SetString(AudioopError,
1088 "weightA should be >= 1, weightB should be >= 0");
1089 return NULL;
1091 if (len % bytes_per_frame != 0) {
1092 PyErr_SetString(AudioopError, "not a whole number of frames");
1093 return NULL;
1095 if (inrate <= 0 || outrate <= 0) {
1096 PyErr_SetString(AudioopError, "sampling rate not > 0");
1097 return NULL;
1099 /* divide inrate and outrate by their greatest common divisor */
1100 d = gcd(inrate, outrate);
1101 inrate /= d;
1102 outrate /= d;
1104 prev_i = (int *) malloc(nchannels * sizeof(int));
1105 cur_i = (int *) malloc(nchannels * sizeof(int));
1106 if (prev_i == NULL || cur_i == NULL) {
1107 (void) PyErr_NoMemory();
1108 goto exit;
1111 len /= bytes_per_frame; /* # of frames */
1113 if (state == Py_None) {
1114 d = -outrate;
1115 for (chan = 0; chan < nchannels; chan++)
1116 prev_i[chan] = cur_i[chan] = 0;
1118 else {
1119 if (!PyArg_ParseTuple(state,
1120 "iO!;audioop.ratecv: illegal state argument",
1121 &d, &PyTuple_Type, &samps))
1122 goto exit;
1123 if (PyTuple_Size(samps) != nchannels) {
1124 PyErr_SetString(AudioopError,
1125 "illegal state argument");
1126 goto exit;
1128 for (chan = 0; chan < nchannels; chan++) {
1129 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1130 "ii:ratecv", &prev_i[chan],
1131 &cur_i[chan]))
1132 goto exit;
1136 /* str <- Space for the output buffer. */
1138 /* There are len input frames, so we need (mathematically)
1139 ceiling(len*outrate/inrate) output frames, and each frame
1140 requires bytes_per_frame bytes. Computing this
1141 without spurious overflow is the challenge; we can
1142 settle for a reasonable upper bound, though. */
1143 int ceiling; /* the number of output frames */
1144 int nbytes; /* the number of output bytes needed */
1145 int q = len / inrate;
1146 /* Now len = q * inrate + r exactly (with r = len % inrate),
1147 and this is less than q * inrate + inrate = (q+1)*inrate.
1148 So a reasonable upper bound on len*outrate/inrate is
1149 ((q+1)*inrate)*outrate/inrate =
1150 (q+1)*outrate.
1152 ceiling = (q+1) * outrate;
1153 nbytes = ceiling * bytes_per_frame;
1154 /* See whether anything overflowed; if not, get the space. */
1155 if (q+1 < 0 ||
1156 ceiling / outrate != q+1 ||
1157 nbytes / bytes_per_frame != ceiling)
1158 str = NULL;
1159 else
1160 str = PyString_FromStringAndSize(NULL, nbytes);
1162 if (str == NULL) {
1163 PyErr_SetString(PyExc_MemoryError,
1164 "not enough memory for output buffer");
1165 goto exit;
1168 ncp = PyString_AsString(str);
1170 for (;;) {
1171 while (d < 0) {
1172 if (len == 0) {
1173 samps = PyTuple_New(nchannels);
1174 if (samps == NULL)
1175 goto exit;
1176 for (chan = 0; chan < nchannels; chan++)
1177 PyTuple_SetItem(samps, chan,
1178 Py_BuildValue("(ii)",
1179 prev_i[chan],
1180 cur_i[chan]));
1181 if (PyErr_Occurred())
1182 goto exit;
1183 /* We have checked before that the length
1184 * of the string fits into int. */
1185 len = (int)(ncp - PyString_AsString(str));
1186 if (len == 0) {
1187 /*don't want to resize to zero length*/
1188 rv = PyString_FromStringAndSize("", 0);
1189 Py_DECREF(str);
1190 str = rv;
1191 } else if (_PyString_Resize(&str, len) < 0)
1192 goto exit;
1193 rv = Py_BuildValue("(O(iO))", str, d, samps);
1194 Py_DECREF(samps);
1195 Py_DECREF(str);
1196 goto exit; /* return rv */
1198 for (chan = 0; chan < nchannels; chan++) {
1199 prev_i[chan] = cur_i[chan];
1200 if (size == 1)
1201 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1202 else if (size == 2)
1203 cur_i[chan] = (int)*SHORTP(cp, 0);
1204 else if (size == 4)
1205 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1206 cp += size;
1207 /* implements a simple digital filter */
1208 cur_i[chan] =
1209 (weightA * cur_i[chan] +
1210 weightB * prev_i[chan]) /
1211 (weightA + weightB);
1213 len--;
1214 d += outrate;
1216 while (d >= 0) {
1217 for (chan = 0; chan < nchannels; chan++) {
1218 cur_o = (prev_i[chan] * d +
1219 cur_i[chan] * (outrate - d)) /
1220 outrate;
1221 if (size == 1)
1222 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1223 else if (size == 2)
1224 *SHORTP(ncp, 0) = (short)(cur_o);
1225 else if (size == 4)
1226 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1227 ncp += size;
1229 d -= inrate;
1232 exit:
1233 if (prev_i != NULL)
1234 free(prev_i);
1235 if (cur_i != NULL)
1236 free(cur_i);
1237 return rv;
1240 static PyObject *
1241 audioop_lin2ulaw(PyObject *self, PyObject *args)
1243 signed char *cp;
1244 unsigned char *ncp;
1245 int len, size, val = 0;
1246 PyObject *rv;
1247 int i;
1249 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1250 &cp, &len, &size) )
1251 return 0 ;
1253 if ( size != 1 && size != 2 && size != 4) {
1254 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1255 return 0;
1258 rv = PyString_FromStringAndSize(NULL, len/size);
1259 if ( rv == 0 )
1260 return 0;
1261 ncp = (unsigned char *)PyString_AsString(rv);
1263 for ( i=0; i < len; i += size ) {
1264 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1265 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1266 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1268 *ncp++ = st_14linear2ulaw(val);
1270 return rv;
1273 static PyObject *
1274 audioop_ulaw2lin(PyObject *self, PyObject *args)
1276 unsigned char *cp;
1277 unsigned char cval;
1278 signed char *ncp;
1279 int len, size, val;
1280 PyObject *rv;
1281 int i;
1283 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1284 &cp, &len, &size) )
1285 return 0;
1287 if ( size != 1 && size != 2 && size != 4) {
1288 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1289 return 0;
1292 rv = PyString_FromStringAndSize(NULL, len*size);
1293 if ( rv == 0 )
1294 return 0;
1295 ncp = (signed char *)PyString_AsString(rv);
1297 for ( i=0; i < len*size; i += size ) {
1298 cval = *cp++;
1299 val = st_ulaw2linear16(cval);
1301 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1302 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1303 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1305 return rv;
1308 static PyObject *
1309 audioop_lin2alaw(PyObject *self, PyObject *args)
1311 signed char *cp;
1312 unsigned char *ncp;
1313 int len, size, val = 0;
1314 PyObject *rv;
1315 int i;
1317 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1318 &cp, &len, &size) )
1319 return 0;
1321 if ( size != 1 && size != 2 && size != 4) {
1322 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1323 return 0;
1326 rv = PyString_FromStringAndSize(NULL, len/size);
1327 if ( rv == 0 )
1328 return 0;
1329 ncp = (unsigned char *)PyString_AsString(rv);
1331 for ( i=0; i < len; i += size ) {
1332 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1333 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1334 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1336 *ncp++ = st_linear2alaw(val);
1338 return rv;
1341 static PyObject *
1342 audioop_alaw2lin(PyObject *self, PyObject *args)
1344 unsigned char *cp;
1345 unsigned char cval;
1346 signed char *ncp;
1347 int len, size, val;
1348 PyObject *rv;
1349 int i;
1351 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1352 &cp, &len, &size) )
1353 return 0;
1355 if ( size != 1 && size != 2 && size != 4) {
1356 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1357 return 0;
1360 rv = PyString_FromStringAndSize(NULL, len*size);
1361 if ( rv == 0 )
1362 return 0;
1363 ncp = (signed char *)PyString_AsString(rv);
1365 for ( i=0; i < len*size; i += size ) {
1366 cval = *cp++;
1367 val = st_alaw2linear16(cval);
1369 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1370 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1371 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1373 return rv;
1376 static PyObject *
1377 audioop_lin2adpcm(PyObject *self, PyObject *args)
1379 signed char *cp;
1380 signed char *ncp;
1381 int len, size, val = 0, step, valpred, delta,
1382 index, sign, vpdiff, diff;
1383 PyObject *rv, *state, *str;
1384 int i, outputbuffer = 0, bufferstep;
1386 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1387 &cp, &len, &size, &state) )
1388 return 0;
1391 if ( size != 1 && size != 2 && size != 4) {
1392 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1393 return 0;
1396 str = PyString_FromStringAndSize(NULL, len/(size*2));
1397 if ( str == 0 )
1398 return 0;
1399 ncp = (signed char *)PyString_AsString(str);
1401 /* Decode state, should have (value, step) */
1402 if ( state == Py_None ) {
1403 /* First time, it seems. Set defaults */
1404 valpred = 0;
1405 step = 7;
1406 index = 0;
1407 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1408 return 0;
1410 step = stepsizeTable[index];
1411 bufferstep = 1;
1413 for ( i=0; i < len; i += size ) {
1414 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1415 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1416 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1418 /* Step 1 - compute difference with previous value */
1419 diff = val - valpred;
1420 sign = (diff < 0) ? 8 : 0;
1421 if ( sign ) diff = (-diff);
1423 /* Step 2 - Divide and clamp */
1424 /* Note:
1425 ** This code *approximately* computes:
1426 ** delta = diff*4/step;
1427 ** vpdiff = (delta+0.5)*step/4;
1428 ** but in shift step bits are dropped. The net result of this
1429 ** is that even if you have fast mul/div hardware you cannot
1430 ** put it to good use since the fixup would be too expensive.
1432 delta = 0;
1433 vpdiff = (step >> 3);
1435 if ( diff >= step ) {
1436 delta = 4;
1437 diff -= step;
1438 vpdiff += step;
1440 step >>= 1;
1441 if ( diff >= step ) {
1442 delta |= 2;
1443 diff -= step;
1444 vpdiff += step;
1446 step >>= 1;
1447 if ( diff >= step ) {
1448 delta |= 1;
1449 vpdiff += step;
1452 /* Step 3 - Update previous value */
1453 if ( sign )
1454 valpred -= vpdiff;
1455 else
1456 valpred += vpdiff;
1458 /* Step 4 - Clamp previous value to 16 bits */
1459 if ( valpred > 32767 )
1460 valpred = 32767;
1461 else if ( valpred < -32768 )
1462 valpred = -32768;
1464 /* Step 5 - Assemble value, update index and step values */
1465 delta |= sign;
1467 index += indexTable[delta];
1468 if ( index < 0 ) index = 0;
1469 if ( index > 88 ) index = 88;
1470 step = stepsizeTable[index];
1472 /* Step 6 - Output value */
1473 if ( bufferstep ) {
1474 outputbuffer = (delta << 4) & 0xf0;
1475 } else {
1476 *ncp++ = (delta & 0x0f) | outputbuffer;
1478 bufferstep = !bufferstep;
1480 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1481 Py_DECREF(str);
1482 return rv;
1485 static PyObject *
1486 audioop_adpcm2lin(PyObject *self, PyObject *args)
1488 signed char *cp;
1489 signed char *ncp;
1490 int len, size, valpred, step, delta, index, sign, vpdiff;
1491 PyObject *rv, *str, *state;
1492 int i, inputbuffer = 0, bufferstep;
1494 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1495 &cp, &len, &size, &state) )
1496 return 0;
1498 if ( size != 1 && size != 2 && size != 4) {
1499 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1500 return 0;
1503 /* Decode state, should have (value, step) */
1504 if ( state == Py_None ) {
1505 /* First time, it seems. Set defaults */
1506 valpred = 0;
1507 step = 7;
1508 index = 0;
1509 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1510 return 0;
1512 str = PyString_FromStringAndSize(NULL, len*size*2);
1513 if ( str == 0 )
1514 return 0;
1515 ncp = (signed char *)PyString_AsString(str);
1517 step = stepsizeTable[index];
1518 bufferstep = 0;
1520 for ( i=0; i < len*size*2; i += size ) {
1521 /* Step 1 - get the delta value and compute next index */
1522 if ( bufferstep ) {
1523 delta = inputbuffer & 0xf;
1524 } else {
1525 inputbuffer = *cp++;
1526 delta = (inputbuffer >> 4) & 0xf;
1529 bufferstep = !bufferstep;
1531 /* Step 2 - Find new index value (for later) */
1532 index += indexTable[delta];
1533 if ( index < 0 ) index = 0;
1534 if ( index > 88 ) index = 88;
1536 /* Step 3 - Separate sign and magnitude */
1537 sign = delta & 8;
1538 delta = delta & 7;
1540 /* Step 4 - Compute difference and new predicted value */
1542 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1543 ** in adpcm_coder.
1545 vpdiff = step >> 3;
1546 if ( delta & 4 ) vpdiff += step;
1547 if ( delta & 2 ) vpdiff += step>>1;
1548 if ( delta & 1 ) vpdiff += step>>2;
1550 if ( sign )
1551 valpred -= vpdiff;
1552 else
1553 valpred += vpdiff;
1555 /* Step 5 - clamp output value */
1556 if ( valpred > 32767 )
1557 valpred = 32767;
1558 else if ( valpred < -32768 )
1559 valpred = -32768;
1561 /* Step 6 - Update step value */
1562 step = stepsizeTable[index];
1564 /* Step 6 - Output value */
1565 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1566 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1567 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1570 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1571 Py_DECREF(str);
1572 return rv;
1575 static PyMethodDef audioop_methods[] = {
1576 { "max", audioop_max, METH_VARARGS },
1577 { "minmax", audioop_minmax, METH_VARARGS },
1578 { "avg", audioop_avg, METH_VARARGS },
1579 { "maxpp", audioop_maxpp, METH_VARARGS },
1580 { "avgpp", audioop_avgpp, METH_VARARGS },
1581 { "rms", audioop_rms, METH_VARARGS },
1582 { "findfit", audioop_findfit, METH_VARARGS },
1583 { "findmax", audioop_findmax, METH_VARARGS },
1584 { "findfactor", audioop_findfactor, METH_VARARGS },
1585 { "cross", audioop_cross, METH_VARARGS },
1586 { "mul", audioop_mul, METH_VARARGS },
1587 { "add", audioop_add, METH_VARARGS },
1588 { "bias", audioop_bias, METH_VARARGS },
1589 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1590 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1591 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1592 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1593 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1594 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1595 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1596 { "tomono", audioop_tomono, METH_VARARGS },
1597 { "tostereo", audioop_tostereo, METH_VARARGS },
1598 { "getsample", audioop_getsample, METH_VARARGS },
1599 { "reverse", audioop_reverse, METH_VARARGS },
1600 { "ratecv", audioop_ratecv, METH_VARARGS },
1601 { 0, 0 }
1604 PyMODINIT_FUNC
1605 initaudioop(void)
1607 PyObject *m, *d;
1608 m = Py_InitModule("audioop", audioop_methods);
1609 if (m == NULL)
1610 return;
1611 d = PyModule_GetDict(m);
1612 if (d == NULL)
1613 return;
1614 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1615 if (AudioopError != NULL)
1616 PyDict_SetItemString(d,"error",AudioopError);