blob: a4d13753b6185a20098e25573952afca5b8bad2c [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Anthony Baxter17471432006-03-20 05:58:21 +000018typedef short PyInt16;
19
Guido van Rossum7b1e9741994-08-29 10:46:42 +000020#if defined(__CHAR_UNSIGNED__)
21#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000022/* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000026
Serhiy Storchaka62e709c2013-02-09 11:10:30 +020027static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
28static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x80000000};
29static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};
30
31static int
32fbound(double val, double minval, double maxval)
33{
34 if (val > maxval)
35 val = maxval;
36 else if (val < minval + 1)
37 val = minval;
38 return val;
39}
40
41
Anthony Baxterfa869072006-03-20 05:21:58 +000042/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000043** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
44
Anthony Baxterfa869072006-03-20 05:21:58 +000045/* From g711.c:
46 *
47 * December 30, 1994:
48 * Functions linear2alaw, linear2ulaw have been updated to correctly
49 * convert unquantized 16 bit values.
50 * Tables for direct u- to A-law and A- to u-law conversions have been
51 * corrected.
52 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
53 * bli@cpk.auc.dk
54 *
55 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000056#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
57#define CLIP 32635
Martin Panter4f23cab2016-05-08 13:45:55 +000058#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
Anthony Baxter17471432006-03-20 05:58:21 +000059#define QUANT_MASK (0xf) /* Quantization field mask. */
60#define SEG_SHIFT (4) /* Left shift for segment number. */
61#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000062
Anthony Baxter17471432006-03-20 05:58:21 +000063static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
64 0x1FF, 0x3FF, 0x7FF, 0xFFF};
65static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
66 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
Anthony Baxterfa869072006-03-20 05:21:58 +000067
Neal Norwitz49c65d02006-03-20 06:34:06 +000068static PyInt16
69search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000070{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000072
Antoine Pitrouc83ea132010-05-09 14:46:46 +000073 for (i = 0; i < size; i++) {
74 if (val <= *table++)
75 return (i);
76 }
77 return (size);
Anthony Baxterfa869072006-03-20 05:21:58 +000078}
79#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
80#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000081
Neal Norwitz49c65d02006-03-20 06:34:06 +000082static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000083 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
84 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
85 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
86 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
87 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
88 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
89 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
90 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
91 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
92 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
93 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
94 -1052, -988, -924, -876, -844, -812, -780,
95 -748, -716, -684, -652, -620, -588, -556,
96 -524, -492, -460, -428, -396, -372, -356,
97 -340, -324, -308, -292, -276, -260, -244,
98 -228, -212, -196, -180, -164, -148, -132,
99 -120, -112, -104, -96, -88, -80, -72,
100 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000101 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21:58 +0000102 27004, 25980, 24956, 23932, 22908, 21884, 20860,
103 19836, 18812, 17788, 16764, 15996, 15484, 14972,
104 14460, 13948, 13436, 12924, 12412, 11900, 11388,
105 10876, 10364, 9852, 9340, 8828, 8316, 7932,
106 7676, 7420, 7164, 6908, 6652, 6396, 6140,
107 5884, 5628, 5372, 5116, 4860, 4604, 4348,
108 4092, 3900, 3772, 3644, 3516, 3388, 3260,
109 3132, 3004, 2876, 2748, 2620, 2492, 2364,
110 2236, 2108, 1980, 1884, 1820, 1756, 1692,
111 1628, 1564, 1500, 1436, 1372, 1308, 1244,
112 1180, 1116, 1052, 988, 924, 876, 844,
113 812, 780, 748, 716, 684, 652, 620,
114 588, 556, 524, 492, 460, 428, 396,
115 372, 356, 340, 324, 308, 292, 276,
116 260, 244, 228, 212, 196, 180, 164,
117 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000118 80, 72, 64, 56, 48, 40, 32,
119 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000120};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000121
Anthony Baxterfa869072006-03-20 05:21:58 +0000122/*
123 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
Martin Panterb362f752015-11-02 03:37:02 +0000124 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000125 * the data shifted such that it only contains information in the lower
126 * 14-bits.
127 *
128 * In order to simplify the encoding process, the original linear magnitude
129 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
130 * (33 - 8191). The result can be seen in the following encoding table:
131 *
Anthony Baxter17471432006-03-20 05:58:21 +0000132 * Biased Linear Input Code Compressed Code
133 * ------------------------ ---------------
134 * 00000001wxyza 000wxyz
135 * 0000001wxyzab 001wxyz
136 * 000001wxyzabc 010wxyz
137 * 00001wxyzabcd 011wxyz
138 * 0001wxyzabcde 100wxyz
139 * 001wxyzabcdef 101wxyz
140 * 01wxyzabcdefg 110wxyz
141 * 1wxyzabcdefgh 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000142 *
143 * Each biased linear code has a leading 1 which identifies the segment
144 * number. The value of the segment number is equal to 7 minus the number
145 * of leading 0's. The quantization interval is directly available as the
146 * four bits wxyz. * The trailing bits (a - h) are ignored.
147 *
148 * Ordinarily the complement of the resulting code word is used for
149 * transmission, and so the code word is complemented before it is returned.
150 *
151 * For further information see John C. Bellamy's Digital Telephony, 1982,
152 * John Wiley & Sons, pps 98-111 and 472-476.
153 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000154static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000155st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000156{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000157 PyInt16 mask;
158 PyInt16 seg;
159 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000160
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000161 /* The original sox code does this in the calling function, not here */
162 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000163
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000164 /* u-law inverts all bits */
165 /* Get the sign and the magnitude of the value. */
166 if (pcm_val < 0) {
167 pcm_val = -pcm_val;
168 mask = 0x7F;
169 } else {
170 mask = 0xFF;
171 }
172 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
173 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000174
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000175 /* Convert the scaled magnitude to segment number. */
176 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000177
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000178 /*
179 * Combine the sign, segment, quantization bits;
180 * and complement the code word.
181 */
182 if (seg >= 8) /* out of range, return maximum value. */
183 return (unsigned char) (0x7F ^ mask);
184 else {
185 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
186 return (uval ^ mask);
187 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000188
189}
190
Neal Norwitz49c65d02006-03-20 06:34:06 +0000191static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000192 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
193 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
194 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
195 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
196 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
197 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
198 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
199 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
200 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
201 -13568, -344, -328, -376, -360, -280, -264,
202 -312, -296, -472, -456, -504, -488, -408,
203 -392, -440, -424, -88, -72, -120, -104,
204 -24, -8, -56, -40, -216, -200, -248,
205 -232, -152, -136, -184, -168, -1376, -1312,
206 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
207 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
208 -688, -656, -752, -720, -560, -528, -624,
209 -592, -944, -912, -1008, -976, -816, -784,
210 -880, -848, 5504, 5248, 6016, 5760, 4480,
211 4224, 4992, 4736, 7552, 7296, 8064, 7808,
212 6528, 6272, 7040, 6784, 2752, 2624, 3008,
213 2880, 2240, 2112, 2496, 2368, 3776, 3648,
214 4032, 3904, 3264, 3136, 3520, 3392, 22016,
215 20992, 24064, 23040, 17920, 16896, 19968, 18944,
216 30208, 29184, 32256, 31232, 26112, 25088, 28160,
217 27136, 11008, 10496, 12032, 11520, 8960, 8448,
218 9984, 9472, 15104, 14592, 16128, 15616, 13056,
219 12544, 14080, 13568, 344, 328, 376, 360,
220 280, 264, 312, 296, 472, 456, 504,
221 488, 408, 392, 440, 424, 88, 72,
222 120, 104, 24, 8, 56, 40, 216,
223 200, 248, 232, 152, 136, 184, 168,
224 1376, 1312, 1504, 1440, 1120, 1056, 1248,
225 1184, 1888, 1824, 2016, 1952, 1632, 1568,
226 1760, 1696, 688, 656, 752, 720, 560,
227 528, 624, 592, 944, 912, 1008, 976,
228 816, 784, 880, 848
229};
230
231/*
Martin Panter4f23cab2016-05-08 13:45:55 +0000232 * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
233 * stored in an unsigned char. This function should only be called with
Anthony Baxterfa869072006-03-20 05:21:58 +0000234 * the data shifted such that it only contains information in the lower
235 * 13-bits.
236 *
Anthony Baxter17471432006-03-20 05:58:21 +0000237 * Linear Input Code Compressed Code
238 * ------------------------ ---------------
239 * 0000000wxyza 000wxyz
240 * 0000001wxyza 001wxyz
241 * 000001wxyzab 010wxyz
242 * 00001wxyzabc 011wxyz
243 * 0001wxyzabcd 100wxyz
244 * 001wxyzabcde 101wxyz
245 * 01wxyzabcdef 110wxyz
246 * 1wxyzabcdefg 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000247 *
248 * For further information see John C. Bellamy's Digital Telephony, 1982,
249 * John Wiley & Sons, pps 98-111 and 472-476.
250 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000251static unsigned char
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000252st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000253{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000254 PyInt16 mask;
255 short seg;
256 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000257
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000258 /* The original sox code does this in the calling function, not here */
259 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000260
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000261 /* A-law using even bit inversion */
262 if (pcm_val >= 0) {
263 mask = 0xD5; /* sign (7th) bit = 1 */
264 } else {
265 mask = 0x55; /* sign bit = 0 */
266 pcm_val = -pcm_val - 1;
267 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000268
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000269 /* Convert the scaled magnitude to segment number. */
270 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000271
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000273
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000274 if (seg >= 8) /* out of range, return maximum value. */
275 return (unsigned char) (0x7F ^ mask);
276 else {
277 aval = (unsigned char) seg << SEG_SHIFT;
278 if (seg < 2)
279 aval |= (pcm_val >> 1) & QUANT_MASK;
280 else
281 aval |= (pcm_val >> seg) & QUANT_MASK;
282 return (aval ^ mask);
283 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000284}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000285/* End of code taken from sox */
286
Guido van Rossumb64e6351992-07-06 14:21:56 +0000287/* Intel ADPCM step variation table */
288static int indexTable[16] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000289 -1, -1, -1, -1, 2, 4, 6, 8,
290 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000291};
292
293static int stepsizeTable[89] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000294 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
295 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
296 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
297 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
298 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
299 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
300 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
301 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
302 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000303};
Brett Cannon9824e7f2010-05-03 23:42:40 +0000304
Guido van Rossumb66efa01992-06-01 16:01:24 +0000305#define CHARP(cp, i) ((signed char *)(cp+i))
306#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000307#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000308
309
310
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000311static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000312
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000313static int
314audioop_check_size(int size)
315{
316 if (size != 1 && size != 2 && size != 4) {
317 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
318 return 0;
319 }
320 else
321 return 1;
322}
323
324static int
325audioop_check_parameters(int len, int size)
326{
327 if (!audioop_check_size(size))
328 return 0;
329 if (len % size != 0) {
330 PyErr_SetString(AudioopError, "not a whole number of frames");
331 return 0;
332 }
333 return 1;
334}
335
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000336static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000337audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000338{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000339 signed char *cp;
340 int len, size, val = 0;
341 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000342
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000343 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
344 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000345 if (!audioop_check_parameters(len, size))
346 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000347 if ( i < 0 || i >= len/size ) {
348 PyErr_SetString(AudioopError, "Index out of range");
349 return 0;
350 }
351 if ( size == 1 ) val = (int)*CHARP(cp, i);
352 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
353 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
354 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000355}
356
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000357static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000358audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000359{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000360 signed char *cp;
361 int len, size, val = 0;
362 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200363 unsigned int absval, max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000364
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000365 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
366 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000367 if (!audioop_check_parameters(len, size))
368 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000369 for ( i=0; i<len; i+= size) {
370 if ( size == 1 ) val = (int)*CHARP(cp, i);
371 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
372 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200373 if (val < 0) absval = (-val);
374 else absval = val;
375 if (absval > max) max = absval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000376 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200377 if (max <= INT_MAX)
378 return PyInt_FromLong(max);
379 else
380 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 Pitrouc83ea132010-05-09 14:46:46 +0000386 signed char *cp;
387 int len, size, val = 0;
388 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200389 int min = 0x7fffffff, max = -0x80000000;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000390
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000391 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
392 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000393 if (!audioop_check_parameters(len, size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000394 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000395 for (i = 0; i < len; i += size) {
396 if (size == 1) val = (int) *CHARP(cp, i);
397 else if (size == 2) val = (int) *SHORTP(cp, i);
398 else if (size == 4) val = (int) *LONGP(cp, i);
399 if (val > max) max = val;
400 if (val < min) min = val;
401 }
402 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000403}
404
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000405static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000406audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000407{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000408 signed char *cp;
409 int len, size, val = 0;
410 int i;
411 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000412
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000413 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
414 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000415 if (!audioop_check_parameters(len, size))
416 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000417 for ( i=0; i<len; i+= size) {
418 if ( size == 1 ) val = (int)*CHARP(cp, i);
419 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
420 else if ( size == 4 ) val = (int)*LONGP(cp, i);
421 avg += val;
422 }
423 if ( len == 0 )
424 val = 0;
425 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200426 val = (int)floor(avg / (double)(len/size));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000427 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000428}
429
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000430static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000431audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000432{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000433 signed char *cp;
434 int len, size, val = 0;
435 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200436 unsigned int res;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000437 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000438
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000439 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
440 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000441 if (!audioop_check_parameters(len, size))
442 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000443 for ( i=0; i<len; i+= size) {
444 if ( size == 1 ) val = (int)*CHARP(cp, i);
445 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
446 else if ( size == 4 ) val = (int)*LONGP(cp, i);
447 sum_squares += (double)val*(double)val;
448 }
449 if ( len == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200450 res = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000451 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200452 res = (unsigned int)sqrt(sum_squares / (double)(len/size));
453 if (res <= INT_MAX)
454 return PyInt_FromLong(res);
455 else
456 return PyLong_FromUnsignedLong(res);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000457}
458
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000459static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000460{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000461 int i;
462 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000463
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000464 for( i=0; i<len; i++) {
465 sum = sum + (double)a[i]*(double)b[i];
466 }
467 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000468}
469
470/*
471** Findfit tries to locate a sample within another sample. Its main use
472** is in echo-cancellation (to find the feedback of the output signal in
473** the input signal).
474** The method used is as follows:
475**
476** let R be the reference signal (length n) and A the input signal (length N)
477** with N > n, and let all sums be over i from 0 to n-1.
478**
479** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
480** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
481** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
482**
483** Next, we compute the relative distance between the original signal and
484** the modified signal and minimize that over j:
485** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
486** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
487**
488** In the code variables correspond as follows:
Anthony Baxter17471432006-03-20 05:58:21 +0000489** cp1 A
490** cp2 R
491** len1 N
492** len2 n
493** aj_m1 A[j-1]
494** aj_lm1 A[j+n-1]
495** sum_ri_2 sum(R[i]^2)
496** sum_aij_2 sum(A[i+j]^2)
497** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000498**
499** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
500** is completely recalculated each step.
501*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000503audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000504{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000505 short *cp1, *cp2;
506 int len1, len2;
507 int j, best_j;
508 double aj_m1, aj_lm1;
509 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000510
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000511 /* Passing a short** for an 's' argument is correct only
512 if the string contents is aligned for interpretation
513 as short[]. Due to the definition of PyStringObject,
514 this is currently (Python 2.6) the case. */
515 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
516 (char**)&cp1, &len1, (char**)&cp2, &len2) )
517 return 0;
518 if ( len1 & 1 || len2 & 1 ) {
519 PyErr_SetString(AudioopError, "Strings should be even-sized");
520 return 0;
521 }
522 len1 >>= 1;
523 len2 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000524
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000525 if ( len1 < len2 ) {
526 PyErr_SetString(AudioopError, "First sample should be longer");
527 return 0;
528 }
529 sum_ri_2 = _sum2(cp2, cp2, len2);
530 sum_aij_2 = _sum2(cp1, cp1, len2);
531 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000532
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000533 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000534
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000535 best_result = result;
536 best_j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000537
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000538 for (j=1; j<=len1-len2; j++) {
539 aj_m1 = (double)cp1[j-1];
540 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000541
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000542 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
543 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000544
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000545 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
546 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000547
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000548 if ( result < best_result ) {
549 best_result = result;
550 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000551 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000552
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000553 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000554
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000555 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
556
557 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000558}
559
560/*
561** findfactor finds a factor f so that the energy in A-fB is minimal.
562** See the comment for findfit for details.
563*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000564static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000565audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000566{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000567 short *cp1, *cp2;
568 int len1, len2;
569 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000570
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000571 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
572 (char**)&cp1, &len1, (char**)&cp2, &len2) )
573 return 0;
574 if ( len1 & 1 || len2 & 1 ) {
575 PyErr_SetString(AudioopError, "Strings should be even-sized");
576 return 0;
577 }
578 if ( len1 != len2 ) {
579 PyErr_SetString(AudioopError, "Samples should be same size");
580 return 0;
581 }
582 len2 >>= 1;
583 sum_ri_2 = _sum2(cp2, cp2, len2);
584 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000585
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000586 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000587
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000588 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000589}
590
591/*
592** findmax returns the index of the n-sized segment of the input sample
593** that contains the most energy.
594*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000595static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000596audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000597{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000598 short *cp1;
599 int len1, len2;
600 int j, best_j;
601 double aj_m1, aj_lm1;
602 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000603
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000604 if ( !PyArg_ParseTuple(args, "s#i:findmax",
605 (char**)&cp1, &len1, &len2) )
606 return 0;
607 if ( len1 & 1 ) {
608 PyErr_SetString(AudioopError, "Strings should be even-sized");
609 return 0;
610 }
611 len1 >>= 1;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000612
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000613 if ( len2 < 0 || len1 < len2 ) {
614 PyErr_SetString(AudioopError, "Input sample should be longer");
615 return 0;
616 }
617
618 result = _sum2(cp1, cp1, len2);
619
620 best_result = result;
621 best_j = 0;
622
623 for (j=1; j<=len1-len2; j++) {
624 aj_m1 = (double)cp1[j-1];
625 aj_lm1 = (double)cp1[j+len2-1];
626
627 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
628
629 if ( result > best_result ) {
630 best_result = result;
631 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000632 }
Jack Jansena90805f1993-02-17 14:29:28 +0000633
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000634 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000635
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000636 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000637}
638
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000639static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000640audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000641{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000642 signed char *cp;
643 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
644 prevextreme = 0;
645 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200646 double sum = 0.0;
647 unsigned int avg;
648 int diff, prevdiff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000649
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000650 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
651 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000652 if (!audioop_check_parameters(len, size))
653 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200654 if (len <= size*2)
655 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000656 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
657 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
658 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200659 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 for ( i=size; i<len; i+= size) {
661 if ( size == 1 ) val = (int)*CHARP(cp, i);
662 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
663 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200664 if (val != prevval) {
665 diff = val < prevval;
666 if (prevdiff == !diff) {
667 /* Derivative changed sign. Compute difference to last
668 ** extreme value and remember.
669 */
670 if (prevextremevalid) {
671 sum += fabs((double)prevval - (double)prevextreme);
672 nextreme++;
673 }
674 prevextremevalid = 1;
675 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000676 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200677 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200679 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000680 }
681 if ( nextreme == 0 )
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200682 avg = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000683 else
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200684 avg = (unsigned int)(sum / (double)nextreme);
685 if (avg <= INT_MAX)
686 return PyInt_FromLong(avg);
687 else
688 return PyLong_FromUnsignedLong(avg);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000689}
690
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000691static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000692audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000693{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000694 signed char *cp;
695 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
696 prevextreme = 0;
697 int i;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200698 unsigned int max = 0, extremediff;
699 int diff, prevdiff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000700
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000701 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
702 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000703 if (!audioop_check_parameters(len, size))
704 return NULL;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200705 if (len <= size)
706 return PyInt_FromLong(0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000707 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
708 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
709 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200710 prevdiff = 17; /* Anything != 0, 1 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000711 for ( i=size; i<len; i+= size) {
712 if ( size == 1 ) val = (int)*CHARP(cp, i);
713 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
714 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200715 if (val != prevval) {
716 diff = val < prevval;
717 if (prevdiff == !diff) {
718 /* Derivative changed sign. Compute difference to
719 ** last extreme value and remember.
720 */
721 if (prevextremevalid) {
722 if (prevval < prevextreme)
723 extremediff = (unsigned int)prevextreme -
724 (unsigned int)prevval;
725 else
726 extremediff = (unsigned int)prevval -
727 (unsigned int)prevextreme;
728 if ( extremediff > max )
729 max = extremediff;
730 }
731 prevextremevalid = 1;
732 prevextreme = prevval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000733 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200734 prevval = val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000735 prevdiff = diff;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200736 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000737 }
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200738 if (max <= INT_MAX)
739 return PyInt_FromLong(max);
740 else
741 return PyLong_FromUnsignedLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000742}
743
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000744static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000745audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000746{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000747 signed char *cp;
748 int len, size, val = 0;
749 int i;
750 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000751
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000752 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
753 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000754 if (!audioop_check_parameters(len, size))
755 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000756 ncross = -1;
757 prevval = 17; /* Anything <> 0,1 */
758 for ( i=0; i<len; i+= size) {
759 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
760 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
761 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
762 val = val & 1;
763 if ( val != prevval ) ncross++;
764 prevval = val;
765 }
766 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000767}
768
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000769static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000770audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000771{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000772 signed char *cp, *ncp;
773 int len, size, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200774 double factor, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000775 PyObject *rv;
776 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000777
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000778 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
779 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000780 if (!audioop_check_parameters(len, size))
781 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000782
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200783 maxval = (double) maxvals[size];
784 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000785
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000786 rv = PyString_FromStringAndSize(NULL, len);
787 if ( rv == 0 )
788 return 0;
789 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000790
791
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000792 for ( i=0; i < len; i += size ) {
793 if ( size == 1 ) val = (int)*CHARP(cp, i);
794 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
795 else if ( size == 4 ) val = (int)*LONGP(cp, i);
796 fval = (double)val*factor;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200797 val = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000798 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
799 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
800 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
801 }
802 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803}
804
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000805static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000806audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000807{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000808 signed char *cp, *ncp;
809 int len, size, val1 = 0, val2 = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200810 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000811 PyObject *rv;
812 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000813
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000814 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
815 &cp, &len, &size, &fac1, &fac2 ) )
816 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000817 if (!audioop_check_parameters(len, size))
818 return NULL;
819 if (((len / size) & 1) != 0) {
820 PyErr_SetString(AudioopError, "not a whole number of frames");
821 return NULL;
822 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000823
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200824 maxval = (double) maxvals[size];
825 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000826
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000827 rv = PyString_FromStringAndSize(NULL, len/2);
828 if ( rv == 0 )
829 return 0;
830 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000831
832
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000833 for ( i=0; i < len; i += size*2 ) {
834 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
835 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
836 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
837 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
838 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
839 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
840 fval = (double)val1*fac1 + (double)val2*fac2;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200841 val1 = (int)floor(fbound(fval, minval, maxval));
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000842 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
843 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
844 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
845 }
846 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000847}
848
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000849static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000850audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000851{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000852 signed char *cp, *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +0000853 int len, size, val1, val2, val = 0;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200854 double fac1, fac2, fval, maxval, minval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000855 PyObject *rv;
856 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000857
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000858 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
859 &cp, &len, &size, &fac1, &fac2 ) )
860 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000861 if (!audioop_check_parameters(len, size))
862 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000863
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200864 maxval = (double) maxvals[size];
865 minval = (double) minvals[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000866
Mark Dickinson932e1622010-05-10 16:07:42 +0000867 if (len > INT_MAX/2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000868 PyErr_SetString(PyExc_MemoryError,
869 "not enough memory for output buffer");
870 return 0;
871 }
Gregory P. Smith9d534572008-06-11 07:41:16 +0000872
Mark Dickinson932e1622010-05-10 16:07:42 +0000873 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000874 if ( rv == 0 )
875 return 0;
876 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000877
878
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000879 for ( i=0; i < len; i += size ) {
880 if ( size == 1 ) val = (int)*CHARP(cp, i);
881 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
882 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000884 fval = (double)val*fac1;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200885 val1 = (int)floor(fbound(fval, minval, maxval));
Guido van Rossumb66efa01992-06-01 16:01:24 +0000886
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000887 fval = (double)val*fac2;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200888 val2 = (int)floor(fbound(fval, minval, maxval));
Guido van Rossumb66efa01992-06-01 16:01:24 +0000889
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000890 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
891 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
892 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000894 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
895 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
896 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
897 }
898 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000899}
900
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000901static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000902audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000903{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000904 signed char *cp1, *cp2, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200905 int len1, len2, size, val1 = 0, val2 = 0, minval, maxval, newval;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000906 PyObject *rv;
907 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000908
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000909 if ( !PyArg_ParseTuple(args, "s#s#i:add",
910 &cp1, &len1, &cp2, &len2, &size ) )
911 return 0;
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000912 if (!audioop_check_parameters(len1, size))
913 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000914 if ( len1 != len2 ) {
915 PyErr_SetString(AudioopError, "Lengths should be the same");
916 return 0;
917 }
Brett Cannon9824e7f2010-05-03 23:42:40 +0000918
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200919 maxval = maxvals[size];
920 minval = minvals[size];
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000922 rv = PyString_FromStringAndSize(NULL, len1);
923 if ( rv == 0 )
924 return 0;
925 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000926
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000927 for ( i=0; i < len1; i += size ) {
928 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
929 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
930 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000931
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000932 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
933 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
934 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000935
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200936 if (size < 4) {
937 newval = val1 + val2;
938 /* truncate in case of overflow */
939 if (newval > maxval)
940 newval = maxval;
941 else if (newval < minval)
942 newval = minval;
943 }
944 else {
945 double fval = (double)val1 + (double)val2;
946 /* truncate in case of overflow */
947 newval = (int)floor(fbound(fval, minval, maxval));
948 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000949
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000950 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
951 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
952 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
953 }
954 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000955}
956
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000957static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000958audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000959{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000960 signed char *cp, *ncp;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200961 int len, size;
962 unsigned int val = 0, mask;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000963 PyObject *rv;
964 int i;
965 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000966
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 if ( !PyArg_ParseTuple(args, "s#ii:bias",
968 &cp, &len, &size , &bias) )
969 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000970
Victor Stinner15e5b1b2010-07-03 13:36:19 +0000971 if (!audioop_check_parameters(len, size))
972 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +0000973
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000974 rv = PyString_FromStringAndSize(NULL, len);
975 if ( rv == 0 )
976 return 0;
977 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000978
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200979 mask = masks[size];
Brett Cannon9824e7f2010-05-03 23:42:40 +0000980
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000981 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200982 if ( size == 1 ) val = (unsigned int)(unsigned char)*CHARP(cp, i);
983 else if ( size == 2 ) val = (unsigned int)(unsigned short)*SHORTP(cp, i);
984 else if ( size == 4 ) val = (unsigned int)(Py_UInt32)*LONGP(cp, i);
Brett Cannon9824e7f2010-05-03 23:42:40 +0000985
Serhiy Storchaka62e709c2013-02-09 11:10:30 +0200986 val += (unsigned int)bias;
987 /* wrap around in case of overflow */
988 val &= mask;
989
990 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(unsigned char)val;
991 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(unsigned short)val;
992 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(Py_UInt32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 }
994 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000995}
996
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000997static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000998audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000999{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001000 signed char *cp;
1001 unsigned char *ncp;
1002 int len, size, val = 0;
1003 PyObject *rv;
1004 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +00001005
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001006 if ( !PyArg_ParseTuple(args, "s#i:reverse",
1007 &cp, &len, &size) )
1008 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +00001009
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001010 if (!audioop_check_parameters(len, size))
1011 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001012
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001013 rv = PyString_FromStringAndSize(NULL, len);
1014 if ( rv == 0 )
1015 return 0;
1016 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001017
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001018 for ( i=0; i < len; i += size ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001019 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1020 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1021 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansen337b20e1993-02-23 13:39:57 +00001022
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001023 j = len - i - size;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001024
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001025 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1026 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1027 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001028 }
1029 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001030}
1031
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001032static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001033audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001034{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001035 signed char *cp;
1036 unsigned char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001037 int len, size, size2, val = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001038 PyObject *rv;
1039 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001040
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001041 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1042 &cp, &len, &size, &size2) )
1043 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001044
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001045 if (!audioop_check_parameters(len, size))
1046 return NULL;
1047 if (!audioop_check_size(size2))
1048 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001049
Mark Dickinson932e1622010-05-10 16:07:42 +00001050 if (len/size > INT_MAX/size2) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001051 PyErr_SetString(PyExc_MemoryError,
1052 "not enough memory for output buffer");
1053 return 0;
1054 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001055 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001056 if ( rv == 0 )
1057 return 0;
1058 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001059
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001060 for ( i=0, j=0; i < len; i += size, j += size2 ) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001061 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 24;
1062 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) << 16;
1063 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Jack Jansena90805f1993-02-17 14:29:28 +00001064
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001065 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 24);
1066 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val >> 16);
1067 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001068 }
1069 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001070}
1071
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001072static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001073gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001074{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001075 while (b > 0) {
1076 int tmp = a % b;
1077 a = b;
1078 b = tmp;
1079 }
1080 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001081}
1082
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001083static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001084audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001085{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001086 char *cp, *ncp;
1087 int len, size, nchannels, inrate, outrate, weightA, weightB;
1088 int chan, d, *prev_i, *cur_i, cur_o;
1089 PyObject *state, *samps, *str, *rv = NULL;
1090 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001091
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001092 weightA = 1;
1093 weightB = 0;
1094 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1095 &nchannels, &inrate, &outrate, &state,
1096 &weightA, &weightB))
1097 return NULL;
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001098 if (!audioop_check_size(size))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001099 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001100 if (nchannels < 1) {
1101 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1102 return NULL;
1103 }
1104 bytes_per_frame = size * nchannels;
1105 if (bytes_per_frame / nchannels != size) {
1106 /* This overflow test is rigorously correct because
1107 both multiplicands are >= 1. Use the argument names
1108 from the docs for the error msg. */
1109 PyErr_SetString(PyExc_OverflowError,
1110 "width * nchannels too big for a C int");
1111 return NULL;
1112 }
1113 if (weightA < 1 || weightB < 0) {
1114 PyErr_SetString(AudioopError,
1115 "weightA should be >= 1, weightB should be >= 0");
1116 return NULL;
1117 }
1118 if (len % bytes_per_frame != 0) {
1119 PyErr_SetString(AudioopError, "not a whole number of frames");
1120 return NULL;
1121 }
1122 if (inrate <= 0 || outrate <= 0) {
1123 PyErr_SetString(AudioopError, "sampling rate not > 0");
1124 return NULL;
1125 }
1126 /* divide inrate and outrate by their greatest common divisor */
1127 d = gcd(inrate, outrate);
1128 inrate /= d;
1129 outrate /= d;
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001130 /* divide weightA and weightB by their greatest common divisor */
1131 d = gcd(weightA, weightB);
1132 weightA /= d;
Serhiy Storchaka1e953402015-05-30 00:53:26 +03001133 weightB /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001134
Mark Dickinson932e1622010-05-10 16:07:42 +00001135 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001136 PyErr_SetString(PyExc_MemoryError,
1137 "not enough memory for output buffer");
1138 return 0;
1139 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001140 prev_i = (int *) malloc(nchannels * sizeof(int));
1141 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001142 if (prev_i == NULL || cur_i == NULL) {
1143 (void) PyErr_NoMemory();
1144 goto exit;
1145 }
1146
1147 len /= bytes_per_frame; /* # of frames */
1148
1149 if (state == Py_None) {
1150 d = -outrate;
1151 for (chan = 0; chan < nchannels; chan++)
1152 prev_i[chan] = cur_i[chan] = 0;
1153 }
1154 else {
1155 if (!PyArg_ParseTuple(state,
1156 "iO!;audioop.ratecv: illegal state argument",
1157 &d, &PyTuple_Type, &samps))
1158 goto exit;
1159 if (PyTuple_Size(samps) != nchannels) {
1160 PyErr_SetString(AudioopError,
1161 "illegal state argument");
1162 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001163 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001164 for (chan = 0; chan < nchannels; chan++) {
1165 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1166 "ii:ratecv", &prev_i[chan],
1167 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001168 goto exit;
1169 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001170 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001171
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001172 /* str <- Space for the output buffer. */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001173 if (len == 0)
1174 str = PyString_FromStringAndSize(NULL, 0);
1175 else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001176 /* There are len input frames, so we need (mathematically)
1177 ceiling(len*outrate/inrate) output frames, and each frame
1178 requires bytes_per_frame bytes. Computing this
1179 without spurious overflow is the challenge; we can
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001180 settle for a reasonable upper bound, though, in this
1181 case ceiling(len/inrate) * outrate. */
1182
1183 /* compute ceiling(len/inrate) without overflow */
1184 int q = len > 0 ? 1 + (len - 1) / inrate : 0;
1185 if (outrate > INT_MAX / q / bytes_per_frame)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001186 str = NULL;
1187 else
Mark Dickinson11bb2cd2010-05-11 13:05:30 +00001188 str = PyString_FromStringAndSize(NULL,
1189 q * outrate * bytes_per_frame);
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001190 }
1191 if (str == NULL) {
1192 PyErr_SetString(PyExc_MemoryError,
1193 "not enough memory for output buffer");
1194 goto exit;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001195 }
1196 ncp = PyString_AsString(str);
1197
1198 for (;;) {
1199 while (d < 0) {
1200 if (len == 0) {
1201 samps = PyTuple_New(nchannels);
1202 if (samps == NULL)
1203 goto exit;
Anthony Baxter17471432006-03-20 05:58:21 +00001204 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001205 PyTuple_SetItem(samps, chan,
1206 Py_BuildValue("(ii)",
1207 prev_i[chan],
1208 cur_i[chan]));
1209 if (PyErr_Occurred())
1210 goto exit;
1211 /* We have checked before that the length
1212 * of the string fits into int. */
1213 len = (int)(ncp - PyString_AsString(str));
1214 if (len == 0) {
1215 /*don't want to resize to zero length*/
1216 rv = PyString_FromStringAndSize("", 0);
1217 Py_DECREF(str);
1218 str = rv;
1219 } else if (_PyString_Resize(&str, len) < 0)
1220 goto exit;
1221 rv = Py_BuildValue("(O(iO))", str, d, samps);
1222 Py_DECREF(samps);
1223 Py_DECREF(str);
1224 goto exit; /* return rv */
1225 }
1226 for (chan = 0; chan < nchannels; chan++) {
1227 prev_i[chan] = cur_i[chan];
1228 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001229 cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001230 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001231 cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001232 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001233 cur_i[chan] = (int)*LONGP(cp, 0);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001234 cp += size;
1235 /* implements a simple digital filter */
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001236 cur_i[chan] = (int)(
1237 ((double)weightA * (double)cur_i[chan] +
1238 (double)weightB * (double)prev_i[chan]) /
1239 ((double)weightA + (double)weightB));
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001240 }
1241 len--;
1242 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001243 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001244 while (d >= 0) {
1245 for (chan = 0; chan < nchannels; chan++) {
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001246 cur_o = (int)(((double)prev_i[chan] * (double)d +
1247 (double)cur_i[chan] * (double)(outrate - d)) /
1248 (double)outrate);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001249 if (size == 1)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001250 *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001251 else if (size == 2)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001252 *SHORTP(ncp, 0) = (short)(cur_o >> 16);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001253 else if (size == 4)
Serhiy Storchaka62e709c2013-02-09 11:10:30 +02001254 *LONGP(ncp, 0) = (Py_Int32)(cur_o);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001255 ncp += size;
1256 }
1257 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001258 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001259 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001260 exit:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001261 if (prev_i != NULL)
1262 free(prev_i);
1263 if (cur_i != NULL)
1264 free(cur_i);
1265 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001266}
Guido van Rossum1851a671997-02-14 16:14:03 +00001267
Roger E. Massec905fff1997-01-17 18:12:04 +00001268static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001269audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001270{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001271 signed char *cp;
1272 unsigned char *ncp;
1273 int len, size, val = 0;
1274 PyObject *rv;
1275 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001276
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001277 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1278 &cp, &len, &size) )
1279 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001280
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001281 if (!audioop_check_parameters(len, size))
1282 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001283
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001284 rv = PyString_FromStringAndSize(NULL, len/size);
1285 if ( rv == 0 )
1286 return 0;
1287 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001288
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001289 for ( i=0; i < len; i += size ) {
1290 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1291 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1292 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001293
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001294 *ncp++ = st_14linear2ulaw(val);
1295 }
1296 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001297}
1298
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001299static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001300audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001301{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001302 unsigned char *cp;
1303 unsigned char cval;
1304 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001305 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001306 PyObject *rv;
1307 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001308
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001309 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1310 &cp, &len, &size) )
1311 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001312
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001313 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001314 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001315
Mark Dickinson932e1622010-05-10 16:07:42 +00001316 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001317 PyErr_SetString(PyExc_MemoryError,
1318 "not enough memory for output buffer");
1319 return 0;
1320 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001321 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001322 if ( rv == 0 )
1323 return 0;
1324 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001325
Mark Dickinson932e1622010-05-10 16:07:42 +00001326 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001327 cval = *cp++;
1328 val = st_ulaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001329
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001330 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1331 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1332 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1333 }
1334 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001335}
1336
1337static PyObject *
1338audioop_lin2alaw(PyObject *self, PyObject *args)
1339{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001340 signed char *cp;
1341 unsigned char *ncp;
1342 int len, size, val = 0;
1343 PyObject *rv;
1344 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001345
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001346 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1347 &cp, &len, &size) )
1348 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001349
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001350 if (!audioop_check_parameters(len, size))
1351 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001352
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001353 rv = PyString_FromStringAndSize(NULL, len/size);
1354 if ( rv == 0 )
1355 return 0;
1356 ncp = (unsigned char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001357
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001358 for ( i=0; i < len; i += size ) {
1359 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1360 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1361 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001362
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 *ncp++ = st_linear2alaw(val);
1364 }
1365 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001366}
1367
1368static PyObject *
1369audioop_alaw2lin(PyObject *self, PyObject *args)
1370{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001371 unsigned char *cp;
1372 unsigned char cval;
1373 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001374 int len, size, val;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001375 PyObject *rv;
1376 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001377
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001378 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1379 &cp, &len, &size) )
1380 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001381
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001382 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001383 return NULL;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001384
Mark Dickinson932e1622010-05-10 16:07:42 +00001385 if (len > INT_MAX/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001386 PyErr_SetString(PyExc_MemoryError,
1387 "not enough memory for output buffer");
1388 return 0;
1389 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001390 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001391 if ( rv == 0 )
1392 return 0;
1393 ncp = (signed char *)PyString_AsString(rv);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001394
Mark Dickinson932e1622010-05-10 16:07:42 +00001395 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001396 cval = *cp++;
1397 val = st_alaw2linear16(cval);
Brett Cannon9824e7f2010-05-03 23:42:40 +00001398
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001399 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1400 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1401 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1402 }
1403 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001404}
1405
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001406static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001407audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001408{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001409 signed char *cp;
1410 signed char *ncp;
1411 int len, size, val = 0, step, valpred, delta,
1412 index, sign, vpdiff, diff;
1413 PyObject *rv, *state, *str;
1414 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001415
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001416 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1417 &cp, &len, &size, &state) )
1418 return 0;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001419
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001420 if (!audioop_check_parameters(len, size))
1421 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001422
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001423 /* Decode state, should have (value, step) */
1424 if ( state == Py_None ) {
1425 /* First time, it seems. Set defaults */
1426 valpred = 0;
1427 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001428 }
1429 else if (!PyTuple_Check(state)) {
1430 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1431 return NULL;
1432 }
1433 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1434 return NULL;
1435 }
1436 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1437 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1438 PyErr_SetString(PyExc_ValueError, "bad state");
1439 return NULL;
1440 }
1441
1442 str = PyString_FromStringAndSize(NULL, len/(size*2));
1443 if ( str == 0 )
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001444 return 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001445 ncp = (signed char *)PyString_AsString(str);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001446
1447 step = stepsizeTable[index];
1448 bufferstep = 1;
1449
1450 for ( i=0; i < len; i += size ) {
1451 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1452 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1453 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1454
1455 /* Step 1 - compute difference with previous value */
1456 diff = val - valpred;
1457 sign = (diff < 0) ? 8 : 0;
1458 if ( sign ) diff = (-diff);
1459
1460 /* Step 2 - Divide and clamp */
1461 /* Note:
1462 ** This code *approximately* computes:
1463 ** delta = diff*4/step;
1464 ** vpdiff = (delta+0.5)*step/4;
1465 ** but in shift step bits are dropped. The net result of this
1466 ** is that even if you have fast mul/div hardware you cannot
1467 ** put it to good use since the fixup would be too expensive.
1468 */
1469 delta = 0;
1470 vpdiff = (step >> 3);
1471
1472 if ( diff >= step ) {
1473 delta = 4;
1474 diff -= step;
1475 vpdiff += step;
1476 }
1477 step >>= 1;
1478 if ( diff >= step ) {
1479 delta |= 2;
1480 diff -= step;
1481 vpdiff += step;
1482 }
1483 step >>= 1;
1484 if ( diff >= step ) {
1485 delta |= 1;
1486 vpdiff += step;
Anthony Baxter17471432006-03-20 05:58:21 +00001487 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001488
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001489 /* Step 3 - Update previous value */
1490 if ( sign )
1491 valpred -= vpdiff;
1492 else
1493 valpred += vpdiff;
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001494
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001495 /* Step 4 - Clamp previous value to 16 bits */
1496 if ( valpred > 32767 )
1497 valpred = 32767;
1498 else if ( valpred < -32768 )
1499 valpred = -32768;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001500
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001501 /* Step 5 - Assemble value, update index and step values */
1502 delta |= sign;
1503
1504 index += indexTable[delta];
1505 if ( index < 0 ) index = 0;
1506 if ( index > 88 ) index = 88;
Anthony Baxter17471432006-03-20 05:58:21 +00001507 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001508
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001509 /* Step 6 - Output value */
1510 if ( bufferstep ) {
1511 outputbuffer = (delta << 4) & 0xf0;
1512 } else {
1513 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001514 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001515 bufferstep = !bufferstep;
1516 }
1517 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1518 Py_DECREF(str);
1519 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001520}
1521
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001522static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001523audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001524{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001525 signed char *cp;
1526 signed char *ncp;
Mark Dickinson932e1622010-05-10 16:07:42 +00001527 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001528 PyObject *rv, *str, *state;
1529 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001530
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001531 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1532 &cp, &len, &size, &state) )
1533 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001534
Antoine Pitrou88c51e82012-01-28 22:01:59 +01001535 if (!audioop_check_size(size))
Victor Stinner15e5b1b2010-07-03 13:36:19 +00001536 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001537
1538 /* Decode state, should have (value, step) */
1539 if ( state == Py_None ) {
1540 /* First time, it seems. Set defaults */
1541 valpred = 0;
1542 index = 0;
Serhiy Storchaka84af51d2015-06-28 17:51:40 +03001543 }
1544 else if (!PyTuple_Check(state)) {
1545 PyErr_SetString(PyExc_TypeError, "state must be a tuple or None");
1546 return NULL;
1547 }
1548 else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) {
1549 return NULL;
1550 }
1551 else if (valpred >= 0x8000 || valpred < -0x8000 ||
1552 (size_t)index >= sizeof(stepsizeTable)/sizeof(stepsizeTable[0])) {
1553 PyErr_SetString(PyExc_ValueError, "bad state");
1554 return NULL;
1555 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001556
Mark Dickinson932e1622010-05-10 16:07:42 +00001557 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001558 PyErr_SetString(PyExc_MemoryError,
1559 "not enough memory for output buffer");
1560 return 0;
1561 }
Mark Dickinson932e1622010-05-10 16:07:42 +00001562 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001563 if ( str == 0 )
1564 return 0;
1565 ncp = (signed char *)PyString_AsString(str);
1566
1567 step = stepsizeTable[index];
1568 bufferstep = 0;
1569
Mark Dickinson932e1622010-05-10 16:07:42 +00001570 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001571 /* Step 1 - get the delta value and compute next index */
1572 if ( bufferstep ) {
1573 delta = inputbuffer & 0xf;
1574 } else {
1575 inputbuffer = *cp++;
1576 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001577 }
Brett Cannon9824e7f2010-05-03 23:42:40 +00001578
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001579 bufferstep = !bufferstep;
Brett Cannon9824e7f2010-05-03 23:42:40 +00001580
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001581 /* Step 2 - Find new index value (for later) */
1582 index += indexTable[delta];
1583 if ( index < 0 ) index = 0;
1584 if ( index > 88 ) index = 88;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001585
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001586 /* Step 3 - Separate sign and magnitude */
1587 sign = delta & 8;
1588 delta = delta & 7;
1589
1590 /* Step 4 - Compute difference and new predicted value */
1591 /*
1592 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1593 ** in adpcm_coder.
1594 */
1595 vpdiff = step >> 3;
1596 if ( delta & 4 ) vpdiff += step;
1597 if ( delta & 2 ) vpdiff += step>>1;
1598 if ( delta & 1 ) vpdiff += step>>2;
1599
1600 if ( sign )
1601 valpred -= vpdiff;
1602 else
1603 valpred += vpdiff;
1604
1605 /* Step 5 - clamp output value */
1606 if ( valpred > 32767 )
1607 valpred = 32767;
1608 else if ( valpred < -32768 )
1609 valpred = -32768;
1610
1611 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001612 step = stepsizeTable[index];
Brett Cannon9824e7f2010-05-03 23:42:40 +00001613
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001614 /* Step 6 - Output value */
1615 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1616 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1617 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1618 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001619
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001620 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1621 Py_DECREF(str);
1622 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001623}
1624
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001625static PyMethodDef audioop_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001626 { "max", audioop_max, METH_VARARGS },
1627 { "minmax", audioop_minmax, METH_VARARGS },
1628 { "avg", audioop_avg, METH_VARARGS },
1629 { "maxpp", audioop_maxpp, METH_VARARGS },
1630 { "avgpp", audioop_avgpp, METH_VARARGS },
1631 { "rms", audioop_rms, METH_VARARGS },
1632 { "findfit", audioop_findfit, METH_VARARGS },
1633 { "findmax", audioop_findmax, METH_VARARGS },
1634 { "findfactor", audioop_findfactor, METH_VARARGS },
1635 { "cross", audioop_cross, METH_VARARGS },
1636 { "mul", audioop_mul, METH_VARARGS },
1637 { "add", audioop_add, METH_VARARGS },
1638 { "bias", audioop_bias, METH_VARARGS },
1639 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1640 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1641 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1642 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1643 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1644 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1645 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1646 { "tomono", audioop_tomono, METH_VARARGS },
1647 { "tostereo", audioop_tostereo, METH_VARARGS },
1648 { "getsample", audioop_getsample, METH_VARARGS },
1649 { "reverse", audioop_reverse, METH_VARARGS },
1650 { "ratecv", audioop_ratecv, METH_VARARGS },
1651 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001652};
1653
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001654PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001655initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001656{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001657 PyObject *m, *d;
1658 m = Py_InitModule("audioop", audioop_methods);
1659 if (m == NULL)
1660 return;
1661 d = PyModule_GetDict(m);
1662 if (d == NULL)
1663 return;
1664 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1665 if (AudioopError != NULL)
1666 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001667}