blob: d83ab5e3371e39b36f1f95f324d9b47751367438 [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
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000018typedef short PyInt16;
19
Guido van Rossum7b1e9741994-08-29 10:46:42 +000020#if defined(__CHAR_UNSIGNED__)
21#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000022/* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000026
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000027/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000028** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
29
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030/* 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 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000041#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
42#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#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. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000047
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
49 0x1FF, 0x3FF, 0x7FF, 0xFFF};
50static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
51 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
52
53static PyInt16
54search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000055{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000058 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
61 }
62 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000063}
64#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
65#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000066
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000067static 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,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000086 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000087 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,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000105};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107/*
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 */
139static unsigned char
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000141{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000145
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000148
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000149 /* 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);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000159
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000163 /*
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 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000173
174}
175
176static 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 */
236static unsigned char
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000238{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000242
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000245
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000246 /* 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 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000257 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000259 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 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
273static int indexTable[16] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
278static int stepsizeTable[89] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000279 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
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000289
Guido van Rossumb66efa01992-06-01 16:01:24 +0000290#define CHARP(cp, i) ((signed char *)(cp+i))
291#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000292#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000293
294
295
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000296static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000297
Victor Stinner8e42fb72010-07-03 13:46:01 +0000298static int
299audioop_check_size(int size)
300{
301 if (size != 1 && size != 2 && size != 4) {
302 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
303 return 0;
304 }
305 else
306 return 1;
307}
308
309static int
310audioop_check_parameters(int len, int size)
311{
312 if (!audioop_check_size(size))
313 return 0;
314 if (len % size != 0) {
315 PyErr_SetString(AudioopError, "not a whole number of frames");
316 return 0;
317 }
318 return 1;
319}
320
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000321static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000322audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000323{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000327
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000328 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
329 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000330 if (!audioop_check_parameters(len, size))
331 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000332 if ( i < 0 || i >= len/size ) {
333 PyErr_SetString(AudioopError, "Index out of range");
334 return 0;
335 }
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
339 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000340}
341
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000342static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000343audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000344{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000345 signed char *cp;
346 int len, size, val = 0;
347 int i;
348 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000349
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000350 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
351 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000352 if (!audioop_check_parameters(len, size))
353 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000354 for ( i=0; i<len; i+= size) {
355 if ( size == 1 ) val = (int)*CHARP(cp, i);
356 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
357 else if ( size == 4 ) val = (int)*LONGP(cp, i);
358 if ( val < 0 ) val = (-val);
359 if ( val > max ) max = val;
360 }
361 return PyLong_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000362}
363
364static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000365audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000366{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000367 signed char *cp;
368 int len, size, val = 0;
369 int i;
370 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000371
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000372 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
373 return NULL;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000374 if (!audioop_check_parameters(len, size))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000375 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000376 for (i = 0; i < len; i += size) {
377 if (size == 1) val = (int) *CHARP(cp, i);
378 else if (size == 2) val = (int) *SHORTP(cp, i);
379 else if (size == 4) val = (int) *LONGP(cp, i);
380 if (val > max) max = val;
381 if (val < min) min = val;
382 }
383 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000384}
385
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000386static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000387audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000388{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000389 signed char *cp;
390 int len, size, val = 0;
391 int i;
392 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000393
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000394 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
395 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000396 if (!audioop_check_parameters(len, size))
397 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000398 for ( i=0; i<len; i+= size) {
399 if ( size == 1 ) val = (int)*CHARP(cp, i);
400 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
401 else if ( size == 4 ) val = (int)*LONGP(cp, i);
402 avg += val;
403 }
404 if ( len == 0 )
405 val = 0;
406 else
407 val = (int)(avg / (double)(len/size));
408 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000409}
410
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000412audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000413{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000414 signed char *cp;
415 int len, size, val = 0;
416 int i;
417 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000418
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000419 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
420 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000421 if (!audioop_check_parameters(len, size))
422 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000423 for ( i=0; i<len; i+= size) {
424 if ( size == 1 ) val = (int)*CHARP(cp, i);
425 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
426 else if ( size == 4 ) val = (int)*LONGP(cp, i);
427 sum_squares += (double)val*(double)val;
428 }
429 if ( len == 0 )
430 val = 0;
431 else
432 val = (int)sqrt(sum_squares / (double)(len/size));
433 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000434}
435
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000436static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000437{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000438 int i;
439 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000440
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000441 for( i=0; i<len; i++) {
442 sum = sum + (double)a[i]*(double)b[i];
443 }
444 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000445}
446
447/*
448** Findfit tries to locate a sample within another sample. Its main use
449** is in echo-cancellation (to find the feedback of the output signal in
450** the input signal).
451** The method used is as follows:
452**
453** let R be the reference signal (length n) and A the input signal (length N)
454** with N > n, and let all sums be over i from 0 to n-1.
455**
456** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
457** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
458** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
459**
460** Next, we compute the relative distance between the original signal and
461** the modified signal and minimize that over j:
462** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
463** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
464**
465** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466** cp1 A
467** cp2 R
468** len1 N
469** len2 n
470** aj_m1 A[j-1]
471** aj_lm1 A[j+n-1]
472** sum_ri_2 sum(R[i]^2)
473** sum_aij_2 sum(A[i+j]^2)
474** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000475**
476** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
477** is completely recalculated each step.
478*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000479static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000480audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000481{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000482 short *cp1, *cp2;
483 int len1, len2;
484 int j, best_j;
485 double aj_m1, aj_lm1;
486 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000487
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000488 /* Passing a short** for an 's' argument is correct only
489 if the string contents is aligned for interpretation
490 as short[]. Due to the definition of PyBytesObject,
491 this is currently (Python 2.6) the case. */
492 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
493 (char**)&cp1, &len1, (char**)&cp2, &len2) )
494 return 0;
495 if ( len1 & 1 || len2 & 1 ) {
496 PyErr_SetString(AudioopError, "Strings should be even-sized");
497 return 0;
498 }
499 len1 >>= 1;
500 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000501
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000502 if ( len1 < len2 ) {
503 PyErr_SetString(AudioopError, "First sample should be longer");
504 return 0;
505 }
506 sum_ri_2 = _sum2(cp2, cp2, len2);
507 sum_aij_2 = _sum2(cp1, cp1, len2);
508 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000509
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000511
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000512 best_result = result;
513 best_j = 0;
514 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000515
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000516 for ( j=1; j<=len1-len2; j++) {
517 aj_m1 = (double)cp1[j-1];
518 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000520 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
521 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000522
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000523 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
524 / sum_aij_2;
525
526 if ( result < best_result ) {
527 best_result = result;
528 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000529 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000530
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000531 }
532
533 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
534
535 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000536}
537
538/*
539** findfactor finds a factor f so that the energy in A-fB is minimal.
540** See the comment for findfit for details.
541*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000542static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000543audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000544{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000545 short *cp1, *cp2;
546 int len1, len2;
547 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000548
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000549 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
550 (char**)&cp1, &len1, (char**)&cp2, &len2) )
551 return 0;
552 if ( len1 & 1 || len2 & 1 ) {
553 PyErr_SetString(AudioopError, "Strings should be even-sized");
554 return 0;
555 }
556 if ( len1 != len2 ) {
557 PyErr_SetString(AudioopError, "Samples should be same size");
558 return 0;
559 }
560 len2 >>= 1;
561 sum_ri_2 = _sum2(cp2, cp2, len2);
562 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000563
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000564 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000565
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000566 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000567}
568
569/*
570** findmax returns the index of the n-sized segment of the input sample
571** that contains the most energy.
572*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000573static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000574audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000575{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000576 short *cp1;
577 int len1, len2;
578 int j, best_j;
579 double aj_m1, aj_lm1;
580 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000581
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000582 if ( !PyArg_ParseTuple(args, "s#i:findmax",
583 (char**)&cp1, &len1, &len2) )
584 return 0;
585 if ( len1 & 1 ) {
586 PyErr_SetString(AudioopError, "Strings should be even-sized");
587 return 0;
588 }
589 len1 >>= 1;
590
591 if ( len2 < 0 || len1 < len2 ) {
592 PyErr_SetString(AudioopError, "Input sample should be longer");
593 return 0;
594 }
595
596 result = _sum2(cp1, cp1, len2);
597
598 best_result = result;
599 best_j = 0;
600 j = 0;
601
602 for ( j=1; j<=len1-len2; j++) {
603 aj_m1 = (double)cp1[j-1];
604 aj_lm1 = (double)cp1[j+len2-1];
605
606 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
607
608 if ( result > best_result ) {
609 best_result = result;
610 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000611 }
Jack Jansena90805f1993-02-17 14:29:28 +0000612
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000613 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000615 return PyLong_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000616}
617
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000618static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000619audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000620{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000621 signed char *cp;
622 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
623 prevextreme = 0;
624 int i;
625 double avg = 0.0;
626 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000627
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000628 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
629 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000630 if (!audioop_check_parameters(len, size))
631 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000632 /* Compute first delta value ahead. Also automatically makes us
633 ** skip the first extreme value
634 */
635 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
636 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
637 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
638 if ( size == 1 ) val = (int)*CHARP(cp, size);
639 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
640 else if ( size == 4 ) val = (int)*LONGP(cp, size);
641 prevdiff = val - prevval;
642
643 for ( i=size; i<len; i+= size) {
644 if ( size == 1 ) val = (int)*CHARP(cp, i);
645 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
646 else if ( size == 4 ) val = (int)*LONGP(cp, i);
647 diff = val - prevval;
648 if ( diff*prevdiff < 0 ) {
649 /* Derivative changed sign. Compute difference to last
650 ** extreme value and remember.
651 */
652 if ( prevextremevalid ) {
653 extremediff = prevval - prevextreme;
654 if ( extremediff < 0 )
655 extremediff = -extremediff;
656 avg += extremediff;
657 nextreme++;
658 }
659 prevextremevalid = 1;
660 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000662 prevval = val;
663 if ( diff != 0 )
664 prevdiff = diff;
665 }
666 if ( nextreme == 0 )
667 val = 0;
668 else
669 val = (int)(avg / (double)nextreme);
670 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000671}
672
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000673static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000674audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000675{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000676 signed char *cp;
677 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
678 prevextreme = 0;
679 int i;
680 int max = 0;
681 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000682
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000683 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
684 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000685 if (!audioop_check_parameters(len, size))
686 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000687 /* Compute first delta value ahead. Also automatically makes us
688 ** skip the first extreme value
689 */
690 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
691 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
692 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
693 if ( size == 1 ) val = (int)*CHARP(cp, size);
694 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
695 else if ( size == 4 ) val = (int)*LONGP(cp, size);
696 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000697
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000698 for ( i=size; i<len; i+= size) {
699 if ( size == 1 ) val = (int)*CHARP(cp, i);
700 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
701 else if ( size == 4 ) val = (int)*LONGP(cp, i);
702 diff = val - prevval;
703 if ( diff*prevdiff < 0 ) {
704 /* Derivative changed sign. Compute difference to
705 ** last extreme value and remember.
706 */
707 if ( prevextremevalid ) {
708 extremediff = prevval - prevextreme;
709 if ( extremediff < 0 )
710 extremediff = -extremediff;
711 if ( extremediff > max )
712 max = extremediff;
713 }
714 prevextremevalid = 1;
715 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000716 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000717 prevval = val;
718 if ( diff != 0 )
719 prevdiff = diff;
720 }
721 return PyLong_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000722}
723
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000724static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000725audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000726{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000727 signed char *cp;
728 int len, size, val = 0;
729 int i;
730 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000731
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000732 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
733 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000734 if (!audioop_check_parameters(len, size))
735 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000736 ncross = -1;
737 prevval = 17; /* Anything <> 0,1 */
738 for ( i=0; i<len; i+= size) {
739 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
740 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
741 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
742 val = val & 1;
743 if ( val != prevval ) ncross++;
744 prevval = val;
745 }
746 return PyLong_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000747}
748
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000749static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000750audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000751{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000752 signed char *cp, *ncp;
753 int len, size, val = 0;
754 double factor, fval, maxval;
755 PyObject *rv;
756 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000757
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000758 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
759 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000760 if (!audioop_check_parameters(len, size))
761 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000762
763 if ( size == 1 ) maxval = (double) 0x7f;
764 else if ( size == 2 ) maxval = (double) 0x7fff;
765 else if ( size == 4 ) maxval = (double) 0x7fffffff;
766 else {
767 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
768 return 0;
769 }
770
771 rv = PyBytes_FromStringAndSize(NULL, len);
772 if ( rv == 0 )
773 return 0;
774 ncp = (signed char *)PyBytes_AsString(rv);
775
776
777 for ( i=0; i < len; i += size ) {
778 if ( size == 1 ) val = (int)*CHARP(cp, i);
779 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
780 else if ( size == 4 ) val = (int)*LONGP(cp, i);
781 fval = (double)val*factor;
782 if ( fval > maxval ) fval = maxval;
783 else if ( fval < -maxval ) fval = -maxval;
784 val = (int)fval;
785 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
786 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
787 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
788 }
789 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790}
791
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000793audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000794{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000795 Py_buffer pcp;
796 signed char *cp, *ncp;
797 int len, size, val1 = 0, val2 = 0;
798 double fac1, fac2, fval, maxval;
799 PyObject *rv;
800 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000801
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000802 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
803 &pcp, &size, &fac1, &fac2 ) )
804 return 0;
805 cp = pcp.buf;
806 len = pcp.len;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000807 if (!audioop_check_parameters(len, size))
808 return NULL;
809 if (((len / size) & 1) != 0) {
810 PyErr_SetString(AudioopError, "not a whole number of frames");
811 return NULL;
812 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000813
814 if ( size == 1 ) maxval = (double) 0x7f;
815 else if ( size == 2 ) maxval = (double) 0x7fff;
816 else if ( size == 4 ) maxval = (double) 0x7fffffff;
817 else {
818 PyBuffer_Release(&pcp);
819 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
820 return 0;
821 }
822
823 rv = PyBytes_FromStringAndSize(NULL, len/2);
824 if ( rv == 0 )
825 return 0;
826 ncp = (signed char *)PyBytes_AsString(rv);
827
828
829 for ( i=0; i < len; i += size*2 ) {
830 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
831 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
832 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
833 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
834 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
835 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
836 fval = (double)val1*fac1 + (double)val2*fac2;
837 if ( fval > maxval ) fval = maxval;
838 else if ( fval < -maxval ) fval = -maxval;
839 val1 = (int)fval;
840 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
841 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
842 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
843 }
844 PyBuffer_Release(&pcp);
845 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000846}
847
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000848static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000849audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000850{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000851 signed char *cp, *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +0000852 int len, size, val1, val2, val = 0;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000853 double fac1, fac2, fval, maxval;
854 PyObject *rv;
855 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000856
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000857 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
858 &cp, &len, &size, &fac1, &fac2 ) )
859 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000860 if (!audioop_check_parameters(len, size))
861 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000862
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000863 if ( size == 1 ) maxval = (double) 0x7f;
864 else if ( size == 2 ) maxval = (double) 0x7fff;
865 else if ( size == 4 ) maxval = (double) 0x7fffffff;
866 else {
867 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
868 return 0;
869 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000870
Mark Dickinson587cb1a2010-05-10 16:39:55 +0000871 if (len > INT_MAX/2) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000872 PyErr_SetString(PyExc_MemoryError,
873 "not enough memory for output buffer");
874 return 0;
875 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876
Mark Dickinson587cb1a2010-05-10 16:39:55 +0000877 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000878 if ( rv == 0 )
879 return 0;
880 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000881
Guido van Rossumb66efa01992-06-01 16:01:24 +0000882
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000883 for ( i=0; i < len; i += size ) {
884 if ( size == 1 ) val = (int)*CHARP(cp, i);
885 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
886 else if ( size == 4 ) val = (int)*LONGP(cp, i);
887
888 fval = (double)val*fac1;
889 if ( fval > maxval ) fval = maxval;
890 else if ( fval < -maxval ) fval = -maxval;
891 val1 = (int)fval;
892
893 fval = (double)val*fac2;
894 if ( fval > maxval ) fval = maxval;
895 else if ( fval < -maxval ) fval = -maxval;
896 val2 = (int)fval;
897
898 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
899 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
900 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
901
902 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
903 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
904 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
905 }
906 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000907}
908
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000909static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000910audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000911{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000912 signed char *cp1, *cp2, *ncp;
913 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
914 PyObject *rv;
915 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000916
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000917 if ( !PyArg_ParseTuple(args, "s#s#i:add",
918 &cp1, &len1, &cp2, &len2, &size ) )
919 return 0;
Victor Stinner8e42fb72010-07-03 13:46:01 +0000920 if (!audioop_check_parameters(len1, size))
921 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000922 if ( len1 != len2 ) {
923 PyErr_SetString(AudioopError, "Lengths should be the same");
924 return 0;
925 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000926
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000927 if ( size == 1 ) maxval = 0x7f;
928 else if ( size == 2 ) maxval = 0x7fff;
929 else if ( size == 4 ) maxval = 0x7fffffff;
930 else {
931 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
932 return 0;
933 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000934
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000935 rv = PyBytes_FromStringAndSize(NULL, len1);
936 if ( rv == 0 )
937 return 0;
938 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000939
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000940 for ( i=0; i < len1; i += size ) {
941 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
942 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
943 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000944
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000945 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
946 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
947 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
948
949 newval = val1 + val2;
950 /* truncate in case of overflow */
951 if (newval > maxval) newval = maxval;
952 else if (newval < -maxval) newval = -maxval;
953 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
954 newval = val1 > 0 ? maxval : - maxval;
955
956 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
957 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
958 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
959 }
960 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000961}
962
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000963static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000964audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000965{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000966 signed char *cp, *ncp;
967 int len, size, val = 0;
968 PyObject *rv;
969 int i;
970 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000971
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000972 if ( !PyArg_ParseTuple(args, "s#ii:bias",
973 &cp, &len, &size , &bias) )
974 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000975
Victor Stinner8e42fb72010-07-03 13:46:01 +0000976 if (!audioop_check_parameters(len, size))
977 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000978
979 rv = PyBytes_FromStringAndSize(NULL, len);
980 if ( rv == 0 )
981 return 0;
982 ncp = (signed char *)PyBytes_AsString(rv);
983
984
985 for ( i=0; i < len; i += size ) {
986 if ( size == 1 ) val = (int)*CHARP(cp, i);
987 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
988 else if ( size == 4 ) val = (int)*LONGP(cp, i);
989
990 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
991 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
992 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
993 }
994 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000995}
996
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000997static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000998audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000999{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001000 signed char *cp;
1001 unsigned char *ncp;
1002 int len, size, val = 0;
1003 PyObject *rv;
1004 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001005
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001006 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1007 &cp, &len, &size) )
1008 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001009
Victor Stinner8e42fb72010-07-03 13:46:01 +00001010 if (!audioop_check_parameters(len, size))
1011 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001012
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001013 rv = PyBytes_FromStringAndSize(NULL, len);
1014 if ( rv == 0 )
1015 return 0;
1016 ncp = (unsigned char *)PyBytes_AsString(rv);
1017
1018 for ( i=0; i < len; i += size ) {
1019 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1020 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1021 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1022
1023 j = len - i - size;
1024
1025 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1026 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1027 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1028 }
1029 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001030}
1031
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001032static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001033audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001034{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001035 signed char *cp;
1036 unsigned char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001037 int len, size, size2, val = 0;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001038 PyObject *rv;
1039 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001040
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001041 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1042 &cp, &len, &size, &size2) )
1043 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001044
Victor Stinner8e42fb72010-07-03 13:46:01 +00001045 if (!audioop_check_parameters(len, size))
1046 return NULL;
1047 if (!audioop_check_size(size2))
1048 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001049
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001050 if (len/size > INT_MAX/size2) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001051 PyErr_SetString(PyExc_MemoryError,
1052 "not enough memory for output buffer");
1053 return 0;
1054 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001055 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001056 if ( rv == 0 )
1057 return 0;
1058 ncp = (unsigned char *)PyBytes_AsString(rv);
1059
1060 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1061 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1062 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1063 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1064
1065 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1066 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1067 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1068 }
1069 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001070}
1071
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001072static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001073gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001074{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001075 while (b > 0) {
1076 int tmp = a % b;
1077 a = b;
1078 b = tmp;
1079 }
1080 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001081}
1082
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001083static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001084audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001085{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001086 char *cp, *ncp;
1087 int len, size, nchannels, inrate, outrate, weightA, weightB;
1088 int chan, d, *prev_i, *cur_i, cur_o;
1089 PyObject *state, *samps, *str, *rv = NULL;
1090 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001091
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001092 weightA = 1;
1093 weightB = 0;
1094 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1095 &nchannels, &inrate, &outrate, &state,
1096 &weightA, &weightB))
1097 return NULL;
Victor Stinner8e42fb72010-07-03 13:46:01 +00001098 if (!audioop_check_size(size))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001099 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001100 if (nchannels < 1) {
1101 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1102 return NULL;
1103 }
1104 bytes_per_frame = size * nchannels;
1105 if (bytes_per_frame / nchannels != size) {
1106 /* This overflow test is rigorously correct because
1107 both multiplicands are >= 1. Use the argument names
1108 from the docs for the error msg. */
1109 PyErr_SetString(PyExc_OverflowError,
1110 "width * nchannels too big for a C int");
1111 return NULL;
1112 }
1113 if (weightA < 1 || weightB < 0) {
1114 PyErr_SetString(AudioopError,
1115 "weightA should be >= 1, weightB should be >= 0");
1116 return NULL;
1117 }
1118 if (len % bytes_per_frame != 0) {
1119 PyErr_SetString(AudioopError, "not a whole number of frames");
1120 return NULL;
1121 }
1122 if (inrate <= 0 || outrate <= 0) {
1123 PyErr_SetString(AudioopError, "sampling rate not > 0");
1124 return NULL;
1125 }
1126 /* divide inrate and outrate by their greatest common divisor */
1127 d = gcd(inrate, outrate);
1128 inrate /= d;
1129 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001130
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001131 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001132 PyErr_SetString(PyExc_MemoryError,
1133 "not enough memory for output buffer");
1134 return 0;
1135 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001136 prev_i = (int *) malloc(nchannels * sizeof(int));
1137 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001138 if (prev_i == NULL || cur_i == NULL) {
1139 (void) PyErr_NoMemory();
1140 goto exit;
1141 }
1142
1143 len /= bytes_per_frame; /* # of frames */
1144
1145 if (state == Py_None) {
1146 d = -outrate;
1147 for (chan = 0; chan < nchannels; chan++)
1148 prev_i[chan] = cur_i[chan] = 0;
1149 }
1150 else {
1151 if (!PyArg_ParseTuple(state,
1152 "iO!;audioop.ratecv: illegal state argument",
1153 &d, &PyTuple_Type, &samps))
1154 goto exit;
1155 if (PyTuple_Size(samps) != nchannels) {
1156 PyErr_SetString(AudioopError,
1157 "illegal state argument");
1158 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001159 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001160 for (chan = 0; chan < nchannels; chan++) {
1161 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1162 "ii:ratecv", &prev_i[chan],
1163 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001164 goto exit;
1165 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001166 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001167
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001168 /* str <- Space for the output buffer. */
1169 {
1170 /* There are len input frames, so we need (mathematically)
1171 ceiling(len*outrate/inrate) output frames, and each frame
1172 requires bytes_per_frame bytes. Computing this
1173 without spurious overflow is the challenge; we can
Mark Dickinsonee289e62010-05-11 13:11:12 +00001174 settle for a reasonable upper bound, though, in this
1175 case ceiling(len/inrate) * outrate. */
1176
1177 /* compute ceiling(len/inrate) without overflow */
1178 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1179 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001180 str = NULL;
1181 else
Mark Dickinsonee289e62010-05-11 13:11:12 +00001182 str = PyBytes_FromStringAndSize(NULL,
1183 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001184
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001185 if (str == NULL) {
1186 PyErr_SetString(PyExc_MemoryError,
1187 "not enough memory for output buffer");
1188 goto exit;
1189 }
1190 }
1191 ncp = PyBytes_AsString(str);
1192
1193 for (;;) {
1194 while (d < 0) {
1195 if (len == 0) {
1196 samps = PyTuple_New(nchannels);
1197 if (samps == NULL)
1198 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001199 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001200 PyTuple_SetItem(samps, chan,
1201 Py_BuildValue("(ii)",
1202 prev_i[chan],
1203 cur_i[chan]));
1204 if (PyErr_Occurred())
1205 goto exit;
1206 /* We have checked before that the length
1207 * of the string fits into int. */
1208 len = (int)(ncp - PyBytes_AsString(str));
1209 rv = PyBytes_FromStringAndSize
1210 (PyBytes_AsString(str), len);
1211 Py_DECREF(str);
1212 str = rv;
1213 if (str == NULL)
1214 goto exit;
1215 rv = Py_BuildValue("(O(iO))", str, d, samps);
1216 Py_DECREF(samps);
1217 Py_DECREF(str);
1218 goto exit; /* return rv */
1219 }
1220 for (chan = 0; chan < nchannels; chan++) {
1221 prev_i[chan] = cur_i[chan];
1222 if (size == 1)
1223 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1224 else if (size == 2)
1225 cur_i[chan] = (int)*SHORTP(cp, 0);
1226 else if (size == 4)
1227 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1228 cp += size;
1229 /* implements a simple digital filter */
1230 cur_i[chan] =
1231 (weightA * cur_i[chan] +
1232 weightB * prev_i[chan]) /
1233 (weightA + weightB);
1234 }
1235 len--;
1236 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001237 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001238 while (d >= 0) {
1239 for (chan = 0; chan < nchannels; chan++) {
1240 cur_o = (prev_i[chan] * d +
1241 cur_i[chan] * (outrate - d)) /
1242 outrate;
1243 if (size == 1)
1244 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1245 else if (size == 2)
1246 *SHORTP(ncp, 0) = (short)(cur_o);
1247 else if (size == 4)
1248 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1249 ncp += size;
1250 }
1251 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001252 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001253 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001254 exit:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001255 if (prev_i != NULL)
1256 free(prev_i);
1257 if (cur_i != NULL)
1258 free(cur_i);
1259 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001260}
Guido van Rossum1851a671997-02-14 16:14:03 +00001261
Roger E. Massec905fff1997-01-17 18:12:04 +00001262static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001263audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001264{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001265 signed char *cp;
1266 unsigned char *ncp;
1267 int len, size, val = 0;
1268 PyObject *rv;
1269 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001270
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001271 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1272 &cp, &len, &size) )
1273 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001274
Victor Stinner8e42fb72010-07-03 13:46:01 +00001275 if (!audioop_check_parameters(len, size))
1276 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001277
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001278 rv = PyBytes_FromStringAndSize(NULL, len/size);
1279 if ( rv == 0 )
1280 return 0;
1281 ncp = (unsigned char *)PyBytes_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;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001291}
1292
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001293static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001294audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001295{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001296 unsigned char *cp;
1297 unsigned char cval;
1298 signed char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001299 int len, size, val;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001300 PyObject *rv;
1301 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001303 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1304 &cp, &len, &size) )
1305 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001306
Victor Stinner8e42fb72010-07-03 13:46:01 +00001307 if (!audioop_check_parameters(len, size))
1308 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001309
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001310 if (len > INT_MAX/size) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001311 PyErr_SetString(PyExc_MemoryError,
1312 "not enough memory for output buffer");
1313 return 0;
1314 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001315 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001316 if ( rv == 0 )
1317 return 0;
1318 ncp = (signed char *)PyBytes_AsString(rv);
1319
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001320 for ( i=0; i < len*size; i += size ) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001321 cval = *cp++;
1322 val = st_ulaw2linear16(cval);
1323
1324 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1325 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1326 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1327 }
1328 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001329}
1330
1331static PyObject *
1332audioop_lin2alaw(PyObject *self, PyObject *args)
1333{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001334 signed char *cp;
1335 unsigned char *ncp;
1336 int len, size, val = 0;
1337 PyObject *rv;
1338 int i;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001339
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001340 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1341 &cp, &len, &size) )
1342 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001343
Victor Stinner8e42fb72010-07-03 13:46:01 +00001344 if (!audioop_check_parameters(len, size))
1345 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001346
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001347 rv = PyBytes_FromStringAndSize(NULL, len/size);
1348 if ( rv == 0 )
1349 return 0;
1350 ncp = (unsigned char *)PyBytes_AsString(rv);
1351
1352 for ( i=0; i < len; i += size ) {
1353 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1354 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1355 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1356
1357 *ncp++ = st_linear2alaw(val);
1358 }
1359 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001360}
1361
1362static PyObject *
1363audioop_alaw2lin(PyObject *self, PyObject *args)
1364{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001365 unsigned char *cp;
1366 unsigned char cval;
1367 signed char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001368 int len, size, val;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001369 PyObject *rv;
1370 int i;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001371
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001372 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1373 &cp, &len, &size) )
1374 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001375
Victor Stinner8e42fb72010-07-03 13:46:01 +00001376 if (!audioop_check_parameters(len, size))
1377 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001378
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001379 if (len > INT_MAX/size) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001380 PyErr_SetString(PyExc_MemoryError,
1381 "not enough memory for output buffer");
1382 return 0;
1383 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001384 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001385 if ( rv == 0 )
1386 return 0;
1387 ncp = (signed char *)PyBytes_AsString(rv);
1388
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001389 for ( i=0; i < len*size; i += size ) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001390 cval = *cp++;
1391 val = st_alaw2linear16(cval);
1392
1393 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1394 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1395 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1396 }
1397 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001398}
1399
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001400static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001401audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001402{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001403 signed char *cp;
1404 signed char *ncp;
1405 int len, size, val = 0, step, valpred, delta,
1406 index, sign, vpdiff, diff;
1407 PyObject *rv, *state, *str;
1408 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001409
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001410 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1411 &cp, &len, &size, &state) )
1412 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001413
Victor Stinner8e42fb72010-07-03 13:46:01 +00001414 if (!audioop_check_parameters(len, size))
1415 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001416
1417 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1418 if ( str == 0 )
1419 return 0;
1420 ncp = (signed char *)PyBytes_AsString(str);
1421
1422 /* Decode state, should have (value, step) */
1423 if ( state == Py_None ) {
1424 /* First time, it seems. Set defaults */
1425 valpred = 0;
1426 step = 7;
1427 index = 0;
1428 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1429 return 0;
1430
1431 step = stepsizeTable[index];
1432 bufferstep = 1;
1433
1434 for ( i=0; i < len; i += size ) {
1435 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1436 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1437 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1438
1439 /* Step 1 - compute difference with previous value */
1440 diff = val - valpred;
1441 sign = (diff < 0) ? 8 : 0;
1442 if ( sign ) diff = (-diff);
1443
1444 /* Step 2 - Divide and clamp */
1445 /* Note:
1446 ** This code *approximately* computes:
1447 ** delta = diff*4/step;
1448 ** vpdiff = (delta+0.5)*step/4;
1449 ** but in shift step bits are dropped. The net result of this
1450 ** is that even if you have fast mul/div hardware you cannot
1451 ** put it to good use since the fixup would be too expensive.
1452 */
1453 delta = 0;
1454 vpdiff = (step >> 3);
1455
1456 if ( diff >= step ) {
1457 delta = 4;
1458 diff -= step;
1459 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001460 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001461 step >>= 1;
1462 if ( diff >= step ) {
1463 delta |= 2;
1464 diff -= step;
1465 vpdiff += step;
1466 }
1467 step >>= 1;
1468 if ( diff >= step ) {
1469 delta |= 1;
1470 vpdiff += step;
1471 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001472
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001473 /* Step 3 - Update previous value */
1474 if ( sign )
1475 valpred -= vpdiff;
1476 else
1477 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001478
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001479 /* Step 4 - Clamp previous value to 16 bits */
1480 if ( valpred > 32767 )
1481 valpred = 32767;
1482 else if ( valpred < -32768 )
1483 valpred = -32768;
1484
1485 /* Step 5 - Assemble value, update index and step values */
1486 delta |= sign;
1487
1488 index += indexTable[delta];
1489 if ( index < 0 ) index = 0;
1490 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001491 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001492
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001493 /* Step 6 - Output value */
1494 if ( bufferstep ) {
1495 outputbuffer = (delta << 4) & 0xf0;
1496 } else {
1497 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001498 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001499 bufferstep = !bufferstep;
1500 }
1501 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1502 Py_DECREF(str);
1503 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001504}
1505
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001506static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001507audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001508{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001509 signed char *cp;
1510 signed char *ncp;
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001511 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001512 PyObject *rv, *str, *state;
1513 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001514
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001515 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1516 &cp, &len, &size, &state) )
1517 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001518
Victor Stinner8e42fb72010-07-03 13:46:01 +00001519 if (!audioop_check_parameters(len, size))
1520 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001521
1522 /* Decode state, should have (value, step) */
1523 if ( state == Py_None ) {
1524 /* First time, it seems. Set defaults */
1525 valpred = 0;
1526 step = 7;
1527 index = 0;
1528 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1529 return 0;
1530
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001531 if (len > (INT_MAX/2)/size) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001532 PyErr_SetString(PyExc_MemoryError,
1533 "not enough memory for output buffer");
1534 return 0;
1535 }
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001536 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001537 if ( str == 0 )
1538 return 0;
1539 ncp = (signed char *)PyBytes_AsString(str);
1540
1541 step = stepsizeTable[index];
1542 bufferstep = 0;
1543
Mark Dickinson587cb1a2010-05-10 16:39:55 +00001544 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001545 /* Step 1 - get the delta value and compute next index */
1546 if ( bufferstep ) {
1547 delta = inputbuffer & 0xf;
1548 } else {
1549 inputbuffer = *cp++;
1550 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001551 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001552
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001553 bufferstep = !bufferstep;
1554
1555 /* Step 2 - Find new index value (for later) */
1556 index += indexTable[delta];
1557 if ( index < 0 ) index = 0;
1558 if ( index > 88 ) index = 88;
1559
1560 /* Step 3 - Separate sign and magnitude */
1561 sign = delta & 8;
1562 delta = delta & 7;
1563
1564 /* Step 4 - Compute difference and new predicted value */
1565 /*
1566 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1567 ** in adpcm_coder.
1568 */
1569 vpdiff = step >> 3;
1570 if ( delta & 4 ) vpdiff += step;
1571 if ( delta & 2 ) vpdiff += step>>1;
1572 if ( delta & 1 ) vpdiff += step>>2;
1573
1574 if ( sign )
1575 valpred -= vpdiff;
1576 else
1577 valpred += vpdiff;
1578
1579 /* Step 5 - clamp output value */
1580 if ( valpred > 32767 )
1581 valpred = 32767;
1582 else if ( valpred < -32768 )
1583 valpred = -32768;
1584
1585 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001586 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001587
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001588 /* Step 6 - Output value */
1589 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1590 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1591 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1592 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001593
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001594 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1595 Py_DECREF(str);
1596 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001597}
1598
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001599static PyMethodDef audioop_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001600 { "max", audioop_max, METH_VARARGS },
1601 { "minmax", audioop_minmax, METH_VARARGS },
1602 { "avg", audioop_avg, METH_VARARGS },
1603 { "maxpp", audioop_maxpp, METH_VARARGS },
1604 { "avgpp", audioop_avgpp, METH_VARARGS },
1605 { "rms", audioop_rms, METH_VARARGS },
1606 { "findfit", audioop_findfit, METH_VARARGS },
1607 { "findmax", audioop_findmax, METH_VARARGS },
1608 { "findfactor", audioop_findfactor, METH_VARARGS },
1609 { "cross", audioop_cross, METH_VARARGS },
1610 { "mul", audioop_mul, METH_VARARGS },
1611 { "add", audioop_add, METH_VARARGS },
1612 { "bias", audioop_bias, METH_VARARGS },
1613 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1614 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1615 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1616 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1617 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1618 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1619 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1620 { "tomono", audioop_tomono, METH_VARARGS },
1621 { "tostereo", audioop_tostereo, METH_VARARGS },
1622 { "getsample", audioop_getsample, METH_VARARGS },
1623 { "reverse", audioop_reverse, METH_VARARGS },
1624 { "ratecv", audioop_ratecv, METH_VARARGS },
1625 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001626};
1627
Martin v. Löwis1a214512008-06-11 05:26:20 +00001628
1629static struct PyModuleDef audioopmodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001630 PyModuleDef_HEAD_INIT,
1631 "audioop",
1632 NULL,
1633 -1,
1634 audioop_methods,
1635 NULL,
1636 NULL,
1637 NULL,
1638 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001639};
1640
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001641PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001642PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001643{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001644 PyObject *m, *d;
1645 m = PyModule_Create(&audioopmodule);
1646 if (m == NULL)
1647 return NULL;
1648 d = PyModule_GetDict(m);
1649 if (d == NULL)
1650 return NULL;
1651 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1652 if (AudioopError != NULL)
1653 PyDict_SetItemString(d,"error",AudioopError);
1654 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001655}