blob: cb54468382d1b08eca2555ac85018ff564e6a334 [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 Pitrouc7c96a92010-05-09 15:15:40 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000141{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000145
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000238{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000242
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000257 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000258
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15: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 Stinnere9123ef2010-07-03 13:39:22 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000327
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000328 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
329 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000330 if (!audioop_check_parameters(len, size))
331 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000350 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
351 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000352 if (!audioop_check_parameters(len, size))
353 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000372 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
373 return NULL;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000374 if (!audioop_check_parameters(len, size))
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000375 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000394 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
395 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000396 if (!audioop_check_parameters(len, size))
397 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000419 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
420 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000421 if (!audioop_check_parameters(len, size))
422 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000438 int i;
439 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000440
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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;
Jack Jansena90805f1993-02-17 14:29:28 +0000501
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000512 best_result = result;
513 best_j = 0;
514 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000515
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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;
Anthony Baxter17471432006-03-20 05:58:21 +0000529 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000530
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000564 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000565
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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;
Anthony Baxter17471432006-03-20 05:58:21 +0000611 }
Jack Jansena90805f1993-02-17 14:29:28 +0000612
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000613 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000615 return PyInt_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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000628 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
629 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000630 if (!audioop_check_parameters(len, size))
631 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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;
Anthony Baxter17471432006-03-20 05:58:21 +0000661 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 PyInt_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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000683 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
684 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000685 if (!audioop_check_parameters(len, size))
686 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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;
Anthony Baxter17471432006-03-20 05:58:21 +0000716 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000717 prevval = val;
718 if ( diff != 0 )
719 prevdiff = diff;
720 }
721 return PyInt_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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000732 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
733 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000734 if (!audioop_check_parameters(len, size))
735 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 PyInt_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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000758 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
759 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000760 if (!audioop_check_parameters(len, size))
761 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 = PyString_FromStringAndSize(NULL, len);
772 if ( rv == 0 )
773 return 0;
774 ncp = (signed char *)PyString_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 Pitrouc7c96a92010-05-09 15:15:40 +0000795 signed char *cp, *ncp;
796 int len, size, val1 = 0, val2 = 0;
797 double fac1, fac2, fval, maxval;
798 PyObject *rv;
799 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000800
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000801 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
802 &cp, &len, &size, &fac1, &fac2 ) )
803 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000804 if (!audioop_check_parameters(len, size))
805 return NULL;
806 if (((len / size) & 1) != 0) {
807 PyErr_SetString(AudioopError, "not a whole number of frames");
808 return NULL;
809 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000810
811 if ( size == 1 ) maxval = (double) 0x7f;
812 else if ( size == 2 ) maxval = (double) 0x7fff;
813 else if ( size == 4 ) maxval = (double) 0x7fffffff;
814 else {
815 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
816 return 0;
817 }
818
819 rv = PyString_FromStringAndSize(NULL, len/2);
820 if ( rv == 0 )
821 return 0;
822 ncp = (signed char *)PyString_AsString(rv);
823
824
825 for ( i=0; i < len; i += size*2 ) {
826 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
827 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
828 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
829 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
830 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
831 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
832 fval = (double)val1*fac1 + (double)val2*fac2;
833 if ( fval > maxval ) fval = maxval;
834 else if ( fval < -maxval ) fval = -maxval;
835 val1 = (int)fval;
836 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
837 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
838 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
839 }
840 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000841}
842
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000843static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000844audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000845{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000846 signed char *cp, *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +0000847 int len, size, val1, val2, val = 0;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000848 double fac1, fac2, fval, maxval;
849 PyObject *rv;
850 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000851
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000852 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
853 &cp, &len, &size, &fac1, &fac2 ) )
854 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000855 if (!audioop_check_parameters(len, size))
856 return NULL;
Gregory P. Smith9d534572008-06-11 07:41:16 +0000857
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000858 if ( size == 1 ) maxval = (double) 0x7f;
859 else if ( size == 2 ) maxval = (double) 0x7fff;
860 else if ( size == 4 ) maxval = (double) 0x7fffffff;
861 else {
862 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
863 return 0;
864 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000865
Mark Dickinson47e3bf22010-05-10 16:16:52 +0000866 if (len > INT_MAX/2) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000867 PyErr_SetString(PyExc_MemoryError,
868 "not enough memory for output buffer");
869 return 0;
870 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000871
Mark Dickinson47e3bf22010-05-10 16:16:52 +0000872 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000873 if ( rv == 0 )
874 return 0;
875 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876
Guido van Rossumb66efa01992-06-01 16:01:24 +0000877
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000878 for ( i=0; i < len; i += size ) {
879 if ( size == 1 ) val = (int)*CHARP(cp, i);
880 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
881 else if ( size == 4 ) val = (int)*LONGP(cp, i);
882
883 fval = (double)val*fac1;
884 if ( fval > maxval ) fval = maxval;
885 else if ( fval < -maxval ) fval = -maxval;
886 val1 = (int)fval;
887
888 fval = (double)val*fac2;
889 if ( fval > maxval ) fval = maxval;
890 else if ( fval < -maxval ) fval = -maxval;
891 val2 = (int)fval;
892
893 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
894 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
895 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
896
897 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
898 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
899 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
900 }
901 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000902}
903
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000904static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000905audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000907 signed char *cp1, *cp2, *ncp;
908 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
909 PyObject *rv;
910 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000911
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000912 if ( !PyArg_ParseTuple(args, "s#s#i:add",
913 &cp1, &len1, &cp2, &len2, &size ) )
914 return 0;
Victor Stinnere9123ef2010-07-03 13:39:22 +0000915 if (!audioop_check_parameters(len1, size))
916 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000917 if ( len1 != len2 ) {
918 PyErr_SetString(AudioopError, "Lengths should be the same");
919 return 0;
920 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000922 if ( size == 1 ) maxval = 0x7f;
923 else if ( size == 2 ) maxval = 0x7fff;
924 else if ( size == 4 ) maxval = 0x7fffffff;
925 else {
926 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
927 return 0;
928 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000929
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000930 rv = PyString_FromStringAndSize(NULL, len1);
931 if ( rv == 0 )
932 return 0;
933 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000934
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000935 for ( i=0; i < len1; i += size ) {
936 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
937 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
938 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000939
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000940 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
941 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
942 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
943
944 newval = val1 + val2;
945 /* truncate in case of overflow */
946 if (newval > maxval) newval = maxval;
947 else if (newval < -maxval) newval = -maxval;
948 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
949 newval = val1 > 0 ? maxval : - maxval;
950
951 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
952 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
953 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
954 }
955 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000956}
957
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000958static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000959audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000960{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000961 signed char *cp, *ncp;
962 int len, size, val = 0;
963 PyObject *rv;
964 int i;
965 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000966
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000967 if ( !PyArg_ParseTuple(args, "s#ii:bias",
968 &cp, &len, &size , &bias) )
969 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000970
Victor Stinnere9123ef2010-07-03 13:39:22 +0000971 if (!audioop_check_parameters(len, size))
972 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000973
974 rv = PyString_FromStringAndSize(NULL, len);
975 if ( rv == 0 )
976 return 0;
977 ncp = (signed char *)PyString_AsString(rv);
978
979
980 for ( i=0; i < len; i += size ) {
981 if ( size == 1 ) val = (int)*CHARP(cp, i);
982 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
983 else if ( size == 4 ) val = (int)*LONGP(cp, i);
984
985 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
986 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
987 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
988 }
989 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000990}
991
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000992static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000993audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000994{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000995 signed char *cp;
996 unsigned char *ncp;
997 int len, size, val = 0;
998 PyObject *rv;
999 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001000
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001001 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1002 &cp, &len, &size) )
1003 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001004
Victor Stinnere9123ef2010-07-03 13:39:22 +00001005 if (!audioop_check_parameters(len, size))
1006 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001007
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001008 rv = PyString_FromStringAndSize(NULL, len);
1009 if ( rv == 0 )
1010 return 0;
1011 ncp = (unsigned char *)PyString_AsString(rv);
1012
1013 for ( i=0; i < len; i += size ) {
1014 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1015 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1016 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1017
1018 j = len - i - size;
1019
1020 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1021 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1022 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1023 }
1024 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001025}
1026
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001027static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001028audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001029{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001030 signed char *cp;
1031 unsigned char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001032 int len, size, size2, val = 0;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001033 PyObject *rv;
1034 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001035
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001036 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1037 &cp, &len, &size, &size2) )
1038 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001039
Victor Stinnere9123ef2010-07-03 13:39:22 +00001040 if (!audioop_check_parameters(len, size))
1041 return NULL;
1042 if (!audioop_check_size(size2))
1043 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001044
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001045 if (len/size > INT_MAX/size2) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001046 PyErr_SetString(PyExc_MemoryError,
1047 "not enough memory for output buffer");
1048 return 0;
1049 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001050 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001051 if ( rv == 0 )
1052 return 0;
1053 ncp = (unsigned char *)PyString_AsString(rv);
1054
1055 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1056 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1057 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1058 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1059
1060 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1061 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1062 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1063 }
1064 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001065}
1066
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001067static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001068gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001069{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001070 while (b > 0) {
1071 int tmp = a % b;
1072 a = b;
1073 b = tmp;
1074 }
1075 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001076}
1077
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001078static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001079audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001080{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001081 char *cp, *ncp;
1082 int len, size, nchannels, inrate, outrate, weightA, weightB;
1083 int chan, d, *prev_i, *cur_i, cur_o;
1084 PyObject *state, *samps, *str, *rv = NULL;
1085 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001086
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001087 weightA = 1;
1088 weightB = 0;
1089 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1090 &nchannels, &inrate, &outrate, &state,
1091 &weightA, &weightB))
1092 return NULL;
Victor Stinnere9123ef2010-07-03 13:39:22 +00001093 if (!audioop_check_size(size))
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001094 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001095 if (nchannels < 1) {
1096 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1097 return NULL;
1098 }
1099 bytes_per_frame = size * nchannels;
1100 if (bytes_per_frame / nchannels != size) {
1101 /* This overflow test is rigorously correct because
1102 both multiplicands are >= 1. Use the argument names
1103 from the docs for the error msg. */
1104 PyErr_SetString(PyExc_OverflowError,
1105 "width * nchannels too big for a C int");
1106 return NULL;
1107 }
1108 if (weightA < 1 || weightB < 0) {
1109 PyErr_SetString(AudioopError,
1110 "weightA should be >= 1, weightB should be >= 0");
1111 return NULL;
1112 }
1113 if (len % bytes_per_frame != 0) {
1114 PyErr_SetString(AudioopError, "not a whole number of frames");
1115 return NULL;
1116 }
1117 if (inrate <= 0 || outrate <= 0) {
1118 PyErr_SetString(AudioopError, "sampling rate not > 0");
1119 return NULL;
1120 }
1121 /* divide inrate and outrate by their greatest common divisor */
1122 d = gcd(inrate, outrate);
1123 inrate /= d;
1124 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001125
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001126 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001127 PyErr_SetString(PyExc_MemoryError,
1128 "not enough memory for output buffer");
1129 return 0;
1130 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001131 prev_i = (int *) malloc(nchannels * sizeof(int));
1132 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001133 if (prev_i == NULL || cur_i == NULL) {
1134 (void) PyErr_NoMemory();
1135 goto exit;
1136 }
1137
1138 len /= bytes_per_frame; /* # of frames */
1139
1140 if (state == Py_None) {
1141 d = -outrate;
1142 for (chan = 0; chan < nchannels; chan++)
1143 prev_i[chan] = cur_i[chan] = 0;
1144 }
1145 else {
1146 if (!PyArg_ParseTuple(state,
1147 "iO!;audioop.ratecv: illegal state argument",
1148 &d, &PyTuple_Type, &samps))
1149 goto exit;
1150 if (PyTuple_Size(samps) != nchannels) {
1151 PyErr_SetString(AudioopError,
1152 "illegal state argument");
1153 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001154 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001155 for (chan = 0; chan < nchannels; chan++) {
1156 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1157 "ii:ratecv", &prev_i[chan],
1158 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001159 goto exit;
1160 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001161 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001162
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001163 /* str <- Space for the output buffer. */
1164 {
1165 /* There are len input frames, so we need (mathematically)
1166 ceiling(len*outrate/inrate) output frames, and each frame
1167 requires bytes_per_frame bytes. Computing this
1168 without spurious overflow is the challenge; we can
Mark Dickinson7ceb4972010-05-11 13:08:26 +00001169 settle for a reasonable upper bound, though, in this
1170 case ceiling(len/inrate) * outrate. */
1171
1172 /* compute ceiling(len/inrate) without overflow */
1173 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1174 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001175 str = NULL;
1176 else
Mark Dickinson7ceb4972010-05-11 13:08:26 +00001177 str = PyString_FromStringAndSize(NULL,
1178 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001179
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001180 if (str == NULL) {
1181 PyErr_SetString(PyExc_MemoryError,
1182 "not enough memory for output buffer");
1183 goto exit;
1184 }
1185 }
1186 ncp = PyString_AsString(str);
1187
1188 for (;;) {
1189 while (d < 0) {
1190 if (len == 0) {
1191 samps = PyTuple_New(nchannels);
1192 if (samps == NULL)
1193 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001194 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001195 PyTuple_SetItem(samps, chan,
1196 Py_BuildValue("(ii)",
1197 prev_i[chan],
1198 cur_i[chan]));
1199 if (PyErr_Occurred())
1200 goto exit;
1201 /* We have checked before that the length
1202 * of the string fits into int. */
1203 len = (int)(ncp - PyString_AsString(str));
1204 if (len == 0) {
1205 /*don't want to resize to zero length*/
1206 rv = PyString_FromStringAndSize("", 0);
1207 Py_DECREF(str);
1208 str = rv;
1209 } else if (_PyString_Resize(&str, len) < 0)
1210 goto exit;
1211 rv = Py_BuildValue("(O(iO))", str, d, samps);
1212 Py_DECREF(samps);
1213 Py_DECREF(str);
1214 goto exit; /* return rv */
1215 }
1216 for (chan = 0; chan < nchannels; chan++) {
1217 prev_i[chan] = cur_i[chan];
1218 if (size == 1)
1219 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1220 else if (size == 2)
1221 cur_i[chan] = (int)*SHORTP(cp, 0);
1222 else if (size == 4)
1223 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1224 cp += size;
1225 /* implements a simple digital filter */
1226 cur_i[chan] =
1227 (weightA * cur_i[chan] +
1228 weightB * prev_i[chan]) /
1229 (weightA + weightB);
1230 }
1231 len--;
1232 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001233 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001234 while (d >= 0) {
1235 for (chan = 0; chan < nchannels; chan++) {
1236 cur_o = (prev_i[chan] * d +
1237 cur_i[chan] * (outrate - d)) /
1238 outrate;
1239 if (size == 1)
1240 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1241 else if (size == 2)
1242 *SHORTP(ncp, 0) = (short)(cur_o);
1243 else if (size == 4)
1244 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1245 ncp += size;
1246 }
1247 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001248 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001249 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001250 exit:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001251 if (prev_i != NULL)
1252 free(prev_i);
1253 if (cur_i != NULL)
1254 free(cur_i);
1255 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001256}
Guido van Rossum1851a671997-02-14 16:14:03 +00001257
Roger E. Massec905fff1997-01-17 18:12:04 +00001258static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001259audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001260{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001261 signed char *cp;
1262 unsigned char *ncp;
1263 int len, size, val = 0;
1264 PyObject *rv;
1265 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001266
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001267 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1268 &cp, &len, &size) )
1269 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001270
Victor Stinnere9123ef2010-07-03 13:39:22 +00001271 if (!audioop_check_parameters(len, size))
1272 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001273
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001274 rv = PyString_FromStringAndSize(NULL, len/size);
1275 if ( rv == 0 )
1276 return 0;
1277 ncp = (unsigned char *)PyString_AsString(rv);
1278
1279 for ( i=0; i < len; i += size ) {
1280 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1281 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1282 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1283
1284 *ncp++ = st_14linear2ulaw(val);
1285 }
1286 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001287}
1288
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001289static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001290audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001291{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001292 unsigned char *cp;
1293 unsigned char cval;
1294 signed char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001295 int len, size, val;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001296 PyObject *rv;
1297 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001298
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001299 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1300 &cp, &len, &size) )
1301 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302
Victor Stinnere9123ef2010-07-03 13:39:22 +00001303 if (!audioop_check_parameters(len, size))
1304 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001305
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001306 if (len > INT_MAX/size) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001307 PyErr_SetString(PyExc_MemoryError,
1308 "not enough memory for output buffer");
1309 return 0;
1310 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001311 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001312 if ( rv == 0 )
1313 return 0;
1314 ncp = (signed char *)PyString_AsString(rv);
1315
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001316 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001317 cval = *cp++;
1318 val = st_ulaw2linear16(cval);
1319
1320 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1321 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1322 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1323 }
1324 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001325}
1326
1327static PyObject *
1328audioop_lin2alaw(PyObject *self, PyObject *args)
1329{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001330 signed char *cp;
1331 unsigned char *ncp;
1332 int len, size, val = 0;
1333 PyObject *rv;
1334 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001335
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001336 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1337 &cp, &len, &size) )
1338 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001339
Victor Stinnere9123ef2010-07-03 13:39:22 +00001340 if (!audioop_check_parameters(len, size))
1341 return NULL;
Anthony Baxterfa869072006-03-20 05:21:58 +00001342
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001343 rv = PyString_FromStringAndSize(NULL, len/size);
1344 if ( rv == 0 )
1345 return 0;
1346 ncp = (unsigned char *)PyString_AsString(rv);
1347
1348 for ( i=0; i < len; i += size ) {
1349 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1350 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1351 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1352
1353 *ncp++ = st_linear2alaw(val);
1354 }
1355 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001356}
1357
1358static PyObject *
1359audioop_alaw2lin(PyObject *self, PyObject *args)
1360{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001361 unsigned char *cp;
1362 unsigned char cval;
1363 signed char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001364 int len, size, val;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001365 PyObject *rv;
1366 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001367
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001368 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1369 &cp, &len, &size) )
1370 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001371
Victor Stinnere9123ef2010-07-03 13:39:22 +00001372 if (!audioop_check_parameters(len, size))
1373 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001374
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001375 if (len > INT_MAX/size) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001376 PyErr_SetString(PyExc_MemoryError,
1377 "not enough memory for output buffer");
1378 return 0;
1379 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001380 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001381 if ( rv == 0 )
1382 return 0;
1383 ncp = (signed char *)PyString_AsString(rv);
1384
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001385 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001386 cval = *cp++;
1387 val = st_alaw2linear16(cval);
1388
1389 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1390 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1391 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1392 }
1393 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001394}
1395
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001396static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001397audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001398{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001399 signed char *cp;
1400 signed char *ncp;
1401 int len, size, val = 0, step, valpred, delta,
1402 index, sign, vpdiff, diff;
1403 PyObject *rv, *state, *str;
1404 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001405
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001406 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1407 &cp, &len, &size, &state) )
1408 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001409
Victor Stinnere9123ef2010-07-03 13:39:22 +00001410 if (!audioop_check_parameters(len, size))
1411 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001412
1413 str = PyString_FromStringAndSize(NULL, len/(size*2));
1414 if ( str == 0 )
1415 return 0;
1416 ncp = (signed char *)PyString_AsString(str);
1417
1418 /* Decode state, should have (value, step) */
1419 if ( state == Py_None ) {
1420 /* First time, it seems. Set defaults */
1421 valpred = 0;
1422 step = 7;
1423 index = 0;
1424 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1425 return 0;
1426
1427 step = stepsizeTable[index];
1428 bufferstep = 1;
1429
1430 for ( i=0; i < len; i += size ) {
1431 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1432 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1433 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1434
1435 /* Step 1 - compute difference with previous value */
1436 diff = val - valpred;
1437 sign = (diff < 0) ? 8 : 0;
1438 if ( sign ) diff = (-diff);
1439
1440 /* Step 2 - Divide and clamp */
1441 /* Note:
1442 ** This code *approximately* computes:
1443 ** delta = diff*4/step;
1444 ** vpdiff = (delta+0.5)*step/4;
1445 ** but in shift step bits are dropped. The net result of this
1446 ** is that even if you have fast mul/div hardware you cannot
1447 ** put it to good use since the fixup would be too expensive.
1448 */
1449 delta = 0;
1450 vpdiff = (step >> 3);
1451
1452 if ( diff >= step ) {
1453 delta = 4;
1454 diff -= step;
1455 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001456 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001457 step >>= 1;
1458 if ( diff >= step ) {
1459 delta |= 2;
1460 diff -= step;
1461 vpdiff += step;
1462 }
1463 step >>= 1;
1464 if ( diff >= step ) {
1465 delta |= 1;
1466 vpdiff += step;
1467 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001468
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001469 /* Step 3 - Update previous value */
1470 if ( sign )
1471 valpred -= vpdiff;
1472 else
1473 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001474
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001475 /* Step 4 - Clamp previous value to 16 bits */
1476 if ( valpred > 32767 )
1477 valpred = 32767;
1478 else if ( valpred < -32768 )
1479 valpred = -32768;
1480
1481 /* Step 5 - Assemble value, update index and step values */
1482 delta |= sign;
1483
1484 index += indexTable[delta];
1485 if ( index < 0 ) index = 0;
1486 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001487 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001488
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001489 /* Step 6 - Output value */
1490 if ( bufferstep ) {
1491 outputbuffer = (delta << 4) & 0xf0;
1492 } else {
1493 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001494 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001495 bufferstep = !bufferstep;
1496 }
1497 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1498 Py_DECREF(str);
1499 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001500}
1501
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001502static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001503audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001504{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001505 signed char *cp;
1506 signed char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001507 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001508 PyObject *rv, *str, *state;
1509 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001510
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001511 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1512 &cp, &len, &size, &state) )
1513 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001514
Victor Stinnere9123ef2010-07-03 13:39:22 +00001515 if (!audioop_check_parameters(len, size))
1516 return NULL;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001517
1518 /* Decode state, should have (value, step) */
1519 if ( state == Py_None ) {
1520 /* First time, it seems. Set defaults */
1521 valpred = 0;
1522 step = 7;
1523 index = 0;
1524 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1525 return 0;
1526
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001527 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001528 PyErr_SetString(PyExc_MemoryError,
1529 "not enough memory for output buffer");
1530 return 0;
1531 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001532 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001533 if ( str == 0 )
1534 return 0;
1535 ncp = (signed char *)PyString_AsString(str);
1536
1537 step = stepsizeTable[index];
1538 bufferstep = 0;
1539
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001540 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001541 /* Step 1 - get the delta value and compute next index */
1542 if ( bufferstep ) {
1543 delta = inputbuffer & 0xf;
1544 } else {
1545 inputbuffer = *cp++;
1546 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001547 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001548
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001549 bufferstep = !bufferstep;
1550
1551 /* Step 2 - Find new index value (for later) */
1552 index += indexTable[delta];
1553 if ( index < 0 ) index = 0;
1554 if ( index > 88 ) index = 88;
1555
1556 /* Step 3 - Separate sign and magnitude */
1557 sign = delta & 8;
1558 delta = delta & 7;
1559
1560 /* Step 4 - Compute difference and new predicted value */
1561 /*
1562 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1563 ** in adpcm_coder.
1564 */
1565 vpdiff = step >> 3;
1566 if ( delta & 4 ) vpdiff += step;
1567 if ( delta & 2 ) vpdiff += step>>1;
1568 if ( delta & 1 ) vpdiff += step>>2;
1569
1570 if ( sign )
1571 valpred -= vpdiff;
1572 else
1573 valpred += vpdiff;
1574
1575 /* Step 5 - clamp output value */
1576 if ( valpred > 32767 )
1577 valpred = 32767;
1578 else if ( valpred < -32768 )
1579 valpred = -32768;
1580
1581 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001582 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001583
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001584 /* Step 6 - Output value */
1585 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1586 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1587 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1588 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001589
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001590 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1591 Py_DECREF(str);
1592 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001593}
1594
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001595static PyMethodDef audioop_methods[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001596 { "max", audioop_max, METH_VARARGS },
1597 { "minmax", audioop_minmax, METH_VARARGS },
1598 { "avg", audioop_avg, METH_VARARGS },
1599 { "maxpp", audioop_maxpp, METH_VARARGS },
1600 { "avgpp", audioop_avgpp, METH_VARARGS },
1601 { "rms", audioop_rms, METH_VARARGS },
1602 { "findfit", audioop_findfit, METH_VARARGS },
1603 { "findmax", audioop_findmax, METH_VARARGS },
1604 { "findfactor", audioop_findfactor, METH_VARARGS },
1605 { "cross", audioop_cross, METH_VARARGS },
1606 { "mul", audioop_mul, METH_VARARGS },
1607 { "add", audioop_add, METH_VARARGS },
1608 { "bias", audioop_bias, METH_VARARGS },
1609 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1610 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1611 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1612 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1613 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1614 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1615 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1616 { "tomono", audioop_tomono, METH_VARARGS },
1617 { "tostereo", audioop_tostereo, METH_VARARGS },
1618 { "getsample", audioop_getsample, METH_VARARGS },
1619 { "reverse", audioop_reverse, METH_VARARGS },
1620 { "ratecv", audioop_ratecv, METH_VARARGS },
1621 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001622};
1623
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001624PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001625initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001626{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001627 PyObject *m, *d;
1628 m = Py_InitModule("audioop", audioop_methods);
1629 if (m == NULL)
1630 return;
1631 d = PyModule_GetDict(m);
1632 if (d == NULL)
1633 return;
1634 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1635 if (AudioopError != NULL)
1636 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001637}