|
1 |
|
2 /* audioopmodule - Module to detect peak values in arrays */ |
|
3 |
|
4 #include "Python.h" |
|
5 |
|
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 |
|
17 |
|
18 typedef short PyInt16; |
|
19 |
|
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 |
|
26 |
|
27 /* Code shamelessly stolen from sox, 12.17.7, g711.c |
|
28 ** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */ |
|
29 |
|
30 /* From g711.c: |
|
31 * |
|
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 |
|
39 * |
|
40 */ |
|
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. */ |
|
47 |
|
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}; |
|
52 |
|
53 static PyInt16 |
|
54 search(PyInt16 val, PyInt16 *table, int size) |
|
55 { |
|
56 int i; |
|
57 |
|
58 for (i = 0; i < size; i++) { |
|
59 if (val <= *table++) |
|
60 return (i); |
|
61 } |
|
62 return (size); |
|
63 } |
|
64 #define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc]) |
|
65 #define st_alaw2linear16(uc) (_st_alaw2linear16[uc]) |
|
66 |
|
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 |
|
105 }; |
|
106 |
|
107 /* |
|
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. |
|
112 * |
|
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: |
|
116 * |
|
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 |
|
127 * |
|
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. |
|
132 * |
|
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. |
|
135 * |
|
136 * For further information see John C. Bellamy's Digital Telephony, 1982, |
|
137 * John Wiley & Sons, pps 98-111 and 472-476. |
|
138 */ |
|
139 static unsigned char |
|
140 st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */ |
|
141 { |
|
142 PyInt16 mask; |
|
143 PyInt16 seg; |
|
144 unsigned char uval; |
|
145 |
|
146 /* The original sox code does this in the calling function, not here */ |
|
147 pcm_val = pcm_val >> 2; |
|
148 |
|
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; |
|
156 } |
|
157 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ |
|
158 pcm_val += (BIAS >> 2); |
|
159 |
|
160 /* Convert the scaled magnitude to segment number. */ |
|
161 seg = search(pcm_val, seg_uend, 8); |
|
162 |
|
163 /* |
|
164 * Combine the sign, segment, quantization bits; |
|
165 * and complement the code word. |
|
166 */ |
|
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); |
|
172 } |
|
173 |
|
174 } |
|
175 |
|
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 |
|
214 }; |
|
215 |
|
216 /* |
|
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. |
|
221 * |
|
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 |
|
232 * |
|
233 * For further information see John C. Bellamy's Digital Telephony, 1982, |
|
234 * John Wiley & Sons, pps 98-111 and 472-476. |
|
235 */ |
|
236 static unsigned char |
|
237 st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */ |
|
238 { |
|
239 PyInt16 mask; |
|
240 short seg; |
|
241 unsigned char aval; |
|
242 |
|
243 /* The original sox code does this in the calling function, not here */ |
|
244 pcm_val = pcm_val >> 3; |
|
245 |
|
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; |
|
252 } |
|
253 |
|
254 /* Convert the scaled magnitude to segment number. */ |
|
255 seg = search(pcm_val, seg_aend, 8); |
|
256 |
|
257 /* Combine the sign, segment, and quantization bits. */ |
|
258 |
|
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); |
|
268 } |
|
269 } |
|
270 /* End of code taken from sox */ |
|
271 |
|
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, |
|
276 }; |
|
277 |
|
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 |
|
288 }; |
|
289 |
|
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)) |
|
293 |
|
294 |
|
295 |
|
296 static PyObject *AudioopError; |
|
297 |
|
298 static PyObject * |
|
299 audioop_getsample(PyObject *self, PyObject *args) |
|
300 { |
|
301 signed char *cp; |
|
302 int len, size, val = 0; |
|
303 int i; |
|
304 |
|
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; |
|
310 } |
|
311 if ( i < 0 || i >= len/size ) { |
|
312 PyErr_SetString(AudioopError, "Index out of range"); |
|
313 return 0; |
|
314 } |
|
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); |
|
319 } |
|
320 |
|
321 static PyObject * |
|
322 audioop_max(PyObject *self, PyObject *args) |
|
323 { |
|
324 signed char *cp; |
|
325 int len, size, val = 0; |
|
326 int i; |
|
327 int max = 0; |
|
328 |
|
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; |
|
334 } |
|
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; |
|
341 } |
|
342 return PyInt_FromLong(max); |
|
343 } |
|
344 |
|
345 static PyObject * |
|
346 audioop_minmax(PyObject *self, PyObject *args) |
|
347 { |
|
348 signed char *cp; |
|
349 int len, size, val = 0; |
|
350 int i; |
|
351 int min = 0x7fffffff, max = -0x7fffffff; |
|
352 |
|
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; |
|
358 } |
|
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; |
|
365 } |
|
366 return Py_BuildValue("(ii)", min, max); |
|
367 } |
|
368 |
|
369 static PyObject * |
|
370 audioop_avg(PyObject *self, PyObject *args) |
|
371 { |
|
372 signed char *cp; |
|
373 int len, size, val = 0; |
|
374 int i; |
|
375 double avg = 0.0; |
|
376 |
|
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; |
|
382 } |
|
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; |
|
388 } |
|
389 if ( len == 0 ) |
|
390 val = 0; |
|
391 else |
|
392 val = (int)(avg / (double)(len/size)); |
|
393 return PyInt_FromLong(val); |
|
394 } |
|
395 |
|
396 static PyObject * |
|
397 audioop_rms(PyObject *self, PyObject *args) |
|
398 { |
|
399 signed char *cp; |
|
400 int len, size, val = 0; |
|
401 int i; |
|
402 double sum_squares = 0.0; |
|
403 |
|
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; |
|
409 } |
|
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; |
|
415 } |
|
416 if ( len == 0 ) |
|
417 val = 0; |
|
418 else |
|
419 val = (int)sqrt(sum_squares / (double)(len/size)); |
|
420 return PyInt_FromLong(val); |
|
421 } |
|
422 |
|
423 static double _sum2(short *a, short *b, int len) |
|
424 { |
|
425 int i; |
|
426 double sum = 0.0; |
|
427 |
|
428 for( i=0; i<len; i++) { |
|
429 sum = sum + (double)a[i]*(double)b[i]; |
|
430 } |
|
431 return sum; |
|
432 } |
|
433 |
|
434 /* |
|
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: |
|
439 ** |
|
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. |
|
442 ** |
|
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). |
|
446 ** |
|
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 ) |
|
451 ** |
|
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]) |
|
462 ** |
|
463 ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri |
|
464 ** is completely recalculated each step. |
|
465 */ |
|
466 static PyObject * |
|
467 audioop_findfit(PyObject *self, PyObject *args) |
|
468 { |
|
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; |
|
474 |
|
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; |
|
485 } |
|
486 len1 >>= 1; |
|
487 len2 >>= 1; |
|
488 |
|
489 if ( len1 < len2 ) { |
|
490 PyErr_SetString(AudioopError, "First sample should be longer"); |
|
491 return 0; |
|
492 } |
|
493 sum_ri_2 = _sum2(cp2, cp2, len2); |
|
494 sum_aij_2 = _sum2(cp1, cp1, len2); |
|
495 sum_aij_ri = _sum2(cp1, cp2, len2); |
|
496 |
|
497 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2; |
|
498 |
|
499 best_result = result; |
|
500 best_j = 0; |
|
501 j = 0; |
|
502 |
|
503 for ( j=1; j<=len1-len2; j++) { |
|
504 aj_m1 = (double)cp1[j-1]; |
|
505 aj_lm1 = (double)cp1[j+len2-1]; |
|
506 |
|
507 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1; |
|
508 sum_aij_ri = _sum2(cp1+j, cp2, len2); |
|
509 |
|
510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) |
|
511 / sum_aij_2; |
|
512 |
|
513 if ( result < best_result ) { |
|
514 best_result = result; |
|
515 best_j = j; |
|
516 } |
|
517 |
|
518 } |
|
519 |
|
520 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2; |
|
521 |
|
522 return Py_BuildValue("(if)", best_j, factor); |
|
523 } |
|
524 |
|
525 /* |
|
526 ** findfactor finds a factor f so that the energy in A-fB is minimal. |
|
527 ** See the comment for findfit for details. |
|
528 */ |
|
529 static PyObject * |
|
530 audioop_findfactor(PyObject *self, PyObject *args) |
|
531 { |
|
532 short *cp1, *cp2; |
|
533 int len1, len2; |
|
534 double sum_ri_2, sum_aij_ri, result; |
|
535 |
|
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; |
|
542 } |
|
543 if ( len1 != len2 ) { |
|
544 PyErr_SetString(AudioopError, "Samples should be same size"); |
|
545 return 0; |
|
546 } |
|
547 len2 >>= 1; |
|
548 sum_ri_2 = _sum2(cp2, cp2, len2); |
|
549 sum_aij_ri = _sum2(cp1, cp2, len2); |
|
550 |
|
551 result = sum_aij_ri / sum_ri_2; |
|
552 |
|
553 return PyFloat_FromDouble(result); |
|
554 } |
|
555 |
|
556 /* |
|
557 ** findmax returns the index of the n-sized segment of the input sample |
|
558 ** that contains the most energy. |
|
559 */ |
|
560 static PyObject * |
|
561 audioop_findmax(PyObject *self, PyObject *args) |
|
562 { |
|
563 short *cp1; |
|
564 int len1, len2; |
|
565 int j, best_j; |
|
566 double aj_m1, aj_lm1; |
|
567 double result, best_result; |
|
568 |
|
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; |
|
575 } |
|
576 len1 >>= 1; |
|
577 |
|
578 if ( len2 < 0 || len1 < len2 ) { |
|
579 PyErr_SetString(AudioopError, "Input sample should be longer"); |
|
580 return 0; |
|
581 } |
|
582 |
|
583 result = _sum2(cp1, cp1, len2); |
|
584 |
|
585 best_result = result; |
|
586 best_j = 0; |
|
587 j = 0; |
|
588 |
|
589 for ( j=1; j<=len1-len2; j++) { |
|
590 aj_m1 = (double)cp1[j-1]; |
|
591 aj_lm1 = (double)cp1[j+len2-1]; |
|
592 |
|
593 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1; |
|
594 |
|
595 if ( result > best_result ) { |
|
596 best_result = result; |
|
597 best_j = j; |
|
598 } |
|
599 |
|
600 } |
|
601 |
|
602 return PyInt_FromLong(best_j); |
|
603 } |
|
604 |
|
605 static PyObject * |
|
606 audioop_avgpp(PyObject *self, PyObject *args) |
|
607 { |
|
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; |
|
614 |
|
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; |
|
620 } |
|
621 /* Compute first delta value ahead. Also automatically makes us |
|
622 ** skip the first extreme value |
|
623 */ |
|
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; |
|
631 |
|
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. |
|
640 */ |
|
641 if ( prevextremevalid ) { |
|
642 extremediff = prevval - prevextreme; |
|
643 if ( extremediff < 0 ) |
|
644 extremediff = -extremediff; |
|
645 avg += extremediff; |
|
646 nextreme++; |
|
647 } |
|
648 prevextremevalid = 1; |
|
649 prevextreme = prevval; |
|
650 } |
|
651 prevval = val; |
|
652 if ( diff != 0 ) |
|
653 prevdiff = diff; |
|
654 } |
|
655 if ( nextreme == 0 ) |
|
656 val = 0; |
|
657 else |
|
658 val = (int)(avg / (double)nextreme); |
|
659 return PyInt_FromLong(val); |
|
660 } |
|
661 |
|
662 static PyObject * |
|
663 audioop_maxpp(PyObject *self, PyObject *args) |
|
664 { |
|
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; |
|
671 |
|
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; |
|
677 } |
|
678 /* Compute first delta value ahead. Also automatically makes us |
|
679 ** skip the first extreme value |
|
680 */ |
|
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; |
|
688 |
|
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. |
|
697 */ |
|
698 if ( prevextremevalid ) { |
|
699 extremediff = prevval - prevextreme; |
|
700 if ( extremediff < 0 ) |
|
701 extremediff = -extremediff; |
|
702 if ( extremediff > max ) |
|
703 max = extremediff; |
|
704 } |
|
705 prevextremevalid = 1; |
|
706 prevextreme = prevval; |
|
707 } |
|
708 prevval = val; |
|
709 if ( diff != 0 ) |
|
710 prevdiff = diff; |
|
711 } |
|
712 return PyInt_FromLong(max); |
|
713 } |
|
714 |
|
715 static PyObject * |
|
716 audioop_cross(PyObject *self, PyObject *args) |
|
717 { |
|
718 signed char *cp; |
|
719 int len, size, val = 0; |
|
720 int i; |
|
721 int prevval, ncross; |
|
722 |
|
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; |
|
728 } |
|
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; |
|
738 } |
|
739 return PyInt_FromLong(ncross); |
|
740 } |
|
741 |
|
742 static PyObject * |
|
743 audioop_mul(PyObject *self, PyObject *args) |
|
744 { |
|
745 signed char *cp, *ncp; |
|
746 int len, size, val = 0; |
|
747 double factor, fval, maxval; |
|
748 PyObject *rv; |
|
749 int i; |
|
750 |
|
751 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) ) |
|
752 return 0; |
|
753 |
|
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; |
|
760 } |
|
761 |
|
762 rv = PyString_FromStringAndSize(NULL, len); |
|
763 if ( rv == 0 ) |
|
764 return 0; |
|
765 ncp = (signed char *)PyString_AsString(rv); |
|
766 |
|
767 |
|
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; |
|
779 } |
|
780 return rv; |
|
781 } |
|
782 |
|
783 static PyObject * |
|
784 audioop_tomono(PyObject *self, PyObject *args) |
|
785 { |
|
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; |
|
791 |
|
792 if ( !PyArg_ParseTuple(args, "s#idd:tomono", |
|
793 &cp, &len, &size, &fac1, &fac2 ) ) |
|
794 return 0; |
|
795 |
|
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; |
|
802 } |
|
803 |
|
804 rv = PyString_FromStringAndSize(NULL, len/2); |
|
805 if ( rv == 0 ) |
|
806 return 0; |
|
807 ncp = (signed char *)PyString_AsString(rv); |
|
808 |
|
809 |
|
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; |
|
824 } |
|
825 return rv; |
|
826 } |
|
827 |
|
828 static PyObject * |
|
829 audioop_tostereo(PyObject *self, PyObject *args) |
|
830 { |
|
831 signed char *cp, *ncp; |
|
832 int len, new_len, size, val1, val2, val = 0; |
|
833 double fac1, fac2, fval, maxval; |
|
834 PyObject *rv; |
|
835 int i; |
|
836 |
|
837 if ( !PyArg_ParseTuple(args, "s#idd:tostereo", |
|
838 &cp, &len, &size, &fac1, &fac2 ) ) |
|
839 return 0; |
|
840 |
|
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; |
|
847 } |
|
848 |
|
849 new_len = len*2; |
|
850 if (new_len < 0) { |
|
851 PyErr_SetString(PyExc_MemoryError, |
|
852 "not enough memory for output buffer"); |
|
853 return 0; |
|
854 } |
|
855 |
|
856 rv = PyString_FromStringAndSize(NULL, new_len); |
|
857 if ( rv == 0 ) |
|
858 return 0; |
|
859 ncp = (signed char *)PyString_AsString(rv); |
|
860 |
|
861 |
|
862 for ( i=0; i < len; i += size ) { |
|
863 if ( size == 1 ) val = (int)*CHARP(cp, i); |
|
864 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
865 else if ( size == 4 ) val = (int)*LONGP(cp, i); |
|
866 |
|
867 fval = (double)val*fac1; |
|
868 if ( fval > maxval ) fval = maxval; |
|
869 else if ( fval < -maxval ) fval = -maxval; |
|
870 val1 = (int)fval; |
|
871 |
|
872 fval = (double)val*fac2; |
|
873 if ( fval > maxval ) fval = maxval; |
|
874 else if ( fval < -maxval ) fval = -maxval; |
|
875 val2 = (int)fval; |
|
876 |
|
877 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1; |
|
878 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1; |
|
879 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1; |
|
880 |
|
881 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2; |
|
882 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2; |
|
883 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2; |
|
884 } |
|
885 return rv; |
|
886 } |
|
887 |
|
888 static PyObject * |
|
889 audioop_add(PyObject *self, PyObject *args) |
|
890 { |
|
891 signed char *cp1, *cp2, *ncp; |
|
892 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval; |
|
893 PyObject *rv; |
|
894 int i; |
|
895 |
|
896 if ( !PyArg_ParseTuple(args, "s#s#i:add", |
|
897 &cp1, &len1, &cp2, &len2, &size ) ) |
|
898 return 0; |
|
899 |
|
900 if ( len1 != len2 ) { |
|
901 PyErr_SetString(AudioopError, "Lengths should be the same"); |
|
902 return 0; |
|
903 } |
|
904 |
|
905 if ( size == 1 ) maxval = 0x7f; |
|
906 else if ( size == 2 ) maxval = 0x7fff; |
|
907 else if ( size == 4 ) maxval = 0x7fffffff; |
|
908 else { |
|
909 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
910 return 0; |
|
911 } |
|
912 |
|
913 rv = PyString_FromStringAndSize(NULL, len1); |
|
914 if ( rv == 0 ) |
|
915 return 0; |
|
916 ncp = (signed char *)PyString_AsString(rv); |
|
917 |
|
918 for ( i=0; i < len1; i += size ) { |
|
919 if ( size == 1 ) val1 = (int)*CHARP(cp1, i); |
|
920 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i); |
|
921 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i); |
|
922 |
|
923 if ( size == 1 ) val2 = (int)*CHARP(cp2, i); |
|
924 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i); |
|
925 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i); |
|
926 |
|
927 newval = val1 + val2; |
|
928 /* truncate in case of overflow */ |
|
929 if (newval > maxval) newval = maxval; |
|
930 else if (newval < -maxval) newval = -maxval; |
|
931 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0) |
|
932 newval = val1 > 0 ? maxval : - maxval; |
|
933 |
|
934 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval; |
|
935 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval; |
|
936 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval; |
|
937 } |
|
938 return rv; |
|
939 } |
|
940 |
|
941 static PyObject * |
|
942 audioop_bias(PyObject *self, PyObject *args) |
|
943 { |
|
944 signed char *cp, *ncp; |
|
945 int len, size, val = 0; |
|
946 PyObject *rv; |
|
947 int i; |
|
948 int bias; |
|
949 |
|
950 if ( !PyArg_ParseTuple(args, "s#ii:bias", |
|
951 &cp, &len, &size , &bias) ) |
|
952 return 0; |
|
953 |
|
954 if ( size != 1 && size != 2 && size != 4) { |
|
955 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
956 return 0; |
|
957 } |
|
958 |
|
959 rv = PyString_FromStringAndSize(NULL, len); |
|
960 if ( rv == 0 ) |
|
961 return 0; |
|
962 ncp = (signed char *)PyString_AsString(rv); |
|
963 |
|
964 |
|
965 for ( i=0; i < len; i += size ) { |
|
966 if ( size == 1 ) val = (int)*CHARP(cp, i); |
|
967 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
968 else if ( size == 4 ) val = (int)*LONGP(cp, i); |
|
969 |
|
970 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias); |
|
971 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias); |
|
972 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias); |
|
973 } |
|
974 return rv; |
|
975 } |
|
976 |
|
977 static PyObject * |
|
978 audioop_reverse(PyObject *self, PyObject *args) |
|
979 { |
|
980 signed char *cp; |
|
981 unsigned char *ncp; |
|
982 int len, size, val = 0; |
|
983 PyObject *rv; |
|
984 int i, j; |
|
985 |
|
986 if ( !PyArg_ParseTuple(args, "s#i:reverse", |
|
987 &cp, &len, &size) ) |
|
988 return 0; |
|
989 |
|
990 if ( size != 1 && size != 2 && size != 4 ) { |
|
991 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
992 return 0; |
|
993 } |
|
994 |
|
995 rv = PyString_FromStringAndSize(NULL, len); |
|
996 if ( rv == 0 ) |
|
997 return 0; |
|
998 ncp = (unsigned char *)PyString_AsString(rv); |
|
999 |
|
1000 for ( i=0; i < len; i += size ) { |
|
1001 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; |
|
1002 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
1003 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16; |
|
1004 |
|
1005 j = len - i - size; |
|
1006 |
|
1007 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8); |
|
1008 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val); |
|
1009 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16); |
|
1010 } |
|
1011 return rv; |
|
1012 } |
|
1013 |
|
1014 static PyObject * |
|
1015 audioop_lin2lin(PyObject *self, PyObject *args) |
|
1016 { |
|
1017 signed char *cp; |
|
1018 unsigned char *ncp; |
|
1019 int len, new_len, size, size2, val = 0; |
|
1020 PyObject *rv; |
|
1021 int i, j; |
|
1022 |
|
1023 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin", |
|
1024 &cp, &len, &size, &size2) ) |
|
1025 return 0; |
|
1026 |
|
1027 if ( (size != 1 && size != 2 && size != 4) || |
|
1028 (size2 != 1 && size2 != 2 && size2 != 4)) { |
|
1029 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1030 return 0; |
|
1031 } |
|
1032 |
|
1033 new_len = (len/size)*size2; |
|
1034 if (new_len < 0) { |
|
1035 PyErr_SetString(PyExc_MemoryError, |
|
1036 "not enough memory for output buffer"); |
|
1037 return 0; |
|
1038 } |
|
1039 rv = PyString_FromStringAndSize(NULL, new_len); |
|
1040 if ( rv == 0 ) |
|
1041 return 0; |
|
1042 ncp = (unsigned char *)PyString_AsString(rv); |
|
1043 |
|
1044 for ( i=0, j=0; i < len; i += size, j += size2 ) { |
|
1045 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; |
|
1046 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
1047 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16; |
|
1048 |
|
1049 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8); |
|
1050 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val); |
|
1051 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16); |
|
1052 } |
|
1053 return rv; |
|
1054 } |
|
1055 |
|
1056 static int |
|
1057 gcd(int a, int b) |
|
1058 { |
|
1059 while (b > 0) { |
|
1060 int tmp = a % b; |
|
1061 a = b; |
|
1062 b = tmp; |
|
1063 } |
|
1064 return a; |
|
1065 } |
|
1066 |
|
1067 static PyObject * |
|
1068 audioop_ratecv(PyObject *self, PyObject *args) |
|
1069 { |
|
1070 char *cp, *ncp; |
|
1071 int len, size, nchannels, inrate, outrate, weightA, weightB; |
|
1072 int chan, d, *prev_i, *cur_i, cur_o; |
|
1073 PyObject *state, *samps, *str, *rv = NULL; |
|
1074 int bytes_per_frame; |
|
1075 size_t alloc_size; |
|
1076 |
|
1077 weightA = 1; |
|
1078 weightB = 0; |
|
1079 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, |
|
1080 &nchannels, &inrate, &outrate, &state, |
|
1081 &weightA, &weightB)) |
|
1082 return NULL; |
|
1083 if (size != 1 && size != 2 && size != 4) { |
|
1084 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1085 return NULL; |
|
1086 } |
|
1087 if (nchannels < 1) { |
|
1088 PyErr_SetString(AudioopError, "# of channels should be >= 1"); |
|
1089 return NULL; |
|
1090 } |
|
1091 bytes_per_frame = size * nchannels; |
|
1092 if (bytes_per_frame / nchannels != size) { |
|
1093 /* This overflow test is rigorously correct because |
|
1094 both multiplicands are >= 1. Use the argument names |
|
1095 from the docs for the error msg. */ |
|
1096 PyErr_SetString(PyExc_OverflowError, |
|
1097 "width * nchannels too big for a C int"); |
|
1098 return NULL; |
|
1099 } |
|
1100 if (weightA < 1 || weightB < 0) { |
|
1101 PyErr_SetString(AudioopError, |
|
1102 "weightA should be >= 1, weightB should be >= 0"); |
|
1103 return NULL; |
|
1104 } |
|
1105 if (len % bytes_per_frame != 0) { |
|
1106 PyErr_SetString(AudioopError, "not a whole number of frames"); |
|
1107 return NULL; |
|
1108 } |
|
1109 if (inrate <= 0 || outrate <= 0) { |
|
1110 PyErr_SetString(AudioopError, "sampling rate not > 0"); |
|
1111 return NULL; |
|
1112 } |
|
1113 /* divide inrate and outrate by their greatest common divisor */ |
|
1114 d = gcd(inrate, outrate); |
|
1115 inrate /= d; |
|
1116 outrate /= d; |
|
1117 |
|
1118 alloc_size = sizeof(int) * (unsigned)nchannels; |
|
1119 if (alloc_size < nchannels) { |
|
1120 PyErr_SetString(PyExc_MemoryError, |
|
1121 "not enough memory for output buffer"); |
|
1122 return 0; |
|
1123 } |
|
1124 prev_i = (int *) malloc(alloc_size); |
|
1125 cur_i = (int *) malloc(alloc_size); |
|
1126 if (prev_i == NULL || cur_i == NULL) { |
|
1127 (void) PyErr_NoMemory(); |
|
1128 goto exit; |
|
1129 } |
|
1130 |
|
1131 len /= bytes_per_frame; /* # of frames */ |
|
1132 |
|
1133 if (state == Py_None) { |
|
1134 d = -outrate; |
|
1135 for (chan = 0; chan < nchannels; chan++) |
|
1136 prev_i[chan] = cur_i[chan] = 0; |
|
1137 } |
|
1138 else { |
|
1139 if (!PyArg_ParseTuple(state, |
|
1140 "iO!;audioop.ratecv: illegal state argument", |
|
1141 &d, &PyTuple_Type, &samps)) |
|
1142 goto exit; |
|
1143 if (PyTuple_Size(samps) != nchannels) { |
|
1144 PyErr_SetString(AudioopError, |
|
1145 "illegal state argument"); |
|
1146 goto exit; |
|
1147 } |
|
1148 for (chan = 0; chan < nchannels; chan++) { |
|
1149 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan), |
|
1150 "ii:ratecv", &prev_i[chan], |
|
1151 &cur_i[chan])) |
|
1152 goto exit; |
|
1153 } |
|
1154 } |
|
1155 |
|
1156 /* str <- Space for the output buffer. */ |
|
1157 { |
|
1158 /* There are len input frames, so we need (mathematically) |
|
1159 ceiling(len*outrate/inrate) output frames, and each frame |
|
1160 requires bytes_per_frame bytes. Computing this |
|
1161 without spurious overflow is the challenge; we can |
|
1162 settle for a reasonable upper bound, though. */ |
|
1163 int ceiling; /* the number of output frames */ |
|
1164 int nbytes; /* the number of output bytes needed */ |
|
1165 int q = len / inrate; |
|
1166 /* Now len = q * inrate + r exactly (with r = len % inrate), |
|
1167 and this is less than q * inrate + inrate = (q+1)*inrate. |
|
1168 So a reasonable upper bound on len*outrate/inrate is |
|
1169 ((q+1)*inrate)*outrate/inrate = |
|
1170 (q+1)*outrate. |
|
1171 */ |
|
1172 ceiling = (q+1) * outrate; |
|
1173 nbytes = ceiling * bytes_per_frame; |
|
1174 /* See whether anything overflowed; if not, get the space. */ |
|
1175 if (q+1 < 0 || |
|
1176 ceiling / outrate != q+1 || |
|
1177 nbytes / bytes_per_frame != ceiling) |
|
1178 str = NULL; |
|
1179 else |
|
1180 str = PyString_FromStringAndSize(NULL, nbytes); |
|
1181 |
|
1182 if (str == NULL) { |
|
1183 PyErr_SetString(PyExc_MemoryError, |
|
1184 "not enough memory for output buffer"); |
|
1185 goto exit; |
|
1186 } |
|
1187 } |
|
1188 ncp = PyString_AsString(str); |
|
1189 |
|
1190 for (;;) { |
|
1191 while (d < 0) { |
|
1192 if (len == 0) { |
|
1193 samps = PyTuple_New(nchannels); |
|
1194 if (samps == NULL) |
|
1195 goto exit; |
|
1196 for (chan = 0; chan < nchannels; chan++) |
|
1197 PyTuple_SetItem(samps, chan, |
|
1198 Py_BuildValue("(ii)", |
|
1199 prev_i[chan], |
|
1200 cur_i[chan])); |
|
1201 if (PyErr_Occurred()) |
|
1202 goto exit; |
|
1203 /* We have checked before that the length |
|
1204 * of the string fits into int. */ |
|
1205 len = (int)(ncp - PyString_AsString(str)); |
|
1206 if (len == 0) { |
|
1207 /*don't want to resize to zero length*/ |
|
1208 rv = PyString_FromStringAndSize("", 0); |
|
1209 Py_DECREF(str); |
|
1210 str = rv; |
|
1211 } else if (_PyString_Resize(&str, len) < 0) |
|
1212 goto exit; |
|
1213 rv = Py_BuildValue("(O(iO))", str, d, samps); |
|
1214 Py_DECREF(samps); |
|
1215 Py_DECREF(str); |
|
1216 goto exit; /* return rv */ |
|
1217 } |
|
1218 for (chan = 0; chan < nchannels; chan++) { |
|
1219 prev_i[chan] = cur_i[chan]; |
|
1220 if (size == 1) |
|
1221 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8; |
|
1222 else if (size == 2) |
|
1223 cur_i[chan] = (int)*SHORTP(cp, 0); |
|
1224 else if (size == 4) |
|
1225 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16; |
|
1226 cp += size; |
|
1227 /* implements a simple digital filter */ |
|
1228 cur_i[chan] = |
|
1229 (weightA * cur_i[chan] + |
|
1230 weightB * prev_i[chan]) / |
|
1231 (weightA + weightB); |
|
1232 } |
|
1233 len--; |
|
1234 d += outrate; |
|
1235 } |
|
1236 while (d >= 0) { |
|
1237 for (chan = 0; chan < nchannels; chan++) { |
|
1238 cur_o = (prev_i[chan] * d + |
|
1239 cur_i[chan] * (outrate - d)) / |
|
1240 outrate; |
|
1241 if (size == 1) |
|
1242 *CHARP(ncp, 0) = (signed char)(cur_o >> 8); |
|
1243 else if (size == 2) |
|
1244 *SHORTP(ncp, 0) = (short)(cur_o); |
|
1245 else if (size == 4) |
|
1246 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16); |
|
1247 ncp += size; |
|
1248 } |
|
1249 d -= inrate; |
|
1250 } |
|
1251 } |
|
1252 exit: |
|
1253 if (prev_i != NULL) |
|
1254 free(prev_i); |
|
1255 if (cur_i != NULL) |
|
1256 free(cur_i); |
|
1257 return rv; |
|
1258 } |
|
1259 |
|
1260 static PyObject * |
|
1261 audioop_lin2ulaw(PyObject *self, PyObject *args) |
|
1262 { |
|
1263 signed char *cp; |
|
1264 unsigned char *ncp; |
|
1265 int len, size, val = 0; |
|
1266 PyObject *rv; |
|
1267 int i; |
|
1268 |
|
1269 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw", |
|
1270 &cp, &len, &size) ) |
|
1271 return 0 ; |
|
1272 |
|
1273 if ( size != 1 && size != 2 && size != 4) { |
|
1274 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1275 return 0; |
|
1276 } |
|
1277 |
|
1278 rv = PyString_FromStringAndSize(NULL, len/size); |
|
1279 if ( rv == 0 ) |
|
1280 return 0; |
|
1281 ncp = (unsigned char *)PyString_AsString(rv); |
|
1282 |
|
1283 for ( i=0; i < len; i += size ) { |
|
1284 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; |
|
1285 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
1286 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16; |
|
1287 |
|
1288 *ncp++ = st_14linear2ulaw(val); |
|
1289 } |
|
1290 return rv; |
|
1291 } |
|
1292 |
|
1293 static PyObject * |
|
1294 audioop_ulaw2lin(PyObject *self, PyObject *args) |
|
1295 { |
|
1296 unsigned char *cp; |
|
1297 unsigned char cval; |
|
1298 signed char *ncp; |
|
1299 int len, new_len, size, val; |
|
1300 PyObject *rv; |
|
1301 int i; |
|
1302 |
|
1303 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin", |
|
1304 &cp, &len, &size) ) |
|
1305 return 0; |
|
1306 |
|
1307 if ( size != 1 && size != 2 && size != 4) { |
|
1308 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1309 return 0; |
|
1310 } |
|
1311 |
|
1312 new_len = len*size; |
|
1313 if (new_len < 0) { |
|
1314 PyErr_SetString(PyExc_MemoryError, |
|
1315 "not enough memory for output buffer"); |
|
1316 return 0; |
|
1317 } |
|
1318 rv = PyString_FromStringAndSize(NULL, new_len); |
|
1319 if ( rv == 0 ) |
|
1320 return 0; |
|
1321 ncp = (signed char *)PyString_AsString(rv); |
|
1322 |
|
1323 for ( i=0; i < new_len; i += size ) { |
|
1324 cval = *cp++; |
|
1325 val = st_ulaw2linear16(cval); |
|
1326 |
|
1327 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8); |
|
1328 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val); |
|
1329 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16); |
|
1330 } |
|
1331 return rv; |
|
1332 } |
|
1333 |
|
1334 static PyObject * |
|
1335 audioop_lin2alaw(PyObject *self, PyObject *args) |
|
1336 { |
|
1337 signed char *cp; |
|
1338 unsigned char *ncp; |
|
1339 int len, size, val = 0; |
|
1340 PyObject *rv; |
|
1341 int i; |
|
1342 |
|
1343 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw", |
|
1344 &cp, &len, &size) ) |
|
1345 return 0; |
|
1346 |
|
1347 if ( size != 1 && size != 2 && size != 4) { |
|
1348 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1349 return 0; |
|
1350 } |
|
1351 |
|
1352 rv = PyString_FromStringAndSize(NULL, len/size); |
|
1353 if ( rv == 0 ) |
|
1354 return 0; |
|
1355 ncp = (unsigned char *)PyString_AsString(rv); |
|
1356 |
|
1357 for ( i=0; i < len; i += size ) { |
|
1358 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; |
|
1359 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
1360 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16; |
|
1361 |
|
1362 *ncp++ = st_linear2alaw(val); |
|
1363 } |
|
1364 return rv; |
|
1365 } |
|
1366 |
|
1367 static PyObject * |
|
1368 audioop_alaw2lin(PyObject *self, PyObject *args) |
|
1369 { |
|
1370 unsigned char *cp; |
|
1371 unsigned char cval; |
|
1372 signed char *ncp; |
|
1373 int len, new_len, size, val; |
|
1374 PyObject *rv; |
|
1375 int i; |
|
1376 |
|
1377 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin", |
|
1378 &cp, &len, &size) ) |
|
1379 return 0; |
|
1380 |
|
1381 if ( size != 1 && size != 2 && size != 4) { |
|
1382 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1383 return 0; |
|
1384 } |
|
1385 |
|
1386 new_len = len*size; |
|
1387 if (new_len < 0) { |
|
1388 PyErr_SetString(PyExc_MemoryError, |
|
1389 "not enough memory for output buffer"); |
|
1390 return 0; |
|
1391 } |
|
1392 rv = PyString_FromStringAndSize(NULL, new_len); |
|
1393 if ( rv == 0 ) |
|
1394 return 0; |
|
1395 ncp = (signed char *)PyString_AsString(rv); |
|
1396 |
|
1397 for ( i=0; i < new_len; i += size ) { |
|
1398 cval = *cp++; |
|
1399 val = st_alaw2linear16(cval); |
|
1400 |
|
1401 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8); |
|
1402 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val); |
|
1403 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16); |
|
1404 } |
|
1405 return rv; |
|
1406 } |
|
1407 |
|
1408 static PyObject * |
|
1409 audioop_lin2adpcm(PyObject *self, PyObject *args) |
|
1410 { |
|
1411 signed char *cp; |
|
1412 signed char *ncp; |
|
1413 int len, size, val = 0, step, valpred, delta, |
|
1414 index, sign, vpdiff, diff; |
|
1415 PyObject *rv, *state, *str; |
|
1416 int i, outputbuffer = 0, bufferstep; |
|
1417 |
|
1418 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm", |
|
1419 &cp, &len, &size, &state) ) |
|
1420 return 0; |
|
1421 |
|
1422 |
|
1423 if ( size != 1 && size != 2 && size != 4) { |
|
1424 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1425 return 0; |
|
1426 } |
|
1427 |
|
1428 str = PyString_FromStringAndSize(NULL, len/(size*2)); |
|
1429 if ( str == 0 ) |
|
1430 return 0; |
|
1431 ncp = (signed char *)PyString_AsString(str); |
|
1432 |
|
1433 /* Decode state, should have (value, step) */ |
|
1434 if ( state == Py_None ) { |
|
1435 /* First time, it seems. Set defaults */ |
|
1436 valpred = 0; |
|
1437 step = 7; |
|
1438 index = 0; |
|
1439 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) ) |
|
1440 return 0; |
|
1441 |
|
1442 step = stepsizeTable[index]; |
|
1443 bufferstep = 1; |
|
1444 |
|
1445 for ( i=0; i < len; i += size ) { |
|
1446 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; |
|
1447 else if ( size == 2 ) val = (int)*SHORTP(cp, i); |
|
1448 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16; |
|
1449 |
|
1450 /* Step 1 - compute difference with previous value */ |
|
1451 diff = val - valpred; |
|
1452 sign = (diff < 0) ? 8 : 0; |
|
1453 if ( sign ) diff = (-diff); |
|
1454 |
|
1455 /* Step 2 - Divide and clamp */ |
|
1456 /* Note: |
|
1457 ** This code *approximately* computes: |
|
1458 ** delta = diff*4/step; |
|
1459 ** vpdiff = (delta+0.5)*step/4; |
|
1460 ** but in shift step bits are dropped. The net result of this |
|
1461 ** is that even if you have fast mul/div hardware you cannot |
|
1462 ** put it to good use since the fixup would be too expensive. |
|
1463 */ |
|
1464 delta = 0; |
|
1465 vpdiff = (step >> 3); |
|
1466 |
|
1467 if ( diff >= step ) { |
|
1468 delta = 4; |
|
1469 diff -= step; |
|
1470 vpdiff += step; |
|
1471 } |
|
1472 step >>= 1; |
|
1473 if ( diff >= step ) { |
|
1474 delta |= 2; |
|
1475 diff -= step; |
|
1476 vpdiff += step; |
|
1477 } |
|
1478 step >>= 1; |
|
1479 if ( diff >= step ) { |
|
1480 delta |= 1; |
|
1481 vpdiff += step; |
|
1482 } |
|
1483 |
|
1484 /* Step 3 - Update previous value */ |
|
1485 if ( sign ) |
|
1486 valpred -= vpdiff; |
|
1487 else |
|
1488 valpred += vpdiff; |
|
1489 |
|
1490 /* Step 4 - Clamp previous value to 16 bits */ |
|
1491 if ( valpred > 32767 ) |
|
1492 valpred = 32767; |
|
1493 else if ( valpred < -32768 ) |
|
1494 valpred = -32768; |
|
1495 |
|
1496 /* Step 5 - Assemble value, update index and step values */ |
|
1497 delta |= sign; |
|
1498 |
|
1499 index += indexTable[delta]; |
|
1500 if ( index < 0 ) index = 0; |
|
1501 if ( index > 88 ) index = 88; |
|
1502 step = stepsizeTable[index]; |
|
1503 |
|
1504 /* Step 6 - Output value */ |
|
1505 if ( bufferstep ) { |
|
1506 outputbuffer = (delta << 4) & 0xf0; |
|
1507 } else { |
|
1508 *ncp++ = (delta & 0x0f) | outputbuffer; |
|
1509 } |
|
1510 bufferstep = !bufferstep; |
|
1511 } |
|
1512 rv = Py_BuildValue("(O(ii))", str, valpred, index); |
|
1513 Py_DECREF(str); |
|
1514 return rv; |
|
1515 } |
|
1516 |
|
1517 static PyObject * |
|
1518 audioop_adpcm2lin(PyObject *self, PyObject *args) |
|
1519 { |
|
1520 signed char *cp; |
|
1521 signed char *ncp; |
|
1522 int len, new_len, size, valpred, step, delta, index, sign, vpdiff; |
|
1523 PyObject *rv, *str, *state; |
|
1524 int i, inputbuffer = 0, bufferstep; |
|
1525 |
|
1526 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin", |
|
1527 &cp, &len, &size, &state) ) |
|
1528 return 0; |
|
1529 |
|
1530 if ( size != 1 && size != 2 && size != 4) { |
|
1531 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); |
|
1532 return 0; |
|
1533 } |
|
1534 |
|
1535 /* Decode state, should have (value, step) */ |
|
1536 if ( state == Py_None ) { |
|
1537 /* First time, it seems. Set defaults */ |
|
1538 valpred = 0; |
|
1539 step = 7; |
|
1540 index = 0; |
|
1541 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) ) |
|
1542 return 0; |
|
1543 |
|
1544 new_len = len*size*2; |
|
1545 if (new_len < 0) { |
|
1546 PyErr_SetString(PyExc_MemoryError, |
|
1547 "not enough memory for output buffer"); |
|
1548 return 0; |
|
1549 } |
|
1550 str = PyString_FromStringAndSize(NULL, new_len); |
|
1551 if ( str == 0 ) |
|
1552 return 0; |
|
1553 ncp = (signed char *)PyString_AsString(str); |
|
1554 |
|
1555 step = stepsizeTable[index]; |
|
1556 bufferstep = 0; |
|
1557 |
|
1558 for ( i=0; i < new_len; i += size ) { |
|
1559 /* Step 1 - get the delta value and compute next index */ |
|
1560 if ( bufferstep ) { |
|
1561 delta = inputbuffer & 0xf; |
|
1562 } else { |
|
1563 inputbuffer = *cp++; |
|
1564 delta = (inputbuffer >> 4) & 0xf; |
|
1565 } |
|
1566 |
|
1567 bufferstep = !bufferstep; |
|
1568 |
|
1569 /* Step 2 - Find new index value (for later) */ |
|
1570 index += indexTable[delta]; |
|
1571 if ( index < 0 ) index = 0; |
|
1572 if ( index > 88 ) index = 88; |
|
1573 |
|
1574 /* Step 3 - Separate sign and magnitude */ |
|
1575 sign = delta & 8; |
|
1576 delta = delta & 7; |
|
1577 |
|
1578 /* Step 4 - Compute difference and new predicted value */ |
|
1579 /* |
|
1580 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment |
|
1581 ** in adpcm_coder. |
|
1582 */ |
|
1583 vpdiff = step >> 3; |
|
1584 if ( delta & 4 ) vpdiff += step; |
|
1585 if ( delta & 2 ) vpdiff += step>>1; |
|
1586 if ( delta & 1 ) vpdiff += step>>2; |
|
1587 |
|
1588 if ( sign ) |
|
1589 valpred -= vpdiff; |
|
1590 else |
|
1591 valpred += vpdiff; |
|
1592 |
|
1593 /* Step 5 - clamp output value */ |
|
1594 if ( valpred > 32767 ) |
|
1595 valpred = 32767; |
|
1596 else if ( valpred < -32768 ) |
|
1597 valpred = -32768; |
|
1598 |
|
1599 /* Step 6 - Update step value */ |
|
1600 step = stepsizeTable[index]; |
|
1601 |
|
1602 /* Step 6 - Output value */ |
|
1603 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8); |
|
1604 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred); |
|
1605 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16); |
|
1606 } |
|
1607 |
|
1608 rv = Py_BuildValue("(O(ii))", str, valpred, index); |
|
1609 Py_DECREF(str); |
|
1610 return rv; |
|
1611 } |
|
1612 |
|
1613 static PyMethodDef audioop_methods[] = { |
|
1614 { "max", audioop_max, METH_VARARGS }, |
|
1615 { "minmax", audioop_minmax, METH_VARARGS }, |
|
1616 { "avg", audioop_avg, METH_VARARGS }, |
|
1617 { "maxpp", audioop_maxpp, METH_VARARGS }, |
|
1618 { "avgpp", audioop_avgpp, METH_VARARGS }, |
|
1619 { "rms", audioop_rms, METH_VARARGS }, |
|
1620 { "findfit", audioop_findfit, METH_VARARGS }, |
|
1621 { "findmax", audioop_findmax, METH_VARARGS }, |
|
1622 { "findfactor", audioop_findfactor, METH_VARARGS }, |
|
1623 { "cross", audioop_cross, METH_VARARGS }, |
|
1624 { "mul", audioop_mul, METH_VARARGS }, |
|
1625 { "add", audioop_add, METH_VARARGS }, |
|
1626 { "bias", audioop_bias, METH_VARARGS }, |
|
1627 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS }, |
|
1628 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS }, |
|
1629 { "alaw2lin", audioop_alaw2lin, METH_VARARGS }, |
|
1630 { "lin2alaw", audioop_lin2alaw, METH_VARARGS }, |
|
1631 { "lin2lin", audioop_lin2lin, METH_VARARGS }, |
|
1632 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS }, |
|
1633 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS }, |
|
1634 { "tomono", audioop_tomono, METH_VARARGS }, |
|
1635 { "tostereo", audioop_tostereo, METH_VARARGS }, |
|
1636 { "getsample", audioop_getsample, METH_VARARGS }, |
|
1637 { "reverse", audioop_reverse, METH_VARARGS }, |
|
1638 { "ratecv", audioop_ratecv, METH_VARARGS }, |
|
1639 { 0, 0 } |
|
1640 }; |
|
1641 |
|
1642 PyMODINIT_FUNC |
|
1643 initaudioop(void) |
|
1644 { |
|
1645 PyObject *m, *d; |
|
1646 m = Py_InitModule("audioop", audioop_methods); |
|
1647 if (m == NULL) |
|
1648 return; |
|
1649 d = PyModule_GetDict(m); |
|
1650 if (d == NULL) |
|
1651 return; |
|
1652 AudioopError = PyErr_NewException("audioop.error", NULL, NULL); |
|
1653 if (AudioopError != NULL) |
|
1654 PyDict_SetItemString(d,"error",AudioopError); |
|
1655 } |