blob: 66f1f1f36a7465a44c4c32909533f119bb53a76b [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Mark Dickinson81fece22010-05-11 13:34:35 +00004#define PY_SSIZE_T_CLEAN
5
Roger E. Masseeaa6e111997-01-03 19:26:27 +00006#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00007
Guido van Rossum69011961998-04-23 20:23:00 +00008#if SIZEOF_INT == 4
9typedef int Py_Int32;
10typedef unsigned int Py_UInt32;
11#else
12#if SIZEOF_LONG == 4
13typedef long Py_Int32;
14typedef unsigned long Py_UInt32;
15#else
16#error "No 4-byte integral type"
17#endif
18#endif
19
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000020typedef short PyInt16;
21
Guido van Rossum7b1e9741994-08-29 10:46:42 +000022#if defined(__CHAR_UNSIGNED__)
23#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000024/* This module currently does not work on systems where only unsigned
25 characters are available. Take it out of Setup. Sorry. */
26#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000027#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000028
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000029/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000030** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
31
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032/* 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 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000043#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
44#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045#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. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000049
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000050static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
51 0x1FF, 0x3FF, 0x7FF, 0xFFF};
52static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
53 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
54
55static PyInt16
56search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 for (i = 0; i < size; i++) {
61 if (val <= *table++)
62 return (i);
63 }
64 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000065}
66#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
67#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000068
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069static 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,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000089 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,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 80, 72, 64, 56, 48, 40, 32,
106 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000108
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000109/*
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 */
141static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 PyInt16 mask;
145 PyInt16 seg;
146 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 /* The original sox code does this in the calling function, not here */
149 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 /* u-law inverts all bits */
152 /* Get the sign and the magnitude of the value. */
153 if (pcm_val < 0) {
154 pcm_val = -pcm_val;
155 mask = 0x7F;
156 } else {
157 mask = 0xFF;
158 }
159 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
160 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 /* Convert the scaled magnitude to segment number. */
163 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 /*
166 * Combine the sign, segment, quantization bits;
167 * and complement the code word.
168 */
169 if (seg >= 8) /* out of range, return maximum value. */
170 return (unsigned char) (0x7F ^ mask);
171 else {
172 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
173 return (uval ^ mask);
174 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000175
176}
177
178static 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 */
238static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 PyInt16 mask;
242 short seg;
243 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 /* The original sox code does this in the calling function, not here */
246 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 /* A-law using even bit inversion */
249 if (pcm_val >= 0) {
250 mask = 0xD5; /* sign (7th) bit = 1 */
251 } else {
252 mask = 0x55; /* sign bit = 0 */
253 pcm_val = -pcm_val - 1;
254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Convert the scaled magnitude to segment number. */
257 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (seg >= 8) /* out of range, return maximum value. */
262 return (unsigned char) (0x7F ^ mask);
263 else {
264 aval = (unsigned char) seg << SEG_SHIFT;
265 if (seg < 2)
266 aval |= (pcm_val >> 1) & QUANT_MASK;
267 else
268 aval |= (pcm_val >> seg) & QUANT_MASK;
269 return (aval ^ mask);
270 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000271}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000272/* End of code taken from sox */
273
Guido van Rossumb64e6351992-07-06 14:21:56 +0000274/* Intel ADPCM step variation table */
275static int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 -1, -1, -1, -1, 2, 4, 6, 8,
277 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000278};
279
280static int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 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
Guido van Rossumb64e6351992-07-06 14:21:56 +0000290};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291
Guido van Rossumb66efa01992-06-01 16:01:24 +0000292#define CHARP(cp, i) ((signed char *)(cp+i))
293#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000294#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000295
296
297
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000298static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000299
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000300static int
301audioop_check_size(int size)
302{
303 if (size != 1 && size != 2 && size != 4) {
304 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
305 return 0;
306 }
307 else
308 return 1;
309}
310
311static int
312audioop_check_parameters(int len, int size)
313{
314 if (!audioop_check_size(size))
315 return 0;
316 if (len % size != 0) {
317 PyErr_SetString(AudioopError, "not a whole number of frames");
318 return 0;
319 }
320 return 1;
321}
322
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000324audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000327 Py_ssize_t len, i;
328 int size, val = 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000329
Mark Dickinson81fece22010-05-11 13:34:35 +0000330 if ( !PyArg_ParseTuple(args, "s#in:getsample", &cp, &len, &size, &i) )
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000332 if (!audioop_check_parameters(len, size))
333 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 if ( i < 0 || i >= len/size ) {
335 PyErr_SetString(AudioopError, "Index out of range");
336 return 0;
337 }
338 if ( size == 1 ) val = (int)*CHARP(cp, i);
339 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
340 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
341 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000342}
343
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000344static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000345audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000348 Py_ssize_t len, i;
349 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
353 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000354 if (!audioop_check_parameters(len, size))
355 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 for ( i=0; i<len; i+= size) {
357 if ( size == 1 ) val = (int)*CHARP(cp, i);
358 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
359 else if ( size == 4 ) val = (int)*LONGP(cp, i);
360 if ( val < 0 ) val = (-val);
361 if ( val > max ) max = val;
362 }
363 return PyLong_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000364}
365
366static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000367audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000370 Py_ssize_t len, i;
371 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
375 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000376 if (!audioop_check_parameters(len, size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 for (i = 0; i < len; i += size) {
379 if (size == 1) val = (int) *CHARP(cp, i);
380 else if (size == 2) val = (int) *SHORTP(cp, i);
381 else if (size == 4) val = (int) *LONGP(cp, i);
382 if (val > max) max = val;
383 if (val < min) min = val;
384 }
385 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000386}
387
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000388static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000389audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000392 Py_ssize_t len, i;
393 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
397 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000398 if (!audioop_check_parameters(len, size))
399 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 for ( i=0; i<len; i+= size) {
401 if ( size == 1 ) val = (int)*CHARP(cp, i);
402 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
403 else if ( size == 4 ) val = (int)*LONGP(cp, i);
404 avg += val;
405 }
406 if ( len == 0 )
407 val = 0;
408 else
409 val = (int)(avg / (double)(len/size));
410 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000411}
412
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000413static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000414audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000417 Py_ssize_t len, i;
418 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
422 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000423 if (!audioop_check_parameters(len, size))
424 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 for ( i=0; i<len; i+= size) {
426 if ( size == 1 ) val = (int)*CHARP(cp, i);
427 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
428 else if ( size == 4 ) val = (int)*LONGP(cp, i);
429 sum_squares += (double)val*(double)val;
430 }
431 if ( len == 0 )
432 val = 0;
433 else
434 val = (int)sqrt(sum_squares / (double)(len/size));
435 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000436}
437
Mark Dickinson81fece22010-05-11 13:34:35 +0000438static double _sum2(short *a, short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000439{
Mark Dickinson81fece22010-05-11 13:34:35 +0000440 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 for( i=0; i<len; i++) {
444 sum = sum + (double)a[i]*(double)b[i];
445 }
446 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000447}
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:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000468** 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])
Jack Jansena90805f1993-02-17 14:29:28 +0000477**
478** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
479** is completely recalculated each step.
480*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000481static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000482audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000485 Py_ssize_t len1, len2;
486 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 double aj_m1, aj_lm1;
488 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 /* 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 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
495 (char**)&cp1, &len1, (char**)&cp2, &len2) )
496 return 0;
497 if ( len1 & 1 || len2 & 1 ) {
498 PyErr_SetString(AudioopError, "Strings should be even-sized");
499 return 0;
500 }
501 len1 >>= 1;
502 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if ( len1 < len2 ) {
505 PyErr_SetString(AudioopError, "First sample should be longer");
506 return 0;
507 }
508 sum_ri_2 = _sum2(cp2, cp2, len2);
509 sum_aij_2 = _sum2(cp1, cp1, len2);
510 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 best_result = result;
515 best_j = 0;
516 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 for ( j=1; j<=len1-len2; j++) {
519 aj_m1 = (double)cp1[j-1];
520 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
523 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
526 / sum_aij_2;
527
528 if ( result < best_result ) {
529 best_result = result;
530 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000531 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 }
534
535 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
536
Mark Dickinson81fece22010-05-11 13:34:35 +0000537 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000538}
539
540/*
541** findfactor finds a factor f so that the energy in A-fB is minimal.
542** See the comment for findfit for details.
543*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000544static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000545audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000548 Py_ssize_t len1, len2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
552 (char**)&cp1, &len1, (char**)&cp2, &len2) )
553 return 0;
554 if ( len1 & 1 || len2 & 1 ) {
555 PyErr_SetString(AudioopError, "Strings should be even-sized");
556 return 0;
557 }
558 if ( len1 != len2 ) {
559 PyErr_SetString(AudioopError, "Samples should be same size");
560 return 0;
561 }
562 len2 >>= 1;
563 sum_ri_2 = _sum2(cp2, cp2, len2);
564 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000569}
570
571/*
572** findmax returns the index of the n-sized segment of the input sample
573** that contains the most energy.
574*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000575static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000576audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000577{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 short *cp1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000579 Py_ssize_t len1, len2;
580 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 double aj_m1, aj_lm1;
582 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000583
Mark Dickinson81fece22010-05-11 13:34:35 +0000584 if ( !PyArg_ParseTuple(args, "s#n:findmax",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 (char**)&cp1, &len1, &len2) )
586 return 0;
587 if ( len1 & 1 ) {
588 PyErr_SetString(AudioopError, "Strings should be even-sized");
589 return 0;
590 }
591 len1 >>= 1;
592
593 if ( len2 < 0 || len1 < len2 ) {
594 PyErr_SetString(AudioopError, "Input sample should be longer");
595 return 0;
596 }
597
598 result = _sum2(cp1, cp1, len2);
599
600 best_result = result;
601 best_j = 0;
602 j = 0;
603
604 for ( j=1; j<=len1-len2; j++) {
605 aj_m1 = (double)cp1[j-1];
606 aj_lm1 = (double)cp1[j+len2-1];
607
608 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
609
610 if ( result > best_result ) {
611 best_result = result;
612 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000613 }
Jack Jansena90805f1993-02-17 14:29:28 +0000614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000616
Mark Dickinson81fece22010-05-11 13:34:35 +0000617 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000618}
619
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000620static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000621audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000624 Py_ssize_t len, i;
625 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 prevextreme = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 double avg = 0.0;
628 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
631 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000632 if (!audioop_check_parameters(len, size))
633 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 /* Compute first delta value ahead. Also automatically makes us
635 ** skip the first extreme value
636 */
637 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
638 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
639 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
640 if ( size == 1 ) val = (int)*CHARP(cp, size);
641 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
642 else if ( size == 4 ) val = (int)*LONGP(cp, size);
643 prevdiff = val - prevval;
644
645 for ( i=size; i<len; i+= size) {
646 if ( size == 1 ) val = (int)*CHARP(cp, i);
647 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
648 else if ( size == 4 ) val = (int)*LONGP(cp, i);
649 diff = val - prevval;
650 if ( diff*prevdiff < 0 ) {
651 /* Derivative changed sign. Compute difference to last
652 ** extreme value and remember.
653 */
654 if ( prevextremevalid ) {
655 extremediff = prevval - prevextreme;
656 if ( extremediff < 0 )
657 extremediff = -extremediff;
658 avg += extremediff;
659 nextreme++;
660 }
661 prevextremevalid = 1;
662 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000663 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 prevval = val;
665 if ( diff != 0 )
666 prevdiff = diff;
667 }
668 if ( nextreme == 0 )
669 val = 0;
670 else
671 val = (int)(avg / (double)nextreme);
672 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000673}
674
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000675static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000676audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000679 Py_ssize_t len, i;
680 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 prevextreme = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 int max = 0;
683 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
686 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000687 if (!audioop_check_parameters(len, size))
688 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 /* Compute first delta value ahead. Also automatically makes us
690 ** skip the first extreme value
691 */
692 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
693 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
694 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
695 if ( size == 1 ) val = (int)*CHARP(cp, size);
696 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
697 else if ( size == 4 ) val = (int)*LONGP(cp, size);
698 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 for ( i=size; i<len; i+= size) {
701 if ( size == 1 ) val = (int)*CHARP(cp, i);
702 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
703 else if ( size == 4 ) val = (int)*LONGP(cp, i);
704 diff = val - prevval;
705 if ( diff*prevdiff < 0 ) {
706 /* Derivative changed sign. Compute difference to
707 ** last extreme value and remember.
708 */
709 if ( prevextremevalid ) {
710 extremediff = prevval - prevextreme;
711 if ( extremediff < 0 )
712 extremediff = -extremediff;
713 if ( extremediff > max )
714 max = extremediff;
715 }
716 prevextremevalid = 1;
717 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000718 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 prevval = val;
720 if ( diff != 0 )
721 prevdiff = diff;
722 }
723 return PyLong_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000724}
725
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000726static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000727audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000730 Py_ssize_t len, i;
731 int size, val = 0;
732 int prevval;
733 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
736 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000737 if (!audioop_check_parameters(len, size))
738 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 ncross = -1;
740 prevval = 17; /* Anything <> 0,1 */
741 for ( i=0; i<len; i+= size) {
742 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
743 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
744 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
745 val = val & 1;
746 if ( val != prevval ) ncross++;
747 prevval = val;
748 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000749 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750}
751
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000752static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000753audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000756 Py_ssize_t len, i;
757 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 double factor, fval, maxval;
759 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
762 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000763 if (!audioop_check_parameters(len, size))
764 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765
766 if ( size == 1 ) maxval = (double) 0x7f;
767 else if ( size == 2 ) maxval = (double) 0x7fff;
768 else if ( size == 4 ) maxval = (double) 0x7fffffff;
769 else {
770 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
771 return 0;
772 }
773
774 rv = PyBytes_FromStringAndSize(NULL, len);
775 if ( rv == 0 )
776 return 0;
777 ncp = (signed char *)PyBytes_AsString(rv);
778
779
780 for ( i=0; i < len; i += size ) {
781 if ( size == 1 ) val = (int)*CHARP(cp, i);
782 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
783 else if ( size == 4 ) val = (int)*LONGP(cp, i);
784 fval = (double)val*factor;
785 if ( fval > maxval ) fval = maxval;
786 else if ( fval < -maxval ) fval = -maxval;
787 val = (int)fval;
788 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
789 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
790 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
791 }
792 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000793}
794
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000795static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000796audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 Py_buffer pcp;
799 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000800 Py_ssize_t len, i;
801 int size, val1 = 0, val2 = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 double fac1, fac2, fval, maxval;
803 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
806 &pcp, &size, &fac1, &fac2 ) )
807 return 0;
808 cp = pcp.buf;
809 len = pcp.len;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000810 if (!audioop_check_parameters(len, size))
811 return NULL;
812 if (((len / size) & 1) != 0) {
813 PyErr_SetString(AudioopError, "not a whole number of frames");
814 return NULL;
815 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816
817 if ( size == 1 ) maxval = (double) 0x7f;
818 else if ( size == 2 ) maxval = (double) 0x7fff;
819 else if ( size == 4 ) maxval = (double) 0x7fffffff;
820 else {
821 PyBuffer_Release(&pcp);
822 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
823 return 0;
824 }
825
826 rv = PyBytes_FromStringAndSize(NULL, len/2);
827 if ( rv == 0 )
828 return 0;
829 ncp = (signed char *)PyBytes_AsString(rv);
830
831
832 for ( i=0; i < len; i += size*2 ) {
833 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
834 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
835 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
836 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
837 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
838 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
839 fval = (double)val1*fac1 + (double)val2*fac2;
840 if ( fval > maxval ) fval = maxval;
841 else if ( fval < -maxval ) fval = -maxval;
842 val1 = (int)fval;
843 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
844 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
845 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
846 }
847 PyBuffer_Release(&pcp);
848 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000849}
850
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000851static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000852audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000855 Py_ssize_t len, i;
856 int size, val1, val2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 double fac1, fac2, fval, maxval;
858 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
861 &cp, &len, &size, &fac1, &fac2 ) )
862 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000863 if (!audioop_check_parameters(len, size))
864 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 if ( size == 1 ) maxval = (double) 0x7f;
867 else if ( size == 2 ) maxval = (double) 0x7fff;
868 else if ( size == 4 ) maxval = (double) 0x7fffffff;
869 else {
870 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
871 return 0;
872 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000873
Mark Dickinson81fece22010-05-11 13:34:35 +0000874 if (len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 PyErr_SetString(PyExc_MemoryError,
876 "not enough memory for output buffer");
877 return 0;
878 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000879
Mark Dickinson85eacea2010-05-10 16:27:45 +0000880 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 if ( rv == 0 )
882 return 0;
883 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000884
Guido van Rossumb66efa01992-06-01 16:01:24 +0000885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 for ( i=0; i < len; i += size ) {
887 if ( size == 1 ) val = (int)*CHARP(cp, i);
888 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
889 else if ( size == 4 ) val = (int)*LONGP(cp, i);
890
891 fval = (double)val*fac1;
892 if ( fval > maxval ) fval = maxval;
893 else if ( fval < -maxval ) fval = -maxval;
894 val1 = (int)fval;
895
896 fval = (double)val*fac2;
897 if ( fval > maxval ) fval = maxval;
898 else if ( fval < -maxval ) fval = -maxval;
899 val2 = (int)fval;
900
901 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
902 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
903 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
904
905 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
906 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
907 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
908 }
909 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000910}
911
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000912static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000913audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000914{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 signed char *cp1, *cp2, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000916 Py_ssize_t len1, len2, i;
917 int size, val1 = 0, val2 = 0, maxval, newval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 if ( !PyArg_ParseTuple(args, "s#s#i:add",
921 &cp1, &len1, &cp2, &len2, &size ) )
922 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000923 if (!audioop_check_parameters(len1, size))
924 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 if ( len1 != len2 ) {
926 PyErr_SetString(AudioopError, "Lengths should be the same");
927 return 0;
928 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 if ( size == 1 ) maxval = 0x7f;
931 else if ( size == 2 ) maxval = 0x7fff;
932 else if ( size == 4 ) maxval = 0x7fffffff;
933 else {
934 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
935 return 0;
936 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 rv = PyBytes_FromStringAndSize(NULL, len1);
939 if ( rv == 0 )
940 return 0;
941 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 for ( i=0; i < len1; i += size ) {
944 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
945 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
946 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
949 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
950 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
951
952 newval = val1 + val2;
953 /* truncate in case of overflow */
954 if (newval > maxval) newval = maxval;
955 else if (newval < -maxval) newval = -maxval;
956 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
957 newval = val1 > 0 ? maxval : - maxval;
958
959 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
960 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
961 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
962 }
963 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000964}
965
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000966static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000967audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000970 Py_ssize_t len, i;
971 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 PyObject *rv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 if ( !PyArg_ParseTuple(args, "s#ii:bias",
976 &cp, &len, &size , &bias) )
977 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000978
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000979 if (!audioop_check_parameters(len, size))
980 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981
982 rv = PyBytes_FromStringAndSize(NULL, len);
983 if ( rv == 0 )
984 return 0;
985 ncp = (signed char *)PyBytes_AsString(rv);
986
987
988 for ( i=0; i < len; i += size ) {
989 if ( size == 1 ) val = (int)*CHARP(cp, i);
990 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
991 else if ( size == 4 ) val = (int)*LONGP(cp, i);
992
993 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
994 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
995 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
996 }
997 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000998}
999
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001000static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001001audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 signed char *cp;
1004 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001005 Py_ssize_t len, i, j;
1006 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1010 &cp, &len, &size) )
1011 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001012
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001013 if (!audioop_check_parameters(len, size))
1014 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 rv = PyBytes_FromStringAndSize(NULL, len);
1017 if ( rv == 0 )
1018 return 0;
1019 ncp = (unsigned char *)PyBytes_AsString(rv);
1020
1021 for ( i=0; i < len; i += size ) {
1022 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1023 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1024 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1025
1026 j = len - i - size;
1027
1028 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1029 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1030 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1031 }
1032 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001033}
1034
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001035static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001036audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001037{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 signed char *cp;
1039 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001040 Py_ssize_t len, i, j;
1041 int size, size2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1045 &cp, &len, &size, &size2) )
1046 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001047
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001048 if (!audioop_check_parameters(len, size))
1049 return NULL;
1050 if (!audioop_check_size(size2))
1051 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001052
Mark Dickinson81fece22010-05-11 13:34:35 +00001053 if (len/size > PY_SSIZE_T_MAX/size2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 PyErr_SetString(PyExc_MemoryError,
1055 "not enough memory for output buffer");
1056 return 0;
1057 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001058 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 if ( rv == 0 )
1060 return 0;
1061 ncp = (unsigned char *)PyBytes_AsString(rv);
1062
1063 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1064 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1065 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1066 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1067
1068 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1069 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1070 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1071 }
1072 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001073}
1074
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001075static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001076gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 while (b > 0) {
1079 int tmp = a % b;
1080 a = b;
1081 b = tmp;
1082 }
1083 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001084}
1085
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001086static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001087audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001090 Py_ssize_t len;
1091 int size, nchannels, inrate, outrate, weightA, weightB;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 int chan, d, *prev_i, *cur_i, cur_o;
1093 PyObject *state, *samps, *str, *rv = NULL;
1094 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 weightA = 1;
1097 weightB = 0;
1098 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1099 &nchannels, &inrate, &outrate, &state,
1100 &weightA, &weightB))
1101 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001102 if (!audioop_check_size(size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 if (nchannels < 1) {
1105 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1106 return NULL;
1107 }
1108 bytes_per_frame = size * nchannels;
1109 if (bytes_per_frame / nchannels != size) {
1110 /* This overflow test is rigorously correct because
1111 both multiplicands are >= 1. Use the argument names
1112 from the docs for the error msg. */
1113 PyErr_SetString(PyExc_OverflowError,
1114 "width * nchannels too big for a C int");
1115 return NULL;
1116 }
1117 if (weightA < 1 || weightB < 0) {
1118 PyErr_SetString(AudioopError,
1119 "weightA should be >= 1, weightB should be >= 0");
1120 return NULL;
1121 }
1122 if (len % bytes_per_frame != 0) {
1123 PyErr_SetString(AudioopError, "not a whole number of frames");
1124 return NULL;
1125 }
1126 if (inrate <= 0 || outrate <= 0) {
1127 PyErr_SetString(AudioopError, "sampling rate not > 0");
1128 return NULL;
1129 }
1130 /* divide inrate and outrate by their greatest common divisor */
1131 d = gcd(inrate, outrate);
1132 inrate /= d;
1133 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001134
Mark Dickinson85eacea2010-05-10 16:27:45 +00001135 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 PyErr_SetString(PyExc_MemoryError,
1137 "not enough memory for output buffer");
1138 return 0;
1139 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001140 prev_i = (int *) malloc(nchannels * sizeof(int));
1141 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 if (prev_i == NULL || cur_i == NULL) {
1143 (void) PyErr_NoMemory();
1144 goto exit;
1145 }
1146
1147 len /= bytes_per_frame; /* # of frames */
1148
1149 if (state == Py_None) {
1150 d = -outrate;
1151 for (chan = 0; chan < nchannels; chan++)
1152 prev_i[chan] = cur_i[chan] = 0;
1153 }
1154 else {
1155 if (!PyArg_ParseTuple(state,
1156 "iO!;audioop.ratecv: illegal state argument",
1157 &d, &PyTuple_Type, &samps))
1158 goto exit;
1159 if (PyTuple_Size(samps) != nchannels) {
1160 PyErr_SetString(AudioopError,
1161 "illegal state argument");
1162 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001163 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 for (chan = 0; chan < nchannels; chan++) {
1165 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1166 "ii:ratecv", &prev_i[chan],
1167 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001168 goto exit;
1169 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 /* str <- Space for the output buffer. */
1173 {
1174 /* There are len input frames, so we need (mathematically)
1175 ceiling(len*outrate/inrate) output frames, and each frame
1176 requires bytes_per_frame bytes. Computing this
1177 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001178 settle for a reasonable upper bound, though, in this
1179 case ceiling(len/inrate) * outrate. */
1180
1181 /* compute ceiling(len/inrate) without overflow */
Mark Dickinson81fece22010-05-11 13:34:35 +00001182 Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
1183 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 str = NULL;
1185 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001186 str = PyBytes_FromStringAndSize(NULL,
1187 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 if (str == NULL) {
1190 PyErr_SetString(PyExc_MemoryError,
1191 "not enough memory for output buffer");
1192 goto exit;
1193 }
1194 }
1195 ncp = PyBytes_AsString(str);
1196
1197 for (;;) {
1198 while (d < 0) {
1199 if (len == 0) {
1200 samps = PyTuple_New(nchannels);
1201 if (samps == NULL)
1202 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001203 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 PyTuple_SetItem(samps, chan,
1205 Py_BuildValue("(ii)",
1206 prev_i[chan],
1207 cur_i[chan]));
1208 if (PyErr_Occurred())
1209 goto exit;
1210 /* We have checked before that the length
1211 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001212 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 rv = PyBytes_FromStringAndSize
1214 (PyBytes_AsString(str), len);
1215 Py_DECREF(str);
1216 str = rv;
1217 if (str == NULL)
1218 goto exit;
1219 rv = Py_BuildValue("(O(iO))", str, d, samps);
1220 Py_DECREF(samps);
1221 Py_DECREF(str);
1222 goto exit; /* return rv */
1223 }
1224 for (chan = 0; chan < nchannels; chan++) {
1225 prev_i[chan] = cur_i[chan];
1226 if (size == 1)
1227 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1228 else if (size == 2)
1229 cur_i[chan] = (int)*SHORTP(cp, 0);
1230 else if (size == 4)
1231 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1232 cp += size;
1233 /* implements a simple digital filter */
1234 cur_i[chan] =
1235 (weightA * cur_i[chan] +
1236 weightB * prev_i[chan]) /
1237 (weightA + weightB);
1238 }
1239 len--;
1240 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001241 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 while (d >= 0) {
1243 for (chan = 0; chan < nchannels; chan++) {
1244 cur_o = (prev_i[chan] * d +
1245 cur_i[chan] * (outrate - d)) /
1246 outrate;
1247 if (size == 1)
1248 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1249 else if (size == 2)
1250 *SHORTP(ncp, 0) = (short)(cur_o);
1251 else if (size == 4)
1252 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1253 ncp += size;
1254 }
1255 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001256 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001258 exit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 if (prev_i != NULL)
1260 free(prev_i);
1261 if (cur_i != NULL)
1262 free(cur_i);
1263 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001264}
Guido van Rossum1851a671997-02-14 16:14:03 +00001265
Roger E. Massec905fff1997-01-17 18:12:04 +00001266static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001267audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 signed char *cp;
1270 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001271 Py_ssize_t len, i;
1272 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1276 &cp, &len, &size) )
1277 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001278
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001279 if (!audioop_check_parameters(len, size))
1280 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 rv = PyBytes_FromStringAndSize(NULL, len/size);
1283 if ( rv == 0 )
1284 return 0;
1285 ncp = (unsigned char *)PyBytes_AsString(rv);
1286
1287 for ( i=0; i < len; i += size ) {
1288 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1289 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1290 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1291
1292 *ncp++ = st_14linear2ulaw(val);
1293 }
1294 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001295}
1296
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001297static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001298audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 unsigned char *cp;
1301 unsigned char cval;
1302 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001303 Py_ssize_t len, i;
1304 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1308 &cp, &len, &size) )
1309 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001310
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001311 if (!audioop_check_parameters(len, size))
1312 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313
Mark Dickinson81fece22010-05-11 13:34:35 +00001314 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 PyErr_SetString(PyExc_MemoryError,
1316 "not enough memory for output buffer");
1317 return 0;
1318 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001319 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if ( rv == 0 )
1321 return 0;
1322 ncp = (signed char *)PyBytes_AsString(rv);
1323
Mark Dickinson85eacea2010-05-10 16:27:45 +00001324 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 cval = *cp++;
1326 val = st_ulaw2linear16(cval);
1327
1328 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1329 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1330 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1331 }
1332 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001333}
1334
1335static PyObject *
1336audioop_lin2alaw(PyObject *self, PyObject *args)
1337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 signed char *cp;
1339 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001340 Py_ssize_t len, i;
1341 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1345 &cp, &len, &size) )
1346 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001347
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001348 if (!audioop_check_parameters(len, size))
1349 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 rv = PyBytes_FromStringAndSize(NULL, len/size);
1352 if ( rv == 0 )
1353 return 0;
1354 ncp = (unsigned char *)PyBytes_AsString(rv);
1355
1356 for ( i=0; i < len; i += size ) {
1357 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1358 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1359 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1360
1361 *ncp++ = st_linear2alaw(val);
1362 }
1363 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001364}
1365
1366static PyObject *
1367audioop_alaw2lin(PyObject *self, PyObject *args)
1368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 unsigned char *cp;
1370 unsigned char cval;
1371 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001372 Py_ssize_t len, i;
1373 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1377 &cp, &len, &size) )
1378 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001379
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001380 if (!audioop_check_parameters(len, size))
1381 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382
Mark Dickinson81fece22010-05-11 13:34:35 +00001383 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 PyErr_SetString(PyExc_MemoryError,
1385 "not enough memory for output buffer");
1386 return 0;
1387 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001388 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 if ( rv == 0 )
1390 return 0;
1391 ncp = (signed char *)PyBytes_AsString(rv);
1392
Mark Dickinson85eacea2010-05-10 16:27:45 +00001393 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 cval = *cp++;
1395 val = st_alaw2linear16(cval);
1396
1397 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1398 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1399 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1400 }
1401 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001402}
1403
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001404static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001405audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001406{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 signed char *cp;
1408 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001409 Py_ssize_t len, i;
1410 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 index, sign, vpdiff, diff;
1412 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001413 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1416 &cp, &len, &size, &state) )
1417 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001418
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001419 if (!audioop_check_parameters(len, size))
1420 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421
1422 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1423 if ( str == 0 )
1424 return 0;
1425 ncp = (signed char *)PyBytes_AsString(str);
1426
1427 /* Decode state, should have (value, step) */
1428 if ( state == Py_None ) {
1429 /* First time, it seems. Set defaults */
1430 valpred = 0;
1431 step = 7;
1432 index = 0;
1433 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1434 return 0;
1435
1436 step = stepsizeTable[index];
1437 bufferstep = 1;
1438
1439 for ( i=0; i < len; i += size ) {
1440 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1441 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1442 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1443
1444 /* Step 1 - compute difference with previous value */
1445 diff = val - valpred;
1446 sign = (diff < 0) ? 8 : 0;
1447 if ( sign ) diff = (-diff);
1448
1449 /* Step 2 - Divide and clamp */
1450 /* Note:
1451 ** This code *approximately* computes:
1452 ** delta = diff*4/step;
1453 ** vpdiff = (delta+0.5)*step/4;
1454 ** but in shift step bits are dropped. The net result of this
1455 ** is that even if you have fast mul/div hardware you cannot
1456 ** put it to good use since the fixup would be too expensive.
1457 */
1458 delta = 0;
1459 vpdiff = (step >> 3);
1460
1461 if ( diff >= step ) {
1462 delta = 4;
1463 diff -= step;
1464 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 step >>= 1;
1467 if ( diff >= step ) {
1468 delta |= 2;
1469 diff -= step;
1470 vpdiff += step;
1471 }
1472 step >>= 1;
1473 if ( diff >= step ) {
1474 delta |= 1;
1475 vpdiff += step;
1476 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 /* Step 3 - Update previous value */
1479 if ( sign )
1480 valpred -= vpdiff;
1481 else
1482 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 /* Step 4 - Clamp previous value to 16 bits */
1485 if ( valpred > 32767 )
1486 valpred = 32767;
1487 else if ( valpred < -32768 )
1488 valpred = -32768;
1489
1490 /* Step 5 - Assemble value, update index and step values */
1491 delta |= sign;
1492
1493 index += indexTable[delta];
1494 if ( index < 0 ) index = 0;
1495 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001496 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 /* Step 6 - Output value */
1499 if ( bufferstep ) {
1500 outputbuffer = (delta << 4) & 0xf0;
1501 } else {
1502 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001503 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 bufferstep = !bufferstep;
1505 }
1506 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1507 Py_DECREF(str);
1508 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001509}
1510
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001511static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001512audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 signed char *cp;
1515 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001516 Py_ssize_t len, i;
1517 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001519 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1522 &cp, &len, &size, &state) )
1523 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001524
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001525 if (!audioop_check_parameters(len, size))
1526 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527
1528 /* Decode state, should have (value, step) */
1529 if ( state == Py_None ) {
1530 /* First time, it seems. Set defaults */
1531 valpred = 0;
1532 step = 7;
1533 index = 0;
1534 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1535 return 0;
1536
Mark Dickinson81fece22010-05-11 13:34:35 +00001537 if (len > (PY_SSIZE_T_MAX/2)/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyErr_SetString(PyExc_MemoryError,
1539 "not enough memory for output buffer");
1540 return 0;
1541 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001542 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 if ( str == 0 )
1544 return 0;
1545 ncp = (signed char *)PyBytes_AsString(str);
1546
1547 step = stepsizeTable[index];
1548 bufferstep = 0;
1549
Mark Dickinson85eacea2010-05-10 16:27:45 +00001550 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 /* Step 1 - get the delta value and compute next index */
1552 if ( bufferstep ) {
1553 delta = inputbuffer & 0xf;
1554 } else {
1555 inputbuffer = *cp++;
1556 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001557 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 bufferstep = !bufferstep;
1560
1561 /* Step 2 - Find new index value (for later) */
1562 index += indexTable[delta];
1563 if ( index < 0 ) index = 0;
1564 if ( index > 88 ) index = 88;
1565
1566 /* Step 3 - Separate sign and magnitude */
1567 sign = delta & 8;
1568 delta = delta & 7;
1569
1570 /* Step 4 - Compute difference and new predicted value */
1571 /*
1572 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1573 ** in adpcm_coder.
1574 */
1575 vpdiff = step >> 3;
1576 if ( delta & 4 ) vpdiff += step;
1577 if ( delta & 2 ) vpdiff += step>>1;
1578 if ( delta & 1 ) vpdiff += step>>2;
1579
1580 if ( sign )
1581 valpred -= vpdiff;
1582 else
1583 valpred += vpdiff;
1584
1585 /* Step 5 - clamp output value */
1586 if ( valpred > 32767 )
1587 valpred = 32767;
1588 else if ( valpred < -32768 )
1589 valpred = -32768;
1590
1591 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001592 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 /* Step 6 - Output value */
1595 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1596 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1597 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1598 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1601 Py_DECREF(str);
1602 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001603}
1604
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001605static PyMethodDef audioop_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 { "max", audioop_max, METH_VARARGS },
1607 { "minmax", audioop_minmax, METH_VARARGS },
1608 { "avg", audioop_avg, METH_VARARGS },
1609 { "maxpp", audioop_maxpp, METH_VARARGS },
1610 { "avgpp", audioop_avgpp, METH_VARARGS },
1611 { "rms", audioop_rms, METH_VARARGS },
1612 { "findfit", audioop_findfit, METH_VARARGS },
1613 { "findmax", audioop_findmax, METH_VARARGS },
1614 { "findfactor", audioop_findfactor, METH_VARARGS },
1615 { "cross", audioop_cross, METH_VARARGS },
1616 { "mul", audioop_mul, METH_VARARGS },
1617 { "add", audioop_add, METH_VARARGS },
1618 { "bias", audioop_bias, METH_VARARGS },
1619 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1620 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1621 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1622 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1623 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1624 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1625 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1626 { "tomono", audioop_tomono, METH_VARARGS },
1627 { "tostereo", audioop_tostereo, METH_VARARGS },
1628 { "getsample", audioop_getsample, METH_VARARGS },
1629 { "reverse", audioop_reverse, METH_VARARGS },
1630 { "ratecv", audioop_ratecv, METH_VARARGS },
1631 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001632};
1633
Martin v. Löwis1a214512008-06-11 05:26:20 +00001634
1635static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 PyModuleDef_HEAD_INIT,
1637 "audioop",
1638 NULL,
1639 -1,
1640 audioop_methods,
1641 NULL,
1642 NULL,
1643 NULL,
1644 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001645};
1646
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001647PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001648PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 PyObject *m, *d;
1651 m = PyModule_Create(&audioopmodule);
1652 if (m == NULL)
1653 return NULL;
1654 d = PyModule_GetDict(m);
1655 if (d == NULL)
1656 return NULL;
1657 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1658 if (AudioopError != NULL)
1659 PyDict_SetItemString(d,"error",AudioopError);
1660 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001661}