blob: daf70dcf9cca2390b01a0ec66c84a6410ee77bd5 [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
Mark Dickinson81fece22010-05-11 13:34:35 +00004#define PY_SSIZE_T_CLEAN
5
Roger E. Masseeaa6e111997-01-03 19:26:27 +00006#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00007
Guido van Rossum69011961998-04-23 20:23:00 +00008#if SIZEOF_INT == 4
9typedef int Py_Int32;
10typedef unsigned int Py_UInt32;
11#else
12#if SIZEOF_LONG == 4
13typedef long Py_Int32;
14typedef unsigned long Py_UInt32;
15#else
16#error "No 4-byte integral type"
17#endif
18#endif
19
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000020typedef short PyInt16;
21
Guido van Rossum7b1e9741994-08-29 10:46:42 +000022#if defined(__CHAR_UNSIGNED__)
23#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000024/* This module currently does not work on systems where only unsigned
25 characters are available. Take it out of Setup. Sorry. */
26#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000027#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000028
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000029/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000030** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
31
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032/* From g711.c:
33 *
34 * December 30, 1994:
35 * Functions linear2alaw, linear2ulaw have been updated to correctly
36 * convert unquantized 16 bit values.
37 * Tables for direct u- to A-law and A- to u-law conversions have been
38 * corrected.
39 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
40 * bli@cpk.auc.dk
41 *
42 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000043#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
44#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
46#define QUANT_MASK (0xf) /* Quantization field mask. */
47#define SEG_SHIFT (4) /* Left shift for segment number. */
48#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000049
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000050static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
51 0x1FF, 0x3FF, 0x7FF, 0xFFF};
52static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
53 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
54
55static PyInt16
56search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 for (i = 0; i < size; i++) {
61 if (val <= *table++)
62 return (i);
63 }
64 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000065}
66#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
67#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000068
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069static PyInt16 _st_ulaw2linear16[256] = {
70 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
71 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
72 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
73 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
74 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
75 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
76 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
77 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
78 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
79 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
80 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
81 -1052, -988, -924, -876, -844, -812, -780,
82 -748, -716, -684, -652, -620, -588, -556,
83 -524, -492, -460, -428, -396, -372, -356,
84 -340, -324, -308, -292, -276, -260, -244,
85 -228, -212, -196, -180, -164, -148, -132,
86 -120, -112, -104, -96, -88, -80, -72,
87 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000089 27004, 25980, 24956, 23932, 22908, 21884, 20860,
90 19836, 18812, 17788, 16764, 15996, 15484, 14972,
91 14460, 13948, 13436, 12924, 12412, 11900, 11388,
92 10876, 10364, 9852, 9340, 8828, 8316, 7932,
93 7676, 7420, 7164, 6908, 6652, 6396, 6140,
94 5884, 5628, 5372, 5116, 4860, 4604, 4348,
95 4092, 3900, 3772, 3644, 3516, 3388, 3260,
96 3132, 3004, 2876, 2748, 2620, 2492, 2364,
97 2236, 2108, 1980, 1884, 1820, 1756, 1692,
98 1628, 1564, 1500, 1436, 1372, 1308, 1244,
99 1180, 1116, 1052, 988, 924, 876, 844,
100 812, 780, 748, 716, 684, 652, 620,
101 588, 556, 524, 492, 460, 428, 396,
102 372, 356, 340, 324, 308, 292, 276,
103 260, 244, 228, 212, 196, 180, 164,
104 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 80, 72, 64, 56, 48, 40, 32,
106 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000108
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000109/*
110 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
111 * stored in a unsigned char. This function should only be called with
112 * the data shifted such that it only contains information in the lower
113 * 14-bits.
114 *
115 * In order to simplify the encoding process, the original linear magnitude
116 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
117 * (33 - 8191). The result can be seen in the following encoding table:
118 *
119 * Biased Linear Input Code Compressed Code
120 * ------------------------ ---------------
121 * 00000001wxyza 000wxyz
122 * 0000001wxyzab 001wxyz
123 * 000001wxyzabc 010wxyz
124 * 00001wxyzabcd 011wxyz
125 * 0001wxyzabcde 100wxyz
126 * 001wxyzabcdef 101wxyz
127 * 01wxyzabcdefg 110wxyz
128 * 1wxyzabcdefgh 111wxyz
129 *
130 * Each biased linear code has a leading 1 which identifies the segment
131 * number. The value of the segment number is equal to 7 minus the number
132 * of leading 0's. The quantization interval is directly available as the
133 * four bits wxyz. * The trailing bits (a - h) are ignored.
134 *
135 * Ordinarily the complement of the resulting code word is used for
136 * transmission, and so the code word is complemented before it is returned.
137 *
138 * For further information see John C. Bellamy's Digital Telephony, 1982,
139 * John Wiley & Sons, pps 98-111 and 472-476.
140 */
141static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 PyInt16 mask;
145 PyInt16 seg;
146 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 /* The original sox code does this in the calling function, not here */
149 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 /* u-law inverts all bits */
152 /* Get the sign and the magnitude of the value. */
153 if (pcm_val < 0) {
154 pcm_val = -pcm_val;
155 mask = 0x7F;
156 } else {
157 mask = 0xFF;
158 }
159 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
160 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 /* Convert the scaled magnitude to segment number. */
163 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 /*
166 * Combine the sign, segment, quantization bits;
167 * and complement the code word.
168 */
169 if (seg >= 8) /* out of range, return maximum value. */
170 return (unsigned char) (0x7F ^ mask);
171 else {
172 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
173 return (uval ^ mask);
174 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000175
176}
177
178static PyInt16 _st_alaw2linear16[256] = {
179 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
180 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
181 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
182 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
183 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
184 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
185 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
186 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
187 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
188 -13568, -344, -328, -376, -360, -280, -264,
189 -312, -296, -472, -456, -504, -488, -408,
190 -392, -440, -424, -88, -72, -120, -104,
191 -24, -8, -56, -40, -216, -200, -248,
192 -232, -152, -136, -184, -168, -1376, -1312,
193 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
194 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
195 -688, -656, -752, -720, -560, -528, -624,
196 -592, -944, -912, -1008, -976, -816, -784,
197 -880, -848, 5504, 5248, 6016, 5760, 4480,
198 4224, 4992, 4736, 7552, 7296, 8064, 7808,
199 6528, 6272, 7040, 6784, 2752, 2624, 3008,
200 2880, 2240, 2112, 2496, 2368, 3776, 3648,
201 4032, 3904, 3264, 3136, 3520, 3392, 22016,
202 20992, 24064, 23040, 17920, 16896, 19968, 18944,
203 30208, 29184, 32256, 31232, 26112, 25088, 28160,
204 27136, 11008, 10496, 12032, 11520, 8960, 8448,
205 9984, 9472, 15104, 14592, 16128, 15616, 13056,
206 12544, 14080, 13568, 344, 328, 376, 360,
207 280, 264, 312, 296, 472, 456, 504,
208 488, 408, 392, 440, 424, 88, 72,
209 120, 104, 24, 8, 56, 40, 216,
210 200, 248, 232, 152, 136, 184, 168,
211 1376, 1312, 1504, 1440, 1120, 1056, 1248,
212 1184, 1888, 1824, 2016, 1952, 1632, 1568,
213 1760, 1696, 688, 656, 752, 720, 560,
214 528, 624, 592, 944, 912, 1008, 976,
215 816, 784, 880, 848
216};
217
218/*
219 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
220 * stored in a unsigned char. This function should only be called with
221 * the data shifted such that it only contains information in the lower
222 * 13-bits.
223 *
224 * Linear Input Code Compressed Code
225 * ------------------------ ---------------
226 * 0000000wxyza 000wxyz
227 * 0000001wxyza 001wxyz
228 * 000001wxyzab 010wxyz
229 * 00001wxyzabc 011wxyz
230 * 0001wxyzabcd 100wxyz
231 * 001wxyzabcde 101wxyz
232 * 01wxyzabcdef 110wxyz
233 * 1wxyzabcdefg 111wxyz
234 *
235 * For further information see John C. Bellamy's Digital Telephony, 1982,
236 * John Wiley & Sons, pps 98-111 and 472-476.
237 */
238static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 PyInt16 mask;
242 short seg;
243 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 /* The original sox code does this in the calling function, not here */
246 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 /* A-law using even bit inversion */
249 if (pcm_val >= 0) {
250 mask = 0xD5; /* sign (7th) bit = 1 */
251 } else {
252 mask = 0x55; /* sign bit = 0 */
253 pcm_val = -pcm_val - 1;
254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Convert the scaled magnitude to segment number. */
257 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (seg >= 8) /* out of range, return maximum value. */
262 return (unsigned char) (0x7F ^ mask);
263 else {
264 aval = (unsigned char) seg << SEG_SHIFT;
265 if (seg < 2)
266 aval |= (pcm_val >> 1) & QUANT_MASK;
267 else
268 aval |= (pcm_val >> seg) & QUANT_MASK;
269 return (aval ^ mask);
270 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000271}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000272/* End of code taken from sox */
273
Guido van Rossumb64e6351992-07-06 14:21:56 +0000274/* Intel ADPCM step variation table */
275static int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 -1, -1, -1, -1, 2, 4, 6, 8,
277 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000278};
279
280static int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
282 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
283 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
284 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
285 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
286 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
287 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
288 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
289 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000290};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291
Guido van Rossumb66efa01992-06-01 16:01:24 +0000292#define CHARP(cp, i) ((signed char *)(cp+i))
293#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000294#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000295
296
297
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000298static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000299
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000300static int
301audioop_check_size(int size)
302{
303 if (size != 1 && size != 2 && size != 4) {
304 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
305 return 0;
306 }
307 else
308 return 1;
309}
310
311static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000312audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000313{
314 if (!audioop_check_size(size))
315 return 0;
316 if (len % size != 0) {
317 PyErr_SetString(AudioopError, "not a whole number of frames");
318 return 0;
319 }
320 return 1;
321}
322
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000324audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000327 Py_ssize_t len, i;
328 int size, val = 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000329
Mark Dickinson81fece22010-05-11 13:34:35 +0000330 if ( !PyArg_ParseTuple(args, "s#in:getsample", &cp, &len, &size, &i) )
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000332 if (!audioop_check_parameters(len, size))
333 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 if ( i < 0 || i >= len/size ) {
335 PyErr_SetString(AudioopError, "Index out of range");
336 return 0;
337 }
338 if ( size == 1 ) val = (int)*CHARP(cp, i);
339 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
340 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
341 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000342}
343
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000344static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000345audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000348 Py_ssize_t len, i;
349 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
353 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000354 if (!audioop_check_parameters(len, size))
355 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 for ( i=0; i<len; i+= size) {
357 if ( size == 1 ) val = (int)*CHARP(cp, i);
358 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
359 else if ( size == 4 ) val = (int)*LONGP(cp, i);
360 if ( val < 0 ) val = (-val);
361 if ( val > max ) max = val;
362 }
363 return PyLong_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000364}
365
366static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000367audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000370 Py_ssize_t len, i;
371 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
375 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000376 if (!audioop_check_parameters(len, size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 for (i = 0; i < len; i += size) {
379 if (size == 1) val = (int) *CHARP(cp, i);
380 else if (size == 2) val = (int) *SHORTP(cp, i);
381 else if (size == 4) val = (int) *LONGP(cp, i);
382 if (val > max) max = val;
383 if (val < min) min = val;
384 }
385 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000386}
387
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000388static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000389audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000392 Py_ssize_t len, i;
393 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
397 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000398 if (!audioop_check_parameters(len, size))
399 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 for ( i=0; i<len; i+= size) {
401 if ( size == 1 ) val = (int)*CHARP(cp, i);
402 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
403 else if ( size == 4 ) val = (int)*LONGP(cp, i);
404 avg += val;
405 }
406 if ( len == 0 )
407 val = 0;
408 else
409 val = (int)(avg / (double)(len/size));
410 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000411}
412
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000413static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000414audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000417 Py_ssize_t len, i;
418 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
422 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000423 if (!audioop_check_parameters(len, size))
424 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 for ( i=0; i<len; i+= size) {
426 if ( size == 1 ) val = (int)*CHARP(cp, i);
427 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
428 else if ( size == 4 ) val = (int)*LONGP(cp, i);
429 sum_squares += (double)val*(double)val;
430 }
431 if ( len == 0 )
432 val = 0;
433 else
434 val = (int)sqrt(sum_squares / (double)(len/size));
435 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000436}
437
Mark Dickinson81fece22010-05-11 13:34:35 +0000438static double _sum2(short *a, short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000439{
Mark Dickinson81fece22010-05-11 13:34:35 +0000440 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 for( i=0; i<len; i++) {
444 sum = sum + (double)a[i]*(double)b[i];
445 }
446 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000447}
448
449/*
450** Findfit tries to locate a sample within another sample. Its main use
451** is in echo-cancellation (to find the feedback of the output signal in
452** the input signal).
453** The method used is as follows:
454**
455** let R be the reference signal (length n) and A the input signal (length N)
456** with N > n, and let all sums be over i from 0 to n-1.
457**
458** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
459** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
460** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
461**
462** Next, we compute the relative distance between the original signal and
463** the modified signal and minimize that over j:
464** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
465** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
466**
467** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000468** cp1 A
469** cp2 R
470** len1 N
471** len2 n
472** aj_m1 A[j-1]
473** aj_lm1 A[j+n-1]
474** sum_ri_2 sum(R[i]^2)
475** sum_aij_2 sum(A[i+j]^2)
476** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000477**
478** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
479** is completely recalculated each step.
480*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000481static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000482audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000485 Py_ssize_t len1, len2;
486 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 double aj_m1, aj_lm1;
488 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 /* Passing a short** for an 's' argument is correct only
491 if the string contents is aligned for interpretation
492 as short[]. Due to the definition of PyBytesObject,
493 this is currently (Python 2.6) the case. */
494 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
495 (char**)&cp1, &len1, (char**)&cp2, &len2) )
496 return 0;
497 if ( len1 & 1 || len2 & 1 ) {
498 PyErr_SetString(AudioopError, "Strings should be even-sized");
499 return 0;
500 }
501 len1 >>= 1;
502 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if ( len1 < len2 ) {
505 PyErr_SetString(AudioopError, "First sample should be longer");
506 return 0;
507 }
508 sum_ri_2 = _sum2(cp2, cp2, len2);
509 sum_aij_2 = _sum2(cp1, cp1, len2);
510 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 best_result = result;
515 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 for ( j=1; j<=len1-len2; j++) {
518 aj_m1 = (double)cp1[j-1];
519 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
522 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
525 / sum_aij_2;
526
527 if ( result < best_result ) {
528 best_result = result;
529 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000530 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 }
533
534 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
535
Mark Dickinson81fece22010-05-11 13:34:35 +0000536 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000537}
538
539/*
540** findfactor finds a factor f so that the energy in A-fB is minimal.
541** See the comment for findfit for details.
542*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000543static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000544audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000547 Py_ssize_t len1, len2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
551 (char**)&cp1, &len1, (char**)&cp2, &len2) )
552 return 0;
553 if ( len1 & 1 || len2 & 1 ) {
554 PyErr_SetString(AudioopError, "Strings should be even-sized");
555 return 0;
556 }
557 if ( len1 != len2 ) {
558 PyErr_SetString(AudioopError, "Samples should be same size");
559 return 0;
560 }
561 len2 >>= 1;
562 sum_ri_2 = _sum2(cp2, cp2, len2);
563 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000568}
569
570/*
571** findmax returns the index of the n-sized segment of the input sample
572** that contains the most energy.
573*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000574static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000575audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 short *cp1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000578 Py_ssize_t len1, len2;
579 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 double aj_m1, aj_lm1;
581 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000582
Mark Dickinson81fece22010-05-11 13:34:35 +0000583 if ( !PyArg_ParseTuple(args, "s#n:findmax",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 (char**)&cp1, &len1, &len2) )
585 return 0;
586 if ( len1 & 1 ) {
587 PyErr_SetString(AudioopError, "Strings should be even-sized");
588 return 0;
589 }
590 len1 >>= 1;
591
592 if ( len2 < 0 || len1 < len2 ) {
593 PyErr_SetString(AudioopError, "Input sample should be longer");
594 return 0;
595 }
596
597 result = _sum2(cp1, cp1, len2);
598
599 best_result = result;
600 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601
602 for ( j=1; j<=len1-len2; j++) {
603 aj_m1 = (double)cp1[j-1];
604 aj_lm1 = (double)cp1[j+len2-1];
605
606 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
607
608 if ( result > best_result ) {
609 best_result = result;
610 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000611 }
Jack Jansena90805f1993-02-17 14:29:28 +0000612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614
Mark Dickinson81fece22010-05-11 13:34:35 +0000615 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000616}
617
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000618static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000619audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000622 Py_ssize_t len, i;
623 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 prevextreme = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 double avg = 0.0;
626 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
629 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000630 if (!audioop_check_parameters(len, size))
631 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 /* Compute first delta value ahead. Also automatically makes us
633 ** skip the first extreme value
634 */
635 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
636 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
637 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
638 if ( size == 1 ) val = (int)*CHARP(cp, size);
639 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
640 else if ( size == 4 ) val = (int)*LONGP(cp, size);
641 prevdiff = val - prevval;
642
643 for ( i=size; i<len; i+= size) {
644 if ( size == 1 ) val = (int)*CHARP(cp, i);
645 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
646 else if ( size == 4 ) val = (int)*LONGP(cp, i);
647 diff = val - prevval;
648 if ( diff*prevdiff < 0 ) {
649 /* Derivative changed sign. Compute difference to last
650 ** extreme value and remember.
651 */
652 if ( prevextremevalid ) {
653 extremediff = prevval - prevextreme;
654 if ( extremediff < 0 )
655 extremediff = -extremediff;
656 avg += extremediff;
657 nextreme++;
658 }
659 prevextremevalid = 1;
660 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 prevval = val;
663 if ( diff != 0 )
664 prevdiff = diff;
665 }
666 if ( nextreme == 0 )
667 val = 0;
668 else
669 val = (int)(avg / (double)nextreme);
670 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000671}
672
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000673static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000674audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000677 Py_ssize_t len, i;
678 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 prevextreme = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 int max = 0;
681 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
684 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000685 if (!audioop_check_parameters(len, size))
686 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 /* Compute first delta value ahead. Also automatically makes us
688 ** skip the first extreme value
689 */
690 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
691 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
692 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
693 if ( size == 1 ) val = (int)*CHARP(cp, size);
694 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
695 else if ( size == 4 ) val = (int)*LONGP(cp, size);
696 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 for ( i=size; i<len; i+= size) {
699 if ( size == 1 ) val = (int)*CHARP(cp, i);
700 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
701 else if ( size == 4 ) val = (int)*LONGP(cp, i);
702 diff = val - prevval;
703 if ( diff*prevdiff < 0 ) {
704 /* Derivative changed sign. Compute difference to
705 ** last extreme value and remember.
706 */
707 if ( prevextremevalid ) {
708 extremediff = prevval - prevextreme;
709 if ( extremediff < 0 )
710 extremediff = -extremediff;
711 if ( extremediff > max )
712 max = extremediff;
713 }
714 prevextremevalid = 1;
715 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000716 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 prevval = val;
718 if ( diff != 0 )
719 prevdiff = diff;
720 }
721 return PyLong_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000722}
723
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000724static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000725audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000728 Py_ssize_t len, i;
729 int size, val = 0;
730 int prevval;
731 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
734 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000735 if (!audioop_check_parameters(len, size))
736 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 ncross = -1;
738 prevval = 17; /* Anything <> 0,1 */
739 for ( i=0; i<len; i+= size) {
740 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
741 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
742 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
743 val = val & 1;
744 if ( val != prevval ) ncross++;
745 prevval = val;
746 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000747 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000748}
749
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000750static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000751audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000754 Py_ssize_t len, i;
755 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 double factor, fval, maxval;
757 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
760 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000761 if (!audioop_check_parameters(len, size))
762 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763
764 if ( size == 1 ) maxval = (double) 0x7f;
765 else if ( size == 2 ) maxval = (double) 0x7fff;
766 else if ( size == 4 ) maxval = (double) 0x7fffffff;
767 else {
768 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
769 return 0;
770 }
771
772 rv = PyBytes_FromStringAndSize(NULL, len);
773 if ( rv == 0 )
774 return 0;
775 ncp = (signed char *)PyBytes_AsString(rv);
776
777
778 for ( i=0; i < len; i += size ) {
779 if ( size == 1 ) val = (int)*CHARP(cp, i);
780 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
781 else if ( size == 4 ) val = (int)*LONGP(cp, i);
782 fval = (double)val*factor;
783 if ( fval > maxval ) fval = maxval;
784 else if ( fval < -maxval ) fval = -maxval;
785 val = (int)fval;
786 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
787 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
788 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
789 }
790 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791}
792
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000793static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000794audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 Py_buffer pcp;
797 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000798 Py_ssize_t len, i;
799 int size, val1 = 0, val2 = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 double fac1, fac2, fval, maxval;
801 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
804 &pcp, &size, &fac1, &fac2 ) )
805 return 0;
806 cp = pcp.buf;
807 len = pcp.len;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000808 if (!audioop_check_parameters(len, size)) {
809 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000810 return NULL;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000811 }
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000812 if (((len / size) & 1) != 0) {
813 PyErr_SetString(AudioopError, "not a whole number of frames");
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000814 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000815 return NULL;
816 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817
818 if ( size == 1 ) maxval = (double) 0x7f;
819 else if ( size == 2 ) maxval = (double) 0x7fff;
820 else if ( size == 4 ) maxval = (double) 0x7fffffff;
821 else {
822 PyBuffer_Release(&pcp);
823 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
824 return 0;
825 }
826
827 rv = PyBytes_FromStringAndSize(NULL, len/2);
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000828 if ( rv == 0 ) {
829 PyBuffer_Release(&pcp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 return 0;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000831 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 ncp = (signed char *)PyBytes_AsString(rv);
833
834
835 for ( i=0; i < len; i += size*2 ) {
836 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
837 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
838 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
839 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
840 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
841 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
842 fval = (double)val1*fac1 + (double)val2*fac2;
843 if ( fval > maxval ) fval = maxval;
844 else if ( fval < -maxval ) fval = -maxval;
845 val1 = (int)fval;
846 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
847 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
848 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
849 }
850 PyBuffer_Release(&pcp);
851 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000852}
853
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000854static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000855audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000858 Py_ssize_t len, i;
859 int size, val1, val2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 double fac1, fac2, fval, maxval;
861 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
864 &cp, &len, &size, &fac1, &fac2 ) )
865 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000866 if (!audioop_check_parameters(len, size))
867 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 if ( size == 1 ) maxval = (double) 0x7f;
870 else if ( size == 2 ) maxval = (double) 0x7fff;
871 else if ( size == 4 ) maxval = (double) 0x7fffffff;
872 else {
873 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
874 return 0;
875 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000876
Mark Dickinson81fece22010-05-11 13:34:35 +0000877 if (len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 PyErr_SetString(PyExc_MemoryError,
879 "not enough memory for output buffer");
880 return 0;
881 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000882
Mark Dickinson85eacea2010-05-10 16:27:45 +0000883 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 if ( rv == 0 )
885 return 0;
886 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000887
Guido van Rossumb66efa01992-06-01 16:01:24 +0000888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 for ( i=0; i < len; i += size ) {
890 if ( size == 1 ) val = (int)*CHARP(cp, i);
891 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
892 else if ( size == 4 ) val = (int)*LONGP(cp, i);
893
894 fval = (double)val*fac1;
895 if ( fval > maxval ) fval = maxval;
896 else if ( fval < -maxval ) fval = -maxval;
897 val1 = (int)fval;
898
899 fval = (double)val*fac2;
900 if ( fval > maxval ) fval = maxval;
901 else if ( fval < -maxval ) fval = -maxval;
902 val2 = (int)fval;
903
904 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
905 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
906 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
907
908 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
909 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
910 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
911 }
912 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000913}
914
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000915static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000916audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 signed char *cp1, *cp2, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000919 Py_ssize_t len1, len2, i;
920 int size, val1 = 0, val2 = 0, maxval, newval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 if ( !PyArg_ParseTuple(args, "s#s#i:add",
924 &cp1, &len1, &cp2, &len2, &size ) )
925 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000926 if (!audioop_check_parameters(len1, size))
927 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 if ( len1 != len2 ) {
929 PyErr_SetString(AudioopError, "Lengths should be the same");
930 return 0;
931 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 if ( size == 1 ) maxval = 0x7f;
934 else if ( size == 2 ) maxval = 0x7fff;
935 else if ( size == 4 ) maxval = 0x7fffffff;
936 else {
937 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
938 return 0;
939 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 rv = PyBytes_FromStringAndSize(NULL, len1);
942 if ( rv == 0 )
943 return 0;
944 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 for ( i=0; i < len1; i += size ) {
947 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
948 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
949 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
952 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
953 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
954
955 newval = val1 + val2;
956 /* truncate in case of overflow */
957 if (newval > maxval) newval = maxval;
958 else if (newval < -maxval) newval = -maxval;
959 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
960 newval = val1 > 0 ? maxval : - maxval;
961
962 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
963 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
964 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
965 }
966 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000967}
968
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000969static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000970audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000973 Py_ssize_t len, i;
974 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 PyObject *rv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 if ( !PyArg_ParseTuple(args, "s#ii:bias",
979 &cp, &len, &size , &bias) )
980 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000981
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000982 if (!audioop_check_parameters(len, size))
983 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984
985 rv = PyBytes_FromStringAndSize(NULL, len);
986 if ( rv == 0 )
987 return 0;
988 ncp = (signed char *)PyBytes_AsString(rv);
989
990
991 for ( i=0; i < len; i += size ) {
992 if ( size == 1 ) val = (int)*CHARP(cp, i);
993 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
994 else if ( size == 4 ) val = (int)*LONGP(cp, i);
995
996 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
997 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
998 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
999 }
1000 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001001}
1002
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001003static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001004audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 signed char *cp;
1007 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001008 Py_ssize_t len, i, j;
1009 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1013 &cp, &len, &size) )
1014 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001015
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001016 if (!audioop_check_parameters(len, size))
1017 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 rv = PyBytes_FromStringAndSize(NULL, len);
1020 if ( rv == 0 )
1021 return 0;
1022 ncp = (unsigned char *)PyBytes_AsString(rv);
1023
1024 for ( i=0; i < len; i += size ) {
1025 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1026 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1027 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1028
1029 j = len - i - size;
1030
1031 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1032 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1033 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1034 }
1035 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001036}
1037
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001038static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001039audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001040{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 signed char *cp;
1042 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001043 Py_ssize_t len, i, j;
1044 int size, size2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1048 &cp, &len, &size, &size2) )
1049 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001050
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001051 if (!audioop_check_parameters(len, size))
1052 return NULL;
1053 if (!audioop_check_size(size2))
1054 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001055
Mark Dickinson81fece22010-05-11 13:34:35 +00001056 if (len/size > PY_SSIZE_T_MAX/size2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 PyErr_SetString(PyExc_MemoryError,
1058 "not enough memory for output buffer");
1059 return 0;
1060 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001061 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 if ( rv == 0 )
1063 return 0;
1064 ncp = (unsigned char *)PyBytes_AsString(rv);
1065
1066 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1067 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1068 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1069 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1070
1071 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1072 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1073 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1074 }
1075 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001076}
1077
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001078static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001079gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 while (b > 0) {
1082 int tmp = a % b;
1083 a = b;
1084 b = tmp;
1085 }
1086 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001087}
1088
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001089static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001090audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001091{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001093 Py_ssize_t len;
1094 int size, nchannels, inrate, outrate, weightA, weightB;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 int chan, d, *prev_i, *cur_i, cur_o;
1096 PyObject *state, *samps, *str, *rv = NULL;
1097 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 weightA = 1;
1100 weightB = 0;
1101 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1102 &nchannels, &inrate, &outrate, &state,
1103 &weightA, &weightB))
1104 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001105 if (!audioop_check_size(size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 if (nchannels < 1) {
1108 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1109 return NULL;
1110 }
1111 bytes_per_frame = size * nchannels;
1112 if (bytes_per_frame / nchannels != size) {
1113 /* This overflow test is rigorously correct because
1114 both multiplicands are >= 1. Use the argument names
1115 from the docs for the error msg. */
1116 PyErr_SetString(PyExc_OverflowError,
1117 "width * nchannels too big for a C int");
1118 return NULL;
1119 }
1120 if (weightA < 1 || weightB < 0) {
1121 PyErr_SetString(AudioopError,
1122 "weightA should be >= 1, weightB should be >= 0");
1123 return NULL;
1124 }
1125 if (len % bytes_per_frame != 0) {
1126 PyErr_SetString(AudioopError, "not a whole number of frames");
1127 return NULL;
1128 }
1129 if (inrate <= 0 || outrate <= 0) {
1130 PyErr_SetString(AudioopError, "sampling rate not > 0");
1131 return NULL;
1132 }
1133 /* divide inrate and outrate by their greatest common divisor */
1134 d = gcd(inrate, outrate);
1135 inrate /= d;
1136 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001137
Mark Dickinson85eacea2010-05-10 16:27:45 +00001138 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 PyErr_SetString(PyExc_MemoryError,
1140 "not enough memory for output buffer");
1141 return 0;
1142 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001143 prev_i = (int *) malloc(nchannels * sizeof(int));
1144 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 if (prev_i == NULL || cur_i == NULL) {
1146 (void) PyErr_NoMemory();
1147 goto exit;
1148 }
1149
1150 len /= bytes_per_frame; /* # of frames */
1151
1152 if (state == Py_None) {
1153 d = -outrate;
1154 for (chan = 0; chan < nchannels; chan++)
1155 prev_i[chan] = cur_i[chan] = 0;
1156 }
1157 else {
1158 if (!PyArg_ParseTuple(state,
1159 "iO!;audioop.ratecv: illegal state argument",
1160 &d, &PyTuple_Type, &samps))
1161 goto exit;
1162 if (PyTuple_Size(samps) != nchannels) {
1163 PyErr_SetString(AudioopError,
1164 "illegal state argument");
1165 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001166 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 for (chan = 0; chan < nchannels; chan++) {
1168 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1169 "ii:ratecv", &prev_i[chan],
1170 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001171 goto exit;
1172 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 /* str <- Space for the output buffer. */
1176 {
1177 /* There are len input frames, so we need (mathematically)
1178 ceiling(len*outrate/inrate) output frames, and each frame
1179 requires bytes_per_frame bytes. Computing this
1180 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001181 settle for a reasonable upper bound, though, in this
1182 case ceiling(len/inrate) * outrate. */
1183
1184 /* compute ceiling(len/inrate) without overflow */
Mark Dickinson81fece22010-05-11 13:34:35 +00001185 Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
1186 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 str = NULL;
1188 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001189 str = PyBytes_FromStringAndSize(NULL,
1190 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 if (str == NULL) {
1193 PyErr_SetString(PyExc_MemoryError,
1194 "not enough memory for output buffer");
1195 goto exit;
1196 }
1197 }
1198 ncp = PyBytes_AsString(str);
1199
1200 for (;;) {
1201 while (d < 0) {
1202 if (len == 0) {
1203 samps = PyTuple_New(nchannels);
1204 if (samps == NULL)
1205 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001206 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 PyTuple_SetItem(samps, chan,
1208 Py_BuildValue("(ii)",
1209 prev_i[chan],
1210 cur_i[chan]));
1211 if (PyErr_Occurred())
1212 goto exit;
1213 /* We have checked before that the length
1214 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001215 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 rv = PyBytes_FromStringAndSize
1217 (PyBytes_AsString(str), len);
1218 Py_DECREF(str);
1219 str = rv;
1220 if (str == NULL)
1221 goto exit;
1222 rv = Py_BuildValue("(O(iO))", str, d, samps);
1223 Py_DECREF(samps);
1224 Py_DECREF(str);
1225 goto exit; /* return rv */
1226 }
1227 for (chan = 0; chan < nchannels; chan++) {
1228 prev_i[chan] = cur_i[chan];
1229 if (size == 1)
1230 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1231 else if (size == 2)
1232 cur_i[chan] = (int)*SHORTP(cp, 0);
1233 else if (size == 4)
1234 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1235 cp += size;
1236 /* implements a simple digital filter */
1237 cur_i[chan] =
1238 (weightA * cur_i[chan] +
1239 weightB * prev_i[chan]) /
1240 (weightA + weightB);
1241 }
1242 len--;
1243 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001244 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 while (d >= 0) {
1246 for (chan = 0; chan < nchannels; chan++) {
1247 cur_o = (prev_i[chan] * d +
1248 cur_i[chan] * (outrate - d)) /
1249 outrate;
1250 if (size == 1)
1251 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1252 else if (size == 2)
1253 *SHORTP(ncp, 0) = (short)(cur_o);
1254 else if (size == 4)
1255 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1256 ncp += size;
1257 }
1258 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001259 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001261 exit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 if (prev_i != NULL)
1263 free(prev_i);
1264 if (cur_i != NULL)
1265 free(cur_i);
1266 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001267}
Guido van Rossum1851a671997-02-14 16:14:03 +00001268
Roger E. Massec905fff1997-01-17 18:12:04 +00001269static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001270audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 signed char *cp;
1273 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001274 Py_ssize_t len, i;
1275 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1279 &cp, &len, &size) )
1280 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001281
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001282 if (!audioop_check_parameters(len, size))
1283 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 rv = PyBytes_FromStringAndSize(NULL, len/size);
1286 if ( rv == 0 )
1287 return 0;
1288 ncp = (unsigned char *)PyBytes_AsString(rv);
1289
1290 for ( i=0; i < len; i += size ) {
1291 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1292 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1293 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1294
1295 *ncp++ = st_14linear2ulaw(val);
1296 }
1297 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001298}
1299
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001300static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001301audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 unsigned char *cp;
1304 unsigned char cval;
1305 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001306 Py_ssize_t len, i;
1307 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1311 &cp, &len, &size) )
1312 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001313
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001314 if (!audioop_check_parameters(len, size))
1315 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316
Mark Dickinson81fece22010-05-11 13:34:35 +00001317 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 PyErr_SetString(PyExc_MemoryError,
1319 "not enough memory for output buffer");
1320 return 0;
1321 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001322 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if ( rv == 0 )
1324 return 0;
1325 ncp = (signed char *)PyBytes_AsString(rv);
1326
Mark Dickinson85eacea2010-05-10 16:27:45 +00001327 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 cval = *cp++;
1329 val = st_ulaw2linear16(cval);
1330
1331 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1332 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1333 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1334 }
1335 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001336}
1337
1338static PyObject *
1339audioop_lin2alaw(PyObject *self, PyObject *args)
1340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 signed char *cp;
1342 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001343 Py_ssize_t len, i;
1344 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1348 &cp, &len, &size) )
1349 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001350
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001351 if (!audioop_check_parameters(len, size))
1352 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 rv = PyBytes_FromStringAndSize(NULL, len/size);
1355 if ( rv == 0 )
1356 return 0;
1357 ncp = (unsigned char *)PyBytes_AsString(rv);
1358
1359 for ( i=0; i < len; i += size ) {
1360 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1361 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1362 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1363
1364 *ncp++ = st_linear2alaw(val);
1365 }
1366 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001367}
1368
1369static PyObject *
1370audioop_alaw2lin(PyObject *self, PyObject *args)
1371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 unsigned char *cp;
1373 unsigned char cval;
1374 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001375 Py_ssize_t len, i;
1376 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1380 &cp, &len, &size) )
1381 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001382
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001383 if (!audioop_check_parameters(len, size))
1384 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385
Mark Dickinson81fece22010-05-11 13:34:35 +00001386 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyErr_SetString(PyExc_MemoryError,
1388 "not enough memory for output buffer");
1389 return 0;
1390 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001391 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 if ( rv == 0 )
1393 return 0;
1394 ncp = (signed char *)PyBytes_AsString(rv);
1395
Mark Dickinson85eacea2010-05-10 16:27:45 +00001396 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 cval = *cp++;
1398 val = st_alaw2linear16(cval);
1399
1400 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1401 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1402 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1403 }
1404 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001405}
1406
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001407static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001408audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 signed char *cp;
1411 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001412 Py_ssize_t len, i;
1413 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 index, sign, vpdiff, diff;
1415 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001416 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1419 &cp, &len, &size, &state) )
1420 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001421
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001422 if (!audioop_check_parameters(len, size))
1423 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424
1425 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1426 if ( str == 0 )
1427 return 0;
1428 ncp = (signed char *)PyBytes_AsString(str);
1429
1430 /* Decode state, should have (value, step) */
1431 if ( state == Py_None ) {
1432 /* First time, it seems. Set defaults */
1433 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 index = 0;
1435 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1436 return 0;
1437
1438 step = stepsizeTable[index];
1439 bufferstep = 1;
1440
1441 for ( i=0; i < len; i += size ) {
1442 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1443 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1444 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1445
1446 /* Step 1 - compute difference with previous value */
1447 diff = val - valpred;
1448 sign = (diff < 0) ? 8 : 0;
1449 if ( sign ) diff = (-diff);
1450
1451 /* Step 2 - Divide and clamp */
1452 /* Note:
1453 ** This code *approximately* computes:
1454 ** delta = diff*4/step;
1455 ** vpdiff = (delta+0.5)*step/4;
1456 ** but in shift step bits are dropped. The net result of this
1457 ** is that even if you have fast mul/div hardware you cannot
1458 ** put it to good use since the fixup would be too expensive.
1459 */
1460 delta = 0;
1461 vpdiff = (step >> 3);
1462
1463 if ( diff >= step ) {
1464 delta = 4;
1465 diff -= step;
1466 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001467 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 step >>= 1;
1469 if ( diff >= step ) {
1470 delta |= 2;
1471 diff -= step;
1472 vpdiff += step;
1473 }
1474 step >>= 1;
1475 if ( diff >= step ) {
1476 delta |= 1;
1477 vpdiff += step;
1478 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 /* Step 3 - Update previous value */
1481 if ( sign )
1482 valpred -= vpdiff;
1483 else
1484 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 /* Step 4 - Clamp previous value to 16 bits */
1487 if ( valpred > 32767 )
1488 valpred = 32767;
1489 else if ( valpred < -32768 )
1490 valpred = -32768;
1491
1492 /* Step 5 - Assemble value, update index and step values */
1493 delta |= sign;
1494
1495 index += indexTable[delta];
1496 if ( index < 0 ) index = 0;
1497 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001498 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 /* Step 6 - Output value */
1501 if ( bufferstep ) {
1502 outputbuffer = (delta << 4) & 0xf0;
1503 } else {
1504 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001505 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 bufferstep = !bufferstep;
1507 }
1508 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1509 Py_DECREF(str);
1510 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001511}
1512
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001513static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001514audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 signed char *cp;
1517 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001518 Py_ssize_t len, i;
1519 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001521 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1524 &cp, &len, &size, &state) )
1525 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001526
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001527 if (!audioop_check_parameters(len, size))
1528 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529
1530 /* Decode state, should have (value, step) */
1531 if ( state == Py_None ) {
1532 /* First time, it seems. Set defaults */
1533 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 index = 0;
1535 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1536 return 0;
1537
Mark Dickinson81fece22010-05-11 13:34:35 +00001538 if (len > (PY_SSIZE_T_MAX/2)/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 PyErr_SetString(PyExc_MemoryError,
1540 "not enough memory for output buffer");
1541 return 0;
1542 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001543 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 if ( str == 0 )
1545 return 0;
1546 ncp = (signed char *)PyBytes_AsString(str);
1547
1548 step = stepsizeTable[index];
1549 bufferstep = 0;
1550
Mark Dickinson85eacea2010-05-10 16:27:45 +00001551 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 /* Step 1 - get the delta value and compute next index */
1553 if ( bufferstep ) {
1554 delta = inputbuffer & 0xf;
1555 } else {
1556 inputbuffer = *cp++;
1557 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001558 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 bufferstep = !bufferstep;
1561
1562 /* Step 2 - Find new index value (for later) */
1563 index += indexTable[delta];
1564 if ( index < 0 ) index = 0;
1565 if ( index > 88 ) index = 88;
1566
1567 /* Step 3 - Separate sign and magnitude */
1568 sign = delta & 8;
1569 delta = delta & 7;
1570
1571 /* Step 4 - Compute difference and new predicted value */
1572 /*
1573 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1574 ** in adpcm_coder.
1575 */
1576 vpdiff = step >> 3;
1577 if ( delta & 4 ) vpdiff += step;
1578 if ( delta & 2 ) vpdiff += step>>1;
1579 if ( delta & 1 ) vpdiff += step>>2;
1580
1581 if ( sign )
1582 valpred -= vpdiff;
1583 else
1584 valpred += vpdiff;
1585
1586 /* Step 5 - clamp output value */
1587 if ( valpred > 32767 )
1588 valpred = 32767;
1589 else if ( valpred < -32768 )
1590 valpred = -32768;
1591
1592 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001593 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 /* Step 6 - Output value */
1596 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1597 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1598 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1599 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1602 Py_DECREF(str);
1603 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001604}
1605
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001606static PyMethodDef audioop_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 { "max", audioop_max, METH_VARARGS },
1608 { "minmax", audioop_minmax, METH_VARARGS },
1609 { "avg", audioop_avg, METH_VARARGS },
1610 { "maxpp", audioop_maxpp, METH_VARARGS },
1611 { "avgpp", audioop_avgpp, METH_VARARGS },
1612 { "rms", audioop_rms, METH_VARARGS },
1613 { "findfit", audioop_findfit, METH_VARARGS },
1614 { "findmax", audioop_findmax, METH_VARARGS },
1615 { "findfactor", audioop_findfactor, METH_VARARGS },
1616 { "cross", audioop_cross, METH_VARARGS },
1617 { "mul", audioop_mul, METH_VARARGS },
1618 { "add", audioop_add, METH_VARARGS },
1619 { "bias", audioop_bias, METH_VARARGS },
1620 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1621 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1622 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1623 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1624 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1625 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1626 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1627 { "tomono", audioop_tomono, METH_VARARGS },
1628 { "tostereo", audioop_tostereo, METH_VARARGS },
1629 { "getsample", audioop_getsample, METH_VARARGS },
1630 { "reverse", audioop_reverse, METH_VARARGS },
1631 { "ratecv", audioop_ratecv, METH_VARARGS },
1632 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001633};
1634
Martin v. Löwis1a214512008-06-11 05:26:20 +00001635
1636static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 PyModuleDef_HEAD_INIT,
1638 "audioop",
1639 NULL,
1640 -1,
1641 audioop_methods,
1642 NULL,
1643 NULL,
1644 NULL,
1645 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001646};
1647
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001648PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001649PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 PyObject *m, *d;
1652 m = PyModule_Create(&audioopmodule);
1653 if (m == NULL)
1654 return NULL;
1655 d = PyModule_GetDict(m);
1656 if (d == NULL)
1657 return NULL;
1658 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1659 if (AudioopError != NULL)
1660 PyDict_SetItemString(d,"error",AudioopError);
1661 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001662}