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