blob: 35c2b437e085ddb8a3f534dc4f191e47cdcc1341 [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{
Anthony Baxter17471432006-03-20 05:58:21 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Anthony Baxter17471432006-03-20 05:58:21 +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,
86 -8, 0, 32124, 31100, 30076, 29052, 28028,
87 27004, 25980, 24956, 23932, 22908, 21884, 20860,
88 19836, 18812, 17788, 16764, 15996, 15484, 14972,
89 14460, 13948, 13436, 12924, 12412, 11900, 11388,
90 10876, 10364, 9852, 9340, 8828, 8316, 7932,
91 7676, 7420, 7164, 6908, 6652, 6396, 6140,
92 5884, 5628, 5372, 5116, 4860, 4604, 4348,
93 4092, 3900, 3772, 3644, 3516, 3388, 3260,
94 3132, 3004, 2876, 2748, 2620, 2492, 2364,
95 2236, 2108, 1980, 1884, 1820, 1756, 1692,
96 1628, 1564, 1500, 1436, 1372, 1308, 1244,
97 1180, 1116, 1052, 988, 924, 876, 844,
98 812, 780, 748, 716, 684, 652, 620,
99 588, 556, 524, 492, 460, 428, 396,
100 372, 356, 340, 324, 308, 292, 276,
101 260, 244, 228, 212, 196, 180, 164,
102 148, 132, 120, 112, 104, 96, 88,
103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
105};
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
140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000141{
Anthony Baxter17471432006-03-20 05:58:21 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000145
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +0000149 /* u-law inverts all bits */
150 /* Get the sign and the magnitude of the value. */
151 if (pcm_val < 0) {
152 pcm_val = -pcm_val;
153 mask = 0x7F;
154 } else {
155 mask = 0xFF;
156 }
157 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
158 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000159
Anthony Baxter17471432006-03-20 05:58:21 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000162
Anthony Baxter17471432006-03-20 05:58:21 +0000163 /*
164 * Combine the sign, segment, quantization bits;
165 * and complement the code word.
166 */
167 if (seg >= 8) /* out of range, return maximum value. */
168 return (unsigned char) (0x7F ^ mask);
169 else {
170 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
171 return (uval ^ mask);
172 }
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
237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000238{
Anthony Baxter17471432006-03-20 05:58:21 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000242
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +0000246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
252 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000253
Anthony Baxter17471432006-03-20 05:58:21 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000256
Anthony Baxter17471432006-03-20 05:58:21 +0000257 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000258
Anthony Baxter17471432006-03-20 05:58:21 +0000259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
273static int indexTable[16] = {
Anthony Baxter17471432006-03-20 05:58:21 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
278static int stepsizeTable[89] = {
Anthony Baxter17471432006-03-20 05:58:21 +0000279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
289
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
Matthias Kloseb7180a82010-10-17 10:48:14 +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{
Anthony Baxter17471432006-03-20 05:58:21 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000327
Georg Brandl660222f2006-05-28 22:34:51 +0000328 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
Anthony Baxter17471432006-03-20 05:58:21 +0000329 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000330 if (!audioop_check_parameters(len, size))
331 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000332 if ( i < 0 || i >= len/size ) {
333 PyErr_SetString(AudioopError, "Index out of range");
334 return 0;
335 }
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
339 return 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{
Anthony Baxter17471432006-03-20 05:58:21 +0000345 signed char *cp;
346 int len, size, val = 0;
347 int i;
348 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000349
Georg Brandl660222f2006-05-28 22:34:51 +0000350 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000351 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000352 if (!audioop_check_parameters(len, size))
353 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000354 for ( i=0; i<len; i+= size) {
355 if ( size == 1 ) val = (int)*CHARP(cp, i);
356 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
357 else if ( size == 4 ) val = (int)*LONGP(cp, i);
358 if ( val < 0 ) val = (-val);
359 if ( val > max ) max = val;
360 }
361 return 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{
Anthony Baxter17471432006-03-20 05:58:21 +0000367 signed char *cp;
368 int len, size, val = 0;
369 int i;
370 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000371
Georg Brandl660222f2006-05-28 22:34:51 +0000372 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
Anthony Baxter17471432006-03-20 05:58:21 +0000373 return NULL;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000374 if (!audioop_check_parameters(len, size))
Anthony Baxter17471432006-03-20 05:58:21 +0000375 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000376 for (i = 0; i < len; i += size) {
377 if (size == 1) val = (int) *CHARP(cp, i);
378 else if (size == 2) val = (int) *SHORTP(cp, i);
379 else if (size == 4) val = (int) *LONGP(cp, i);
380 if (val > max) max = val;
381 if (val < min) min = val;
382 }
383 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000384}
385
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000386static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000387audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000388{
Anthony Baxter17471432006-03-20 05:58:21 +0000389 signed char *cp;
390 int len, size, val = 0;
391 int i;
392 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000393
Georg Brandl660222f2006-05-28 22:34:51 +0000394 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000395 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000396 if (!audioop_check_parameters(len, size))
397 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000398 for ( i=0; i<len; i+= size) {
399 if ( size == 1 ) val = (int)*CHARP(cp, i);
400 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
401 else if ( size == 4 ) val = (int)*LONGP(cp, i);
402 avg += val;
403 }
404 if ( len == 0 )
405 val = 0;
406 else
407 val = (int)(avg / (double)(len/size));
408 return 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{
Anthony Baxter17471432006-03-20 05:58:21 +0000414 signed char *cp;
415 int len, size, val = 0;
416 int i;
417 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000418
Georg Brandl660222f2006-05-28 22:34:51 +0000419 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000420 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000421 if (!audioop_check_parameters(len, size))
422 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000423 for ( i=0; i<len; i+= size) {
424 if ( size == 1 ) val = (int)*CHARP(cp, i);
425 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
426 else if ( size == 4 ) val = (int)*LONGP(cp, i);
427 sum_squares += (double)val*(double)val;
428 }
429 if ( len == 0 )
430 val = 0;
431 else
432 val = (int)sqrt(sum_squares / (double)(len/size));
433 return 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{
Anthony Baxter17471432006-03-20 05:58:21 +0000438 int i;
439 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000440
Anthony Baxter17471432006-03-20 05:58:21 +0000441 for( i=0; i<len; i++) {
442 sum = sum + (double)a[i]*(double)b[i];
443 }
444 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000445}
446
447/*
448** Findfit tries to locate a sample within another sample. Its main use
449** is in echo-cancellation (to find the feedback of the output signal in
450** the input signal).
451** The method used is as follows:
452**
453** let R be the reference signal (length n) and A the input signal (length N)
454** with N > n, and let all sums be over i from 0 to n-1.
455**
456** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
457** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
458** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
459**
460** Next, we compute the relative distance between the original signal and
461** the modified signal and minimize that over j:
462** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
463** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
464**
465** In the code variables correspond as follows:
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{
Anthony Baxter17471432006-03-20 05:58:21 +0000482 short *cp1, *cp2;
483 int len1, len2;
484 int j, best_j;
485 double aj_m1, aj_lm1;
486 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000487
Georg Brandl660222f2006-05-28 22:34:51 +0000488 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
489 &cp1, &len1, &cp2, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000490 return 0;
491 if ( len1 & 1 || len2 & 1 ) {
492 PyErr_SetString(AudioopError, "Strings should be even-sized");
493 return 0;
494 }
495 len1 >>= 1;
496 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000497
Anthony Baxter17471432006-03-20 05:58:21 +0000498 if ( len1 < len2 ) {
499 PyErr_SetString(AudioopError, "First sample should be longer");
500 return 0;
501 }
502 sum_ri_2 = _sum2(cp2, cp2, len2);
503 sum_aij_2 = _sum2(cp1, cp1, len2);
504 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000505
Anthony Baxter17471432006-03-20 05:58:21 +0000506 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000507
Anthony Baxter17471432006-03-20 05:58:21 +0000508 best_result = result;
509 best_j = 0;
510 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000511
Anthony Baxter17471432006-03-20 05:58:21 +0000512 for ( j=1; j<=len1-len2; j++) {
513 aj_m1 = (double)cp1[j-1];
514 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000515
Anthony Baxter17471432006-03-20 05:58:21 +0000516 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
517 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000518
Anthony Baxter17471432006-03-20 05:58:21 +0000519 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
520 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000521
Anthony Baxter17471432006-03-20 05:58:21 +0000522 if ( result < best_result ) {
523 best_result = result;
524 best_j = j;
525 }
526
527 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000528
Anthony Baxter17471432006-03-20 05:58:21 +0000529 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000530
Anthony Baxter17471432006-03-20 05:58:21 +0000531 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000532}
533
534/*
535** findfactor finds a factor f so that the energy in A-fB is minimal.
536** See the comment for findfit for details.
537*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000538static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000539audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000540{
Anthony Baxter17471432006-03-20 05:58:21 +0000541 short *cp1, *cp2;
542 int len1, len2;
543 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000544
Georg Brandl660222f2006-05-28 22:34:51 +0000545 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
546 &cp1, &len1, &cp2, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000547 return 0;
548 if ( len1 & 1 || len2 & 1 ) {
549 PyErr_SetString(AudioopError, "Strings should be even-sized");
550 return 0;
551 }
552 if ( len1 != len2 ) {
553 PyErr_SetString(AudioopError, "Samples should be same size");
554 return 0;
555 }
556 len2 >>= 1;
557 sum_ri_2 = _sum2(cp2, cp2, len2);
558 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000559
Anthony Baxter17471432006-03-20 05:58:21 +0000560 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000561
Anthony Baxter17471432006-03-20 05:58:21 +0000562 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000563}
564
565/*
566** findmax returns the index of the n-sized segment of the input sample
567** that contains the most energy.
568*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000569static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000570audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000571{
Anthony Baxter17471432006-03-20 05:58:21 +0000572 short *cp1;
573 int len1, len2;
574 int j, best_j;
575 double aj_m1, aj_lm1;
576 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000577
Georg Brandl660222f2006-05-28 22:34:51 +0000578 if ( !PyArg_ParseTuple(args, "s#i:findmax", &cp1, &len1, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000579 return 0;
580 if ( len1 & 1 ) {
581 PyErr_SetString(AudioopError, "Strings should be even-sized");
582 return 0;
583 }
584 len1 >>= 1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000585
Anthony Baxter17471432006-03-20 05:58:21 +0000586 if ( len1 < len2 ) {
587 PyErr_SetString(AudioopError, "Input sample should be longer");
588 return 0;
589 }
Jack Jansena90805f1993-02-17 14:29:28 +0000590
Anthony Baxter17471432006-03-20 05:58:21 +0000591 result = _sum2(cp1, cp1, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000592
Anthony Baxter17471432006-03-20 05:58:21 +0000593 best_result = result;
594 best_j = 0;
595 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000596
Anthony Baxter17471432006-03-20 05:58:21 +0000597 for ( j=1; j<=len1-len2; j++) {
598 aj_m1 = (double)cp1[j-1];
599 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600
Anthony Baxter17471432006-03-20 05:58:21 +0000601 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000602
Anthony Baxter17471432006-03-20 05:58:21 +0000603 if ( result > best_result ) {
604 best_result = result;
605 best_j = j;
606 }
607
608 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000609
Anthony Baxter17471432006-03-20 05:58:21 +0000610 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000611}
612
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000613static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000614audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000615{
Anthony Baxter17471432006-03-20 05:58:21 +0000616 signed char *cp;
617 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
618 prevextreme = 0;
619 int i;
620 double avg = 0.0;
621 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000622
Georg Brandl660222f2006-05-28 22:34:51 +0000623 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000624 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000625 if (!audioop_check_parameters(len, size))
626 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000627 /* Compute first delta value ahead. Also automatically makes us
628 ** skip the first extreme value
629 */
630 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
631 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
632 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
633 if ( size == 1 ) val = (int)*CHARP(cp, size);
634 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
635 else if ( size == 4 ) val = (int)*LONGP(cp, size);
636 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637
Anthony Baxter17471432006-03-20 05:58:21 +0000638 for ( i=size; i<len; i+= size) {
639 if ( size == 1 ) val = (int)*CHARP(cp, i);
640 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
641 else if ( size == 4 ) val = (int)*LONGP(cp, i);
642 diff = val - prevval;
643 if ( diff*prevdiff < 0 ) {
644 /* Derivative changed sign. Compute difference to last
645 ** extreme value and remember.
646 */
647 if ( prevextremevalid ) {
648 extremediff = prevval - prevextreme;
649 if ( extremediff < 0 )
650 extremediff = -extremediff;
651 avg += extremediff;
652 nextreme++;
653 }
654 prevextremevalid = 1;
655 prevextreme = prevval;
656 }
657 prevval = val;
658 if ( diff != 0 )
659 prevdiff = diff;
660 }
661 if ( nextreme == 0 )
662 val = 0;
663 else
664 val = (int)(avg / (double)nextreme);
665 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000666}
667
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000668static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000669audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000670{
Anthony Baxter17471432006-03-20 05:58:21 +0000671 signed char *cp;
672 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
673 prevextreme = 0;
674 int i;
675 int max = 0;
676 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000677
Georg Brandl660222f2006-05-28 22:34:51 +0000678 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000679 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000680 if (!audioop_check_parameters(len, size))
681 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000682 /* Compute first delta value ahead. Also automatically makes us
683 ** skip the first extreme value
684 */
685 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
686 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
687 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
688 if ( size == 1 ) val = (int)*CHARP(cp, size);
689 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
690 else if ( size == 4 ) val = (int)*LONGP(cp, size);
691 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000692
Anthony Baxter17471432006-03-20 05:58:21 +0000693 for ( i=size; i<len; i+= size) {
694 if ( size == 1 ) val = (int)*CHARP(cp, i);
695 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
696 else if ( size == 4 ) val = (int)*LONGP(cp, i);
697 diff = val - prevval;
698 if ( diff*prevdiff < 0 ) {
699 /* Derivative changed sign. Compute difference to
700 ** last extreme value and remember.
701 */
702 if ( prevextremevalid ) {
703 extremediff = prevval - prevextreme;
704 if ( extremediff < 0 )
705 extremediff = -extremediff;
706 if ( extremediff > max )
707 max = extremediff;
708 }
709 prevextremevalid = 1;
710 prevextreme = prevval;
711 }
712 prevval = val;
713 if ( diff != 0 )
714 prevdiff = diff;
715 }
716 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000717}
718
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000719static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000720audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000721{
Anthony Baxter17471432006-03-20 05:58:21 +0000722 signed char *cp;
723 int len, size, val = 0;
724 int i;
725 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000726
Georg Brandl660222f2006-05-28 22:34:51 +0000727 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000728 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000729 if (!audioop_check_parameters(len, size))
730 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000731 ncross = -1;
732 prevval = 17; /* Anything <> 0,1 */
733 for ( i=0; i<len; i+= size) {
734 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
735 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
736 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
737 val = val & 1;
738 if ( val != prevval ) ncross++;
739 prevval = val;
740 }
741 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000742}
743
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000744static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000745audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000746{
Anthony Baxter17471432006-03-20 05:58:21 +0000747 signed char *cp, *ncp;
748 int len, size, val = 0;
749 double factor, fval, maxval;
750 PyObject *rv;
751 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000752
Georg Brandl660222f2006-05-28 22:34:51 +0000753 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000754 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000755 if (!audioop_check_parameters(len, size))
756 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000757
Anthony Baxter17471432006-03-20 05:58:21 +0000758 if ( size == 1 ) maxval = (double) 0x7f;
759 else if ( size == 2 ) maxval = (double) 0x7fff;
760 else if ( size == 4 ) maxval = (double) 0x7fffffff;
761 else {
762 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
763 return 0;
764 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000765
Anthony Baxter17471432006-03-20 05:58:21 +0000766 rv = PyString_FromStringAndSize(NULL, len);
767 if ( rv == 0 )
768 return 0;
769 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000770
771
Anthony Baxter17471432006-03-20 05:58:21 +0000772 for ( i=0; i < len; i += size ) {
773 if ( size == 1 ) val = (int)*CHARP(cp, i);
774 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
775 else if ( size == 4 ) val = (int)*LONGP(cp, i);
776 fval = (double)val*factor;
777 if ( fval > maxval ) fval = maxval;
778 else if ( fval < -maxval ) fval = -maxval;
779 val = (int)fval;
780 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
781 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
782 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
783 }
784 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000785}
786
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000787static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000788audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000789{
Anthony Baxter17471432006-03-20 05:58:21 +0000790 signed char *cp, *ncp;
791 int len, size, val1 = 0, val2 = 0;
792 double fac1, fac2, fval, maxval;
793 PyObject *rv;
794 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Georg Brandl660222f2006-05-28 22:34:51 +0000796 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
797 &cp, &len, &size, &fac1, &fac2 ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000798 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000799 if (!audioop_check_parameters(len, size))
800 return NULL;
801 if (((len / size) & 1) != 0) {
802 PyErr_SetString(AudioopError, "not a whole number of frames");
803 return NULL;
804 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000805
Anthony Baxter17471432006-03-20 05:58:21 +0000806 if ( size == 1 ) maxval = (double) 0x7f;
807 else if ( size == 2 ) maxval = (double) 0x7fff;
808 else if ( size == 4 ) maxval = (double) 0x7fffffff;
809 else {
810 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
811 return 0;
812 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000813
Anthony Baxter17471432006-03-20 05:58:21 +0000814 rv = PyString_FromStringAndSize(NULL, len/2);
815 if ( rv == 0 )
816 return 0;
817 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000818
819
Anthony Baxter17471432006-03-20 05:58:21 +0000820 for ( i=0; i < len; i += size*2 ) {
821 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
822 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
823 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
824 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
825 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
826 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
827 fval = (double)val1*fac1 + (double)val2*fac2;
828 if ( fval > maxval ) fval = maxval;
829 else if ( fval < -maxval ) fval = -maxval;
830 val1 = (int)fval;
831 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
832 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
833 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
834 }
835 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000836}
837
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000838static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000839audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000840{
Anthony Baxter17471432006-03-20 05:58:21 +0000841 signed char *cp, *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +0000842 int len, size, val1, val2, val = 0;
Anthony Baxter17471432006-03-20 05:58:21 +0000843 double fac1, fac2, fval, maxval;
844 PyObject *rv;
845 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000846
Georg Brandl660222f2006-05-28 22:34:51 +0000847 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
848 &cp, &len, &size, &fac1, &fac2 ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000849 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000850 if (!audioop_check_parameters(len, size))
851 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000852
Anthony Baxter17471432006-03-20 05:58:21 +0000853 if ( size == 1 ) maxval = (double) 0x7f;
854 else if ( size == 2 ) maxval = (double) 0x7fff;
855 else if ( size == 4 ) maxval = (double) 0x7fffffff;
856 else {
857 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
858 return 0;
859 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
Matthias Klose192b7142010-10-17 10:28:49 +0000861 if (len > INT_MAX/2) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +0000862 PyErr_SetString(PyExc_MemoryError,
863 "not enough memory for output buffer");
864 return 0;
865 }
866
Matthias Klose192b7142010-10-17 10:28:49 +0000867 rv = PyString_FromStringAndSize(NULL, len*2);
Anthony Baxter17471432006-03-20 05:58:21 +0000868 if ( rv == 0 )
869 return 0;
870 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000871
872
Anthony Baxter17471432006-03-20 05:58:21 +0000873 for ( i=0; i < len; i += size ) {
874 if ( size == 1 ) val = (int)*CHARP(cp, i);
875 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
876 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000877
Anthony Baxter17471432006-03-20 05:58:21 +0000878 fval = (double)val*fac1;
879 if ( fval > maxval ) fval = maxval;
880 else if ( fval < -maxval ) fval = -maxval;
881 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000882
Anthony Baxter17471432006-03-20 05:58:21 +0000883 fval = (double)val*fac2;
884 if ( fval > maxval ) fval = maxval;
885 else if ( fval < -maxval ) fval = -maxval;
886 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000887
Anthony Baxter17471432006-03-20 05:58:21 +0000888 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
889 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
890 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000891
Anthony Baxter17471432006-03-20 05:58:21 +0000892 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
893 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
894 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
895 }
896 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000897}
898
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000899static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000900audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000901{
Anthony Baxter17471432006-03-20 05:58:21 +0000902 signed char *cp1, *cp2, *ncp;
903 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
904 PyObject *rv;
905 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906
Georg Brandl660222f2006-05-28 22:34:51 +0000907 if ( !PyArg_ParseTuple(args, "s#s#i:add",
Anthony Baxter17471432006-03-20 05:58:21 +0000908 &cp1, &len1, &cp2, &len2, &size ) )
909 return 0;
Matthias Kloseb7180a82010-10-17 10:48:14 +0000910 if (!audioop_check_parameters(len1, size))
911 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +0000912 if ( len1 != len2 ) {
913 PyErr_SetString(AudioopError, "Lengths should be the same");
914 return 0;
915 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000916
Anthony Baxter17471432006-03-20 05:58:21 +0000917 if ( size == 1 ) maxval = 0x7f;
918 else if ( size == 2 ) maxval = 0x7fff;
919 else if ( size == 4 ) maxval = 0x7fffffff;
920 else {
921 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
922 return 0;
923 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000924
Anthony Baxter17471432006-03-20 05:58:21 +0000925 rv = PyString_FromStringAndSize(NULL, len1);
926 if ( rv == 0 )
927 return 0;
928 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000929
Anthony Baxter17471432006-03-20 05:58:21 +0000930 for ( i=0; i < len1; i += size ) {
931 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
932 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
933 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
934
935 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
936 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
937 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000938
Anthony Baxter17471432006-03-20 05:58:21 +0000939 newval = val1 + val2;
940 /* truncate in case of overflow */
941 if (newval > maxval) newval = maxval;
942 else if (newval < -maxval) newval = -maxval;
943 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
944 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000945
Anthony Baxter17471432006-03-20 05:58:21 +0000946 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
947 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
948 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
949 }
950 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000951}
952
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000953static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000954audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000955{
Anthony Baxter17471432006-03-20 05:58:21 +0000956 signed char *cp, *ncp;
957 int len, size, val = 0;
958 PyObject *rv;
959 int i;
960 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000961
Georg Brandl660222f2006-05-28 22:34:51 +0000962 if ( !PyArg_ParseTuple(args, "s#ii:bias",
Anthony Baxter17471432006-03-20 05:58:21 +0000963 &cp, &len, &size , &bias) )
964 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000965
Matthias Kloseb7180a82010-10-17 10:48:14 +0000966 if (!audioop_check_parameters(len, size))
967 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000968
Anthony Baxter17471432006-03-20 05:58:21 +0000969 rv = PyString_FromStringAndSize(NULL, len);
970 if ( rv == 0 )
971 return 0;
972 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000973
974
Anthony Baxter17471432006-03-20 05:58:21 +0000975 for ( i=0; i < len; i += size ) {
976 if ( size == 1 ) val = (int)*CHARP(cp, i);
977 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
978 else if ( size == 4 ) val = (int)*LONGP(cp, i);
979
980 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
981 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
982 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
983 }
984 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000985}
986
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000987static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000988audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000989{
Anthony Baxter17471432006-03-20 05:58:21 +0000990 signed char *cp;
991 unsigned char *ncp;
992 int len, size, val = 0;
993 PyObject *rv;
994 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000995
Georg Brandl660222f2006-05-28 22:34:51 +0000996 if ( !PyArg_ParseTuple(args, "s#i:reverse",
Anthony Baxter17471432006-03-20 05:58:21 +0000997 &cp, &len, &size) )
998 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000999
Matthias Kloseb7180a82010-10-17 10:48:14 +00001000 if (!audioop_check_parameters(len, size))
1001 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001002
Anthony Baxter17471432006-03-20 05:58:21 +00001003 rv = PyString_FromStringAndSize(NULL, len);
1004 if ( rv == 0 )
1005 return 0;
1006 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +00001007
Anthony Baxter17471432006-03-20 05:58:21 +00001008 for ( i=0; i < len; i += size ) {
1009 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1010 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1011 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +00001012
Anthony Baxter17471432006-03-20 05:58:21 +00001013 j = len - i - size;
1014
1015 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1016 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1017 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1018 }
1019 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001020}
1021
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001022static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001023audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001024{
Anthony Baxter17471432006-03-20 05:58:21 +00001025 signed char *cp;
1026 unsigned char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001027 int len, size, size2, val = 0;
Anthony Baxter17471432006-03-20 05:58:21 +00001028 PyObject *rv;
1029 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001030
Georg Brandl660222f2006-05-28 22:34:51 +00001031 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
Anthony Baxter17471432006-03-20 05:58:21 +00001032 &cp, &len, &size, &size2) )
1033 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001034
Matthias Kloseb7180a82010-10-17 10:48:14 +00001035 if (!audioop_check_parameters(len, size))
1036 return NULL;
1037 if (!audioop_check_size(size2))
1038 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001039
Matthias Klose192b7142010-10-17 10:28:49 +00001040 if (len/size > INT_MAX/size2) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001041 PyErr_SetString(PyExc_MemoryError,
1042 "not enough memory for output buffer");
1043 return 0;
1044 }
Matthias Klose192b7142010-10-17 10:28:49 +00001045 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Anthony Baxter17471432006-03-20 05:58:21 +00001046 if ( rv == 0 )
1047 return 0;
1048 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001049
Anthony Baxter17471432006-03-20 05:58:21 +00001050 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1051 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1052 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1053 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001054
Anthony Baxter17471432006-03-20 05:58:21 +00001055 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1056 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1057 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1058 }
1059 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001060}
1061
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001062static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001063gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001064{
Anthony Baxter17471432006-03-20 05:58:21 +00001065 while (b > 0) {
1066 int tmp = a % b;
1067 a = b;
1068 b = tmp;
1069 }
1070 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001071}
1072
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001073static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001074audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001075{
Anthony Baxter17471432006-03-20 05:58:21 +00001076 char *cp, *ncp;
1077 int len, size, nchannels, inrate, outrate, weightA, weightB;
1078 int chan, d, *prev_i, *cur_i, cur_o;
1079 PyObject *state, *samps, *str, *rv = NULL;
1080 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001081
Anthony Baxter17471432006-03-20 05:58:21 +00001082 weightA = 1;
1083 weightB = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001084 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1085 &nchannels, &inrate, &outrate, &state,
1086 &weightA, &weightB))
Anthony Baxter17471432006-03-20 05:58:21 +00001087 return NULL;
Matthias Kloseb7180a82010-10-17 10:48:14 +00001088 if (!audioop_check_size(size))
Anthony Baxter17471432006-03-20 05:58:21 +00001089 return NULL;
Anthony Baxter17471432006-03-20 05:58:21 +00001090 if (nchannels < 1) {
1091 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1092 return NULL;
1093 }
1094 bytes_per_frame = size * nchannels;
1095 if (bytes_per_frame / nchannels != size) {
1096 /* This overflow test is rigorously correct because
1097 both multiplicands are >= 1. Use the argument names
1098 from the docs for the error msg. */
1099 PyErr_SetString(PyExc_OverflowError,
1100 "width * nchannels too big for a C int");
1101 return NULL;
1102 }
1103 if (weightA < 1 || weightB < 0) {
1104 PyErr_SetString(AudioopError,
1105 "weightA should be >= 1, weightB should be >= 0");
1106 return NULL;
1107 }
1108 if (len % bytes_per_frame != 0) {
1109 PyErr_SetString(AudioopError, "not a whole number of frames");
1110 return NULL;
1111 }
1112 if (inrate <= 0 || outrate <= 0) {
1113 PyErr_SetString(AudioopError, "sampling rate not > 0");
1114 return NULL;
1115 }
1116 /* divide inrate and outrate by their greatest common divisor */
1117 d = gcd(inrate, outrate);
1118 inrate /= d;
1119 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001120
Matthias Klose192b7142010-10-17 10:28:49 +00001121 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001122 PyErr_SetString(PyExc_MemoryError,
1123 "not enough memory for output buffer");
1124 return 0;
1125 }
Matthias Klose192b7142010-10-17 10:28:49 +00001126 prev_i = (int *) malloc(nchannels * sizeof(int));
1127 cur_i = (int *) malloc(nchannels * sizeof(int));
Anthony Baxter17471432006-03-20 05:58:21 +00001128 if (prev_i == NULL || cur_i == NULL) {
1129 (void) PyErr_NoMemory();
1130 goto exit;
1131 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001132
Anthony Baxter17471432006-03-20 05:58:21 +00001133 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001134
Anthony Baxter17471432006-03-20 05:58:21 +00001135 if (state == Py_None) {
1136 d = -outrate;
1137 for (chan = 0; chan < nchannels; chan++)
1138 prev_i[chan] = cur_i[chan] = 0;
1139 }
1140 else {
1141 if (!PyArg_ParseTuple(state,
1142 "iO!;audioop.ratecv: illegal state argument",
1143 &d, &PyTuple_Type, &samps))
1144 goto exit;
1145 if (PyTuple_Size(samps) != nchannels) {
1146 PyErr_SetString(AudioopError,
1147 "illegal state argument");
1148 goto exit;
1149 }
1150 for (chan = 0; chan < nchannels; chan++) {
1151 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Georg Brandl660222f2006-05-28 22:34:51 +00001152 "ii:ratecv", &prev_i[chan],
1153 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001154 goto exit;
1155 }
1156 }
Tim Peters1691bd92001-12-05 06:05:07 +00001157
Anthony Baxter17471432006-03-20 05:58:21 +00001158 /* str <- Space for the output buffer. */
1159 {
1160 /* There are len input frames, so we need (mathematically)
1161 ceiling(len*outrate/inrate) output frames, and each frame
1162 requires bytes_per_frame bytes. Computing this
1163 without spurious overflow is the challenge; we can
Matthias Klosed4367c22010-10-17 10:34:40 +00001164 settle for a reasonable upper bound, though, in this
1165 case ceiling(len/inrate) * outrate. */
1166
1167 /* compute ceiling(len/inrate) without overflow */
1168 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1169 if (outrate > INT_MAX / q / bytes_per_frame)
Anthony Baxter17471432006-03-20 05:58:21 +00001170 str = NULL;
1171 else
Matthias Klosed4367c22010-10-17 10:34:40 +00001172 str = PyString_FromStringAndSize(NULL,
1173 q * outrate * bytes_per_frame);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001174
Anthony Baxter17471432006-03-20 05:58:21 +00001175 if (str == NULL) {
1176 PyErr_SetString(PyExc_MemoryError,
1177 "not enough memory for output buffer");
1178 goto exit;
1179 }
1180 }
1181 ncp = PyString_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001182
Anthony Baxter17471432006-03-20 05:58:21 +00001183 for (;;) {
1184 while (d < 0) {
1185 if (len == 0) {
1186 samps = PyTuple_New(nchannels);
1187 if (samps == NULL)
1188 goto exit;
1189 for (chan = 0; chan < nchannels; chan++)
1190 PyTuple_SetItem(samps, chan,
1191 Py_BuildValue("(ii)",
1192 prev_i[chan],
1193 cur_i[chan]));
1194 if (PyErr_Occurred())
1195 goto exit;
1196 /* We have checked before that the length
1197 * of the string fits into int. */
1198 len = (int)(ncp - PyString_AsString(str));
1199 if (len == 0) {
1200 /*don't want to resize to zero length*/
1201 rv = PyString_FromStringAndSize("", 0);
1202 Py_DECREF(str);
1203 str = rv;
1204 } else if (_PyString_Resize(&str, len) < 0)
1205 goto exit;
1206 rv = Py_BuildValue("(O(iO))", str, d, samps);
1207 Py_DECREF(samps);
1208 Py_DECREF(str);
1209 goto exit; /* return rv */
1210 }
1211 for (chan = 0; chan < nchannels; chan++) {
1212 prev_i[chan] = cur_i[chan];
1213 if (size == 1)
1214 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1215 else if (size == 2)
1216 cur_i[chan] = (int)*SHORTP(cp, 0);
1217 else if (size == 4)
1218 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1219 cp += size;
1220 /* implements a simple digital filter */
1221 cur_i[chan] =
1222 (weightA * cur_i[chan] +
1223 weightB * prev_i[chan]) /
1224 (weightA + weightB);
1225 }
1226 len--;
1227 d += outrate;
1228 }
1229 while (d >= 0) {
1230 for (chan = 0; chan < nchannels; chan++) {
1231 cur_o = (prev_i[chan] * d +
1232 cur_i[chan] * (outrate - d)) /
1233 outrate;
1234 if (size == 1)
1235 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1236 else if (size == 2)
1237 *SHORTP(ncp, 0) = (short)(cur_o);
1238 else if (size == 4)
1239 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1240 ncp += size;
1241 }
1242 d -= inrate;
1243 }
1244 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001245 exit:
Anthony Baxter17471432006-03-20 05:58:21 +00001246 if (prev_i != NULL)
1247 free(prev_i);
1248 if (cur_i != NULL)
1249 free(cur_i);
1250 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001251}
Guido van Rossum1851a671997-02-14 16:14:03 +00001252
Roger E. Massec905fff1997-01-17 18:12:04 +00001253static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001254audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001255{
Anthony Baxter17471432006-03-20 05:58:21 +00001256 signed char *cp;
1257 unsigned char *ncp;
1258 int len, size, val = 0;
1259 PyObject *rv;
1260 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001261
Georg Brandl660222f2006-05-28 22:34:51 +00001262 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1263 &cp, &len, &size) )
1264 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001265
Matthias Kloseb7180a82010-10-17 10:48:14 +00001266 if (!audioop_check_parameters(len, size))
1267 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001268
Anthony Baxter17471432006-03-20 05:58:21 +00001269 rv = PyString_FromStringAndSize(NULL, len/size);
1270 if ( rv == 0 )
1271 return 0;
1272 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001273
Anthony Baxter17471432006-03-20 05:58:21 +00001274 for ( i=0; i < len; i += size ) {
1275 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1276 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1277 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001278
Anthony Baxter17471432006-03-20 05:58:21 +00001279 *ncp++ = st_14linear2ulaw(val);
1280 }
1281 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001282}
1283
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001284static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001285audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001286{
Anthony Baxter17471432006-03-20 05:58:21 +00001287 unsigned char *cp;
1288 unsigned char cval;
1289 signed char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001290 int len, size, val;
Anthony Baxter17471432006-03-20 05:58:21 +00001291 PyObject *rv;
1292 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001293
Georg Brandl660222f2006-05-28 22:34:51 +00001294 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1295 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001296 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001297
Matthias Kloseb7180a82010-10-17 10:48:14 +00001298 if (!audioop_check_parameters(len, size))
1299 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001300
Matthias Klose192b7142010-10-17 10:28:49 +00001301 if (len > INT_MAX/size) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001302 PyErr_SetString(PyExc_MemoryError,
1303 "not enough memory for output buffer");
1304 return 0;
1305 }
Matthias Klose192b7142010-10-17 10:28:49 +00001306 rv = PyString_FromStringAndSize(NULL, len*size);
Anthony Baxter17471432006-03-20 05:58:21 +00001307 if ( rv == 0 )
1308 return 0;
1309 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001310
Matthias Klose192b7142010-10-17 10:28:49 +00001311 for ( i=0; i < len*size; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001312 cval = *cp++;
1313 val = st_ulaw2linear16(cval);
1314
1315 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1316 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1317 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1318 }
1319 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001320}
1321
1322static PyObject *
1323audioop_lin2alaw(PyObject *self, PyObject *args)
1324{
Anthony Baxter17471432006-03-20 05:58:21 +00001325 signed char *cp;
1326 unsigned char *ncp;
1327 int len, size, val = 0;
1328 PyObject *rv;
1329 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001330
Georg Brandl660222f2006-05-28 22:34:51 +00001331 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1332 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001333 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001334
Matthias Kloseb7180a82010-10-17 10:48:14 +00001335 if (!audioop_check_parameters(len, size))
1336 return NULL;
Anthony Baxterfa869072006-03-20 05:21:58 +00001337
Anthony Baxter17471432006-03-20 05:58:21 +00001338 rv = PyString_FromStringAndSize(NULL, len/size);
1339 if ( rv == 0 )
1340 return 0;
1341 ncp = (unsigned char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001342
Anthony Baxter17471432006-03-20 05:58:21 +00001343 for ( i=0; i < len; i += size ) {
1344 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1345 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1346 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001347
Anthony Baxter17471432006-03-20 05:58:21 +00001348 *ncp++ = st_linear2alaw(val);
1349 }
1350 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001351}
1352
1353static PyObject *
1354audioop_alaw2lin(PyObject *self, PyObject *args)
1355{
Anthony Baxter17471432006-03-20 05:58:21 +00001356 unsigned char *cp;
1357 unsigned char cval;
1358 signed char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001359 int len, size, val;
Anthony Baxter17471432006-03-20 05:58:21 +00001360 PyObject *rv;
1361 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001362
Georg Brandl660222f2006-05-28 22:34:51 +00001363 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1364 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001365 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001366
Matthias Kloseb7180a82010-10-17 10:48:14 +00001367 if (!audioop_check_parameters(len, size))
1368 return NULL;
Anthony Baxterfa869072006-03-20 05:21:58 +00001369
Matthias Klose192b7142010-10-17 10:28:49 +00001370 if (len > INT_MAX/size) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001371 PyErr_SetString(PyExc_MemoryError,
1372 "not enough memory for output buffer");
1373 return 0;
1374 }
Matthias Klose192b7142010-10-17 10:28:49 +00001375 rv = PyString_FromStringAndSize(NULL, len*size);
Anthony Baxter17471432006-03-20 05:58:21 +00001376 if ( rv == 0 )
1377 return 0;
1378 ncp = (signed char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001379
Matthias Klose192b7142010-10-17 10:28:49 +00001380 for ( i=0; i < len*size; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001381 cval = *cp++;
1382 val = st_alaw2linear16(cval);
1383
1384 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1385 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1386 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1387 }
1388 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001389}
1390
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001391static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001392audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001393{
Anthony Baxter17471432006-03-20 05:58:21 +00001394 signed char *cp;
1395 signed char *ncp;
1396 int len, size, val = 0, step, valpred, delta,
1397 index, sign, vpdiff, diff;
1398 PyObject *rv, *state, *str;
1399 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001400
Georg Brandl660222f2006-05-28 22:34:51 +00001401 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1402 &cp, &len, &size, &state) )
Anthony Baxter17471432006-03-20 05:58:21 +00001403 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001404
Matthias Kloseb7180a82010-10-17 10:48:14 +00001405 if (!audioop_check_parameters(len, size))
1406 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001407
Anthony Baxter17471432006-03-20 05:58:21 +00001408 str = PyString_FromStringAndSize(NULL, len/(size*2));
1409 if ( str == 0 )
1410 return 0;
1411 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001412
Anthony Baxter17471432006-03-20 05:58:21 +00001413 /* Decode state, should have (value, step) */
1414 if ( state == Py_None ) {
1415 /* First time, it seems. Set defaults */
1416 valpred = 0;
1417 step = 7;
1418 index = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001419 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Anthony Baxter17471432006-03-20 05:58:21 +00001420 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001421
Anthony Baxter17471432006-03-20 05:58:21 +00001422 step = stepsizeTable[index];
1423 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001424
Anthony Baxter17471432006-03-20 05:58:21 +00001425 for ( i=0; i < len; i += size ) {
1426 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1427 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1428 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001429
Anthony Baxter17471432006-03-20 05:58:21 +00001430 /* Step 1 - compute difference with previous value */
1431 diff = val - valpred;
1432 sign = (diff < 0) ? 8 : 0;
1433 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001434
Anthony Baxter17471432006-03-20 05:58:21 +00001435 /* Step 2 - Divide and clamp */
1436 /* Note:
1437 ** This code *approximately* computes:
1438 ** delta = diff*4/step;
1439 ** vpdiff = (delta+0.5)*step/4;
1440 ** but in shift step bits are dropped. The net result of this
1441 ** is that even if you have fast mul/div hardware you cannot
1442 ** put it to good use since the fixup would be too expensive.
1443 */
1444 delta = 0;
1445 vpdiff = (step >> 3);
1446
1447 if ( diff >= step ) {
1448 delta = 4;
1449 diff -= step;
1450 vpdiff += step;
1451 }
1452 step >>= 1;
1453 if ( diff >= step ) {
1454 delta |= 2;
1455 diff -= step;
1456 vpdiff += step;
1457 }
1458 step >>= 1;
1459 if ( diff >= step ) {
1460 delta |= 1;
1461 vpdiff += step;
1462 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001463
Anthony Baxter17471432006-03-20 05:58:21 +00001464 /* Step 3 - Update previous value */
1465 if ( sign )
1466 valpred -= vpdiff;
1467 else
1468 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001469
Anthony Baxter17471432006-03-20 05:58:21 +00001470 /* Step 4 - Clamp previous value to 16 bits */
1471 if ( valpred > 32767 )
1472 valpred = 32767;
1473 else if ( valpred < -32768 )
1474 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001475
Anthony Baxter17471432006-03-20 05:58:21 +00001476 /* Step 5 - Assemble value, update index and step values */
1477 delta |= sign;
1478
1479 index += indexTable[delta];
1480 if ( index < 0 ) index = 0;
1481 if ( index > 88 ) index = 88;
1482 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001483
Anthony Baxter17471432006-03-20 05:58:21 +00001484 /* Step 6 - Output value */
1485 if ( bufferstep ) {
1486 outputbuffer = (delta << 4) & 0xf0;
1487 } else {
1488 *ncp++ = (delta & 0x0f) | outputbuffer;
1489 }
1490 bufferstep = !bufferstep;
1491 }
1492 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1493 Py_DECREF(str);
1494 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001495}
1496
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001497static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001498audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001499{
Anthony Baxter17471432006-03-20 05:58:21 +00001500 signed char *cp;
1501 signed char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001502 int len, size, valpred, step, delta, index, sign, vpdiff;
Anthony Baxter17471432006-03-20 05:58:21 +00001503 PyObject *rv, *str, *state;
1504 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001505
Georg Brandl660222f2006-05-28 22:34:51 +00001506 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1507 &cp, &len, &size, &state) )
Anthony Baxter17471432006-03-20 05:58:21 +00001508 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001509
Matthias Kloseb7180a82010-10-17 10:48:14 +00001510 if (!audioop_check_parameters(len, size))
1511 return NULL;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001512
Anthony Baxter17471432006-03-20 05:58:21 +00001513 /* Decode state, should have (value, step) */
1514 if ( state == Py_None ) {
1515 /* First time, it seems. Set defaults */
1516 valpred = 0;
1517 step = 7;
1518 index = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001519 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Anthony Baxter17471432006-03-20 05:58:21 +00001520 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001521
Matthias Klose192b7142010-10-17 10:28:49 +00001522 if (len > (INT_MAX/2)/size) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001523 PyErr_SetString(PyExc_MemoryError,
1524 "not enough memory for output buffer");
1525 return 0;
1526 }
Matthias Klose192b7142010-10-17 10:28:49 +00001527 str = PyString_FromStringAndSize(NULL, len*size*2);
Anthony Baxter17471432006-03-20 05:58:21 +00001528 if ( str == 0 )
1529 return 0;
1530 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001531
Anthony Baxter17471432006-03-20 05:58:21 +00001532 step = stepsizeTable[index];
1533 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001534
Matthias Klose192b7142010-10-17 10:28:49 +00001535 for ( i=0; i < len*size*2; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001536 /* Step 1 - get the delta value and compute next index */
1537 if ( bufferstep ) {
1538 delta = inputbuffer & 0xf;
1539 } else {
1540 inputbuffer = *cp++;
1541 delta = (inputbuffer >> 4) & 0xf;
1542 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001543
Anthony Baxter17471432006-03-20 05:58:21 +00001544 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001545
Anthony Baxter17471432006-03-20 05:58:21 +00001546 /* Step 2 - Find new index value (for later) */
1547 index += indexTable[delta];
1548 if ( index < 0 ) index = 0;
1549 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001550
Anthony Baxter17471432006-03-20 05:58:21 +00001551 /* Step 3 - Separate sign and magnitude */
1552 sign = delta & 8;
1553 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001554
Anthony Baxter17471432006-03-20 05:58:21 +00001555 /* Step 4 - Compute difference and new predicted value */
1556 /*
1557 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1558 ** in adpcm_coder.
1559 */
1560 vpdiff = step >> 3;
1561 if ( delta & 4 ) vpdiff += step;
1562 if ( delta & 2 ) vpdiff += step>>1;
1563 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001564
Anthony Baxter17471432006-03-20 05:58:21 +00001565 if ( sign )
1566 valpred -= vpdiff;
1567 else
1568 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001569
Anthony Baxter17471432006-03-20 05:58:21 +00001570 /* Step 5 - clamp output value */
1571 if ( valpred > 32767 )
1572 valpred = 32767;
1573 else if ( valpred < -32768 )
1574 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001575
Anthony Baxter17471432006-03-20 05:58:21 +00001576 /* Step 6 - Update step value */
1577 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001578
Anthony Baxter17471432006-03-20 05:58:21 +00001579 /* Step 6 - Output value */
1580 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1581 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1582 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1583 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001584
Anthony Baxter17471432006-03-20 05:58:21 +00001585 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1586 Py_DECREF(str);
1587 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001588}
1589
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001590static PyMethodDef audioop_methods[] = {
Georg Brandl660222f2006-05-28 22:34:51 +00001591 { "max", audioop_max, METH_VARARGS },
1592 { "minmax", audioop_minmax, METH_VARARGS },
1593 { "avg", audioop_avg, METH_VARARGS },
1594 { "maxpp", audioop_maxpp, METH_VARARGS },
1595 { "avgpp", audioop_avgpp, METH_VARARGS },
1596 { "rms", audioop_rms, METH_VARARGS },
1597 { "findfit", audioop_findfit, METH_VARARGS },
1598 { "findmax", audioop_findmax, METH_VARARGS },
1599 { "findfactor", audioop_findfactor, METH_VARARGS },
1600 { "cross", audioop_cross, METH_VARARGS },
1601 { "mul", audioop_mul, METH_VARARGS },
1602 { "add", audioop_add, METH_VARARGS },
1603 { "bias", audioop_bias, METH_VARARGS },
1604 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1605 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1606 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1607 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1608 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1609 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1610 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1611 { "tomono", audioop_tomono, METH_VARARGS },
1612 { "tostereo", audioop_tostereo, METH_VARARGS },
1613 { "getsample", audioop_getsample, METH_VARARGS },
1614 { "reverse", audioop_reverse, METH_VARARGS },
Anthony Baxter17471432006-03-20 05:58:21 +00001615 { "ratecv", audioop_ratecv, METH_VARARGS },
1616 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001617};
1618
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001619PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001620initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001621{
Anthony Baxter17471432006-03-20 05:58:21 +00001622 PyObject *m, *d;
1623 m = Py_InitModule("audioop", audioop_methods);
1624 if (m == NULL)
1625 return;
1626 d = PyModule_GetDict(m);
Neal Norwitz49c65d02006-03-20 06:34:06 +00001627 if (d == NULL)
1628 return;
Anthony Baxter17471432006-03-20 05:58:21 +00001629 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1630 if (AudioopError != NULL)
1631 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001632}