blob: 13f43dd5f1500fe0d7cb28043851c000f71e3072 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Anthony Baxter17471432006-03-20 05:58:21 +000018typedef short PyInt16;
19
Guido van Rossum7b1e9741994-08-29 10:46:42 +000020#if defined(__CHAR_UNSIGNED__)
21#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000022/* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000026
Anthony Baxterfa869072006-03-20 05:21:58 +000027/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000028** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
29
Anthony Baxterfa869072006-03-20 05:21:58 +000030/* From g711.c:
31 *
32 * December 30, 1994:
33 * Functions linear2alaw, linear2ulaw have been updated to correctly
34 * convert unquantized 16 bit values.
35 * Tables for direct u- to A-law and A- to u-law conversions have been
36 * corrected.
37 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
38 * bli@cpk.auc.dk
39 *
40 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000041#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
42#define CLIP 32635
Anthony Baxter17471432006-03-20 05:58:21 +000043#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
44#define QUANT_MASK (0xf) /* Quantization field mask. */
45#define SEG_SHIFT (4) /* Left shift for segment number. */
46#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000047
Anthony Baxter17471432006-03-20 05:58:21 +000048static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
49 0x1FF, 0x3FF, 0x7FF, 0xFFF};
50static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
51 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
Anthony Baxterfa869072006-03-20 05:21:58 +000052
Neal Norwitz49c65d02006-03-20 06:34:06 +000053static PyInt16
54search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000055{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Antoine Pitrouc83ea132010-05-09 14:46:46 +000058 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
61 }
62 return (size);
Anthony Baxterfa869072006-03-20 05:21:58 +000063}
64#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
65#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000066
Neal Norwitz49c65d02006-03-20 06:34:06 +000067static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000068 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
69 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
70 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
71 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
72 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
73 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
74 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
75 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
76 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
77 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
78 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
79 -1052, -988, -924, -876, -844, -812, -780,
80 -748, -716, -684, -652, -620, -588, -556,
81 -524, -492, -460, -428, -396, -372, -356,
82 -340, -324, -308, -292, -276, -260, -244,
83 -228, -212, -196, -180, -164, -148, -132,
84 -120, -112, -104, -96, -88, -80, -72,
85 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouc83ea132010-05-09 14:46:46 +000086 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21:58 +000087 27004, 25980, 24956, 23932, 22908, 21884, 20860,
88 19836, 18812, 17788, 16764, 15996, 15484, 14972,
89 14460, 13948, 13436, 12924, 12412, 11900, 11388,
90 10876, 10364, 9852, 9340, 8828, 8316, 7932,
91 7676, 7420, 7164, 6908, 6652, 6396, 6140,
92 5884, 5628, 5372, 5116, 4860, 4604, 4348,
93 4092, 3900, 3772, 3644, 3516, 3388, 3260,
94 3132, 3004, 2876, 2748, 2620, 2492, 2364,
95 2236, 2108, 1980, 1884, 1820, 1756, 1692,
96 1628, 1564, 1500, 1436, 1372, 1308, 1244,
97 1180, 1116, 1052, 988, 924, 876, 844,
98 812, 780, 748, 716, 684, 652, 620,
99 588, 556, 524, 492, 460, 428, 396,
100 372, 356, 340, 324, 308, 292, 276,
101 260, 244, 228, 212, 196, 180, 164,
102 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000105};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Anthony Baxterfa869072006-03-20 05:21:58 +0000107/*
108 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
109 * stored in a unsigned char. This function should only be called with
110 * the data shifted such that it only contains information in the lower
111 * 14-bits.
112 *
113 * In order to simplify the encoding process, the original linear magnitude
114 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
115 * (33 - 8191). The result can be seen in the following encoding table:
116 *
Anthony Baxter17471432006-03-20 05:58:21 +0000117 * Biased Linear Input Code Compressed Code
118 * ------------------------ ---------------
119 * 00000001wxyza 000wxyz
120 * 0000001wxyzab 001wxyz
121 * 000001wxyzabc 010wxyz
122 * 00001wxyzabcd 011wxyz
123 * 0001wxyzabcde 100wxyz
124 * 001wxyzabcdef 101wxyz
125 * 01wxyzabcdefg 110wxyz
126 * 1wxyzabcdefgh 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000127 *
128 * Each biased linear code has a leading 1 which identifies the segment
129 * number. The value of the segment number is equal to 7 minus the number
130 * of leading 0's. The quantization interval is directly available as the
131 * four bits wxyz. * The trailing bits (a - h) are ignored.
132 *
133 * Ordinarily the complement of the resulting code word is used for
134 * transmission, and so the code word is complemented before it is returned.
135 *
136 * For further information see John C. Bellamy's Digital Telephony, 1982,
137 * John Wiley & Sons, pps 98-111 and 472-476.
138 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000139static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000141{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000145
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000148
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000149 /* u-law inverts all bits */
150 /* Get the sign and the magnitude of the value. */
151 if (pcm_val < 0) {
152 pcm_val = -pcm_val;
153 mask = 0x7F;
154 } else {
155 mask = 0xFF;
156 }
157 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
158 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000159
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000162
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000163 /*
164 * Combine the sign, segment, quantization bits;
165 * and complement the code word.
166 */
167 if (seg >= 8) /* out of range, return maximum value. */
168 return (unsigned char) (0x7F ^ mask);
169 else {
170 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
171 return (uval ^ mask);
172 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000173
174}
175
Neal Norwitz49c65d02006-03-20 06:34:06 +0000176static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000177 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
178 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
179 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
180 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
181 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
182 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
183 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
184 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
185 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
186 -13568, -344, -328, -376, -360, -280, -264,
187 -312, -296, -472, -456, -504, -488, -408,
188 -392, -440, -424, -88, -72, -120, -104,
189 -24, -8, -56, -40, -216, -200, -248,
190 -232, -152, -136, -184, -168, -1376, -1312,
191 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
192 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
193 -688, -656, -752, -720, -560, -528, -624,
194 -592, -944, -912, -1008, -976, -816, -784,
195 -880, -848, 5504, 5248, 6016, 5760, 4480,
196 4224, 4992, 4736, 7552, 7296, 8064, 7808,
197 6528, 6272, 7040, 6784, 2752, 2624, 3008,
198 2880, 2240, 2112, 2496, 2368, 3776, 3648,
199 4032, 3904, 3264, 3136, 3520, 3392, 22016,
200 20992, 24064, 23040, 17920, 16896, 19968, 18944,
201 30208, 29184, 32256, 31232, 26112, 25088, 28160,
202 27136, 11008, 10496, 12032, 11520, 8960, 8448,
203 9984, 9472, 15104, 14592, 16128, 15616, 13056,
204 12544, 14080, 13568, 344, 328, 376, 360,
205 280, 264, 312, 296, 472, 456, 504,
206 488, 408, 392, 440, 424, 88, 72,
207 120, 104, 24, 8, 56, 40, 216,
208 200, 248, 232, 152, 136, 184, 168,
209 1376, 1312, 1504, 1440, 1120, 1056, 1248,
210 1184, 1888, 1824, 2016, 1952, 1632, 1568,
211 1760, 1696, 688, 656, 752, 720, 560,
212 528, 624, 592, 944, 912, 1008, 976,
213 816, 784, 880, 848
214};
215
216/*
217 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
218 * stored in a unsigned char. This function should only be called with
219 * the data shifted such that it only contains information in the lower
220 * 13-bits.
221 *
Anthony Baxter17471432006-03-20 05:58:21 +0000222 * Linear Input Code Compressed Code
223 * ------------------------ ---------------
224 * 0000000wxyza 000wxyz
225 * 0000001wxyza 001wxyz
226 * 000001wxyzab 010wxyz
227 * 00001wxyzabc 011wxyz
228 * 0001wxyzabcd 100wxyz
229 * 001wxyzabcde 101wxyz
230 * 01wxyzabcdef 110wxyz
231 * 1wxyzabcdefg 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000232 *
233 * For further information see John C. Bellamy's Digital Telephony, 1982,
234 * John Wiley & Sons, pps 98-111 and 472-476.
235 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000236static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000238{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000242
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000245
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
252 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000253
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000256
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000257 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000258
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
273static int indexTable[16] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
278static int stepsizeTable[89] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
Brett Cannon9824e7f2010-05-03 23:42:40 +0000289
Guido van Rossumb66efa01992-06-01 16:01:24 +0000290#define CHARP(cp, i) ((signed char *)(cp+i))
291#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000292#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000293
294
295
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000296static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000297
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000298static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000299audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000300{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000301 signed char *cp;
302 int len, size, val = 0;
303 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000304
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000305 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
306 return 0;
307 if ( size != 1 && size != 2 && size != 4 ) {
308 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
309 return 0;
310 }
311 if ( i < 0 || i >= len/size ) {
312 PyErr_SetString(AudioopError, "Index out of range");
313 return 0;
314 }
315 if ( size == 1 ) val = (int)*CHARP(cp, i);
316 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
317 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
318 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000319}
320
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000321static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000322audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
327 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000329 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
330 return 0;
331 if ( size != 1 && size != 2 && size != 4 ) {
332 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
333 return 0;
334 }
335 for ( i=0; i<len; i+= size) {
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i);
339 if ( val < 0 ) val = (-val);
340 if ( val > max ) max = val;
341 }
342 return PyInt_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000343}
344
345static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000346audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000347{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000348 signed char *cp;
349 int len, size, val = 0;
350 int i;
351 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000352
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000353 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
354 return NULL;
355 if (size != 1 && size != 2 && size != 4) {
356 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
357 return NULL;
358 }
359 for (i = 0; i < len; i += size) {
360 if (size == 1) val = (int) *CHARP(cp, i);
361 else if (size == 2) val = (int) *SHORTP(cp, i);
362 else if (size == 4) val = (int) *LONGP(cp, i);
363 if (val > max) max = val;
364 if (val < min) min = val;
365 }
366 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000367}
368
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000369static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000370audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000371{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000372 signed char *cp;
373 int len, size, val = 0;
374 int i;
375 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000376
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000377 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
378 return 0;
379 if ( size != 1 && size != 2 && size != 4 ) {
380 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
381 return 0;
382 }
383 for ( i=0; i<len; i+= size) {
384 if ( size == 1 ) val = (int)*CHARP(cp, i);
385 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
386 else if ( size == 4 ) val = (int)*LONGP(cp, i);
387 avg += val;
388 }
389 if ( len == 0 )
390 val = 0;
391 else
392 val = (int)(avg / (double)(len/size));
393 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000394}
395
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000396static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000397audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000398{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000399 signed char *cp;
400 int len, size, val = 0;
401 int i;
402 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000403
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000404 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
405 return 0;
406 if ( size != 1 && size != 2 && size != 4 ) {
407 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
408 return 0;
409 }
410 for ( i=0; i<len; i+= size) {
411 if ( size == 1 ) val = (int)*CHARP(cp, i);
412 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
413 else if ( size == 4 ) val = (int)*LONGP(cp, i);
414 sum_squares += (double)val*(double)val;
415 }
416 if ( len == 0 )
417 val = 0;
418 else
419 val = (int)sqrt(sum_squares / (double)(len/size));
420 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000421}
422
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000423static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000424{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000425 int i;
426 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000427
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000428 for( i=0; i<len; i++) {
429 sum = sum + (double)a[i]*(double)b[i];
430 }
431 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000432}
433
434/*
435** Findfit tries to locate a sample within another sample. Its main use
436** is in echo-cancellation (to find the feedback of the output signal in
437** the input signal).
438** The method used is as follows:
439**
440** let R be the reference signal (length n) and A the input signal (length N)
441** with N > n, and let all sums be over i from 0 to n-1.
442**
443** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
444** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
445** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
446**
447** Next, we compute the relative distance between the original signal and
448** the modified signal and minimize that over j:
449** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
450** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
451**
452** In the code variables correspond as follows:
Anthony Baxter17471432006-03-20 05:58:21 +0000453** cp1 A
454** cp2 R
455** len1 N
456** len2 n
457** aj_m1 A[j-1]
458** aj_lm1 A[j+n-1]
459** sum_ri_2 sum(R[i]^2)
460** sum_aij_2 sum(A[i+j]^2)
461** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000462**
463** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
464** is completely recalculated each step.
465*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000466static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000467audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000468{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000469 short *cp1, *cp2;
470 int len1, len2;
471 int j, best_j;
472 double aj_m1, aj_lm1;
473 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000474
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000475 /* Passing a short** for an 's' argument is correct only
476 if the string contents is aligned for interpretation
477 as short[]. Due to the definition of PyStringObject,
478 this is currently (Python 2.6) the case. */
479 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
480 (char**)&cp1, &len1, (char**)&cp2, &len2) )
481 return 0;
482 if ( len1 & 1 || len2 & 1 ) {
483 PyErr_SetString(AudioopError, "Strings should be even-sized");
484 return 0;
485 }
486 len1 >>= 1;
487 len2 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000488
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000489 if ( len1 < len2 ) {
490 PyErr_SetString(AudioopError, "First sample should be longer");
491 return 0;
492 }
493 sum_ri_2 = _sum2(cp2, cp2, len2);
494 sum_aij_2 = _sum2(cp1, cp1, len2);
495 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000496
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000497 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000498
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000499 best_result = result;
500 best_j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000501
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000502 for (j=1; j<=len1-len2; j++) {
503 aj_m1 = (double)cp1[j-1];
504 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000505
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000506 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
507 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000508
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000509 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
510 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000511
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000512 if ( result < best_result ) {
513 best_result = result;
514 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000515 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000516
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000517 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000518
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000519 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
520
521 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000522}
523
524/*
525** findfactor finds a factor f so that the energy in A-fB is minimal.
526** See the comment for findfit for details.
527*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000528static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000529audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000530{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000531 short *cp1, *cp2;
532 int len1, len2;
533 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000534
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000535 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
536 (char**)&cp1, &len1, (char**)&cp2, &len2) )
537 return 0;
538 if ( len1 & 1 || len2 & 1 ) {
539 PyErr_SetString(AudioopError, "Strings should be even-sized");
540 return 0;
541 }
542 if ( len1 != len2 ) {
543 PyErr_SetString(AudioopError, "Samples should be same size");
544 return 0;
545 }
546 len2 >>= 1;
547 sum_ri_2 = _sum2(cp2, cp2, len2);
548 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000549
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000551
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000552 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000553}
554
555/*
556** findmax returns the index of the n-sized segment of the input sample
557** that contains the most energy.
558*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000559static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000560audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000561{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000562 short *cp1;
563 int len1, len2;
564 int j, best_j;
565 double aj_m1, aj_lm1;
566 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000567
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000568 if ( !PyArg_ParseTuple(args, "s#i:findmax",
569 (char**)&cp1, &len1, &len2) )
570 return 0;
571 if ( len1 & 1 ) {
572 PyErr_SetString(AudioopError, "Strings should be even-sized");
573 return 0;
574 }
575 len1 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000576
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000577 if ( len2 < 0 || len1 < len2 ) {
578 PyErr_SetString(AudioopError, "Input sample should be longer");
579 return 0;
580 }
581
582 result = _sum2(cp1, cp1, len2);
583
584 best_result = result;
585 best_j = 0;
586
587 for (j=1; j<=len1-len2; j++) {
588 aj_m1 = (double)cp1[j-1];
589 aj_lm1 = (double)cp1[j+len2-1];
590
591 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
592
593 if ( result > best_result ) {
594 best_result = result;
595 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000596 }
Jack Jansena90805f1993-02-17 14:29:28 +0000597
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000598 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000599
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000600 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000601}
602
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000603static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000604audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000605{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000606 signed char *cp;
607 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
608 prevextreme = 0;
609 int i;
610 double avg = 0.0;
611 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000612
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000613 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
614 return 0;
615 if ( size != 1 && size != 2 && size != 4 ) {
616 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
617 return 0;
618 }
619 /* Compute first delta value ahead. Also automatically makes us
620 ** skip the first extreme value
621 */
622 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
623 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
624 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
625 if ( size == 1 ) val = (int)*CHARP(cp, size);
626 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
627 else if ( size == 4 ) val = (int)*LONGP(cp, size);
628 prevdiff = val - prevval;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000629
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000630 for ( i=size; i<len; i+= size) {
631 if ( size == 1 ) val = (int)*CHARP(cp, i);
632 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
633 else if ( size == 4 ) val = (int)*LONGP(cp, i);
634 diff = val - prevval;
635 if ( diff*prevdiff < 0 ) {
636 /* Derivative changed sign. Compute difference to last
637 ** extreme value and remember.
638 */
639 if ( prevextremevalid ) {
640 extremediff = prevval - prevextreme;
641 if ( extremediff < 0 )
642 extremediff = -extremediff;
643 avg += extremediff;
644 nextreme++;
645 }
646 prevextremevalid = 1;
647 prevextreme = prevval;
Anthony Baxter17471432006-03-20 05:58:21 +0000648 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000649 prevval = val;
650 if ( diff != 0 )
651 prevdiff = diff;
652 }
653 if ( nextreme == 0 )
654 val = 0;
655 else
656 val = (int)(avg / (double)nextreme);
657 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000658}
659
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000660static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000661audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000662{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000663 signed char *cp;
664 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
665 prevextreme = 0;
666 int i;
667 int max = 0;
668 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000669
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000670 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
671 return 0;
672 if ( size != 1 && size != 2 && size != 4 ) {
673 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
674 return 0;
675 }
676 /* Compute first delta value ahead. Also automatically makes us
677 ** skip the first extreme value
678 */
679 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
680 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
681 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
682 if ( size == 1 ) val = (int)*CHARP(cp, size);
683 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
684 else if ( size == 4 ) val = (int)*LONGP(cp, size);
685 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000686
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000687 for ( i=size; i<len; i+= size) {
688 if ( size == 1 ) val = (int)*CHARP(cp, i);
689 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
690 else if ( size == 4 ) val = (int)*LONGP(cp, i);
691 diff = val - prevval;
692 if ( diff*prevdiff < 0 ) {
693 /* Derivative changed sign. Compute difference to
694 ** last extreme value and remember.
695 */
696 if ( prevextremevalid ) {
697 extremediff = prevval - prevextreme;
698 if ( extremediff < 0 )
699 extremediff = -extremediff;
700 if ( extremediff > max )
701 max = extremediff;
702 }
703 prevextremevalid = 1;
704 prevextreme = prevval;
Anthony Baxter17471432006-03-20 05:58:21 +0000705 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000706 prevval = val;
707 if ( diff != 0 )
708 prevdiff = diff;
709 }
710 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000711}
712
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000713static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000714audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000715{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000716 signed char *cp;
717 int len, size, val = 0;
718 int i;
719 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000720
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000721 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
722 return 0;
723 if ( size != 1 && size != 2 && size != 4 ) {
724 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
725 return 0;
726 }
727 ncross = -1;
728 prevval = 17; /* Anything <> 0,1 */
729 for ( i=0; i<len; i+= size) {
730 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
731 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
732 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
733 val = val & 1;
734 if ( val != prevval ) ncross++;
735 prevval = val;
736 }
737 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000738}
739
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000740static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000741audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000742{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000743 signed char *cp, *ncp;
744 int len, size, val = 0;
745 double factor, fval, maxval;
746 PyObject *rv;
747 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000748
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000749 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
750 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000751
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000752 if ( size == 1 ) maxval = (double) 0x7f;
753 else if ( size == 2 ) maxval = (double) 0x7fff;
754 else if ( size == 4 ) maxval = (double) 0x7fffffff;
755 else {
756 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
757 return 0;
758 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000759
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000760 rv = PyString_FromStringAndSize(NULL, len);
761 if ( rv == 0 )
762 return 0;
763 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000764
765
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000766 for ( i=0; i < len; i += size ) {
767 if ( size == 1 ) val = (int)*CHARP(cp, i);
768 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
769 else if ( size == 4 ) val = (int)*LONGP(cp, i);
770 fval = (double)val*factor;
771 if ( fval > maxval ) fval = maxval;
772 else if ( fval < -maxval ) fval = -maxval;
773 val = (int)fval;
774 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
775 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
776 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
777 }
778 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000779}
780
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000781static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000782audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000783{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000784 signed char *cp, *ncp;
785 int len, size, val1 = 0, val2 = 0;
786 double fac1, fac2, fval, maxval;
787 PyObject *rv;
788 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000789
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000790 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
791 &cp, &len, &size, &fac1, &fac2 ) )
792 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000793
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000794 if ( size == 1 ) maxval = (double) 0x7f;
795 else if ( size == 2 ) maxval = (double) 0x7fff;
796 else if ( size == 4 ) maxval = (double) 0x7fffffff;
797 else {
798 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
799 return 0;
800 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000801
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000802 rv = PyString_FromStringAndSize(NULL, len/2);
803 if ( rv == 0 )
804 return 0;
805 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000806
807
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000808 for ( i=0; i < len; i += size*2 ) {
809 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
810 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
811 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
812 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
813 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
814 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
815 fval = (double)val1*fac1 + (double)val2*fac2;
816 if ( fval > maxval ) fval = maxval;
817 else if ( fval < -maxval ) fval = -maxval;
818 val1 = (int)fval;
819 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
820 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
821 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
822 }
823 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000824}
825
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000826static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000827audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000828{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000829 signed char *cp, *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +0000830 int len, size, val1, val2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000831 double fac1, fac2, fval, maxval;
832 PyObject *rv;
833 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000835 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
836 &cp, &len, &size, &fac1, &fac2 ) )
837 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000838
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000839 if ( size == 1 ) maxval = (double) 0x7f;
840 else if ( size == 2 ) maxval = (double) 0x7fff;
841 else if ( size == 4 ) maxval = (double) 0x7fffffff;
842 else {
843 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
844 return 0;
845 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000846
Mark Dickinson932e1622010-05-10 16:07:42 +0000847 if (len > INT_MAX/2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 PyErr_SetString(PyExc_MemoryError,
849 "not enough memory for output buffer");
850 return 0;
851 }
Gregory P. Smith9d534572008-06-11 07:41:16 +0000852
Mark Dickinson932e1622010-05-10 16:07:42 +0000853 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000854 if ( rv == 0 )
855 return 0;
856 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000857
858
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000859 for ( i=0; i < len; i += size ) {
860 if ( size == 1 ) val = (int)*CHARP(cp, i);
861 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
862 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000863
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000864 fval = (double)val*fac1;
865 if ( fval > maxval ) fval = maxval;
866 else if ( fval < -maxval ) fval = -maxval;
867 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000868
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000869 fval = (double)val*fac2;
870 if ( fval > maxval ) fval = maxval;
871 else if ( fval < -maxval ) fval = -maxval;
872 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000873
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000874 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
875 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
876 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000877
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000878 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
879 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
880 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
881 }
882 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883}
884
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000885static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000886audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000887{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000888 signed char *cp1, *cp2, *ncp;
889 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
890 PyObject *rv;
891 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000892
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000893 if ( !PyArg_ParseTuple(args, "s#s#i:add",
894 &cp1, &len1, &cp2, &len2, &size ) )
895 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000896
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000897 if ( len1 != len2 ) {
898 PyErr_SetString(AudioopError, "Lengths should be the same");
899 return 0;
900 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000901
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000902 if ( size == 1 ) maxval = 0x7f;
903 else if ( size == 2 ) maxval = 0x7fff;
904 else if ( size == 4 ) maxval = 0x7fffffff;
905 else {
906 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
907 return 0;
908 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000909
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000910 rv = PyString_FromStringAndSize(NULL, len1);
911 if ( rv == 0 )
912 return 0;
913 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000914
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000915 for ( i=0; i < len1; i += size ) {
916 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
917 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
918 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000919
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000920 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
921 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
922 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000923
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000924 newval = val1 + val2;
925 /* truncate in case of overflow */
926 if (newval > maxval) newval = maxval;
927 else if (newval < -maxval) newval = -maxval;
928 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
929 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000930
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000931 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
932 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
933 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
934 }
935 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000936}
937
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000938static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000939audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000940{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000941 signed char *cp, *ncp;
942 int len, size, val = 0;
943 PyObject *rv;
944 int i;
945 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000946
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000947 if ( !PyArg_ParseTuple(args, "s#ii:bias",
948 &cp, &len, &size , &bias) )
949 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000950
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000951 if ( size != 1 && size != 2 && size != 4) {
952 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
953 return 0;
954 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000955
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000956 rv = PyString_FromStringAndSize(NULL, len);
957 if ( rv == 0 )
958 return 0;
959 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000960
961
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000962 for ( i=0; i < len; i += size ) {
963 if ( size == 1 ) val = (int)*CHARP(cp, i);
964 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
965 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000966
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
968 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
969 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
970 }
971 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000972}
973
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000974static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000975audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000976{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000977 signed char *cp;
978 unsigned char *ncp;
979 int len, size, val = 0;
980 PyObject *rv;
981 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000982
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000983 if ( !PyArg_ParseTuple(args, "s#i:reverse",
984 &cp, &len, &size) )
985 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000986
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000987 if ( size != 1 && size != 2 && size != 4 ) {
988 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
989 return 0;
990 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000991
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000992 rv = PyString_FromStringAndSize(NULL, len);
993 if ( rv == 0 )
994 return 0;
995 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000996
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000997 for ( i=0; i < len; i += size ) {
998 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
999 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1000 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +00001001
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001002 j = len - i - size;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001003
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001004 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1005 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1006 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1007 }
1008 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001009}
1010
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001011static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001012audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001013{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001014 signed char *cp;
1015 unsigned char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001016 int len, size, size2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001017 PyObject *rv;
1018 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001019
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001020 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1021 &cp, &len, &size, &size2) )
1022 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001023
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001024 if ( (size != 1 && size != 2 && size != 4) ||
1025 (size2 != 1 && size2 != 2 && size2 != 4)) {
1026 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1027 return 0;
1028 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001029
Mark Dickinson932e1622010-05-10 16:07:42 +00001030 if (len/size > INT_MAX/size2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001031 PyErr_SetString(PyExc_MemoryError,
1032 "not enough memory for output buffer");
1033 return 0;
1034 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001035 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001036 if ( rv == 0 )
1037 return 0;
1038 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001039
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001040 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1041 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1042 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1043 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001044
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001045 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1046 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1047 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1048 }
1049 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001050}
1051
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001052static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001053gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001054{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001055 while (b > 0) {
1056 int tmp = a % b;
1057 a = b;
1058 b = tmp;
1059 }
1060 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001061}
1062
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001063static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001064audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001065{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001066 char *cp, *ncp;
1067 int len, size, nchannels, inrate, outrate, weightA, weightB;
1068 int chan, d, *prev_i, *cur_i, cur_o;
1069 PyObject *state, *samps, *str, *rv = NULL;
1070 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001071
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001072 weightA = 1;
1073 weightB = 0;
1074 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1075 &nchannels, &inrate, &outrate, &state,
1076 &weightA, &weightB))
1077 return NULL;
1078 if (size != 1 && size != 2 && size != 4) {
1079 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1080 return NULL;
1081 }
1082 if (nchannels < 1) {
1083 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1084 return NULL;
1085 }
1086 bytes_per_frame = size * nchannels;
1087 if (bytes_per_frame / nchannels != size) {
1088 /* This overflow test is rigorously correct because
1089 both multiplicands are >= 1. Use the argument names
1090 from the docs for the error msg. */
1091 PyErr_SetString(PyExc_OverflowError,
1092 "width * nchannels too big for a C int");
1093 return NULL;
1094 }
1095 if (weightA < 1 || weightB < 0) {
1096 PyErr_SetString(AudioopError,
1097 "weightA should be >= 1, weightB should be >= 0");
1098 return NULL;
1099 }
1100 if (len % bytes_per_frame != 0) {
1101 PyErr_SetString(AudioopError, "not a whole number of frames");
1102 return NULL;
1103 }
1104 if (inrate <= 0 || outrate <= 0) {
1105 PyErr_SetString(AudioopError, "sampling rate not > 0");
1106 return NULL;
1107 }
1108 /* divide inrate and outrate by their greatest common divisor */
1109 d = gcd(inrate, outrate);
1110 inrate /= d;
1111 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001112
Mark Dickinson932e1622010-05-10 16:07:42 +00001113 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001114 PyErr_SetString(PyExc_MemoryError,
1115 "not enough memory for output buffer");
1116 return 0;
1117 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001118 prev_i = (int *) malloc(nchannels * sizeof(int));
1119 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001120 if (prev_i == NULL || cur_i == NULL) {
1121 (void) PyErr_NoMemory();
1122 goto exit;
1123 }
1124
1125 len /= bytes_per_frame; /* # of frames */
1126
1127 if (state == Py_None) {
1128 d = -outrate;
1129 for (chan = 0; chan < nchannels; chan++)
1130 prev_i[chan] = cur_i[chan] = 0;
1131 }
1132 else {
1133 if (!PyArg_ParseTuple(state,
1134 "iO!;audioop.ratecv: illegal state argument",
1135 &d, &PyTuple_Type, &samps))
1136 goto exit;
1137 if (PyTuple_Size(samps) != nchannels) {
1138 PyErr_SetString(AudioopError,
1139 "illegal state argument");
1140 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001141 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001142 for (chan = 0; chan < nchannels; chan++) {
1143 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1144 "ii:ratecv", &prev_i[chan],
1145 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001146 goto exit;
1147 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001148 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001149
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001150 /* str <- Space for the output buffer. */
1151 {
1152 /* There are len input frames, so we need (mathematically)
1153 ceiling(len*outrate/inrate) output frames, and each frame
1154 requires bytes_per_frame bytes. Computing this
1155 without spurious overflow is the challenge; we can
1156 settle for a reasonable upper bound, though. */
1157 int ceiling; /* the number of output frames */
1158 int nbytes; /* the number of output bytes needed */
1159 int q = len / inrate;
1160 /* Now len = q * inrate + r exactly (with r = len % inrate),
1161 and this is less than q * inrate + inrate = (q+1)*inrate.
1162 So a reasonable upper bound on len*outrate/inrate is
1163 ((q+1)*inrate)*outrate/inrate =
1164 (q+1)*outrate.
1165 */
1166 ceiling = (q+1) * outrate;
1167 nbytes = ceiling * bytes_per_frame;
1168 /* See whether anything overflowed; if not, get the space. */
1169 if (q+1 < 0 ||
1170 ceiling / outrate != q+1 ||
1171 nbytes / bytes_per_frame != ceiling)
1172 str = NULL;
1173 else
1174 str = PyString_FromStringAndSize(NULL, nbytes);
Tim Peters1691bd92001-12-05 06:05:07 +00001175
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001176 if (str == NULL) {
1177 PyErr_SetString(PyExc_MemoryError,
1178 "not enough memory for output buffer");
1179 goto exit;
1180 }
1181 }
1182 ncp = PyString_AsString(str);
1183
1184 for (;;) {
1185 while (d < 0) {
1186 if (len == 0) {
1187 samps = PyTuple_New(nchannels);
1188 if (samps == NULL)
1189 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001190 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001191 PyTuple_SetItem(samps, chan,
1192 Py_BuildValue("(ii)",
1193 prev_i[chan],
1194 cur_i[chan]));
1195 if (PyErr_Occurred())
1196 goto exit;
1197 /* We have checked before that the length
1198 * of the string fits into int. */
1199 len = (int)(ncp - PyString_AsString(str));
1200 if (len == 0) {
1201 /*don't want to resize to zero length*/
1202 rv = PyString_FromStringAndSize("", 0);
1203 Py_DECREF(str);
1204 str = rv;
1205 } else if (_PyString_Resize(&str, len) < 0)
1206 goto exit;
1207 rv = Py_BuildValue("(O(iO))", str, d, samps);
1208 Py_DECREF(samps);
1209 Py_DECREF(str);
1210 goto exit; /* return rv */
1211 }
1212 for (chan = 0; chan < nchannels; chan++) {
1213 prev_i[chan] = cur_i[chan];
1214 if (size == 1)
1215 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1216 else if (size == 2)
1217 cur_i[chan] = (int)*SHORTP(cp, 0);
1218 else if (size == 4)
1219 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1220 cp += size;
1221 /* implements a simple digital filter */
1222 cur_i[chan] =
1223 (weightA * cur_i[chan] +
1224 weightB * prev_i[chan]) /
1225 (weightA + weightB);
1226 }
1227 len--;
1228 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001229 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001230 while (d >= 0) {
1231 for (chan = 0; chan < nchannels; chan++) {
1232 cur_o = (prev_i[chan] * d +
1233 cur_i[chan] * (outrate - d)) /
1234 outrate;
1235 if (size == 1)
1236 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1237 else if (size == 2)
1238 *SHORTP(ncp, 0) = (short)(cur_o);
1239 else if (size == 4)
1240 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1241 ncp += size;
1242 }
1243 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001244 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001245 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001246 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001247 if (prev_i != NULL)
1248 free(prev_i);
1249 if (cur_i != NULL)
1250 free(cur_i);
1251 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001252}
Guido van Rossum1851a671997-02-14 16:14:03 +00001253
Roger E. Massec905fff1997-01-17 18:12:04 +00001254static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001255audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001256{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001257 signed char *cp;
1258 unsigned char *ncp;
1259 int len, size, val = 0;
1260 PyObject *rv;
1261 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001262
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001263 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1264 &cp, &len, &size) )
1265 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001266
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001267 if ( size != 1 && size != 2 && size != 4) {
1268 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1269 return 0;
1270 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001271
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001272 rv = PyString_FromStringAndSize(NULL, len/size);
1273 if ( rv == 0 )
1274 return 0;
1275 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001276
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001277 for ( i=0; i < len; i += size ) {
1278 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1279 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1280 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001282 *ncp++ = st_14linear2ulaw(val);
1283 }
1284 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001285}
1286
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001287static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001288audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001289{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001290 unsigned char *cp;
1291 unsigned char cval;
1292 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001293 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001294 PyObject *rv;
1295 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001296
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001297 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1298 &cp, &len, &size) )
1299 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001300
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001301 if ( size != 1 && size != 2 && size != 4) {
1302 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1303 return 0;
1304 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001305
Mark Dickinson932e1622010-05-10 16:07:42 +00001306 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001307 PyErr_SetString(PyExc_MemoryError,
1308 "not enough memory for output buffer");
1309 return 0;
1310 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001311 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001312 if ( rv == 0 )
1313 return 0;
1314 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001315
Mark Dickinson932e1622010-05-10 16:07:42 +00001316 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001317 cval = *cp++;
1318 val = st_ulaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001319
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001320 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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +00001336 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1337 &cp, &len, &size) )
1338 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001339
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001340 if ( size != 1 && size != 2 && size != 4) {
1341 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1342 return 0;
1343 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001344
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001345 rv = PyString_FromStringAndSize(NULL, len/size);
1346 if ( rv == 0 )
1347 return 0;
1348 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001349
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001350 for ( i=0; i < len; i += size ) {
1351 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1352 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1353 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001354
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001355 *ncp++ = st_linear2alaw(val);
1356 }
1357 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001358}
1359
1360static PyObject *
1361audioop_alaw2lin(PyObject *self, PyObject *args)
1362{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 unsigned char *cp;
1364 unsigned char cval;
1365 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001366 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001367 PyObject *rv;
1368 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001369
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001370 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1371 &cp, &len, &size) )
1372 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001373
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001374 if ( size != 1 && size != 2 && size != 4) {
1375 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1376 return 0;
1377 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001378
Mark Dickinson932e1622010-05-10 16:07:42 +00001379 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001380 PyErr_SetString(PyExc_MemoryError,
1381 "not enough memory for output buffer");
1382 return 0;
1383 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001384 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001385 if ( rv == 0 )
1386 return 0;
1387 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001388
Mark Dickinson932e1622010-05-10 16:07:42 +00001389 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001390 cval = *cp++;
1391 val = st_alaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001392
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001393 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1394 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1395 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1396 }
1397 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001398}
1399
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001400static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001401audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001402{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001403 signed char *cp;
1404 signed char *ncp;
1405 int len, size, val = 0, step, valpred, delta,
1406 index, sign, vpdiff, diff;
1407 PyObject *rv, *state, *str;
1408 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001409
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001410 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1411 &cp, &len, &size, &state) )
1412 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001413
Guido van Rossumb64e6351992-07-06 14:21:56 +00001414
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001415 if ( size != 1 && size != 2 && size != 4) {
1416 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1417 return 0;
1418 }
1419
1420 str = PyString_FromStringAndSize(NULL, len/(size*2));
1421 if ( str == 0 )
1422 return 0;
1423 ncp = (signed char *)PyString_AsString(str);
1424
1425 /* Decode state, should have (value, step) */
1426 if ( state == Py_None ) {
1427 /* First time, it seems. Set defaults */
1428 valpred = 0;
1429 index = 0;
1430 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1431 return 0;
1432
1433 step = stepsizeTable[index];
1434 bufferstep = 1;
1435
1436 for ( i=0; i < len; i += size ) {
1437 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1438 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1439 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1440
1441 /* Step 1 - compute difference with previous value */
1442 diff = val - valpred;
1443 sign = (diff < 0) ? 8 : 0;
1444 if ( sign ) diff = (-diff);
1445
1446 /* Step 2 - Divide and clamp */
1447 /* Note:
1448 ** This code *approximately* computes:
1449 ** delta = diff*4/step;
1450 ** vpdiff = (delta+0.5)*step/4;
1451 ** but in shift step bits are dropped. The net result of this
1452 ** is that even if you have fast mul/div hardware you cannot
1453 ** put it to good use since the fixup would be too expensive.
1454 */
1455 delta = 0;
1456 vpdiff = (step >> 3);
1457
1458 if ( diff >= step ) {
1459 delta = 4;
1460 diff -= step;
1461 vpdiff += step;
1462 }
1463 step >>= 1;
1464 if ( diff >= step ) {
1465 delta |= 2;
1466 diff -= step;
1467 vpdiff += step;
1468 }
1469 step >>= 1;
1470 if ( diff >= step ) {
1471 delta |= 1;
1472 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001473 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001474
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001475 /* Step 3 - Update previous value */
1476 if ( sign )
1477 valpred -= vpdiff;
1478 else
1479 valpred += vpdiff;
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001480
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001481 /* Step 4 - Clamp previous value to 16 bits */
1482 if ( valpred > 32767 )
1483 valpred = 32767;
1484 else if ( valpred < -32768 )
1485 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001486
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001487 /* Step 5 - Assemble value, update index and step values */
1488 delta |= sign;
1489
1490 index += indexTable[delta];
1491 if ( index < 0 ) index = 0;
1492 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001493 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001494
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001495 /* Step 6 - Output value */
1496 if ( bufferstep ) {
1497 outputbuffer = (delta << 4) & 0xf0;
1498 } else {
1499 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001500 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001501 bufferstep = !bufferstep;
1502 }
1503 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1504 Py_DECREF(str);
1505 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001506}
1507
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001508static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001509audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001510{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001511 signed char *cp;
1512 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001513 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001514 PyObject *rv, *str, *state;
1515 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001516
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001517 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1518 &cp, &len, &size, &state) )
1519 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001520
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001521 if ( size != 1 && size != 2 && size != 4) {
1522 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1523 return 0;
1524 }
1525
1526 /* Decode state, should have (value, step) */
1527 if ( state == Py_None ) {
1528 /* First time, it seems. Set defaults */
1529 valpred = 0;
1530 index = 0;
1531 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1532 return 0;
1533
Mark Dickinson932e1622010-05-10 16:07:42 +00001534 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001535 PyErr_SetString(PyExc_MemoryError,
1536 "not enough memory for output buffer");
1537 return 0;
1538 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001539 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001540 if ( str == 0 )
1541 return 0;
1542 ncp = (signed char *)PyString_AsString(str);
1543
1544 step = stepsizeTable[index];
1545 bufferstep = 0;
1546
Mark Dickinson932e1622010-05-10 16:07:42 +00001547 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001548 /* Step 1 - get the delta value and compute next index */
1549 if ( bufferstep ) {
1550 delta = inputbuffer & 0xf;
1551 } else {
1552 inputbuffer = *cp++;
1553 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001554 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001555
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001556 bufferstep = !bufferstep;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001557
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001558 /* Step 2 - Find new index value (for later) */
1559 index += indexTable[delta];
1560 if ( index < 0 ) index = 0;
1561 if ( index > 88 ) index = 88;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001562
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001563 /* Step 3 - Separate sign and magnitude */
1564 sign = delta & 8;
1565 delta = delta & 7;
1566
1567 /* Step 4 - Compute difference and new predicted value */
1568 /*
1569 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1570 ** in adpcm_coder.
1571 */
1572 vpdiff = step >> 3;
1573 if ( delta & 4 ) vpdiff += step;
1574 if ( delta & 2 ) vpdiff += step>>1;
1575 if ( delta & 1 ) vpdiff += step>>2;
1576
1577 if ( sign )
1578 valpred -= vpdiff;
1579 else
1580 valpred += vpdiff;
1581
1582 /* Step 5 - clamp output value */
1583 if ( valpred > 32767 )
1584 valpred = 32767;
1585 else if ( valpred < -32768 )
1586 valpred = -32768;
1587
1588 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001589 step = stepsizeTable[index];
Brett Cannon9824e7f2010-05-03 23:42:40 +00001590
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001591 /* Step 6 - Output value */
1592 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1593 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1594 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1595 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001596
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001597 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1598 Py_DECREF(str);
1599 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001600}
1601
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001602static PyMethodDef audioop_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001603 { "max", audioop_max, METH_VARARGS },
1604 { "minmax", audioop_minmax, METH_VARARGS },
1605 { "avg", audioop_avg, METH_VARARGS },
1606 { "maxpp", audioop_maxpp, METH_VARARGS },
1607 { "avgpp", audioop_avgpp, METH_VARARGS },
1608 { "rms", audioop_rms, METH_VARARGS },
1609 { "findfit", audioop_findfit, METH_VARARGS },
1610 { "findmax", audioop_findmax, METH_VARARGS },
1611 { "findfactor", audioop_findfactor, METH_VARARGS },
1612 { "cross", audioop_cross, METH_VARARGS },
1613 { "mul", audioop_mul, METH_VARARGS },
1614 { "add", audioop_add, METH_VARARGS },
1615 { "bias", audioop_bias, METH_VARARGS },
1616 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1617 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1618 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1619 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1620 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1621 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1622 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1623 { "tomono", audioop_tomono, METH_VARARGS },
1624 { "tostereo", audioop_tostereo, METH_VARARGS },
1625 { "getsample", audioop_getsample, METH_VARARGS },
1626 { "reverse", audioop_reverse, METH_VARARGS },
1627 { "ratecv", audioop_ratecv, METH_VARARGS },
1628 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001629};
1630
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001631PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001632initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001633{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001634 PyObject *m, *d;
1635 m = Py_InitModule("audioop", audioop_methods);
1636 if (m == NULL)
1637 return;
1638 d = PyModule_GetDict(m);
1639 if (d == NULL)
1640 return;
1641 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1642 if (AudioopError != NULL)
1643 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001644}