blob: 3f047623ebb25a851568b3df3a60545732cf85e3 [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
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020029static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
Tim Golden63741202013-10-31 17:38:24 +000030/* -1 trick is needed on Windows to support -0x80000000 without a warning */
31static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
Serhiy Storchaka01ad6222013-02-09 11:10:53 +020032static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
33
34static int
35fbound(double val, double minval, double maxval)
36{
37 if (val > maxval)
38 val = maxval;
39 else if (val < minval + 1)
40 val = minval;
41 return val;
42}
43
44
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000046** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
47
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048/* From g711.c:
49 *
50 * December 30, 1994:
51 * Functions linear2alaw, linear2ulaw have been updated to correctly
52 * convert unquantized 16 bit values.
53 * Tables for direct u- to A-law and A- to u-law conversions have been
54 * corrected.
55 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
56 * bli@cpk.auc.dk
57 *
58 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000059#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
60#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000061#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
62#define QUANT_MASK (0xf) /* Quantization field mask. */
63#define SEG_SHIFT (4) /* Left shift for segment number. */
64#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000065
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000066static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
67 0x1FF, 0x3FF, 0x7FF, 0xFFF};
68static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
69 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
70
71static PyInt16
72search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 for (i = 0; i < size; i++) {
77 if (val <= *table++)
78 return (i);
79 }
80 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000081}
82#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
83#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000084
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000085static PyInt16 _st_ulaw2linear16[256] = {
86 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
87 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
88 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
89 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
90 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
91 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
92 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
93 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
94 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
95 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
96 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
97 -1052, -988, -924, -876, -844, -812, -780,
98 -748, -716, -684, -652, -620, -588, -556,
99 -524, -492, -460, -428, -396, -372, -356,
100 -340, -324, -308, -292, -276, -260, -244,
101 -228, -212, -196, -180, -164, -148, -132,
102 -120, -112, -104, -96, -88, -80, -72,
103 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000105 27004, 25980, 24956, 23932, 22908, 21884, 20860,
106 19836, 18812, 17788, 16764, 15996, 15484, 14972,
107 14460, 13948, 13436, 12924, 12412, 11900, 11388,
108 10876, 10364, 9852, 9340, 8828, 8316, 7932,
109 7676, 7420, 7164, 6908, 6652, 6396, 6140,
110 5884, 5628, 5372, 5116, 4860, 4604, 4348,
111 4092, 3900, 3772, 3644, 3516, 3388, 3260,
112 3132, 3004, 2876, 2748, 2620, 2492, 2364,
113 2236, 2108, 1980, 1884, 1820, 1756, 1692,
114 1628, 1564, 1500, 1436, 1372, 1308, 1244,
115 1180, 1116, 1052, 988, 924, 876, 844,
116 812, 780, 748, 716, 684, 652, 620,
117 588, 556, 524, 492, 460, 428, 396,
118 372, 356, 340, 324, 308, 292, 276,
119 260, 244, 228, 212, 196, 180, 164,
120 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 80, 72, 64, 56, 48, 40, 32,
122 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000123};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000124
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000125/*
126 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
127 * stored in a unsigned char. This function should only be called with
128 * the data shifted such that it only contains information in the lower
129 * 14-bits.
130 *
131 * In order to simplify the encoding process, the original linear magnitude
132 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
133 * (33 - 8191). The result can be seen in the following encoding table:
134 *
135 * Biased Linear Input Code Compressed Code
136 * ------------------------ ---------------
137 * 00000001wxyza 000wxyz
138 * 0000001wxyzab 001wxyz
139 * 000001wxyzabc 010wxyz
140 * 00001wxyzabcd 011wxyz
141 * 0001wxyzabcde 100wxyz
142 * 001wxyzabcdef 101wxyz
143 * 01wxyzabcdefg 110wxyz
144 * 1wxyzabcdefgh 111wxyz
145 *
146 * Each biased linear code has a leading 1 which identifies the segment
147 * number. The value of the segment number is equal to 7 minus the number
148 * of leading 0's. The quantization interval is directly available as the
149 * four bits wxyz. * The trailing bits (a - h) are ignored.
150 *
151 * Ordinarily the complement of the resulting code word is used for
152 * transmission, and so the code word is complemented before it is returned.
153 *
154 * For further information see John C. Bellamy's Digital Telephony, 1982,
155 * John Wiley & Sons, pps 98-111 and 472-476.
156 */
157static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 PyInt16 mask;
161 PyInt16 seg;
162 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 /* The original sox code does this in the calling function, not here */
165 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 /* u-law inverts all bits */
168 /* Get the sign and the magnitude of the value. */
169 if (pcm_val < 0) {
170 pcm_val = -pcm_val;
171 mask = 0x7F;
172 } else {
173 mask = 0xFF;
174 }
175 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
176 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 /* Convert the scaled magnitude to segment number. */
179 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 /*
182 * Combine the sign, segment, quantization bits;
183 * and complement the code word.
184 */
185 if (seg >= 8) /* out of range, return maximum value. */
186 return (unsigned char) (0x7F ^ mask);
187 else {
188 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
189 return (uval ^ mask);
190 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000191
192}
193
194static PyInt16 _st_alaw2linear16[256] = {
195 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
196 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
197 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
198 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
199 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
200 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
201 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
202 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
203 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
204 -13568, -344, -328, -376, -360, -280, -264,
205 -312, -296, -472, -456, -504, -488, -408,
206 -392, -440, -424, -88, -72, -120, -104,
207 -24, -8, -56, -40, -216, -200, -248,
208 -232, -152, -136, -184, -168, -1376, -1312,
209 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
210 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
211 -688, -656, -752, -720, -560, -528, -624,
212 -592, -944, -912, -1008, -976, -816, -784,
213 -880, -848, 5504, 5248, 6016, 5760, 4480,
214 4224, 4992, 4736, 7552, 7296, 8064, 7808,
215 6528, 6272, 7040, 6784, 2752, 2624, 3008,
216 2880, 2240, 2112, 2496, 2368, 3776, 3648,
217 4032, 3904, 3264, 3136, 3520, 3392, 22016,
218 20992, 24064, 23040, 17920, 16896, 19968, 18944,
219 30208, 29184, 32256, 31232, 26112, 25088, 28160,
220 27136, 11008, 10496, 12032, 11520, 8960, 8448,
221 9984, 9472, 15104, 14592, 16128, 15616, 13056,
222 12544, 14080, 13568, 344, 328, 376, 360,
223 280, 264, 312, 296, 472, 456, 504,
224 488, 408, 392, 440, 424, 88, 72,
225 120, 104, 24, 8, 56, 40, 216,
226 200, 248, 232, 152, 136, 184, 168,
227 1376, 1312, 1504, 1440, 1120, 1056, 1248,
228 1184, 1888, 1824, 2016, 1952, 1632, 1568,
229 1760, 1696, 688, 656, 752, 720, 560,
230 528, 624, 592, 944, 912, 1008, 976,
231 816, 784, 880, 848
232};
233
234/*
235 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
236 * stored in a unsigned char. This function should only be called with
237 * the data shifted such that it only contains information in the lower
238 * 13-bits.
239 *
240 * Linear Input Code Compressed Code
241 * ------------------------ ---------------
242 * 0000000wxyza 000wxyz
243 * 0000001wxyza 001wxyz
244 * 000001wxyzab 010wxyz
245 * 00001wxyzabc 011wxyz
246 * 0001wxyzabcd 100wxyz
247 * 001wxyzabcde 101wxyz
248 * 01wxyzabcdef 110wxyz
249 * 1wxyzabcdefg 111wxyz
250 *
251 * For further information see John C. Bellamy's Digital Telephony, 1982,
252 * John Wiley & Sons, pps 98-111 and 472-476.
253 */
254static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 PyInt16 mask;
258 short seg;
259 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 /* The original sox code does this in the calling function, not here */
262 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 /* A-law using even bit inversion */
265 if (pcm_val >= 0) {
266 mask = 0xD5; /* sign (7th) bit = 1 */
267 } else {
268 mask = 0x55; /* sign bit = 0 */
269 pcm_val = -pcm_val - 1;
270 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 /* Convert the scaled magnitude to segment number. */
273 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 if (seg >= 8) /* out of range, return maximum value. */
278 return (unsigned char) (0x7F ^ mask);
279 else {
280 aval = (unsigned char) seg << SEG_SHIFT;
281 if (seg < 2)
282 aval |= (pcm_val >> 1) & QUANT_MASK;
283 else
284 aval |= (pcm_val >> seg) & QUANT_MASK;
285 return (aval ^ mask);
286 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000287}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000288/* End of code taken from sox */
289
Guido van Rossumb64e6351992-07-06 14:21:56 +0000290/* Intel ADPCM step variation table */
291static int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 -1, -1, -1, -1, 2, 4, 6, 8,
293 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000294};
295
296static int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
298 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
299 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
300 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
301 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
302 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
303 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
304 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
305 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000306};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307
Guido van Rossumb66efa01992-06-01 16:01:24 +0000308#define CHARP(cp, i) ((signed char *)(cp+i))
309#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000310#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000311
312
313
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000314static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000315
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000316static int
317audioop_check_size(int size)
318{
319 if (size != 1 && size != 2 && size != 4) {
320 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
321 return 0;
322 }
323 else
324 return 1;
325}
326
327static int
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000328audioop_check_parameters(Py_ssize_t len, int size)
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000329{
330 if (!audioop_check_size(size))
331 return 0;
332 if (len % size != 0) {
333 PyErr_SetString(AudioopError, "not a whole number of frames");
334 return 0;
335 }
336 return 1;
337}
338
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000339static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000340audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000343 Py_ssize_t len, i;
344 int size, val = 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000345
Mark Dickinson81fece22010-05-11 13:34:35 +0000346 if ( !PyArg_ParseTuple(args, "s#in:getsample", &cp, &len, &size, &i) )
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000348 if (!audioop_check_parameters(len, size))
349 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 if ( i < 0 || i >= len/size ) {
351 PyErr_SetString(AudioopError, "Index out of range");
352 return 0;
353 }
354 if ( size == 1 ) val = (int)*CHARP(cp, i);
355 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
356 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
357 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000358}
359
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000360static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000361audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000364 Py_ssize_t len, i;
365 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200366 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
369 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000370 if (!audioop_check_parameters(len, size))
371 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 for ( i=0; i<len; i+= size) {
373 if ( size == 1 ) val = (int)*CHARP(cp, i);
374 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
375 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200376 if (val < 0) absval = (-val);
377 else absval = val;
378 if (absval > max) max = absval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200380 return PyLong_FromUnsignedLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000381}
382
383static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000384audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000387 Py_ssize_t len, i;
388 int size, val = 0;
Tim Golden63741202013-10-31 17:38:24 +0000389 /* -1 trick below is needed on Windows to support -0x80000000 without
390 a warning */
391 int min = 0x7fffffff, max = -0x7FFFFFFF-1;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
394 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000395 if (!audioop_check_parameters(len, size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 for (i = 0; i < len; i += size) {
398 if (size == 1) val = (int) *CHARP(cp, i);
399 else if (size == 2) val = (int) *SHORTP(cp, i);
400 else if (size == 4) val = (int) *LONGP(cp, i);
401 if (val > max) max = val;
402 if (val < min) min = val;
403 }
404 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000405}
406
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000408audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000411 Py_ssize_t len, i;
412 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
416 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000417 if (!audioop_check_parameters(len, size))
418 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 for ( i=0; i<len; i+= size) {
420 if ( size == 1 ) val = (int)*CHARP(cp, i);
421 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
422 else if ( size == 4 ) val = (int)*LONGP(cp, i);
423 avg += val;
424 }
425 if ( len == 0 )
426 val = 0;
427 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200428 val = (int)floor(avg / (double)(len/size));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000430}
431
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000432static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000433audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000436 Py_ssize_t len, i;
437 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200438 unsigned int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
442 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000443 if (!audioop_check_parameters(len, size))
444 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 for ( i=0; i<len; i+= size) {
446 if ( size == 1 ) val = (int)*CHARP(cp, i);
447 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
448 else if ( size == 4 ) val = (int)*LONGP(cp, i);
449 sum_squares += (double)val*(double)val;
450 }
451 if ( len == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200452 res = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200454 res = (unsigned int)sqrt(sum_squares / (double)(len/size));
455 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000456}
457
Mark Dickinson81fece22010-05-11 13:34:35 +0000458static double _sum2(short *a, short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000459{
Mark Dickinson81fece22010-05-11 13:34:35 +0000460 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 for( i=0; i<len; i++) {
464 sum = sum + (double)a[i]*(double)b[i];
465 }
466 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000467}
468
469/*
470** Findfit tries to locate a sample within another sample. Its main use
471** is in echo-cancellation (to find the feedback of the output signal in
472** the input signal).
473** The method used is as follows:
474**
475** let R be the reference signal (length n) and A the input signal (length N)
476** with N > n, and let all sums be over i from 0 to n-1.
477**
478** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
479** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
480** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
481**
482** Next, we compute the relative distance between the original signal and
483** the modified signal and minimize that over j:
484** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
485** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
486**
487** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000488** cp1 A
489** cp2 R
490** len1 N
491** len2 n
492** aj_m1 A[j-1]
493** aj_lm1 A[j+n-1]
494** sum_ri_2 sum(R[i]^2)
495** sum_aij_2 sum(A[i+j]^2)
496** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000497**
498** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
499** is completely recalculated each step.
500*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000501static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000502audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000505 Py_ssize_t len1, len2;
506 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 double aj_m1, aj_lm1;
508 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 /* Passing a short** for an 's' argument is correct only
511 if the string contents is aligned for interpretation
512 as short[]. Due to the definition of PyBytesObject,
513 this is currently (Python 2.6) the case. */
514 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
515 (char**)&cp1, &len1, (char**)&cp2, &len2) )
516 return 0;
517 if ( len1 & 1 || len2 & 1 ) {
518 PyErr_SetString(AudioopError, "Strings should be even-sized");
519 return 0;
520 }
521 len1 >>= 1;
522 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 if ( len1 < len2 ) {
525 PyErr_SetString(AudioopError, "First sample should be longer");
526 return 0;
527 }
528 sum_ri_2 = _sum2(cp2, cp2, len2);
529 sum_aij_2 = _sum2(cp1, cp1, len2);
530 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 best_result = result;
535 best_j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 for ( j=1; j<=len1-len2; j++) {
538 aj_m1 = (double)cp1[j-1];
539 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
542 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
545 / sum_aij_2;
546
547 if ( result < best_result ) {
548 best_result = result;
549 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000550 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 }
553
554 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
555
Mark Dickinson81fece22010-05-11 13:34:35 +0000556 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000557}
558
559/*
560** findfactor finds a factor f so that the energy in A-fB is minimal.
561** See the comment for findfit for details.
562*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000563static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000564audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000567 Py_ssize_t len1, len2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
571 (char**)&cp1, &len1, (char**)&cp2, &len2) )
572 return 0;
573 if ( len1 & 1 || len2 & 1 ) {
574 PyErr_SetString(AudioopError, "Strings should be even-sized");
575 return 0;
576 }
577 if ( len1 != len2 ) {
578 PyErr_SetString(AudioopError, "Samples should be same size");
579 return 0;
580 }
581 len2 >>= 1;
582 sum_ri_2 = _sum2(cp2, cp2, len2);
583 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000588}
589
590/*
591** findmax returns the index of the n-sized segment of the input sample
592** that contains the most energy.
593*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000594static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000595audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 short *cp1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000598 Py_ssize_t len1, len2;
599 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 double aj_m1, aj_lm1;
601 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000602
Mark Dickinson81fece22010-05-11 13:34:35 +0000603 if ( !PyArg_ParseTuple(args, "s#n:findmax",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 (char**)&cp1, &len1, &len2) )
605 return 0;
606 if ( len1 & 1 ) {
607 PyErr_SetString(AudioopError, "Strings should be even-sized");
608 return 0;
609 }
610 len1 >>= 1;
611
612 if ( len2 < 0 || len1 < len2 ) {
613 PyErr_SetString(AudioopError, "Input sample should be longer");
614 return 0;
615 }
616
617 result = _sum2(cp1, cp1, len2);
618
619 best_result = result;
620 best_j = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621
622 for ( j=1; j<=len1-len2; j++) {
623 aj_m1 = (double)cp1[j-1];
624 aj_lm1 = (double)cp1[j+len2-1];
625
626 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
627
628 if ( result > best_result ) {
629 best_result = result;
630 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000631 }
Jack Jansena90805f1993-02-17 14:29:28 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000634
Mark Dickinson81fece22010-05-11 13:34:35 +0000635 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000636}
637
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000638static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000639audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000642 Py_ssize_t len, i;
643 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200645 double sum = 0.0;
646 unsigned int avg;
647 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
650 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000651 if (!audioop_check_parameters(len, size))
652 return NULL;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200653 if (len <= size)
654 return PyLong_FromLong(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
656 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
657 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200658 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 for ( i=size; i<len; i+= size) {
660 if ( size == 1 ) val = (int)*CHARP(cp, i);
661 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
662 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200663 if (val != prevval) {
664 diff = val < prevval;
665 if (prevdiff == !diff) {
666 /* Derivative changed sign. Compute difference to last
667 ** extreme value and remember.
668 */
669 if (prevextremevalid) {
670 sum += fabs((double)prevval - (double)prevextreme);
671 nextreme++;
672 }
673 prevextremevalid = 1;
674 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200676 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200678 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 }
680 if ( nextreme == 0 )
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200681 avg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 else
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200683 avg = (unsigned int)(sum / (double)nextreme);
684 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000685}
686
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000687static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000688audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000691 Py_ssize_t len, i;
692 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 prevextreme = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200694 unsigned int max = 0, extremediff;
695 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
698 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000699 if (!audioop_check_parameters(len, size))
700 return NULL;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200701 if (len <= size)
702 return PyLong_FromLong(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
704 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
705 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200706 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 for ( i=size; i<len; i+= size) {
708 if ( size == 1 ) val = (int)*CHARP(cp, i);
709 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
710 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200711 if (val != prevval) {
712 diff = val < prevval;
713 if (prevdiff == !diff) {
714 /* Derivative changed sign. Compute difference to
715 ** last extreme value and remember.
716 */
717 if (prevextremevalid) {
718 if (prevval < prevextreme)
719 extremediff = (unsigned int)prevextreme -
720 (unsigned int)prevval;
721 else
722 extremediff = (unsigned int)prevval -
723 (unsigned int)prevextreme;
724 if ( extremediff > max )
725 max = extremediff;
726 }
727 prevextremevalid = 1;
728 prevextreme = prevval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200730 prevval = val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 prevdiff = diff;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200732 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 }
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200734 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000735}
736
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000738audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000741 Py_ssize_t len, i;
742 int size, val = 0;
743 int prevval;
744 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
747 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000748 if (!audioop_check_parameters(len, size))
749 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 ncross = -1;
751 prevval = 17; /* Anything <> 0,1 */
752 for ( i=0; i<len; i+= size) {
753 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
754 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
755 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
756 val = val & 1;
757 if ( val != prevval ) ncross++;
758 prevval = val;
759 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000760 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761}
762
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000763static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000764audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000767 Py_ssize_t len, i;
768 int size, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200769 double factor, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
773 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000774 if (!audioop_check_parameters(len, size))
775 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200777 maxval = (double) maxvals[size];
778 minval = (double) minvals[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779
780 rv = PyBytes_FromStringAndSize(NULL, len);
781 if ( rv == 0 )
782 return 0;
783 ncp = (signed char *)PyBytes_AsString(rv);
784
785
786 for ( i=0; i < len; i += size ) {
787 if ( size == 1 ) val = (int)*CHARP(cp, i);
788 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
789 else if ( size == 4 ) val = (int)*LONGP(cp, i);
790 fval = (double)val*factor;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200791 val = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
793 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
794 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
795 }
796 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000797}
798
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000799static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000800audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 Py_buffer pcp;
803 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000804 Py_ssize_t len, i;
805 int size, val1 = 0, val2 = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200806 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
810 &pcp, &size, &fac1, &fac2 ) )
811 return 0;
812 cp = pcp.buf;
813 len = pcp.len;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000814 if (!audioop_check_parameters(len, size)) {
815 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000816 return NULL;
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000817 }
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000818 if (((len / size) & 1) != 0) {
819 PyErr_SetString(AudioopError, "not a whole number of frames");
Mark Dickinsoncc588c12010-07-04 10:15:11 +0000820 PyBuffer_Release(&pcp);
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000821 return NULL;
822 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200824 maxval = (double) maxvals[size];
825 minval = (double) minvals[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826
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;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200843 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
845 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
846 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
847 }
848 PyBuffer_Release(&pcp);
849 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000850}
851
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000852static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000853audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000856 Py_ssize_t len, i;
857 int size, val1, val2, val = 0;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200858 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
862 &cp, &len, &size, &fac1, &fac2 ) )
863 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000864 if (!audioop_check_parameters(len, size))
865 return NULL;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000866
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200867 maxval = (double) maxvals[size];
868 minval = (double) minvals[size];
Guido van Rossumb66efa01992-06-01 16:01:24 +0000869
Mark Dickinson81fece22010-05-11 13:34:35 +0000870 if (len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 PyErr_SetString(PyExc_MemoryError,
872 "not enough memory for output buffer");
873 return 0;
874 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000875
Mark Dickinson85eacea2010-05-10 16:27:45 +0000876 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 if ( rv == 0 )
878 return 0;
879 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880
Guido van Rossumb66efa01992-06-01 16:01:24 +0000881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 for ( i=0; i < len; i += size ) {
883 if ( size == 1 ) val = (int)*CHARP(cp, i);
884 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
885 else if ( size == 4 ) val = (int)*LONGP(cp, i);
886
887 fval = (double)val*fac1;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200888 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889
890 fval = (double)val*fac2;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200891 val2 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892
893 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
894 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
895 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
896
897 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
898 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
899 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
900 }
901 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000902}
903
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000904static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000905audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 signed char *cp1, *cp2, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000908 Py_ssize_t len1, len2, i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200909 int size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 if ( !PyArg_ParseTuple(args, "s#s#i:add",
913 &cp1, &len1, &cp2, &len2, &size ) )
914 return 0;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000915 if (!audioop_check_parameters(len1, size))
916 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 if ( len1 != len2 ) {
918 PyErr_SetString(AudioopError, "Lengths should be the same");
919 return 0;
920 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200922 maxval = maxvals[size];
923 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 rv = PyBytes_FromStringAndSize(NULL, len1);
926 if ( rv == 0 )
927 return 0;
928 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 for ( i=0; i < len1; i += size ) {
931 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
932 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
933 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
936 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
937 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
938
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200939 if (size < 4) {
940 newval = val1 + val2;
941 /* truncate in case of overflow */
942 if (newval > maxval)
943 newval = maxval;
944 else if (newval < minval)
945 newval = minval;
946 }
947 else {
948 double fval = (double)val1 + (double)val2;
949 /* truncate in case of overflow */
950 newval = (int)floor(fbound(fval, minval, maxval));
951 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952
953 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
954 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
955 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
956 }
957 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000958}
959
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000960static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000961audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000964 Py_ssize_t len, i;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200965 int size, bias;
966 unsigned int val = 0, mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 if ( !PyArg_ParseTuple(args, "s#ii:bias",
970 &cp, &len, &size , &bias) )
971 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000972
Victor Stinnerbc5c54b2010-07-03 13:44:22 +0000973 if (!audioop_check_parameters(len, size))
974 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975
976 rv = PyBytes_FromStringAndSize(NULL, len);
977 if ( rv == 0 )
978 return 0;
979 ncp = (signed char *)PyBytes_AsString(rv);
980
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200981 mask = masks[size];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982
983 for ( i=0; i < len; i += size ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200984 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
985 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
986 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987
Serhiy Storchaka01ad6222013-02-09 11:10:53 +0200988 val += (unsigned int)bias;
989 /* wrap around in case of overflow */
990 val &= mask;
991
992 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
993 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
994 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 }
996 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000997}
998
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000999static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001000audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +00001001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 signed char *cp;
1003 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001004 Py_ssize_t len, i, j;
1005 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1009 &cp, &len, &size) )
1010 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001011
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001012 if (!audioop_check_parameters(len, size))
1013 return NULL;
Jack Jansen337b20e1993-02-23 13:39:57 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 rv = PyBytes_FromStringAndSize(NULL, len);
1016 if ( rv == 0 )
1017 return 0;
1018 ncp = (unsigned char *)PyBytes_AsString(rv);
1019
1020 for ( i=0; i < len; i += size ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001021 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1022 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1023 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024
1025 j = len - i - size;
1026
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001027 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1028 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1029 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 }
1031 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001032}
1033
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001034static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001035audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001036{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 signed char *cp;
1038 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001039 Py_ssize_t len, i, j;
1040 int size, size2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1044 &cp, &len, &size, &size2) )
1045 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001046
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001047 if (!audioop_check_parameters(len, size))
1048 return NULL;
1049 if (!audioop_check_size(size2))
1050 return NULL;
Jack Jansena90805f1993-02-17 14:29:28 +00001051
Mark Dickinson81fece22010-05-11 13:34:35 +00001052 if (len/size > PY_SSIZE_T_MAX/size2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 PyErr_SetString(PyExc_MemoryError,
1054 "not enough memory for output buffer");
1055 return 0;
1056 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001057 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 if ( rv == 0 )
1059 return 0;
1060 ncp = (unsigned char *)PyBytes_AsString(rv);
1061
1062 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001063 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1064 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1065 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001067 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1068 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1069 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 }
1071 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001072}
1073
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001074static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001075gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 while (b > 0) {
1078 int tmp = a % b;
1079 a = b;
1080 b = tmp;
1081 }
1082 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001083}
1084
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001085static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001086audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001089 Py_ssize_t len;
1090 int size, nchannels, inrate, outrate, weightA, weightB;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 int chan, d, *prev_i, *cur_i, cur_o;
1092 PyObject *state, *samps, *str, *rv = NULL;
1093 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 weightA = 1;
1096 weightB = 0;
1097 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1098 &nchannels, &inrate, &outrate, &state,
1099 &weightA, &weightB))
1100 return NULL;
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001101 if (!audioop_check_size(size))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 if (nchannels < 1) {
1104 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1105 return NULL;
1106 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001107 if (size > INT_MAX / nchannels) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 /* This overflow test is rigorously correct because
1109 both multiplicands are >= 1. Use the argument names
1110 from the docs for the error msg. */
1111 PyErr_SetString(PyExc_OverflowError,
1112 "width * nchannels too big for a C int");
1113 return NULL;
1114 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001115 bytes_per_frame = size * nchannels;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 if (weightA < 1 || weightB < 0) {
1117 PyErr_SetString(AudioopError,
1118 "weightA should be >= 1, weightB should be >= 0");
1119 return NULL;
1120 }
1121 if (len % bytes_per_frame != 0) {
1122 PyErr_SetString(AudioopError, "not a whole number of frames");
1123 return NULL;
1124 }
1125 if (inrate <= 0 || outrate <= 0) {
1126 PyErr_SetString(AudioopError, "sampling rate not > 0");
1127 return NULL;
1128 }
1129 /* divide inrate and outrate by their greatest common divisor */
1130 d = gcd(inrate, outrate);
1131 inrate /= d;
1132 outrate /= d;
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001133 /* divide weightA and weightB by their greatest common divisor */
1134 d = gcd(weightA, weightB);
1135 weightA /= d;
1136 weightA /= 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. */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001176 if (len == 0)
1177 str = PyBytes_FromStringAndSize(NULL, 0);
1178 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 /* There are len input frames, so we need (mathematically)
1180 ceiling(len*outrate/inrate) output frames, and each frame
1181 requires bytes_per_frame bytes. Computing this
1182 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001183 settle for a reasonable upper bound, though, in this
1184 case ceiling(len/inrate) * outrate. */
1185
1186 /* compute ceiling(len/inrate) without overflow */
Mark Dickinson81fece22010-05-11 13:34:35 +00001187 Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
1188 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 str = NULL;
1190 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001191 str = PyBytes_FromStringAndSize(NULL,
1192 q * outrate * bytes_per_frame);
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001193 }
1194 if (str == NULL) {
1195 PyErr_SetString(PyExc_MemoryError,
1196 "not enough memory for output buffer");
1197 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 }
1199 ncp = PyBytes_AsString(str);
1200
1201 for (;;) {
1202 while (d < 0) {
1203 if (len == 0) {
1204 samps = PyTuple_New(nchannels);
1205 if (samps == NULL)
1206 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001207 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 PyTuple_SetItem(samps, chan,
1209 Py_BuildValue("(ii)",
1210 prev_i[chan],
1211 cur_i[chan]));
1212 if (PyErr_Occurred())
1213 goto exit;
1214 /* We have checked before that the length
1215 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001216 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 rv = PyBytes_FromStringAndSize
1218 (PyBytes_AsString(str), len);
1219 Py_DECREF(str);
1220 str = rv;
1221 if (str == NULL)
1222 goto exit;
1223 rv = Py_BuildValue("(O(iO))", str, d, samps);
1224 Py_DECREF(samps);
1225 Py_DECREF(str);
1226 goto exit; /* return rv */
1227 }
1228 for (chan = 0; chan < nchannels; chan++) {
1229 prev_i[chan] = cur_i[chan];
1230 if (size == 1)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001231 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 else if (size == 2)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001233 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 else if (size == 4)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001235 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 cp += size;
1237 /* implements a simple digital filter */
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001238 cur_i[chan] = (int)(
1239 ((double)weightA * (double)cur_i[chan] +
1240 (double)weightB * (double)prev_i[chan]) /
1241 ((double)weightA + (double)weightB));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 }
1243 len--;
1244 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001245 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 while (d >= 0) {
1247 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001248 cur_o = (int)(((double)prev_i[chan] * (double)d +
1249 (double)cur_i[chan] * (double)(outrate - d)) /
1250 (double)outrate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 if (size == 1)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001252 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 else if (size == 2)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001254 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 else if (size == 4)
Serhiy Storchaka01ad6222013-02-09 11:10:53 +02001256 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 ncp += size;
1258 }
1259 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001260 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001262 exit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 if (prev_i != NULL)
1264 free(prev_i);
1265 if (cur_i != NULL)
1266 free(cur_i);
1267 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001268}
Guido van Rossum1851a671997-02-14 16:14:03 +00001269
Roger E. Massec905fff1997-01-17 18:12:04 +00001270static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001271audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 signed char *cp;
1274 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001275 Py_ssize_t len, i;
1276 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1280 &cp, &len, &size) )
1281 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001282
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001283 if (!audioop_check_parameters(len, size))
1284 return NULL;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 rv = PyBytes_FromStringAndSize(NULL, len/size);
1287 if ( rv == 0 )
1288 return 0;
1289 ncp = (unsigned char *)PyBytes_AsString(rv);
1290
1291 for ( i=0; i < len; i += size ) {
1292 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1293 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1294 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1295
1296 *ncp++ = st_14linear2ulaw(val);
1297 }
1298 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001299}
1300
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001301static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001302audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 unsigned char *cp;
1305 unsigned char cval;
1306 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001307 Py_ssize_t len, i;
1308 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1312 &cp, &len, &size) )
1313 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001314
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001315 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001316 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317
Mark Dickinson81fece22010-05-11 13:34:35 +00001318 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 PyErr_SetString(PyExc_MemoryError,
1320 "not enough memory for output buffer");
1321 return 0;
1322 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001323 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 if ( rv == 0 )
1325 return 0;
1326 ncp = (signed char *)PyBytes_AsString(rv);
1327
Mark Dickinson85eacea2010-05-10 16:27:45 +00001328 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 cval = *cp++;
1330 val = st_ulaw2linear16(cval);
1331
1332 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1333 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1334 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1335 }
1336 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001337}
1338
1339static PyObject *
1340audioop_lin2alaw(PyObject *self, PyObject *args)
1341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 signed char *cp;
1343 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001344 Py_ssize_t len, i;
1345 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1349 &cp, &len, &size) )
1350 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001351
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001352 if (!audioop_check_parameters(len, size))
1353 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 rv = PyBytes_FromStringAndSize(NULL, len/size);
1356 if ( rv == 0 )
1357 return 0;
1358 ncp = (unsigned char *)PyBytes_AsString(rv);
1359
1360 for ( i=0; i < len; i += size ) {
1361 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1362 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1363 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1364
1365 *ncp++ = st_linear2alaw(val);
1366 }
1367 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001368}
1369
1370static PyObject *
1371audioop_alaw2lin(PyObject *self, PyObject *args)
1372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 unsigned char *cp;
1374 unsigned char cval;
1375 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001376 Py_ssize_t len, i;
1377 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1381 &cp, &len, &size) )
1382 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001383
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001384 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001385 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386
Mark Dickinson81fece22010-05-11 13:34:35 +00001387 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyErr_SetString(PyExc_MemoryError,
1389 "not enough memory for output buffer");
1390 return 0;
1391 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001392 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 if ( rv == 0 )
1394 return 0;
1395 ncp = (signed char *)PyBytes_AsString(rv);
1396
Mark Dickinson85eacea2010-05-10 16:27:45 +00001397 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 signed char *cp;
1412 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001413 Py_ssize_t len, i;
1414 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 index, sign, vpdiff, diff;
1416 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001417 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1420 &cp, &len, &size, &state) )
1421 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001422
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001423 if (!audioop_check_parameters(len, size))
1424 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425
1426 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1427 if ( str == 0 )
1428 return 0;
1429 ncp = (signed char *)PyBytes_AsString(str);
1430
1431 /* Decode state, should have (value, step) */
1432 if ( state == Py_None ) {
1433 /* First time, it seems. Set defaults */
1434 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 index = 0;
1436 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1437 return 0;
1438
1439 step = stepsizeTable[index];
1440 bufferstep = 1;
1441
1442 for ( i=0; i < len; i += size ) {
1443 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1444 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1445 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1446
1447 /* Step 1 - compute difference with previous value */
1448 diff = val - valpred;
1449 sign = (diff < 0) ? 8 : 0;
1450 if ( sign ) diff = (-diff);
1451
1452 /* Step 2 - Divide and clamp */
1453 /* Note:
1454 ** This code *approximately* computes:
1455 ** delta = diff*4/step;
1456 ** vpdiff = (delta+0.5)*step/4;
1457 ** but in shift step bits are dropped. The net result of this
1458 ** is that even if you have fast mul/div hardware you cannot
1459 ** put it to good use since the fixup would be too expensive.
1460 */
1461 delta = 0;
1462 vpdiff = (step >> 3);
1463
1464 if ( diff >= step ) {
1465 delta = 4;
1466 diff -= step;
1467 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001468 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 step >>= 1;
1470 if ( diff >= step ) {
1471 delta |= 2;
1472 diff -= step;
1473 vpdiff += step;
1474 }
1475 step >>= 1;
1476 if ( diff >= step ) {
1477 delta |= 1;
1478 vpdiff += step;
1479 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 /* Step 3 - Update previous value */
1482 if ( sign )
1483 valpred -= vpdiff;
1484 else
1485 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 /* Step 4 - Clamp previous value to 16 bits */
1488 if ( valpred > 32767 )
1489 valpred = 32767;
1490 else if ( valpred < -32768 )
1491 valpred = -32768;
1492
1493 /* Step 5 - Assemble value, update index and step values */
1494 delta |= sign;
1495
1496 index += indexTable[delta];
1497 if ( index < 0 ) index = 0;
1498 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001499 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 /* Step 6 - Output value */
1502 if ( bufferstep ) {
1503 outputbuffer = (delta << 4) & 0xf0;
1504 } else {
1505 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001506 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 bufferstep = !bufferstep;
1508 }
1509 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1510 Py_DECREF(str);
1511 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001512}
1513
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001514static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001515audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 signed char *cp;
1518 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001519 Py_ssize_t len, i;
1520 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001522 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1525 &cp, &len, &size, &state) )
1526 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001527
Antoine Pitrou75ff65e2012-01-28 22:01:59 +01001528 if (!audioop_check_size(size))
Victor Stinnerbc5c54b2010-07-03 13:44:22 +00001529 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530
1531 /* Decode state, should have (value, step) */
1532 if ( state == Py_None ) {
1533 /* First time, it seems. Set defaults */
1534 valpred = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 index = 0;
1536 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1537 return 0;
1538
Mark Dickinson81fece22010-05-11 13:34:35 +00001539 if (len > (PY_SSIZE_T_MAX/2)/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 PyErr_SetString(PyExc_MemoryError,
1541 "not enough memory for output buffer");
1542 return 0;
1543 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001544 str = PyBytes_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 if ( str == 0 )
1546 return 0;
1547 ncp = (signed char *)PyBytes_AsString(str);
1548
1549 step = stepsizeTable[index];
1550 bufferstep = 0;
1551
Mark Dickinson85eacea2010-05-10 16:27:45 +00001552 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 /* Step 1 - get the delta value and compute next index */
1554 if ( bufferstep ) {
1555 delta = inputbuffer & 0xf;
1556 } else {
1557 inputbuffer = *cp++;
1558 delta = (inputbuffer >> 4) & 0xf;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001559 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 bufferstep = !bufferstep;
1562
1563 /* Step 2 - Find new index value (for later) */
1564 index += indexTable[delta];
1565 if ( index < 0 ) index = 0;
1566 if ( index > 88 ) index = 88;
1567
1568 /* Step 3 - Separate sign and magnitude */
1569 sign = delta & 8;
1570 delta = delta & 7;
1571
1572 /* Step 4 - Compute difference and new predicted value */
1573 /*
1574 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1575 ** in adpcm_coder.
1576 */
1577 vpdiff = step >> 3;
1578 if ( delta & 4 ) vpdiff += step;
1579 if ( delta & 2 ) vpdiff += step>>1;
1580 if ( delta & 1 ) vpdiff += step>>2;
1581
1582 if ( sign )
1583 valpred -= vpdiff;
1584 else
1585 valpred += vpdiff;
1586
1587 /* Step 5 - clamp output value */
1588 if ( valpred > 32767 )
1589 valpred = 32767;
1590 else if ( valpred < -32768 )
1591 valpred = -32768;
1592
1593 /* Step 6 - Update step value */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001594 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 /* Step 6 - Output value */
1597 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1598 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1599 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1600 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1603 Py_DECREF(str);
1604 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001605}
1606
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001607static PyMethodDef audioop_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 { "max", audioop_max, METH_VARARGS },
1609 { "minmax", audioop_minmax, METH_VARARGS },
1610 { "avg", audioop_avg, METH_VARARGS },
1611 { "maxpp", audioop_maxpp, METH_VARARGS },
1612 { "avgpp", audioop_avgpp, METH_VARARGS },
1613 { "rms", audioop_rms, METH_VARARGS },
1614 { "findfit", audioop_findfit, METH_VARARGS },
1615 { "findmax", audioop_findmax, METH_VARARGS },
1616 { "findfactor", audioop_findfactor, METH_VARARGS },
1617 { "cross", audioop_cross, METH_VARARGS },
1618 { "mul", audioop_mul, METH_VARARGS },
1619 { "add", audioop_add, METH_VARARGS },
1620 { "bias", audioop_bias, METH_VARARGS },
1621 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1622 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1623 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1624 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1625 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1626 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1627 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1628 { "tomono", audioop_tomono, METH_VARARGS },
1629 { "tostereo", audioop_tostereo, METH_VARARGS },
1630 { "getsample", audioop_getsample, METH_VARARGS },
1631 { "reverse", audioop_reverse, METH_VARARGS },
1632 { "ratecv", audioop_ratecv, METH_VARARGS },
1633 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001634};
1635
Martin v. Löwis1a214512008-06-11 05:26:20 +00001636
1637static struct PyModuleDef audioopmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 PyModuleDef_HEAD_INIT,
1639 "audioop",
1640 NULL,
1641 -1,
1642 audioop_methods,
1643 NULL,
1644 NULL,
1645 NULL,
1646 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001647};
1648
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001649PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001650PyInit_audioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 PyObject *m, *d;
1653 m = PyModule_Create(&audioopmodule);
1654 if (m == NULL)
1655 return NULL;
1656 d = PyModule_GetDict(m);
1657 if (d == NULL)
1658 return NULL;
1659 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1660 if (AudioopError != NULL)
1661 PyDict_SetItemString(d,"error",AudioopError);
1662 return m;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001663}