blob: 31e3fa4870e1210b961090f617ddb7ef60ed02ca [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
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{
Anthony Baxter17471432006-03-20 05:58:21 +0000301 signed char *cp;
302 int len, size, val = 0;
303 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000304
Georg Brandl660222f2006-05-28 22:34:51 +0000305 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
Anthony Baxter17471432006-03-20 05:58:21 +0000306 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000329 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000330 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000353 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
Anthony Baxter17471432006-03-20 05:58:21 +0000354 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000377 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000378 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000404 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000405 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{
Anthony Baxter17471432006-03-20 05:58:21 +0000425 int i;
426 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000427
Anthony Baxter17471432006-03-20 05:58:21 +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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Martin v. Löwisa811c382006-10-19 11:00:37 +0000475 /* Passing a short** for an 's' argument is correct only
476 if the string contents is aligned for interpretation
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000477 as short[]. Due to the definition of PyStringObject,
Martin v. Löwisa811c382006-10-19 11:00:37 +0000478 this is currently (Python 2.6) the case. */
Georg Brandl660222f2006-05-28 22:34:51 +0000479 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
Martin v. Löwisa811c382006-10-19 11:00:37 +0000480 (char**)&cp1, &len1, (char**)&cp2, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000481 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;
Jack Jansena90805f1993-02-17 14:29:28 +0000488
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +0000499 best_result = result;
500 best_j = 0;
501 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000502
Anthony Baxter17471432006-03-20 05:58:21 +0000503 for ( j=1; j<=len1-len2; j++) {
504 aj_m1 = (double)cp1[j-1];
505 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000506
Anthony Baxter17471432006-03-20 05:58:21 +0000507 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
508 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000509
Anthony Baxter17471432006-03-20 05:58:21 +0000510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
511 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000512
Anthony Baxter17471432006-03-20 05:58:21 +0000513 if ( result < best_result ) {
514 best_result = result;
515 best_j = j;
516 }
517
518 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519
Anthony Baxter17471432006-03-20 05:58:21 +0000520 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000521
Anthony Baxter17471432006-03-20 05:58:21 +0000522 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000523}
524
525/*
526** findfactor finds a factor f so that the energy in A-fB is minimal.
527** See the comment for findfit for details.
528*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000529static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000530audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000531{
Anthony Baxter17471432006-03-20 05:58:21 +0000532 short *cp1, *cp2;
533 int len1, len2;
534 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000535
Georg Brandl660222f2006-05-28 22:34:51 +0000536 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
Martin v. Löwisa811c382006-10-19 11:00:37 +0000537 (char**)&cp1, &len1, (char**)&cp2, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000538 return 0;
539 if ( len1 & 1 || len2 & 1 ) {
540 PyErr_SetString(AudioopError, "Strings should be even-sized");
541 return 0;
542 }
543 if ( len1 != len2 ) {
544 PyErr_SetString(AudioopError, "Samples should be same size");
545 return 0;
546 }
547 len2 >>= 1;
548 sum_ri_2 = _sum2(cp2, cp2, len2);
549 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000550
Anthony Baxter17471432006-03-20 05:58:21 +0000551 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000552
Anthony Baxter17471432006-03-20 05:58:21 +0000553 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000554}
555
556/*
557** findmax returns the index of the n-sized segment of the input sample
558** that contains the most energy.
559*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000561audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000562{
Anthony Baxter17471432006-03-20 05:58:21 +0000563 short *cp1;
564 int len1, len2;
565 int j, best_j;
566 double aj_m1, aj_lm1;
567 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000568
Martin v. Löwisa811c382006-10-19 11:00:37 +0000569 if ( !PyArg_ParseTuple(args, "s#i:findmax",
570 (char**)&cp1, &len1, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000571 return 0;
572 if ( len1 & 1 ) {
573 PyErr_SetString(AudioopError, "Strings should be even-sized");
574 return 0;
575 }
576 len1 >>= 1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000577
Anthony Baxter17471432006-03-20 05:58:21 +0000578 if ( len1 < len2 ) {
579 PyErr_SetString(AudioopError, "Input sample should be longer");
580 return 0;
581 }
Jack Jansena90805f1993-02-17 14:29:28 +0000582
Anthony Baxter17471432006-03-20 05:58:21 +0000583 result = _sum2(cp1, cp1, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000584
Anthony Baxter17471432006-03-20 05:58:21 +0000585 best_result = result;
586 best_j = 0;
587 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000588
Anthony Baxter17471432006-03-20 05:58:21 +0000589 for ( j=1; j<=len1-len2; j++) {
590 aj_m1 = (double)cp1[j-1];
591 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000592
Anthony Baxter17471432006-03-20 05:58:21 +0000593 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000594
Anthony Baxter17471432006-03-20 05:58:21 +0000595 if ( result > best_result ) {
596 best_result = result;
597 best_j = j;
598 }
599
600 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000601
Anthony Baxter17471432006-03-20 05:58:21 +0000602 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000603}
604
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000606audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000607{
Anthony Baxter17471432006-03-20 05:58:21 +0000608 signed char *cp;
609 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
610 prevextreme = 0;
611 int i;
612 double avg = 0.0;
613 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000614
Georg Brandl660222f2006-05-28 22:34:51 +0000615 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000616 return 0;
617 if ( size != 1 && size != 2 && size != 4 ) {
618 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
619 return 0;
620 }
621 /* Compute first delta value ahead. Also automatically makes us
622 ** skip the first extreme value
623 */
624 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
625 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
626 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
627 if ( size == 1 ) val = (int)*CHARP(cp, size);
628 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
629 else if ( size == 4 ) val = (int)*LONGP(cp, size);
630 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000631
Anthony Baxter17471432006-03-20 05:58:21 +0000632 for ( i=size; i<len; i+= size) {
633 if ( size == 1 ) val = (int)*CHARP(cp, i);
634 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
635 else if ( size == 4 ) val = (int)*LONGP(cp, i);
636 diff = val - prevval;
637 if ( diff*prevdiff < 0 ) {
638 /* Derivative changed sign. Compute difference to last
639 ** extreme value and remember.
640 */
641 if ( prevextremevalid ) {
642 extremediff = prevval - prevextreme;
643 if ( extremediff < 0 )
644 extremediff = -extremediff;
645 avg += extremediff;
646 nextreme++;
647 }
648 prevextremevalid = 1;
649 prevextreme = prevval;
650 }
651 prevval = val;
652 if ( diff != 0 )
653 prevdiff = diff;
654 }
655 if ( nextreme == 0 )
656 val = 0;
657 else
658 val = (int)(avg / (double)nextreme);
659 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000660}
661
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000662static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000663audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000664{
Anthony Baxter17471432006-03-20 05:58:21 +0000665 signed char *cp;
666 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
667 prevextreme = 0;
668 int i;
669 int max = 0;
670 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000671
Georg Brandl660222f2006-05-28 22:34:51 +0000672 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000673 return 0;
674 if ( size != 1 && size != 2 && size != 4 ) {
675 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
676 return 0;
677 }
678 /* Compute first delta value ahead. Also automatically makes us
679 ** skip the first extreme value
680 */
681 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
682 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
683 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
684 if ( size == 1 ) val = (int)*CHARP(cp, size);
685 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
686 else if ( size == 4 ) val = (int)*LONGP(cp, size);
687 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000688
Anthony Baxter17471432006-03-20 05:58:21 +0000689 for ( i=size; i<len; i+= size) {
690 if ( size == 1 ) val = (int)*CHARP(cp, i);
691 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
692 else if ( size == 4 ) val = (int)*LONGP(cp, i);
693 diff = val - prevval;
694 if ( diff*prevdiff < 0 ) {
695 /* Derivative changed sign. Compute difference to
696 ** last extreme value and remember.
697 */
698 if ( prevextremevalid ) {
699 extremediff = prevval - prevextreme;
700 if ( extremediff < 0 )
701 extremediff = -extremediff;
702 if ( extremediff > max )
703 max = extremediff;
704 }
705 prevextremevalid = 1;
706 prevextreme = prevval;
707 }
708 prevval = val;
709 if ( diff != 0 )
710 prevdiff = diff;
711 }
712 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000713}
714
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000715static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000716audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717{
Anthony Baxter17471432006-03-20 05:58:21 +0000718 signed char *cp;
719 int len, size, val = 0;
720 int i;
721 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722
Georg Brandl660222f2006-05-28 22:34:51 +0000723 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000724 return 0;
725 if ( size != 1 && size != 2 && size != 4 ) {
726 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
727 return 0;
728 }
729 ncross = -1;
730 prevval = 17; /* Anything <> 0,1 */
731 for ( i=0; i<len; i+= size) {
732 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
733 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
734 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
735 val = val & 1;
736 if ( val != prevval ) ncross++;
737 prevval = val;
738 }
739 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000740}
741
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000742static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000743audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000744{
Anthony Baxter17471432006-03-20 05:58:21 +0000745 signed char *cp, *ncp;
746 int len, size, val = 0;
747 double factor, fval, maxval;
748 PyObject *rv;
749 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
Georg Brandl660222f2006-05-28 22:34:51 +0000751 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000752 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000753
Anthony Baxter17471432006-03-20 05:58:21 +0000754 if ( size == 1 ) maxval = (double) 0x7f;
755 else if ( size == 2 ) maxval = (double) 0x7fff;
756 else if ( size == 4 ) maxval = (double) 0x7fffffff;
757 else {
758 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
759 return 0;
760 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000762 rv = PyString_FromStringAndSize(NULL, len);
Anthony Baxter17471432006-03-20 05:58:21 +0000763 if ( rv == 0 )
764 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000765 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000766
767
Anthony Baxter17471432006-03-20 05:58:21 +0000768 for ( i=0; i < len; i += size ) {
769 if ( size == 1 ) val = (int)*CHARP(cp, i);
770 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
771 else if ( size == 4 ) val = (int)*LONGP(cp, i);
772 fval = (double)val*factor;
773 if ( fval > maxval ) fval = maxval;
774 else if ( fval < -maxval ) fval = -maxval;
775 val = (int)fval;
776 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
777 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
778 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
779 }
780 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000781}
782
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000784audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000785{
Anthony Baxter17471432006-03-20 05:58:21 +0000786 signed char *cp, *ncp;
787 int len, size, val1 = 0, val2 = 0;
788 double fac1, fac2, fval, maxval;
789 PyObject *rv;
790 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791
Georg Brandl660222f2006-05-28 22:34:51 +0000792 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
793 &cp, &len, &size, &fac1, &fac2 ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000794 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Anthony Baxter17471432006-03-20 05:58:21 +0000796 if ( size == 1 ) maxval = (double) 0x7f;
797 else if ( size == 2 ) maxval = (double) 0x7fff;
798 else if ( size == 4 ) maxval = (double) 0x7fffffff;
799 else {
800 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
801 return 0;
802 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000804 rv = PyString_FromStringAndSize(NULL, len/2);
Anthony Baxter17471432006-03-20 05:58:21 +0000805 if ( rv == 0 )
806 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000807 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000808
809
Anthony Baxter17471432006-03-20 05:58:21 +0000810 for ( i=0; i < len; i += size*2 ) {
811 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
812 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
813 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
814 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
815 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
816 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
817 fval = (double)val1*fac1 + (double)val2*fac2;
818 if ( fval > maxval ) fval = maxval;
819 else if ( fval < -maxval ) fval = -maxval;
820 val1 = (int)fval;
821 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
822 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
823 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
824 }
825 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000826}
827
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000828static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000829audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000830{
Anthony Baxter17471432006-03-20 05:58:21 +0000831 signed char *cp, *ncp;
Gregory P. Smith9d534572008-06-11 07:41:16 +0000832 int len, new_len, size, val1, val2, val = 0;
Anthony Baxter17471432006-03-20 05:58:21 +0000833 double fac1, fac2, fval, maxval;
834 PyObject *rv;
835 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000836
Georg Brandl660222f2006-05-28 22:34:51 +0000837 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
838 &cp, &len, &size, &fac1, &fac2 ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000839 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000840
Anthony Baxter17471432006-03-20 05:58:21 +0000841 if ( size == 1 ) maxval = (double) 0x7f;
842 else if ( size == 2 ) maxval = (double) 0x7fff;
843 else if ( size == 4 ) maxval = (double) 0x7fffffff;
844 else {
845 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
846 return 0;
847 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000848
Gregory P. Smith9d534572008-06-11 07:41:16 +0000849 new_len = len*2;
850 if (new_len < 0) {
851 PyErr_SetString(PyExc_MemoryError,
852 "not enough memory for output buffer");
853 return 0;
854 }
855
856 rv = PyString_FromStringAndSize(NULL, new_len);
Anthony Baxter17471432006-03-20 05:58:21 +0000857 if ( rv == 0 )
858 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000859 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
861
Anthony Baxter17471432006-03-20 05:58:21 +0000862 for ( i=0; i < len; i += size ) {
863 if ( size == 1 ) val = (int)*CHARP(cp, i);
864 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
865 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000866
Anthony Baxter17471432006-03-20 05:58:21 +0000867 fval = (double)val*fac1;
868 if ( fval > maxval ) fval = maxval;
869 else if ( fval < -maxval ) fval = -maxval;
870 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000871
Anthony Baxter17471432006-03-20 05:58:21 +0000872 fval = (double)val*fac2;
873 if ( fval > maxval ) fval = maxval;
874 else if ( fval < -maxval ) fval = -maxval;
875 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876
Anthony Baxter17471432006-03-20 05:58:21 +0000877 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
878 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
879 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880
Anthony Baxter17471432006-03-20 05:58:21 +0000881 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
882 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
883 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
884 }
885 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000886}
887
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000888static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000889audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000890{
Anthony Baxter17471432006-03-20 05:58:21 +0000891 signed char *cp1, *cp2, *ncp;
892 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
893 PyObject *rv;
894 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000895
Georg Brandl660222f2006-05-28 22:34:51 +0000896 if ( !PyArg_ParseTuple(args, "s#s#i:add",
Anthony Baxter17471432006-03-20 05:58:21 +0000897 &cp1, &len1, &cp2, &len2, &size ) )
898 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000899
Anthony Baxter17471432006-03-20 05:58:21 +0000900 if ( len1 != len2 ) {
901 PyErr_SetString(AudioopError, "Lengths should be the same");
902 return 0;
903 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000904
Anthony Baxter17471432006-03-20 05:58:21 +0000905 if ( size == 1 ) maxval = 0x7f;
906 else if ( size == 2 ) maxval = 0x7fff;
907 else if ( size == 4 ) maxval = 0x7fffffff;
908 else {
909 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
910 return 0;
911 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000912
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000913 rv = PyString_FromStringAndSize(NULL, len1);
Anthony Baxter17471432006-03-20 05:58:21 +0000914 if ( rv == 0 )
915 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000916 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000917
Anthony Baxter17471432006-03-20 05:58:21 +0000918 for ( i=0; i < len1; i += size ) {
919 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
920 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
921 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
922
923 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
924 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
925 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000926
Anthony Baxter17471432006-03-20 05:58:21 +0000927 newval = val1 + val2;
928 /* truncate in case of overflow */
929 if (newval > maxval) newval = maxval;
930 else if (newval < -maxval) newval = -maxval;
931 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
932 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000933
Anthony Baxter17471432006-03-20 05:58:21 +0000934 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
935 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
936 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
937 }
938 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000939}
940
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000941static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000942audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000943{
Anthony Baxter17471432006-03-20 05:58:21 +0000944 signed char *cp, *ncp;
945 int len, size, val = 0;
946 PyObject *rv;
947 int i;
948 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000949
Georg Brandl660222f2006-05-28 22:34:51 +0000950 if ( !PyArg_ParseTuple(args, "s#ii:bias",
Anthony Baxter17471432006-03-20 05:58:21 +0000951 &cp, &len, &size , &bias) )
952 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000953
Anthony Baxter17471432006-03-20 05:58:21 +0000954 if ( size != 1 && size != 2 && size != 4) {
955 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
956 return 0;
957 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000958
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000959 rv = PyString_FromStringAndSize(NULL, len);
Anthony Baxter17471432006-03-20 05:58:21 +0000960 if ( rv == 0 )
961 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000962 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000963
964
Anthony Baxter17471432006-03-20 05:58:21 +0000965 for ( i=0; i < len; i += size ) {
966 if ( size == 1 ) val = (int)*CHARP(cp, i);
967 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
968 else if ( size == 4 ) val = (int)*LONGP(cp, i);
969
970 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
971 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
972 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
973 }
974 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000975}
976
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000977static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000978audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000979{
Anthony Baxter17471432006-03-20 05:58:21 +0000980 signed char *cp;
981 unsigned char *ncp;
982 int len, size, val = 0;
983 PyObject *rv;
984 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000985
Georg Brandl660222f2006-05-28 22:34:51 +0000986 if ( !PyArg_ParseTuple(args, "s#i:reverse",
Anthony Baxter17471432006-03-20 05:58:21 +0000987 &cp, &len, &size) )
988 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000989
Anthony Baxter17471432006-03-20 05:58:21 +0000990 if ( size != 1 && size != 2 && size != 4 ) {
991 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
992 return 0;
993 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000994
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000995 rv = PyString_FromStringAndSize(NULL, len);
Anthony Baxter17471432006-03-20 05:58:21 +0000996 if ( rv == 0 )
997 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000998 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000999
Anthony Baxter17471432006-03-20 05:58:21 +00001000 for ( i=0; i < len; i += size ) {
1001 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1002 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1003 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +00001004
Anthony Baxter17471432006-03-20 05:58:21 +00001005 j = len - i - size;
1006
1007 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1008 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1009 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1010 }
1011 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001012}
1013
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001014static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001015audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001016{
Anthony Baxter17471432006-03-20 05:58:21 +00001017 signed char *cp;
1018 unsigned char *ncp;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001019 int len, new_len, size, size2, val = 0;
Anthony Baxter17471432006-03-20 05:58:21 +00001020 PyObject *rv;
1021 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001022
Georg Brandl660222f2006-05-28 22:34:51 +00001023 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
Anthony Baxter17471432006-03-20 05:58:21 +00001024 &cp, &len, &size, &size2) )
1025 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001026
Anthony Baxter17471432006-03-20 05:58:21 +00001027 if ( (size != 1 && size != 2 && size != 4) ||
1028 (size2 != 1 && size2 != 2 && size2 != 4)) {
1029 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1030 return 0;
1031 }
Jack Jansena90805f1993-02-17 14:29:28 +00001032
Gregory P. Smith9d534572008-06-11 07:41:16 +00001033 new_len = (len/size)*size2;
1034 if (new_len < 0) {
1035 PyErr_SetString(PyExc_MemoryError,
1036 "not enough memory for output buffer");
1037 return 0;
1038 }
1039 rv = PyString_FromStringAndSize(NULL, new_len);
Anthony Baxter17471432006-03-20 05:58:21 +00001040 if ( rv == 0 )
1041 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001042 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001043
Anthony Baxter17471432006-03-20 05:58:21 +00001044 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1045 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1046 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1047 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001048
Anthony Baxter17471432006-03-20 05:58:21 +00001049 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1050 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1051 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1052 }
1053 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001054}
1055
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001056static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001057gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001058{
Anthony Baxter17471432006-03-20 05:58:21 +00001059 while (b > 0) {
1060 int tmp = a % b;
1061 a = b;
1062 b = tmp;
1063 }
1064 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001065}
1066
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001067static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001068audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001069{
Anthony Baxter17471432006-03-20 05:58:21 +00001070 char *cp, *ncp;
1071 int len, size, nchannels, inrate, outrate, weightA, weightB;
1072 int chan, d, *prev_i, *cur_i, cur_o;
1073 PyObject *state, *samps, *str, *rv = NULL;
1074 int bytes_per_frame;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001075 size_t alloc_size;
Guido van Rossum1851a671997-02-14 16:14:03 +00001076
Anthony Baxter17471432006-03-20 05:58:21 +00001077 weightA = 1;
1078 weightB = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001079 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1080 &nchannels, &inrate, &outrate, &state,
1081 &weightA, &weightB))
Anthony Baxter17471432006-03-20 05:58:21 +00001082 return NULL;
1083 if (size != 1 && size != 2 && size != 4) {
1084 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1085 return NULL;
1086 }
1087 if (nchannels < 1) {
1088 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1089 return NULL;
1090 }
1091 bytes_per_frame = size * nchannels;
1092 if (bytes_per_frame / nchannels != size) {
1093 /* This overflow test is rigorously correct because
1094 both multiplicands are >= 1. Use the argument names
1095 from the docs for the error msg. */
1096 PyErr_SetString(PyExc_OverflowError,
1097 "width * nchannels too big for a C int");
1098 return NULL;
1099 }
1100 if (weightA < 1 || weightB < 0) {
1101 PyErr_SetString(AudioopError,
1102 "weightA should be >= 1, weightB should be >= 0");
1103 return NULL;
1104 }
1105 if (len % bytes_per_frame != 0) {
1106 PyErr_SetString(AudioopError, "not a whole number of frames");
1107 return NULL;
1108 }
1109 if (inrate <= 0 || outrate <= 0) {
1110 PyErr_SetString(AudioopError, "sampling rate not > 0");
1111 return NULL;
1112 }
1113 /* divide inrate and outrate by their greatest common divisor */
1114 d = gcd(inrate, outrate);
1115 inrate /= d;
1116 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001117
Gregory P. Smith9d534572008-06-11 07:41:16 +00001118 alloc_size = sizeof(int) * (unsigned)nchannels;
1119 if (alloc_size < nchannels) {
1120 PyErr_SetString(PyExc_MemoryError,
1121 "not enough memory for output buffer");
1122 return 0;
1123 }
1124 prev_i = (int *) malloc(alloc_size);
1125 cur_i = (int *) malloc(alloc_size);
Anthony Baxter17471432006-03-20 05:58:21 +00001126 if (prev_i == NULL || cur_i == NULL) {
1127 (void) PyErr_NoMemory();
1128 goto exit;
1129 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001130
Anthony Baxter17471432006-03-20 05:58:21 +00001131 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001132
Anthony Baxter17471432006-03-20 05:58:21 +00001133 if (state == Py_None) {
1134 d = -outrate;
1135 for (chan = 0; chan < nchannels; chan++)
1136 prev_i[chan] = cur_i[chan] = 0;
1137 }
1138 else {
1139 if (!PyArg_ParseTuple(state,
1140 "iO!;audioop.ratecv: illegal state argument",
1141 &d, &PyTuple_Type, &samps))
1142 goto exit;
1143 if (PyTuple_Size(samps) != nchannels) {
1144 PyErr_SetString(AudioopError,
1145 "illegal state argument");
1146 goto exit;
1147 }
1148 for (chan = 0; chan < nchannels; chan++) {
1149 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Georg Brandl660222f2006-05-28 22:34:51 +00001150 "ii:ratecv", &prev_i[chan],
1151 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001152 goto exit;
1153 }
1154 }
Tim Peters1691bd92001-12-05 06:05:07 +00001155
Anthony Baxter17471432006-03-20 05:58:21 +00001156 /* str <- Space for the output buffer. */
1157 {
1158 /* There are len input frames, so we need (mathematically)
1159 ceiling(len*outrate/inrate) output frames, and each frame
1160 requires bytes_per_frame bytes. Computing this
1161 without spurious overflow is the challenge; we can
1162 settle for a reasonable upper bound, though. */
1163 int ceiling; /* the number of output frames */
1164 int nbytes; /* the number of output bytes needed */
1165 int q = len / inrate;
1166 /* Now len = q * inrate + r exactly (with r = len % inrate),
1167 and this is less than q * inrate + inrate = (q+1)*inrate.
1168 So a reasonable upper bound on len*outrate/inrate is
1169 ((q+1)*inrate)*outrate/inrate =
1170 (q+1)*outrate.
1171 */
1172 ceiling = (q+1) * outrate;
1173 nbytes = ceiling * bytes_per_frame;
1174 /* See whether anything overflowed; if not, get the space. */
1175 if (q+1 < 0 ||
1176 ceiling / outrate != q+1 ||
1177 nbytes / bytes_per_frame != ceiling)
1178 str = NULL;
1179 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001180 str = PyString_FromStringAndSize(NULL, nbytes);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001181
Anthony Baxter17471432006-03-20 05:58:21 +00001182 if (str == NULL) {
1183 PyErr_SetString(PyExc_MemoryError,
1184 "not enough memory for output buffer");
1185 goto exit;
1186 }
1187 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001188 ncp = PyString_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001189
Anthony Baxter17471432006-03-20 05:58:21 +00001190 for (;;) {
1191 while (d < 0) {
1192 if (len == 0) {
1193 samps = PyTuple_New(nchannels);
1194 if (samps == NULL)
1195 goto exit;
1196 for (chan = 0; chan < nchannels; chan++)
1197 PyTuple_SetItem(samps, chan,
1198 Py_BuildValue("(ii)",
1199 prev_i[chan],
1200 cur_i[chan]));
1201 if (PyErr_Occurred())
1202 goto exit;
1203 /* We have checked before that the length
1204 * of the string fits into int. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001205 len = (int)(ncp - PyString_AsString(str));
Anthony Baxter17471432006-03-20 05:58:21 +00001206 if (len == 0) {
1207 /*don't want to resize to zero length*/
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001208 rv = PyString_FromStringAndSize("", 0);
Anthony Baxter17471432006-03-20 05:58:21 +00001209 Py_DECREF(str);
1210 str = rv;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001211 } else if (_PyString_Resize(&str, len) < 0)
Anthony Baxter17471432006-03-20 05:58:21 +00001212 goto exit;
1213 rv = Py_BuildValue("(O(iO))", str, d, samps);
1214 Py_DECREF(samps);
1215 Py_DECREF(str);
1216 goto exit; /* return rv */
1217 }
1218 for (chan = 0; chan < nchannels; chan++) {
1219 prev_i[chan] = cur_i[chan];
1220 if (size == 1)
1221 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1222 else if (size == 2)
1223 cur_i[chan] = (int)*SHORTP(cp, 0);
1224 else if (size == 4)
1225 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1226 cp += size;
1227 /* implements a simple digital filter */
1228 cur_i[chan] =
1229 (weightA * cur_i[chan] +
1230 weightB * prev_i[chan]) /
1231 (weightA + weightB);
1232 }
1233 len--;
1234 d += outrate;
1235 }
1236 while (d >= 0) {
1237 for (chan = 0; chan < nchannels; chan++) {
1238 cur_o = (prev_i[chan] * d +
1239 cur_i[chan] * (outrate - d)) /
1240 outrate;
1241 if (size == 1)
1242 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1243 else if (size == 2)
1244 *SHORTP(ncp, 0) = (short)(cur_o);
1245 else if (size == 4)
1246 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1247 ncp += size;
1248 }
1249 d -= inrate;
1250 }
1251 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001252 exit:
Anthony Baxter17471432006-03-20 05:58:21 +00001253 if (prev_i != NULL)
1254 free(prev_i);
1255 if (cur_i != NULL)
1256 free(cur_i);
1257 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001258}
Guido van Rossum1851a671997-02-14 16:14:03 +00001259
Roger E. Massec905fff1997-01-17 18:12:04 +00001260static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001261audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001262{
Anthony Baxter17471432006-03-20 05:58:21 +00001263 signed char *cp;
1264 unsigned char *ncp;
1265 int len, size, val = 0;
1266 PyObject *rv;
1267 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001268
Georg Brandl660222f2006-05-28 22:34:51 +00001269 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1270 &cp, &len, &size) )
1271 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001272
Anthony Baxter17471432006-03-20 05:58:21 +00001273 if ( size != 1 && size != 2 && size != 4) {
1274 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1275 return 0;
1276 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001277
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001278 rv = PyString_FromStringAndSize(NULL, len/size);
Anthony Baxter17471432006-03-20 05:58:21 +00001279 if ( rv == 0 )
1280 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001281 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001282
Anthony Baxter17471432006-03-20 05:58:21 +00001283 for ( i=0; i < len; i += size ) {
1284 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1285 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1286 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001287
Anthony Baxter17471432006-03-20 05:58:21 +00001288 *ncp++ = st_14linear2ulaw(val);
1289 }
1290 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001291}
1292
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001293static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001294audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001295{
Anthony Baxter17471432006-03-20 05:58:21 +00001296 unsigned char *cp;
1297 unsigned char cval;
1298 signed char *ncp;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001299 int len, new_len, size, val;
Anthony Baxter17471432006-03-20 05:58:21 +00001300 PyObject *rv;
1301 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302
Georg Brandl660222f2006-05-28 22:34:51 +00001303 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1304 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001305 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001306
Anthony Baxter17471432006-03-20 05:58:21 +00001307 if ( size != 1 && size != 2 && size != 4) {
1308 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1309 return 0;
1310 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001311
Gregory P. Smith9d534572008-06-11 07:41:16 +00001312 new_len = len*size;
1313 if (new_len < 0) {
1314 PyErr_SetString(PyExc_MemoryError,
1315 "not enough memory for output buffer");
1316 return 0;
1317 }
1318 rv = PyString_FromStringAndSize(NULL, new_len);
Anthony Baxter17471432006-03-20 05:58:21 +00001319 if ( rv == 0 )
1320 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001321 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001322
Gregory P. Smith9d534572008-06-11 07:41:16 +00001323 for ( i=0; i < new_len; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001324 cval = *cp++;
1325 val = st_ulaw2linear16(cval);
1326
1327 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1328 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1329 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1330 }
1331 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001332}
1333
1334static PyObject *
1335audioop_lin2alaw(PyObject *self, PyObject *args)
1336{
Anthony Baxter17471432006-03-20 05:58:21 +00001337 signed char *cp;
1338 unsigned char *ncp;
1339 int len, size, val = 0;
1340 PyObject *rv;
1341 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001342
Georg Brandl660222f2006-05-28 22:34:51 +00001343 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1344 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001345 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001346
Anthony Baxter17471432006-03-20 05:58:21 +00001347 if ( size != 1 && size != 2 && size != 4) {
1348 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1349 return 0;
1350 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001351
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001352 rv = PyString_FromStringAndSize(NULL, len/size);
Anthony Baxter17471432006-03-20 05:58:21 +00001353 if ( rv == 0 )
1354 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001355 ncp = (unsigned char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001356
Anthony Baxter17471432006-03-20 05:58:21 +00001357 for ( i=0; i < len; i += size ) {
1358 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1359 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1360 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001361
Anthony Baxter17471432006-03-20 05:58:21 +00001362 *ncp++ = st_linear2alaw(val);
1363 }
1364 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001365}
1366
1367static PyObject *
1368audioop_alaw2lin(PyObject *self, PyObject *args)
1369{
Anthony Baxter17471432006-03-20 05:58:21 +00001370 unsigned char *cp;
1371 unsigned char cval;
1372 signed char *ncp;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001373 int len, new_len, size, val;
Anthony Baxter17471432006-03-20 05:58:21 +00001374 PyObject *rv;
1375 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001376
Georg Brandl660222f2006-05-28 22:34:51 +00001377 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1378 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001379 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001380
Anthony Baxter17471432006-03-20 05:58:21 +00001381 if ( size != 1 && size != 2 && size != 4) {
1382 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1383 return 0;
1384 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001385
Gregory P. Smith9d534572008-06-11 07:41:16 +00001386 new_len = len*size;
1387 if (new_len < 0) {
1388 PyErr_SetString(PyExc_MemoryError,
1389 "not enough memory for output buffer");
1390 return 0;
1391 }
1392 rv = PyString_FromStringAndSize(NULL, new_len);
Anthony Baxter17471432006-03-20 05:58:21 +00001393 if ( rv == 0 )
1394 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001395 ncp = (signed char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001396
Gregory P. Smith9d534572008-06-11 07:41:16 +00001397 for ( i=0; i < new_len; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001398 cval = *cp++;
1399 val = st_alaw2linear16(cval);
1400
1401 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1402 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1403 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1404 }
1405 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001406}
1407
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001408static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001409audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001410{
Anthony Baxter17471432006-03-20 05:58:21 +00001411 signed char *cp;
1412 signed char *ncp;
1413 int len, size, val = 0, step, valpred, delta,
1414 index, sign, vpdiff, diff;
1415 PyObject *rv, *state, *str;
1416 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001417
Georg Brandl660222f2006-05-28 22:34:51 +00001418 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1419 &cp, &len, &size, &state) )
Anthony Baxter17471432006-03-20 05:58:21 +00001420 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001421
1422
Anthony Baxter17471432006-03-20 05:58:21 +00001423 if ( size != 1 && size != 2 && size != 4) {
1424 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1425 return 0;
1426 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001427
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001428 str = PyString_FromStringAndSize(NULL, len/(size*2));
Anthony Baxter17471432006-03-20 05:58:21 +00001429 if ( str == 0 )
1430 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001431 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001432
Anthony Baxter17471432006-03-20 05:58:21 +00001433 /* Decode state, should have (value, step) */
1434 if ( state == Py_None ) {
1435 /* First time, it seems. Set defaults */
1436 valpred = 0;
1437 step = 7;
1438 index = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001439 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Anthony Baxter17471432006-03-20 05:58:21 +00001440 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001441
Anthony Baxter17471432006-03-20 05:58:21 +00001442 step = stepsizeTable[index];
1443 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001444
Anthony Baxter17471432006-03-20 05:58:21 +00001445 for ( i=0; i < len; i += size ) {
1446 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1447 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1448 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001449
Anthony Baxter17471432006-03-20 05:58:21 +00001450 /* Step 1 - compute difference with previous value */
1451 diff = val - valpred;
1452 sign = (diff < 0) ? 8 : 0;
1453 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001454
Anthony Baxter17471432006-03-20 05:58:21 +00001455 /* Step 2 - Divide and clamp */
1456 /* Note:
1457 ** This code *approximately* computes:
1458 ** delta = diff*4/step;
1459 ** vpdiff = (delta+0.5)*step/4;
1460 ** but in shift step bits are dropped. The net result of this
1461 ** is that even if you have fast mul/div hardware you cannot
1462 ** put it to good use since the fixup would be too expensive.
1463 */
1464 delta = 0;
1465 vpdiff = (step >> 3);
1466
1467 if ( diff >= step ) {
1468 delta = 4;
1469 diff -= step;
1470 vpdiff += step;
1471 }
1472 step >>= 1;
1473 if ( diff >= step ) {
1474 delta |= 2;
1475 diff -= step;
1476 vpdiff += step;
1477 }
1478 step >>= 1;
1479 if ( diff >= step ) {
1480 delta |= 1;
1481 vpdiff += step;
1482 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001483
Anthony Baxter17471432006-03-20 05:58:21 +00001484 /* Step 3 - Update previous value */
1485 if ( sign )
1486 valpred -= vpdiff;
1487 else
1488 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001489
Anthony Baxter17471432006-03-20 05:58:21 +00001490 /* Step 4 - Clamp previous value to 16 bits */
1491 if ( valpred > 32767 )
1492 valpred = 32767;
1493 else if ( valpred < -32768 )
1494 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001495
Anthony Baxter17471432006-03-20 05:58:21 +00001496 /* Step 5 - Assemble value, update index and step values */
1497 delta |= sign;
1498
1499 index += indexTable[delta];
1500 if ( index < 0 ) index = 0;
1501 if ( index > 88 ) index = 88;
1502 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001503
Anthony Baxter17471432006-03-20 05:58:21 +00001504 /* Step 6 - Output value */
1505 if ( bufferstep ) {
1506 outputbuffer = (delta << 4) & 0xf0;
1507 } else {
1508 *ncp++ = (delta & 0x0f) | outputbuffer;
1509 }
1510 bufferstep = !bufferstep;
1511 }
1512 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1513 Py_DECREF(str);
1514 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001515}
1516
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001517static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001518audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001519{
Anthony Baxter17471432006-03-20 05:58:21 +00001520 signed char *cp;
1521 signed char *ncp;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001522 int len, new_len, size, valpred, step, delta, index, sign, vpdiff;
Anthony Baxter17471432006-03-20 05:58:21 +00001523 PyObject *rv, *str, *state;
1524 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001525
Georg Brandl660222f2006-05-28 22:34:51 +00001526 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1527 &cp, &len, &size, &state) )
Anthony Baxter17471432006-03-20 05:58:21 +00001528 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001529
Anthony Baxter17471432006-03-20 05:58:21 +00001530 if ( size != 1 && size != 2 && size != 4) {
1531 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1532 return 0;
1533 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001534
Anthony Baxter17471432006-03-20 05:58:21 +00001535 /* Decode state, should have (value, step) */
1536 if ( state == Py_None ) {
1537 /* First time, it seems. Set defaults */
1538 valpred = 0;
1539 step = 7;
1540 index = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001541 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Anthony Baxter17471432006-03-20 05:58:21 +00001542 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001543
Gregory P. Smith9d534572008-06-11 07:41:16 +00001544 new_len = len*size*2;
1545 if (new_len < 0) {
1546 PyErr_SetString(PyExc_MemoryError,
1547 "not enough memory for output buffer");
1548 return 0;
1549 }
1550 str = PyString_FromStringAndSize(NULL, new_len);
Anthony Baxter17471432006-03-20 05:58:21 +00001551 if ( str == 0 )
1552 return 0;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001553 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001554
Anthony Baxter17471432006-03-20 05:58:21 +00001555 step = stepsizeTable[index];
1556 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001557
Gregory P. Smith9d534572008-06-11 07:41:16 +00001558 for ( i=0; i < new_len; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001559 /* Step 1 - get the delta value and compute next index */
1560 if ( bufferstep ) {
1561 delta = inputbuffer & 0xf;
1562 } else {
1563 inputbuffer = *cp++;
1564 delta = (inputbuffer >> 4) & 0xf;
1565 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001566
Anthony Baxter17471432006-03-20 05:58:21 +00001567 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001568
Anthony Baxter17471432006-03-20 05:58:21 +00001569 /* Step 2 - Find new index value (for later) */
1570 index += indexTable[delta];
1571 if ( index < 0 ) index = 0;
1572 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001573
Anthony Baxter17471432006-03-20 05:58:21 +00001574 /* Step 3 - Separate sign and magnitude */
1575 sign = delta & 8;
1576 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001577
Anthony Baxter17471432006-03-20 05:58:21 +00001578 /* Step 4 - Compute difference and new predicted value */
1579 /*
1580 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1581 ** in adpcm_coder.
1582 */
1583 vpdiff = step >> 3;
1584 if ( delta & 4 ) vpdiff += step;
1585 if ( delta & 2 ) vpdiff += step>>1;
1586 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001587
Anthony Baxter17471432006-03-20 05:58:21 +00001588 if ( sign )
1589 valpred -= vpdiff;
1590 else
1591 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001592
Anthony Baxter17471432006-03-20 05:58:21 +00001593 /* Step 5 - clamp output value */
1594 if ( valpred > 32767 )
1595 valpred = 32767;
1596 else if ( valpred < -32768 )
1597 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001598
Anthony Baxter17471432006-03-20 05:58:21 +00001599 /* Step 6 - Update step value */
1600 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001601
Anthony Baxter17471432006-03-20 05:58:21 +00001602 /* Step 6 - Output value */
1603 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1604 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1605 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1606 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001607
Anthony Baxter17471432006-03-20 05:58:21 +00001608 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1609 Py_DECREF(str);
1610 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001611}
1612
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001613static PyMethodDef audioop_methods[] = {
Georg Brandl660222f2006-05-28 22:34:51 +00001614 { "max", audioop_max, METH_VARARGS },
1615 { "minmax", audioop_minmax, METH_VARARGS },
1616 { "avg", audioop_avg, METH_VARARGS },
1617 { "maxpp", audioop_maxpp, METH_VARARGS },
1618 { "avgpp", audioop_avgpp, METH_VARARGS },
1619 { "rms", audioop_rms, METH_VARARGS },
1620 { "findfit", audioop_findfit, METH_VARARGS },
1621 { "findmax", audioop_findmax, METH_VARARGS },
1622 { "findfactor", audioop_findfactor, METH_VARARGS },
1623 { "cross", audioop_cross, METH_VARARGS },
1624 { "mul", audioop_mul, METH_VARARGS },
1625 { "add", audioop_add, METH_VARARGS },
1626 { "bias", audioop_bias, METH_VARARGS },
1627 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1628 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1629 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1630 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1631 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1632 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1633 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1634 { "tomono", audioop_tomono, METH_VARARGS },
1635 { "tostereo", audioop_tostereo, METH_VARARGS },
1636 { "getsample", audioop_getsample, METH_VARARGS },
1637 { "reverse", audioop_reverse, METH_VARARGS },
Anthony Baxter17471432006-03-20 05:58:21 +00001638 { "ratecv", audioop_ratecv, METH_VARARGS },
1639 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001640};
1641
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001642PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001643initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001644{
Anthony Baxter17471432006-03-20 05:58:21 +00001645 PyObject *m, *d;
1646 m = Py_InitModule("audioop", audioop_methods);
1647 if (m == NULL)
1648 return;
1649 d = PyModule_GetDict(m);
Neal Norwitz49c65d02006-03-20 06:34:06 +00001650 if (d == NULL)
1651 return;
Anthony Baxter17471432006-03-20 05:58:21 +00001652 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1653 if (AudioopError != NULL)
1654 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001655}