blob: fb69ed38d6fa55c2f7ef5bdb68dc65128c70989d [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
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxterfa869072006-03-20 05:21: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
Anthony Baxterfa869072006-03-20 05:21: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
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +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};
Anthony Baxterfa869072006-03-20 05:21:58 +000052
Neal Norwitz49c65d02006-03-20 06:34:06 +000053static PyInt16
54search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000055{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Antoine Pitrouc83ea132010-05-09 14:46:46 +000058 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
61 }
62 return (size);
Anthony Baxterfa869072006-03-20 05:21: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
Neal Norwitz49c65d02006-03-20 06:34:06 +000067static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000068 -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 Pitrouc83ea132010-05-09 14:46:46 +000086 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21: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 Pitrouc83ea132010-05-09 14:46:46 +0000103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000105};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Anthony Baxterfa869072006-03-20 05:21: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 *
Anthony Baxter17471432006-03-20 05:58:21 +0000117 * 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
Anthony Baxterfa869072006-03-20 05:21:58 +0000127 *
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 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000139static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000141{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000145
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000148
Antoine Pitrouc83ea132010-05-09 14:46:46 +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);
Anthony Baxterfa869072006-03-20 05:21:58 +0000159
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000162
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000173
174}
175
Neal Norwitz49c65d02006-03-20 06:34:06 +0000176static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000177 -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 *
Anthony Baxter17471432006-03-20 05:58:21 +0000222 * 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
Anthony Baxterfa869072006-03-20 05:21:58 +0000232 *
233 * For further information see John C. Bellamy's Digital Telephony, 1982,
234 * John Wiley & Sons, pps 98-111 and 472-476.
235 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000236static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000238{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000242
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000245
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000253
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000256
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000257 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000258
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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};
Brett Cannon9824e7f2010-05-03 23:42:40 +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 Stinner15e5b1b2010-07-03 13:36:19 +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 Pitrouc83ea132010-05-09 14:46:46 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000327
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000328 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
329 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000330 if (!audioop_check_parameters(len, size))
331 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 PyInt_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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000350 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
351 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000352 if (!audioop_check_parameters(len, size))
353 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 PyInt_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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000372 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
373 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000374 if (!audioop_check_parameters(len, size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000375 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000394 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
395 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000396 if (!audioop_check_parameters(len, size))
397 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 PyInt_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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000419 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
420 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000421 if (!audioop_check_parameters(len, size))
422 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 PyInt_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 Pitrouc83ea132010-05-09 14:46:46 +0000438 int i;
439 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000440
Antoine Pitrouc83ea132010-05-09 14:46:46 +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:
Anthony Baxter17471432006-03-20 05:58:21 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 PyStringObject,
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;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000501
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000512 best_result = result;
513 best_j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000514
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000515 for (j=1; j<=len1-len2; j++) {
516 aj_m1 = (double)cp1[j-1];
517 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000518
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000519 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
520 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000521
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000522 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
523 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000525 if ( result < best_result ) {
526 best_result = result;
527 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000528 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000529
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000530 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000531
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000532 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
533
534 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000535}
536
537/*
538** findfactor finds a factor f so that the energy in A-fB is minimal.
539** See the comment for findfit for details.
540*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000541static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000542audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000543{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000544 short *cp1, *cp2;
545 int len1, len2;
546 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000547
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000548 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
549 (char**)&cp1, &len1, (char**)&cp2, &len2) )
550 return 0;
551 if ( len1 & 1 || len2 & 1 ) {
552 PyErr_SetString(AudioopError, "Strings should be even-sized");
553 return 0;
554 }
555 if ( len1 != len2 ) {
556 PyErr_SetString(AudioopError, "Samples should be same size");
557 return 0;
558 }
559 len2 >>= 1;
560 sum_ri_2 = _sum2(cp2, cp2, len2);
561 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000562
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000563 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000564
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000565 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000566}
567
568/*
569** findmax returns the index of the n-sized segment of the input sample
570** that contains the most energy.
571*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000572static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000573audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000574{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000575 short *cp1;
576 int len1, len2;
577 int j, best_j;
578 double aj_m1, aj_lm1;
579 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000580
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000581 if ( !PyArg_ParseTuple(args, "s#i:findmax",
582 (char**)&cp1, &len1, &len2) )
583 return 0;
584 if ( len1 & 1 ) {
585 PyErr_SetString(AudioopError, "Strings should be even-sized");
586 return 0;
587 }
588 len1 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000589
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000590 if ( len2 < 0 || len1 < len2 ) {
591 PyErr_SetString(AudioopError, "Input sample should be longer");
592 return 0;
593 }
594
595 result = _sum2(cp1, cp1, len2);
596
597 best_result = result;
598 best_j = 0;
599
600 for (j=1; j<=len1-len2; j++) {
601 aj_m1 = (double)cp1[j-1];
602 aj_lm1 = (double)cp1[j+len2-1];
603
604 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
605
606 if ( result > best_result ) {
607 best_result = result;
608 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000609 }
Jack Jansena90805f1993-02-17 14:29:28 +0000610
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000611 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000612
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000613 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000614}
615
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000616static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000617audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000618{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000619 signed char *cp;
620 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
621 prevextreme = 0;
622 int i;
623 double avg = 0.0;
624 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000625
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000626 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
627 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000628 if (!audioop_check_parameters(len, size))
629 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000630 /* Compute first delta value ahead. Also automatically makes us
631 ** skip the first extreme value
632 */
633 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
634 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
635 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
636 if ( size == 1 ) val = (int)*CHARP(cp, size);
637 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
638 else if ( size == 4 ) val = (int)*LONGP(cp, size);
639 prevdiff = val - prevval;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000640
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000641 for ( i=size; i<len; i+= size) {
642 if ( size == 1 ) val = (int)*CHARP(cp, i);
643 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
644 else if ( size == 4 ) val = (int)*LONGP(cp, i);
645 diff = val - prevval;
646 if ( diff*prevdiff < 0 ) {
647 /* Derivative changed sign. Compute difference to last
648 ** extreme value and remember.
649 */
650 if ( prevextremevalid ) {
651 extremediff = prevval - prevextreme;
652 if ( extremediff < 0 )
653 extremediff = -extremediff;
654 avg += extremediff;
655 nextreme++;
656 }
657 prevextremevalid = 1;
658 prevextreme = prevval;
Anthony Baxter17471432006-03-20 05:58:21 +0000659 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 prevval = val;
661 if ( diff != 0 )
662 prevdiff = diff;
663 }
664 if ( nextreme == 0 )
665 val = 0;
666 else
667 val = (int)(avg / (double)nextreme);
668 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000669}
670
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000671static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000672audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000673{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000674 signed char *cp;
675 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
676 prevextreme = 0;
677 int i;
678 int max = 0;
679 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000680
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000681 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
682 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000683 if (!audioop_check_parameters(len, size))
684 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000685 /* Compute first delta value ahead. Also automatically makes us
686 ** skip the first extreme value
687 */
688 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
689 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
690 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
691 if ( size == 1 ) val = (int)*CHARP(cp, size);
692 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
693 else if ( size == 4 ) val = (int)*LONGP(cp, size);
694 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000695
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000696 for ( i=size; i<len; i+= size) {
697 if ( size == 1 ) val = (int)*CHARP(cp, i);
698 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
699 else if ( size == 4 ) val = (int)*LONGP(cp, i);
700 diff = val - prevval;
701 if ( diff*prevdiff < 0 ) {
702 /* Derivative changed sign. Compute difference to
703 ** last extreme value and remember.
704 */
705 if ( prevextremevalid ) {
706 extremediff = prevval - prevextreme;
707 if ( extremediff < 0 )
708 extremediff = -extremediff;
709 if ( extremediff > max )
710 max = extremediff;
711 }
712 prevextremevalid = 1;
713 prevextreme = prevval;
Anthony Baxter17471432006-03-20 05:58:21 +0000714 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000715 prevval = val;
716 if ( diff != 0 )
717 prevdiff = diff;
718 }
719 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000720}
721
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000722static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000723audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000724{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000725 signed char *cp;
726 int len, size, val = 0;
727 int i;
728 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000729
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000730 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
731 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000732 if (!audioop_check_parameters(len, size))
733 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000734 ncross = -1;
735 prevval = 17; /* Anything <> 0,1 */
736 for ( i=0; i<len; i+= size) {
737 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
738 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
739 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
740 val = val & 1;
741 if ( val != prevval ) ncross++;
742 prevval = val;
743 }
744 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745}
746
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000747static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000748audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000749{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000750 signed char *cp, *ncp;
751 int len, size, val = 0;
752 double factor, fval, maxval;
753 PyObject *rv;
754 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000755
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000756 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
757 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000758 if (!audioop_check_parameters(len, size))
759 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000760
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000761 if ( size == 1 ) maxval = (double) 0x7f;
762 else if ( size == 2 ) maxval = (double) 0x7fff;
763 else if ( size == 4 ) maxval = (double) 0x7fffffff;
764 else {
765 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
766 return 0;
767 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000768
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000769 rv = PyString_FromStringAndSize(NULL, len);
770 if ( rv == 0 )
771 return 0;
772 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000773
774
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000775 for ( i=0; i < len; i += size ) {
776 if ( size == 1 ) val = (int)*CHARP(cp, i);
777 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
778 else if ( size == 4 ) val = (int)*LONGP(cp, i);
779 fval = (double)val*factor;
780 if ( fval > maxval ) fval = maxval;
781 else if ( fval < -maxval ) fval = -maxval;
782 val = (int)fval;
783 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
784 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
785 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
786 }
787 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000788}
789
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000790static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000791audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000792{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000793 signed char *cp, *ncp;
794 int len, size, val1 = 0, val2 = 0;
795 double fac1, fac2, fval, maxval;
796 PyObject *rv;
797 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000798
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000799 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
800 &cp, &len, &size, &fac1, &fac2 ) )
801 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000802 if (!audioop_check_parameters(len, size))
803 return NULL;
804 if (((len / size) & 1) != 0) {
805 PyErr_SetString(AudioopError, "not a whole number of frames");
806 return NULL;
807 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000808
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000809 if ( size == 1 ) maxval = (double) 0x7f;
810 else if ( size == 2 ) maxval = (double) 0x7fff;
811 else if ( size == 4 ) maxval = (double) 0x7fffffff;
812 else {
813 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
814 return 0;
815 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000816
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000817 rv = PyString_FromStringAndSize(NULL, len/2);
818 if ( rv == 0 )
819 return 0;
820 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000821
822
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000823 for ( i=0; i < len; i += size*2 ) {
824 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
825 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
826 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
827 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
828 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
829 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
830 fval = (double)val1*fac1 + (double)val2*fac2;
831 if ( fval > maxval ) fval = maxval;
832 else if ( fval < -maxval ) fval = -maxval;
833 val1 = (int)fval;
834 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
835 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
836 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
837 }
838 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000839}
840
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000841static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000842audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000844 signed char *cp, *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +0000845 int len, size, val1, val2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000846 double fac1, fac2, fval, maxval;
847 PyObject *rv;
848 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000849
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000850 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
851 &cp, &len, &size, &fac1, &fac2 ) )
852 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000853 if (!audioop_check_parameters(len, size))
854 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000855
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000856 if ( size == 1 ) maxval = (double) 0x7f;
857 else if ( size == 2 ) maxval = (double) 0x7fff;
858 else if ( size == 4 ) maxval = (double) 0x7fffffff;
859 else {
860 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
861 return 0;
862 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000863
Mark Dickinson932e1622010-05-10 16:07:42 +0000864 if (len > INT_MAX/2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000865 PyErr_SetString(PyExc_MemoryError,
866 "not enough memory for output buffer");
867 return 0;
868 }
Gregory P. Smith9d534572008-06-11 07:41:16 +0000869
Mark Dickinson932e1622010-05-10 16:07:42 +0000870 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000871 if ( rv == 0 )
872 return 0;
873 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000874
875
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000876 for ( i=0; i < len; i += size ) {
877 if ( size == 1 ) val = (int)*CHARP(cp, i);
878 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
879 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000881 fval = (double)val*fac1;
882 if ( fval > maxval ) fval = maxval;
883 else if ( fval < -maxval ) fval = -maxval;
884 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000885
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000886 fval = (double)val*fac2;
887 if ( fval > maxval ) fval = maxval;
888 else if ( fval < -maxval ) fval = -maxval;
889 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000890
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000891 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
892 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
893 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000894
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000895 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
896 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
897 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
898 }
899 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000900}
901
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000902static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000903audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000904{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000905 signed char *cp1, *cp2, *ncp;
906 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
907 PyObject *rv;
908 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000909
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000910 if ( !PyArg_ParseTuple(args, "s#s#i:add",
911 &cp1, &len1, &cp2, &len2, &size ) )
912 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000913 if (!audioop_check_parameters(len1, size))
914 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000915 if ( len1 != len2 ) {
916 PyErr_SetString(AudioopError, "Lengths should be the same");
917 return 0;
918 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000919
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000920 if ( size == 1 ) maxval = 0x7f;
921 else if ( size == 2 ) maxval = 0x7fff;
922 else if ( size == 4 ) maxval = 0x7fffffff;
923 else {
924 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
925 return 0;
926 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000927
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000928 rv = PyString_FromStringAndSize(NULL, len1);
929 if ( rv == 0 )
930 return 0;
931 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000932
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000933 for ( i=0; i < len1; i += size ) {
934 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
935 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
936 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000937
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000938 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
939 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
940 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000941
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000942 newval = val1 + val2;
943 /* truncate in case of overflow */
944 if (newval > maxval) newval = maxval;
945 else if (newval < -maxval) newval = -maxval;
946 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
947 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000948
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000949 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
950 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
951 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
952 }
953 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000954}
955
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000956static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000957audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000958{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000959 signed char *cp, *ncp;
960 int len, size, val = 0;
961 PyObject *rv;
962 int i;
963 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000964
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000965 if ( !PyArg_ParseTuple(args, "s#ii:bias",
966 &cp, &len, &size , &bias) )
967 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000968
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000969 if (!audioop_check_parameters(len, size))
970 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000971
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000972 rv = PyString_FromStringAndSize(NULL, len);
973 if ( rv == 0 )
974 return 0;
975 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000976
977
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000978 for ( i=0; i < len; i += size ) {
979 if ( size == 1 ) val = (int)*CHARP(cp, i);
980 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
981 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000982
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000983 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
984 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
985 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
986 }
987 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000988}
989
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000990static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000991audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000992{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 signed char *cp;
994 unsigned char *ncp;
995 int len, size, val = 0;
996 PyObject *rv;
997 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000998
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000999 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1000 &cp, &len, &size) )
1001 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001002
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001003 if (!audioop_check_parameters(len, size))
1004 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001005
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001006 rv = PyString_FromStringAndSize(NULL, len);
1007 if ( rv == 0 )
1008 return 0;
1009 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001010
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001011 for ( i=0; i < len; i += size ) {
1012 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1013 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1014 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +00001015
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001016 j = len - i - size;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001017
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001018 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1019 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1020 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1021 }
1022 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001023}
1024
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001025static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001026audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001027{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001028 signed char *cp;
1029 unsigned char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001030 int len, size, size2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001031 PyObject *rv;
1032 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001033
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001034 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1035 &cp, &len, &size, &size2) )
1036 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001037
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001038 if (!audioop_check_parameters(len, size))
1039 return NULL;
1040 if (!audioop_check_size(size2))
1041 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001042
Mark Dickinson932e1622010-05-10 16:07:42 +00001043 if (len/size > INT_MAX/size2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001044 PyErr_SetString(PyExc_MemoryError,
1045 "not enough memory for output buffer");
1046 return 0;
1047 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001048 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001049 if ( rv == 0 )
1050 return 0;
1051 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001052
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001053 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1054 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1055 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1056 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001057
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001058 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1059 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1060 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1061 }
1062 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001063}
1064
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001065static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001066gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001067{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001068 while (b > 0) {
1069 int tmp = a % b;
1070 a = b;
1071 b = tmp;
1072 }
1073 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001074}
1075
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001076static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001077audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001078{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001079 char *cp, *ncp;
1080 int len, size, nchannels, inrate, outrate, weightA, weightB;
1081 int chan, d, *prev_i, *cur_i, cur_o;
1082 PyObject *state, *samps, *str, *rv = NULL;
1083 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001084
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001085 weightA = 1;
1086 weightB = 0;
1087 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1088 &nchannels, &inrate, &outrate, &state,
1089 &weightA, &weightB))
1090 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001091 if (!audioop_check_size(size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001092 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001093 if (nchannels < 1) {
1094 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1095 return NULL;
1096 }
1097 bytes_per_frame = size * nchannels;
1098 if (bytes_per_frame / nchannels != size) {
1099 /* This overflow test is rigorously correct because
1100 both multiplicands are >= 1. Use the argument names
1101 from the docs for the error msg. */
1102 PyErr_SetString(PyExc_OverflowError,
1103 "width * nchannels too big for a C int");
1104 return NULL;
1105 }
1106 if (weightA < 1 || weightB < 0) {
1107 PyErr_SetString(AudioopError,
1108 "weightA should be >= 1, weightB should be >= 0");
1109 return NULL;
1110 }
1111 if (len % bytes_per_frame != 0) {
1112 PyErr_SetString(AudioopError, "not a whole number of frames");
1113 return NULL;
1114 }
1115 if (inrate <= 0 || outrate <= 0) {
1116 PyErr_SetString(AudioopError, "sampling rate not > 0");
1117 return NULL;
1118 }
1119 /* divide inrate and outrate by their greatest common divisor */
1120 d = gcd(inrate, outrate);
1121 inrate /= d;
1122 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001123
Mark Dickinson932e1622010-05-10 16:07:42 +00001124 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001125 PyErr_SetString(PyExc_MemoryError,
1126 "not enough memory for output buffer");
1127 return 0;
1128 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001129 prev_i = (int *) malloc(nchannels * sizeof(int));
1130 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001131 if (prev_i == NULL || cur_i == NULL) {
1132 (void) PyErr_NoMemory();
1133 goto exit;
1134 }
1135
1136 len /= bytes_per_frame; /* # of frames */
1137
1138 if (state == Py_None) {
1139 d = -outrate;
1140 for (chan = 0; chan < nchannels; chan++)
1141 prev_i[chan] = cur_i[chan] = 0;
1142 }
1143 else {
1144 if (!PyArg_ParseTuple(state,
1145 "iO!;audioop.ratecv: illegal state argument",
1146 &d, &PyTuple_Type, &samps))
1147 goto exit;
1148 if (PyTuple_Size(samps) != nchannels) {
1149 PyErr_SetString(AudioopError,
1150 "illegal state argument");
1151 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001152 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001153 for (chan = 0; chan < nchannels; chan++) {
1154 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1155 "ii:ratecv", &prev_i[chan],
1156 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001157 goto exit;
1158 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001159 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001160
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001161 /* str <- Space for the output buffer. */
1162 {
1163 /* There are len input frames, so we need (mathematically)
1164 ceiling(len*outrate/inrate) output frames, and each frame
1165 requires bytes_per_frame bytes. Computing this
1166 without spurious overflow is the challenge; we can
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001167 settle for a reasonable upper bound, though, in this
1168 case ceiling(len/inrate) * outrate. */
1169
1170 /* compute ceiling(len/inrate) without overflow */
1171 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1172 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001173 str = NULL;
1174 else
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001175 str = PyString_FromStringAndSize(NULL,
1176 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001177
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001178 if (str == NULL) {
1179 PyErr_SetString(PyExc_MemoryError,
1180 "not enough memory for output buffer");
1181 goto exit;
1182 }
1183 }
1184 ncp = PyString_AsString(str);
1185
1186 for (;;) {
1187 while (d < 0) {
1188 if (len == 0) {
1189 samps = PyTuple_New(nchannels);
1190 if (samps == NULL)
1191 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001192 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001193 PyTuple_SetItem(samps, chan,
1194 Py_BuildValue("(ii)",
1195 prev_i[chan],
1196 cur_i[chan]));
1197 if (PyErr_Occurred())
1198 goto exit;
1199 /* We have checked before that the length
1200 * of the string fits into int. */
1201 len = (int)(ncp - PyString_AsString(str));
1202 if (len == 0) {
1203 /*don't want to resize to zero length*/
1204 rv = PyString_FromStringAndSize("", 0);
1205 Py_DECREF(str);
1206 str = rv;
1207 } else if (_PyString_Resize(&str, len) < 0)
1208 goto exit;
1209 rv = Py_BuildValue("(O(iO))", str, d, samps);
1210 Py_DECREF(samps);
1211 Py_DECREF(str);
1212 goto exit; /* return rv */
1213 }
1214 for (chan = 0; chan < nchannels; chan++) {
1215 prev_i[chan] = cur_i[chan];
1216 if (size == 1)
1217 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1218 else if (size == 2)
1219 cur_i[chan] = (int)*SHORTP(cp, 0);
1220 else if (size == 4)
1221 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1222 cp += size;
1223 /* implements a simple digital filter */
1224 cur_i[chan] =
1225 (weightA * cur_i[chan] +
1226 weightB * prev_i[chan]) /
1227 (weightA + weightB);
1228 }
1229 len--;
1230 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001231 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001232 while (d >= 0) {
1233 for (chan = 0; chan < nchannels; chan++) {
1234 cur_o = (prev_i[chan] * d +
1235 cur_i[chan] * (outrate - d)) /
1236 outrate;
1237 if (size == 1)
1238 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1239 else if (size == 2)
1240 *SHORTP(ncp, 0) = (short)(cur_o);
1241 else if (size == 4)
1242 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1243 ncp += size;
1244 }
1245 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001246 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001247 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001248 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001249 if (prev_i != NULL)
1250 free(prev_i);
1251 if (cur_i != NULL)
1252 free(cur_i);
1253 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001254}
Guido van Rossum1851a671997-02-14 16:14:03 +00001255
Roger E. Massec905fff1997-01-17 18:12:04 +00001256static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001257audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001258{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001259 signed char *cp;
1260 unsigned char *ncp;
1261 int len, size, val = 0;
1262 PyObject *rv;
1263 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001264
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001265 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1266 &cp, &len, &size) )
1267 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001268
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001269 if (!audioop_check_parameters(len, size))
1270 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001271
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001272 rv = PyString_FromStringAndSize(NULL, len/size);
1273 if ( rv == 0 )
1274 return 0;
1275 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001276
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001277 for ( i=0; i < len; i += size ) {
1278 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1279 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1280 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001282 *ncp++ = st_14linear2ulaw(val);
1283 }
1284 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001285}
1286
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001287static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001288audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001289{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001290 unsigned char *cp;
1291 unsigned char cval;
1292 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001293 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001294 PyObject *rv;
1295 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001296
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001297 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1298 &cp, &len, &size) )
1299 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001300
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001301 if (!audioop_check_parameters(len, size))
1302 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001303
Mark Dickinson932e1622010-05-10 16:07:42 +00001304 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001305 PyErr_SetString(PyExc_MemoryError,
1306 "not enough memory for output buffer");
1307 return 0;
1308 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001309 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001310 if ( rv == 0 )
1311 return 0;
1312 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001313
Mark Dickinson932e1622010-05-10 16:07:42 +00001314 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001315 cval = *cp++;
1316 val = st_ulaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001317
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001318 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1319 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1320 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1321 }
1322 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001323}
1324
1325static PyObject *
1326audioop_lin2alaw(PyObject *self, PyObject *args)
1327{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001328 signed char *cp;
1329 unsigned char *ncp;
1330 int len, size, val = 0;
1331 PyObject *rv;
1332 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001333
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001334 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1335 &cp, &len, &size) )
1336 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001337
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001338 if (!audioop_check_parameters(len, size))
1339 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001340
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001341 rv = PyString_FromStringAndSize(NULL, len/size);
1342 if ( rv == 0 )
1343 return 0;
1344 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001345
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001346 for ( i=0; i < len; i += size ) {
1347 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1348 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1349 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001350
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001351 *ncp++ = st_linear2alaw(val);
1352 }
1353 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001354}
1355
1356static PyObject *
1357audioop_alaw2lin(PyObject *self, PyObject *args)
1358{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001359 unsigned char *cp;
1360 unsigned char cval;
1361 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001362 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 PyObject *rv;
1364 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001365
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001366 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1367 &cp, &len, &size) )
1368 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001369
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001370 if (!audioop_check_parameters(len, size))
1371 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001372
Mark Dickinson932e1622010-05-10 16:07:42 +00001373 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001374 PyErr_SetString(PyExc_MemoryError,
1375 "not enough memory for output buffer");
1376 return 0;
1377 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001378 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001379 if ( rv == 0 )
1380 return 0;
1381 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001382
Mark Dickinson932e1622010-05-10 16:07:42 +00001383 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001384 cval = *cp++;
1385 val = st_alaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001386
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001387 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1388 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1389 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1390 }
1391 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001392}
1393
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001394static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001395audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001396{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001397 signed char *cp;
1398 signed char *ncp;
1399 int len, size, val = 0, step, valpred, delta,
1400 index, sign, vpdiff, diff;
1401 PyObject *rv, *state, *str;
1402 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001403
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001404 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1405 &cp, &len, &size, &state) )
1406 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001407
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001408 if (!audioop_check_parameters(len, size))
1409 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001410
1411 str = PyString_FromStringAndSize(NULL, len/(size*2));
1412 if ( str == 0 )
1413 return 0;
1414 ncp = (signed char *)PyString_AsString(str);
1415
1416 /* Decode state, should have (value, step) */
1417 if ( state == Py_None ) {
1418 /* First time, it seems. Set defaults */
1419 valpred = 0;
1420 index = 0;
1421 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1422 return 0;
1423
1424 step = stepsizeTable[index];
1425 bufferstep = 1;
1426
1427 for ( i=0; i < len; i += size ) {
1428 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1429 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1430 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1431
1432 /* Step 1 - compute difference with previous value */
1433 diff = val - valpred;
1434 sign = (diff < 0) ? 8 : 0;
1435 if ( sign ) diff = (-diff);
1436
1437 /* Step 2 - Divide and clamp */
1438 /* Note:
1439 ** This code *approximately* computes:
1440 ** delta = diff*4/step;
1441 ** vpdiff = (delta+0.5)*step/4;
1442 ** but in shift step bits are dropped. The net result of this
1443 ** is that even if you have fast mul/div hardware you cannot
1444 ** put it to good use since the fixup would be too expensive.
1445 */
1446 delta = 0;
1447 vpdiff = (step >> 3);
1448
1449 if ( diff >= step ) {
1450 delta = 4;
1451 diff -= step;
1452 vpdiff += step;
1453 }
1454 step >>= 1;
1455 if ( diff >= step ) {
1456 delta |= 2;
1457 diff -= step;
1458 vpdiff += step;
1459 }
1460 step >>= 1;
1461 if ( diff >= step ) {
1462 delta |= 1;
1463 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001464 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001465
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001466 /* Step 3 - Update previous value */
1467 if ( sign )
1468 valpred -= vpdiff;
1469 else
1470 valpred += vpdiff;
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001471
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001472 /* Step 4 - Clamp previous value to 16 bits */
1473 if ( valpred > 32767 )
1474 valpred = 32767;
1475 else if ( valpred < -32768 )
1476 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001477
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001478 /* Step 5 - Assemble value, update index and step values */
1479 delta |= sign;
1480
1481 index += indexTable[delta];
1482 if ( index < 0 ) index = 0;
1483 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001484 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001485
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001486 /* Step 6 - Output value */
1487 if ( bufferstep ) {
1488 outputbuffer = (delta << 4) & 0xf0;
1489 } else {
1490 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001491 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001492 bufferstep = !bufferstep;
1493 }
1494 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1495 Py_DECREF(str);
1496 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001497}
1498
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001499static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001500audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001501{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001502 signed char *cp;
1503 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001504 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001505 PyObject *rv, *str, *state;
1506 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001507
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001508 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1509 &cp, &len, &size, &state) )
1510 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001511
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001512 if (!audioop_check_parameters(len, size))
1513 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001514
1515 /* Decode state, should have (value, step) */
1516 if ( state == Py_None ) {
1517 /* First time, it seems. Set defaults */
1518 valpred = 0;
1519 index = 0;
1520 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1521 return 0;
1522
Mark Dickinson932e1622010-05-10 16:07:42 +00001523 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001524 PyErr_SetString(PyExc_MemoryError,
1525 "not enough memory for output buffer");
1526 return 0;
1527 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001528 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001529 if ( str == 0 )
1530 return 0;
1531 ncp = (signed char *)PyString_AsString(str);
1532
1533 step = stepsizeTable[index];
1534 bufferstep = 0;
1535
Mark Dickinson932e1622010-05-10 16:07:42 +00001536 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001537 /* Step 1 - get the delta value and compute next index */
1538 if ( bufferstep ) {
1539 delta = inputbuffer & 0xf;
1540 } else {
1541 inputbuffer = *cp++;
1542 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001543 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001544
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001545 bufferstep = !bufferstep;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001546
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001547 /* Step 2 - Find new index value (for later) */
1548 index += indexTable[delta];
1549 if ( index < 0 ) index = 0;
1550 if ( index > 88 ) index = 88;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001551
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001552 /* Step 3 - Separate sign and magnitude */
1553 sign = delta & 8;
1554 delta = delta & 7;
1555
1556 /* Step 4 - Compute difference and new predicted value */
1557 /*
1558 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1559 ** in adpcm_coder.
1560 */
1561 vpdiff = step >> 3;
1562 if ( delta & 4 ) vpdiff += step;
1563 if ( delta & 2 ) vpdiff += step>>1;
1564 if ( delta & 1 ) vpdiff += step>>2;
1565
1566 if ( sign )
1567 valpred -= vpdiff;
1568 else
1569 valpred += vpdiff;
1570
1571 /* Step 5 - clamp output value */
1572 if ( valpred > 32767 )
1573 valpred = 32767;
1574 else if ( valpred < -32768 )
1575 valpred = -32768;
1576
1577 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001578 step = stepsizeTable[index];
Brett Cannon9824e7f2010-05-03 23:42:40 +00001579
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001580 /* Step 6 - Output value */
1581 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1582 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1583 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1584 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001585
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001586 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1587 Py_DECREF(str);
1588 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001589}
1590
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001591static PyMethodDef audioop_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001592 { "max", audioop_max, METH_VARARGS },
1593 { "minmax", audioop_minmax, METH_VARARGS },
1594 { "avg", audioop_avg, METH_VARARGS },
1595 { "maxpp", audioop_maxpp, METH_VARARGS },
1596 { "avgpp", audioop_avgpp, METH_VARARGS },
1597 { "rms", audioop_rms, METH_VARARGS },
1598 { "findfit", audioop_findfit, METH_VARARGS },
1599 { "findmax", audioop_findmax, METH_VARARGS },
1600 { "findfactor", audioop_findfactor, METH_VARARGS },
1601 { "cross", audioop_cross, METH_VARARGS },
1602 { "mul", audioop_mul, METH_VARARGS },
1603 { "add", audioop_add, METH_VARARGS },
1604 { "bias", audioop_bias, METH_VARARGS },
1605 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1606 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1607 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1608 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1609 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1610 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1611 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1612 { "tomono", audioop_tomono, METH_VARARGS },
1613 { "tostereo", audioop_tostereo, METH_VARARGS },
1614 { "getsample", audioop_getsample, METH_VARARGS },
1615 { "reverse", audioop_reverse, METH_VARARGS },
1616 { "ratecv", audioop_ratecv, METH_VARARGS },
1617 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001618};
1619
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001620PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001621initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001622{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001623 PyObject *m, *d;
1624 m = Py_InitModule("audioop", audioop_methods);
1625 if (m == NULL)
1626 return;
1627 d = PyModule_GetDict(m);
1628 if (d == NULL)
1629 return;
1630 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1631 if (AudioopError != NULL)
1632 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001633}