blob: 7da046225aa4d31459954242d27db15efeb9b438 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Mark Dickinson81fece22010-05-11 13:34:35 +00004#define PY_SSIZE_T_CLEAN
5
Roger E. Masseeaa6e111997-01-03 19:26:27 +00006#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00007
Guido van Rossum69011961998-04-23 20:23:00 +00008#if SIZEOF_INT == 4
9typedef int Py_Int32;
10typedef unsigned int Py_UInt32;
11#else
12#if SIZEOF_LONG == 4
13typedef long Py_Int32;
14typedef unsigned long Py_UInt32;
15#else
16#error "No 4-byte integral type"
17#endif
18#endif
19
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000020typedef short PyInt16;
21
Guido van Rossum7b1e9741994-08-29 10:46:42 +000022#if defined(__CHAR_UNSIGNED__)
23#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000024/* This module currently does not work on systems where only unsigned
25 characters are available. Take it out of Setup. Sorry. */
26#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000027#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000028
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000029/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000030** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
31
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032/* From g711.c:
33 *
34 * December 30, 1994:
35 * Functions linear2alaw, linear2ulaw have been updated to correctly
36 * convert unquantized 16 bit values.
37 * Tables for direct u- to A-law and A- to u-law conversions have been
38 * corrected.
39 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
40 * bli@cpk.auc.dk
41 *
42 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000043#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
44#define CLIP 32635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
46#define QUANT_MASK (0xf) /* Quantization field mask. */
47#define SEG_SHIFT (4) /* Left shift for segment number. */
48#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000049
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000050static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
51 0x1FF, 0x3FF, 0x7FF, 0xFFF};
52static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
53 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
54
55static PyInt16
56search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 for (i = 0; i < size; i++) {
61 if (val <= *table++)
62 return (i);
63 }
64 return (size);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000065}
66#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
67#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000068
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069static PyInt16 _st_ulaw2linear16[256] = {
70 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
71 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
72 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
73 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
74 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
75 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
76 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
77 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
78 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
79 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
80 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
81 -1052, -988, -924, -876, -844, -812, -780,
82 -748, -716, -684, -652, -620, -588, -556,
83 -524, -492, -460, -428, -396, -372, -356,
84 -340, -324, -308, -292, -276, -260, -244,
85 -228, -212, -196, -180, -164, -148, -132,
86 -120, -112, -104, -96, -88, -80, -72,
87 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 -8, 0, 32124, 31100, 30076, 29052, 28028,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000089 27004, 25980, 24956, 23932, 22908, 21884, 20860,
90 19836, 18812, 17788, 16764, 15996, 15484, 14972,
91 14460, 13948, 13436, 12924, 12412, 11900, 11388,
92 10876, 10364, 9852, 9340, 8828, 8316, 7932,
93 7676, 7420, 7164, 6908, 6652, 6396, 6140,
94 5884, 5628, 5372, 5116, 4860, 4604, 4348,
95 4092, 3900, 3772, 3644, 3516, 3388, 3260,
96 3132, 3004, 2876, 2748, 2620, 2492, 2364,
97 2236, 2108, 1980, 1884, 1820, 1756, 1692,
98 1628, 1564, 1500, 1436, 1372, 1308, 1244,
99 1180, 1116, 1052, 988, 924, 876, 844,
100 812, 780, 748, 716, 684, 652, 620,
101 588, 556, 524, 492, 460, 428, 396,
102 372, 356, 340, 324, 308, 292, 276,
103 260, 244, 228, 212, 196, 180, 164,
104 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 80, 72, 64, 56, 48, 40, 32,
106 24, 16, 8, 0
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000108
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000109/*
110 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
111 * stored in a unsigned char. This function should only be called with
112 * the data shifted such that it only contains information in the lower
113 * 14-bits.
114 *
115 * In order to simplify the encoding process, the original linear magnitude
116 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
117 * (33 - 8191). The result can be seen in the following encoding table:
118 *
119 * Biased Linear Input Code Compressed Code
120 * ------------------------ ---------------
121 * 00000001wxyza 000wxyz
122 * 0000001wxyzab 001wxyz
123 * 000001wxyzabc 010wxyz
124 * 00001wxyzabcd 011wxyz
125 * 0001wxyzabcde 100wxyz
126 * 001wxyzabcdef 101wxyz
127 * 01wxyzabcdefg 110wxyz
128 * 1wxyzabcdefgh 111wxyz
129 *
130 * Each biased linear code has a leading 1 which identifies the segment
131 * number. The value of the segment number is equal to 7 minus the number
132 * of leading 0's. The quantization interval is directly available as the
133 * four bits wxyz. * The trailing bits (a - h) are ignored.
134 *
135 * Ordinarily the complement of the resulting code word is used for
136 * transmission, and so the code word is complemented before it is returned.
137 *
138 * For further information see John C. Bellamy's Digital Telephony, 1982,
139 * John Wiley & Sons, pps 98-111 and 472-476.
140 */
141static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 PyInt16 mask;
145 PyInt16 seg;
146 unsigned char uval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 /* The original sox code does this in the calling function, not here */
149 pcm_val = pcm_val >> 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 /* u-law inverts all bits */
152 /* Get the sign and the magnitude of the value. */
153 if (pcm_val < 0) {
154 pcm_val = -pcm_val;
155 mask = 0x7F;
156 } else {
157 mask = 0xFF;
158 }
159 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
160 pcm_val += (BIAS >> 2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 /* Convert the scaled magnitude to segment number. */
163 seg = search(pcm_val, seg_uend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 /*
166 * Combine the sign, segment, quantization bits;
167 * and complement the code word.
168 */
169 if (seg >= 8) /* out of range, return maximum value. */
170 return (unsigned char) (0x7F ^ mask);
171 else {
172 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
173 return (uval ^ mask);
174 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000175
176}
177
178static PyInt16 _st_alaw2linear16[256] = {
179 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
180 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
181 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
182 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
183 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
184 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
185 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
186 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
187 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
188 -13568, -344, -328, -376, -360, -280, -264,
189 -312, -296, -472, -456, -504, -488, -408,
190 -392, -440, -424, -88, -72, -120, -104,
191 -24, -8, -56, -40, -216, -200, -248,
192 -232, -152, -136, -184, -168, -1376, -1312,
193 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
194 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
195 -688, -656, -752, -720, -560, -528, -624,
196 -592, -944, -912, -1008, -976, -816, -784,
197 -880, -848, 5504, 5248, 6016, 5760, 4480,
198 4224, 4992, 4736, 7552, 7296, 8064, 7808,
199 6528, 6272, 7040, 6784, 2752, 2624, 3008,
200 2880, 2240, 2112, 2496, 2368, 3776, 3648,
201 4032, 3904, 3264, 3136, 3520, 3392, 22016,
202 20992, 24064, 23040, 17920, 16896, 19968, 18944,
203 30208, 29184, 32256, 31232, 26112, 25088, 28160,
204 27136, 11008, 10496, 12032, 11520, 8960, 8448,
205 9984, 9472, 15104, 14592, 16128, 15616, 13056,
206 12544, 14080, 13568, 344, 328, 376, 360,
207 280, 264, 312, 296, 472, 456, 504,
208 488, 408, 392, 440, 424, 88, 72,
209 120, 104, 24, 8, 56, 40, 216,
210 200, 248, 232, 152, 136, 184, 168,
211 1376, 1312, 1504, 1440, 1120, 1056, 1248,
212 1184, 1888, 1824, 2016, 1952, 1632, 1568,
213 1760, 1696, 688, 656, 752, 720, 560,
214 528, 624, 592, 944, 912, 1008, 976,
215 816, 784, 880, 848
216};
217
218/*
219 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
220 * stored in a unsigned char. This function should only be called with
221 * the data shifted such that it only contains information in the lower
222 * 13-bits.
223 *
224 * Linear Input Code Compressed Code
225 * ------------------------ ---------------
226 * 0000000wxyza 000wxyz
227 * 0000001wxyza 001wxyz
228 * 000001wxyzab 010wxyz
229 * 00001wxyzabc 011wxyz
230 * 0001wxyzabcd 100wxyz
231 * 001wxyzabcde 101wxyz
232 * 01wxyzabcdef 110wxyz
233 * 1wxyzabcdefg 111wxyz
234 *
235 * For further information see John C. Bellamy's Digital Telephony, 1982,
236 * John Wiley & Sons, pps 98-111 and 472-476.
237 */
238static unsigned char
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 PyInt16 mask;
242 short seg;
243 unsigned char aval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 /* The original sox code does this in the calling function, not here */
246 pcm_val = pcm_val >> 3;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 /* A-law using even bit inversion */
249 if (pcm_val >= 0) {
250 mask = 0xD5; /* sign (7th) bit = 1 */
251 } else {
252 mask = 0x55; /* sign bit = 0 */
253 pcm_val = -pcm_val - 1;
254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Convert the scaled magnitude to segment number. */
257 seg = search(pcm_val, seg_aend, 8);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 /* Combine the sign, segment, and quantization bits. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (seg >= 8) /* out of range, return maximum value. */
262 return (unsigned char) (0x7F ^ mask);
263 else {
264 aval = (unsigned char) seg << SEG_SHIFT;
265 if (seg < 2)
266 aval |= (pcm_val >> 1) & QUANT_MASK;
267 else
268 aval |= (pcm_val >> seg) & QUANT_MASK;
269 return (aval ^ mask);
270 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000271}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000272/* End of code taken from sox */
273
Guido van Rossumb64e6351992-07-06 14:21:56 +0000274/* Intel ADPCM step variation table */
275static int indexTable[16] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 -1, -1, -1, -1, 2, 4, 6, 8,
277 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000278};
279
280static int stepsizeTable[89] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
282 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
283 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
284 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
285 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
286 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
287 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
288 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
289 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000290};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291
Guido van Rossumb66efa01992-06-01 16:01:24 +0000292#define CHARP(cp, i) ((signed char *)(cp+i))
293#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000294#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000295
296
297
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000298static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000299
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000300static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000301audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000304 Py_ssize_t len, i;
305 int size, val = 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000306
Mark Dickinson81fece22010-05-11 13:34:35 +0000307 if ( !PyArg_ParseTuple(args, "s#in:getsample", &cp, &len, &size, &i) )
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 return 0;
309 if ( size != 1 && size != 2 && size != 4 ) {
310 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
311 return 0;
312 }
313 if ( i < 0 || i >= len/size ) {
314 PyErr_SetString(AudioopError, "Index out of range");
315 return 0;
316 }
317 if ( size == 1 ) val = (int)*CHARP(cp, i);
318 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
319 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
320 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000321}
322
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000324audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000327 Py_ssize_t len, i;
328 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
332 return 0;
333 if ( size != 1 && size != 2 && size != 4 ) {
334 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
335 return 0;
336 }
337 for ( i=0; i<len; i+= size) {
338 if ( size == 1 ) val = (int)*CHARP(cp, i);
339 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
340 else if ( size == 4 ) val = (int)*LONGP(cp, i);
341 if ( val < 0 ) val = (-val);
342 if ( val > max ) max = val;
343 }
344 return PyLong_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000345}
346
347static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000348audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000351 Py_ssize_t len, i;
352 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
356 return NULL;
357 if (size != 1 && size != 2 && size != 4) {
358 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
359 return NULL;
360 }
361 for (i = 0; i < len; i += size) {
362 if (size == 1) val = (int) *CHARP(cp, i);
363 else if (size == 2) val = (int) *SHORTP(cp, i);
364 else if (size == 4) val = (int) *LONGP(cp, i);
365 if (val > max) max = val;
366 if (val < min) min = val;
367 }
368 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000369}
370
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000371static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000372audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000375 Py_ssize_t len, i;
376 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
380 return 0;
381 if ( size != 1 && size != 2 && size != 4 ) {
382 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
383 return 0;
384 }
385 for ( i=0; i<len; i+= size) {
386 if ( size == 1 ) val = (int)*CHARP(cp, i);
387 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
388 else if ( size == 4 ) val = (int)*LONGP(cp, i);
389 avg += val;
390 }
391 if ( len == 0 )
392 val = 0;
393 else
394 val = (int)(avg / (double)(len/size));
395 return PyLong_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000396}
397
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000398static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000399audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000400{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000402 Py_ssize_t len, i;
403 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
407 return 0;
408 if ( size != 1 && size != 2 && size != 4 ) {
409 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
410 return 0;
411 }
412 for ( i=0; i<len; i+= size) {
413 if ( size == 1 ) val = (int)*CHARP(cp, i);
414 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
415 else if ( size == 4 ) val = (int)*LONGP(cp, i);
416 sum_squares += (double)val*(double)val;
417 }
418 if ( len == 0 )
419 val = 0;
420 else
421 val = (int)sqrt(sum_squares / (double)(len/size));
422 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000423}
424
Mark Dickinson81fece22010-05-11 13:34:35 +0000425static double _sum2(short *a, short *b, Py_ssize_t len)
Jack Jansena90805f1993-02-17 14:29:28 +0000426{
Mark Dickinson81fece22010-05-11 13:34:35 +0000427 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 for( i=0; i<len; i++) {
431 sum = sum + (double)a[i]*(double)b[i];
432 }
433 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000434}
435
436/*
437** Findfit tries to locate a sample within another sample. Its main use
438** is in echo-cancellation (to find the feedback of the output signal in
439** the input signal).
440** The method used is as follows:
441**
442** let R be the reference signal (length n) and A the input signal (length N)
443** with N > n, and let all sums be over i from 0 to n-1.
444**
445** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
446** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
447** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
448**
449** Next, we compute the relative distance between the original signal and
450** the modified signal and minimize that over j:
451** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
452** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
453**
454** In the code variables correspond as follows:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000455** cp1 A
456** cp2 R
457** len1 N
458** len2 n
459** aj_m1 A[j-1]
460** aj_lm1 A[j+n-1]
461** sum_ri_2 sum(R[i]^2)
462** sum_aij_2 sum(A[i+j]^2)
463** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000464**
465** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
466** is completely recalculated each step.
467*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000468static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000469audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000472 Py_ssize_t len1, len2;
473 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 double aj_m1, aj_lm1;
475 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 /* Passing a short** for an 's' argument is correct only
478 if the string contents is aligned for interpretation
479 as short[]. Due to the definition of PyBytesObject,
480 this is currently (Python 2.6) the case. */
481 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
482 (char**)&cp1, &len1, (char**)&cp2, &len2) )
483 return 0;
484 if ( len1 & 1 || len2 & 1 ) {
485 PyErr_SetString(AudioopError, "Strings should be even-sized");
486 return 0;
487 }
488 len1 >>= 1;
489 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 if ( len1 < len2 ) {
492 PyErr_SetString(AudioopError, "First sample should be longer");
493 return 0;
494 }
495 sum_ri_2 = _sum2(cp2, cp2, len2);
496 sum_aij_2 = _sum2(cp1, cp1, len2);
497 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 best_result = result;
502 best_j = 0;
503 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 for ( j=1; j<=len1-len2; j++) {
506 aj_m1 = (double)cp1[j-1];
507 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
510 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
513 / sum_aij_2;
514
515 if ( result < best_result ) {
516 best_result = result;
517 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000518 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 }
521
522 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
523
Mark Dickinson81fece22010-05-11 13:34:35 +0000524 return Py_BuildValue("(nf)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000525}
526
527/*
528** findfactor finds a factor f so that the energy in A-fB is minimal.
529** See the comment for findfit for details.
530*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000531static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000532audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 short *cp1, *cp2;
Mark Dickinson81fece22010-05-11 13:34:35 +0000535 Py_ssize_t len1, len2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
539 (char**)&cp1, &len1, (char**)&cp2, &len2) )
540 return 0;
541 if ( len1 & 1 || len2 & 1 ) {
542 PyErr_SetString(AudioopError, "Strings should be even-sized");
543 return 0;
544 }
545 if ( len1 != len2 ) {
546 PyErr_SetString(AudioopError, "Samples should be same size");
547 return 0;
548 }
549 len2 >>= 1;
550 sum_ri_2 = _sum2(cp2, cp2, len2);
551 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000556}
557
558/*
559** findmax returns the index of the n-sized segment of the input sample
560** that contains the most energy.
561*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000562static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000563audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 short *cp1;
Mark Dickinson81fece22010-05-11 13:34:35 +0000566 Py_ssize_t len1, len2;
567 Py_ssize_t j, best_j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 double aj_m1, aj_lm1;
569 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000570
Mark Dickinson81fece22010-05-11 13:34:35 +0000571 if ( !PyArg_ParseTuple(args, "s#n:findmax",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 (char**)&cp1, &len1, &len2) )
573 return 0;
574 if ( len1 & 1 ) {
575 PyErr_SetString(AudioopError, "Strings should be even-sized");
576 return 0;
577 }
578 len1 >>= 1;
579
580 if ( len2 < 0 || len1 < len2 ) {
581 PyErr_SetString(AudioopError, "Input sample should be longer");
582 return 0;
583 }
584
585 result = _sum2(cp1, cp1, len2);
586
587 best_result = result;
588 best_j = 0;
589 j = 0;
590
591 for ( j=1; j<=len1-len2; j++) {
592 aj_m1 = (double)cp1[j-1];
593 aj_lm1 = (double)cp1[j+len2-1];
594
595 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
596
597 if ( result > best_result ) {
598 best_result = result;
599 best_j = j;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000600 }
Jack Jansena90805f1993-02-17 14:29:28 +0000601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000603
Mark Dickinson81fece22010-05-11 13:34:35 +0000604 return PyLong_FromSsize_t(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000605}
606
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000607static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000608audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000611 Py_ssize_t len, i;
612 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 prevextreme = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 double avg = 0.0;
615 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
618 return 0;
619 if ( size != 1 && size != 2 && size != 4 ) {
620 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
621 return 0;
622 }
623 /* Compute first delta value ahead. Also automatically makes us
624 ** skip the first extreme value
625 */
626 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
627 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
628 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
629 if ( size == 1 ) val = (int)*CHARP(cp, size);
630 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
631 else if ( size == 4 ) val = (int)*LONGP(cp, size);
632 prevdiff = val - prevval;
633
634 for ( i=size; i<len; i+= size) {
635 if ( size == 1 ) val = (int)*CHARP(cp, i);
636 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
637 else if ( size == 4 ) val = (int)*LONGP(cp, i);
638 diff = val - prevval;
639 if ( diff*prevdiff < 0 ) {
640 /* Derivative changed sign. Compute difference to last
641 ** extreme value and remember.
642 */
643 if ( prevextremevalid ) {
644 extremediff = prevval - prevextreme;
645 if ( extremediff < 0 )
646 extremediff = -extremediff;
647 avg += extremediff;
648 nextreme++;
649 }
650 prevextremevalid = 1;
651 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000652 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 prevval = val;
654 if ( diff != 0 )
655 prevdiff = diff;
656 }
657 if ( nextreme == 0 )
658 val = 0;
659 else
660 val = (int)(avg / (double)nextreme);
661 return PyLong_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000662}
663
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000664static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000665audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000668 Py_ssize_t len, i;
669 int size, val = 0, prevval = 0, prevextremevalid = 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 prevextreme = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 int max = 0;
672 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
675 return 0;
676 if ( size != 1 && size != 2 && size != 4 ) {
677 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
678 return 0;
679 }
680 /* Compute first delta value ahead. Also automatically makes us
681 ** skip the first extreme value
682 */
683 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
684 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
685 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
686 if ( size == 1 ) val = (int)*CHARP(cp, size);
687 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
688 else if ( size == 4 ) val = (int)*LONGP(cp, size);
689 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 for ( i=size; i<len; i+= size) {
692 if ( size == 1 ) val = (int)*CHARP(cp, i);
693 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
694 else if ( size == 4 ) val = (int)*LONGP(cp, i);
695 diff = val - prevval;
696 if ( diff*prevdiff < 0 ) {
697 /* Derivative changed sign. Compute difference to
698 ** last extreme value and remember.
699 */
700 if ( prevextremevalid ) {
701 extremediff = prevval - prevextreme;
702 if ( extremediff < 0 )
703 extremediff = -extremediff;
704 if ( extremediff > max )
705 max = extremediff;
706 }
707 prevextremevalid = 1;
708 prevextreme = prevval;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000709 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 prevval = val;
711 if ( diff != 0 )
712 prevdiff = diff;
713 }
714 return PyLong_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000715}
716
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000717static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000718audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 signed char *cp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000721 Py_ssize_t len, i;
722 int size, val = 0;
723 int prevval;
724 Py_ssize_t ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
727 return 0;
728 if ( size != 1 && size != 2 && size != 4 ) {
729 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
730 return 0;
731 }
732 ncross = -1;
733 prevval = 17; /* Anything <> 0,1 */
734 for ( i=0; i<len; i+= size) {
735 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
736 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
737 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
738 val = val & 1;
739 if ( val != prevval ) ncross++;
740 prevval = val;
741 }
Mark Dickinson81fece22010-05-11 13:34:35 +0000742 return PyLong_FromSsize_t(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000743}
744
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000745static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000746audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000749 Py_ssize_t len, i;
750 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 double factor, fval, maxval;
752 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
755 return 0;
756
757 if ( size == 1 ) maxval = (double) 0x7f;
758 else if ( size == 2 ) maxval = (double) 0x7fff;
759 else if ( size == 4 ) maxval = (double) 0x7fffffff;
760 else {
761 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
762 return 0;
763 }
764
765 rv = PyBytes_FromStringAndSize(NULL, len);
766 if ( rv == 0 )
767 return 0;
768 ncp = (signed char *)PyBytes_AsString(rv);
769
770
771 for ( i=0; i < len; i += size ) {
772 if ( size == 1 ) val = (int)*CHARP(cp, i);
773 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
774 else if ( size == 4 ) val = (int)*LONGP(cp, i);
775 fval = (double)val*factor;
776 if ( fval > maxval ) fval = maxval;
777 else if ( fval < -maxval ) fval = -maxval;
778 val = (int)fval;
779 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
780 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
781 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
782 }
783 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000784}
785
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000786static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000787audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 Py_buffer pcp;
790 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000791 Py_ssize_t len, i;
792 int size, val1 = 0, val2 = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 double fac1, fac2, fval, maxval;
794 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 if ( !PyArg_ParseTuple(args, "s*idd:tomono",
797 &pcp, &size, &fac1, &fac2 ) )
798 return 0;
799 cp = pcp.buf;
800 len = pcp.len;
801
802 if ( size == 1 ) maxval = (double) 0x7f;
803 else if ( size == 2 ) maxval = (double) 0x7fff;
804 else if ( size == 4 ) maxval = (double) 0x7fffffff;
805 else {
806 PyBuffer_Release(&pcp);
807 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
808 return 0;
809 }
810
811 rv = PyBytes_FromStringAndSize(NULL, len/2);
812 if ( rv == 0 )
813 return 0;
814 ncp = (signed char *)PyBytes_AsString(rv);
815
816
817 for ( i=0; i < len; i += size*2 ) {
818 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
819 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
820 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
821 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
822 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
823 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
824 fval = (double)val1*fac1 + (double)val2*fac2;
825 if ( fval > maxval ) fval = maxval;
826 else if ( fval < -maxval ) fval = -maxval;
827 val1 = (int)fval;
828 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
829 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
830 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
831 }
832 PyBuffer_Release(&pcp);
833 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834}
835
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000836static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000837audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000840 Py_ssize_t len, i;
841 int size, val1, val2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 double fac1, fac2, fval, maxval;
843 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
846 &cp, &len, &size, &fac1, &fac2 ) )
847 return 0;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +0000848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 if ( size == 1 ) maxval = (double) 0x7f;
850 else if ( size == 2 ) maxval = (double) 0x7fff;
851 else if ( size == 4 ) maxval = (double) 0x7fffffff;
852 else {
853 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
854 return 0;
855 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000856
Mark Dickinson81fece22010-05-11 13:34:35 +0000857 if (len > PY_SSIZE_T_MAX/2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 PyErr_SetString(PyExc_MemoryError,
859 "not enough memory for output buffer");
860 return 0;
861 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000862
Mark Dickinson85eacea2010-05-10 16:27:45 +0000863 rv = PyBytes_FromStringAndSize(NULL, len*2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 if ( rv == 0 )
865 return 0;
866 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000867
Guido van Rossumb66efa01992-06-01 16:01:24 +0000868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 for ( i=0; i < len; i += size ) {
870 if ( size == 1 ) val = (int)*CHARP(cp, i);
871 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
872 else if ( size == 4 ) val = (int)*LONGP(cp, i);
873
874 fval = (double)val*fac1;
875 if ( fval > maxval ) fval = maxval;
876 else if ( fval < -maxval ) fval = -maxval;
877 val1 = (int)fval;
878
879 fval = (double)val*fac2;
880 if ( fval > maxval ) fval = maxval;
881 else if ( fval < -maxval ) fval = -maxval;
882 val2 = (int)fval;
883
884 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
885 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
886 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
887
888 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
889 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
890 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
891 }
892 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893}
894
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000895static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000896audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 signed char *cp1, *cp2, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000899 Py_ssize_t len1, len2, i;
900 int size, val1 = 0, val2 = 0, maxval, newval;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 if ( !PyArg_ParseTuple(args, "s#s#i:add",
904 &cp1, &len1, &cp2, &len2, &size ) )
905 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 if ( len1 != len2 ) {
908 PyErr_SetString(AudioopError, "Lengths should be the same");
909 return 0;
910 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 if ( size == 1 ) maxval = 0x7f;
913 else if ( size == 2 ) maxval = 0x7fff;
914 else if ( size == 4 ) maxval = 0x7fffffff;
915 else {
916 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
917 return 0;
918 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 rv = PyBytes_FromStringAndSize(NULL, len1);
921 if ( rv == 0 )
922 return 0;
923 ncp = (signed char *)PyBytes_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 for ( i=0; i < len1; i += size ) {
926 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
927 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
928 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
931 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
932 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
933
934 newval = val1 + val2;
935 /* truncate in case of overflow */
936 if (newval > maxval) newval = maxval;
937 else if (newval < -maxval) newval = -maxval;
938 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
939 newval = val1 > 0 ? maxval : - maxval;
940
941 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
942 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
943 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
944 }
945 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000946}
947
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000948static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000949audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 signed char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000952 Py_ssize_t len, i;
953 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 PyObject *rv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if ( !PyArg_ParseTuple(args, "s#ii:bias",
958 &cp, &len, &size , &bias) )
959 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 if ( size != 1 && size != 2 && size != 4) {
962 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
963 return 0;
964 }
965
966 rv = PyBytes_FromStringAndSize(NULL, len);
967 if ( rv == 0 )
968 return 0;
969 ncp = (signed char *)PyBytes_AsString(rv);
970
971
972 for ( i=0; i < len; i += size ) {
973 if ( size == 1 ) val = (int)*CHARP(cp, i);
974 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
975 else if ( size == 4 ) val = (int)*LONGP(cp, i);
976
977 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
978 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
979 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
980 }
981 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000982}
983
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000984static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000985audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 signed char *cp;
988 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +0000989 Py_ssize_t len, i, j;
990 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 PyObject *rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 if ( !PyArg_ParseTuple(args, "s#i:reverse",
994 &cp, &len, &size) )
995 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 if ( size != 1 && size != 2 && size != 4 ) {
998 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
999 return 0;
1000 }
Jack Jansen337b20e1993-02-23 13:39:57 +00001001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 rv = PyBytes_FromStringAndSize(NULL, len);
1003 if ( rv == 0 )
1004 return 0;
1005 ncp = (unsigned char *)PyBytes_AsString(rv);
1006
1007 for ( i=0; i < len; i += size ) {
1008 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1009 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1010 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1011
1012 j = len - i - size;
1013
1014 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1015 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1016 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1017 }
1018 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001019}
1020
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001021static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001022audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001023{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 signed char *cp;
1025 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001026 Py_ssize_t len, i, j;
1027 int size, size2, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 PyObject *rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1031 &cp, &len, &size, &size2) )
1032 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 if ( (size != 1 && size != 2 && size != 4) ||
1035 (size2 != 1 && size2 != 2 && size2 != 4)) {
1036 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1037 return 0;
1038 }
Jack Jansena90805f1993-02-17 14:29:28 +00001039
Mark Dickinson81fece22010-05-11 13:34:35 +00001040 if (len/size > PY_SSIZE_T_MAX/size2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 PyErr_SetString(PyExc_MemoryError,
1042 "not enough memory for output buffer");
1043 return 0;
1044 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001045 rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 if ( rv == 0 )
1047 return 0;
1048 ncp = (unsigned char *)PyBytes_AsString(rv);
1049
1050 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1051 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1052 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1053 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1054
1055 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1056 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1057 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1058 }
1059 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001060}
1061
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001062static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001063gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 while (b > 0) {
1066 int tmp = a % b;
1067 a = b;
1068 b = tmp;
1069 }
1070 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001071}
1072
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001073static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001074audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 char *cp, *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001077 Py_ssize_t len;
1078 int size, nchannels, inrate, outrate, weightA, weightB;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 int chan, d, *prev_i, *cur_i, cur_o;
1080 PyObject *state, *samps, *str, *rv = NULL;
1081 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 weightA = 1;
1084 weightB = 0;
1085 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1086 &nchannels, &inrate, &outrate, &state,
1087 &weightA, &weightB))
1088 return NULL;
1089 if (size != 1 && size != 2 && size != 4) {
1090 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1091 return NULL;
1092 }
1093 if (nchannels < 1) {
1094 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1095 return NULL;
1096 }
1097 bytes_per_frame = size * nchannels;
1098 if (bytes_per_frame / nchannels != size) {
1099 /* This overflow test is rigorously correct because
1100 both multiplicands are >= 1. Use the argument names
1101 from the docs for the error msg. */
1102 PyErr_SetString(PyExc_OverflowError,
1103 "width * nchannels too big for a C int");
1104 return NULL;
1105 }
1106 if (weightA < 1 || weightB < 0) {
1107 PyErr_SetString(AudioopError,
1108 "weightA should be >= 1, weightB should be >= 0");
1109 return NULL;
1110 }
1111 if (len % bytes_per_frame != 0) {
1112 PyErr_SetString(AudioopError, "not a whole number of frames");
1113 return NULL;
1114 }
1115 if (inrate <= 0 || outrate <= 0) {
1116 PyErr_SetString(AudioopError, "sampling rate not > 0");
1117 return NULL;
1118 }
1119 /* divide inrate and outrate by their greatest common divisor */
1120 d = gcd(inrate, outrate);
1121 inrate /= d;
1122 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001123
Mark Dickinson85eacea2010-05-10 16:27:45 +00001124 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 PyErr_SetString(PyExc_MemoryError,
1126 "not enough memory for output buffer");
1127 return 0;
1128 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001129 prev_i = (int *) malloc(nchannels * sizeof(int));
1130 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 if (prev_i == NULL || cur_i == NULL) {
1132 (void) PyErr_NoMemory();
1133 goto exit;
1134 }
1135
1136 len /= bytes_per_frame; /* # of frames */
1137
1138 if (state == Py_None) {
1139 d = -outrate;
1140 for (chan = 0; chan < nchannels; chan++)
1141 prev_i[chan] = cur_i[chan] = 0;
1142 }
1143 else {
1144 if (!PyArg_ParseTuple(state,
1145 "iO!;audioop.ratecv: illegal state argument",
1146 &d, &PyTuple_Type, &samps))
1147 goto exit;
1148 if (PyTuple_Size(samps) != nchannels) {
1149 PyErr_SetString(AudioopError,
1150 "illegal state argument");
1151 goto exit;
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001152 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 for (chan = 0; chan < nchannels; chan++) {
1154 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1155 "ii:ratecv", &prev_i[chan],
1156 &cur_i[chan]))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001157 goto exit;
1158 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 /* str <- Space for the output buffer. */
1162 {
1163 /* There are len input frames, so we need (mathematically)
1164 ceiling(len*outrate/inrate) output frames, and each frame
1165 requires bytes_per_frame bytes. Computing this
1166 without spurious overflow is the challenge; we can
Mark Dickinson393b97a2010-05-11 13:09:58 +00001167 settle for a reasonable upper bound, though, in this
1168 case ceiling(len/inrate) * outrate. */
1169
1170 /* compute ceiling(len/inrate) without overflow */
Mark Dickinson81fece22010-05-11 13:34:35 +00001171 Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0;
1172 if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 str = NULL;
1174 else
Mark Dickinson393b97a2010-05-11 13:09:58 +00001175 str = PyBytes_FromStringAndSize(NULL,
1176 q * outrate * bytes_per_frame);
Tim Peters1691bd92001-12-05 06:05:07 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 if (str == NULL) {
1179 PyErr_SetString(PyExc_MemoryError,
1180 "not enough memory for output buffer");
1181 goto exit;
1182 }
1183 }
1184 ncp = PyBytes_AsString(str);
1185
1186 for (;;) {
1187 while (d < 0) {
1188 if (len == 0) {
1189 samps = PyTuple_New(nchannels);
1190 if (samps == NULL)
1191 goto exit;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001192 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 PyTuple_SetItem(samps, chan,
1194 Py_BuildValue("(ii)",
1195 prev_i[chan],
1196 cur_i[chan]));
1197 if (PyErr_Occurred())
1198 goto exit;
1199 /* We have checked before that the length
1200 * of the string fits into int. */
Mark Dickinson81fece22010-05-11 13:34:35 +00001201 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 rv = PyBytes_FromStringAndSize
1203 (PyBytes_AsString(str), len);
1204 Py_DECREF(str);
1205 str = rv;
1206 if (str == NULL)
1207 goto exit;
1208 rv = Py_BuildValue("(O(iO))", str, d, samps);
1209 Py_DECREF(samps);
1210 Py_DECREF(str);
1211 goto exit; /* return rv */
1212 }
1213 for (chan = 0; chan < nchannels; chan++) {
1214 prev_i[chan] = cur_i[chan];
1215 if (size == 1)
1216 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1217 else if (size == 2)
1218 cur_i[chan] = (int)*SHORTP(cp, 0);
1219 else if (size == 4)
1220 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1221 cp += size;
1222 /* implements a simple digital filter */
1223 cur_i[chan] =
1224 (weightA * cur_i[chan] +
1225 weightB * prev_i[chan]) /
1226 (weightA + weightB);
1227 }
1228 len--;
1229 d += outrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001230 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 while (d >= 0) {
1232 for (chan = 0; chan < nchannels; chan++) {
1233 cur_o = (prev_i[chan] * d +
1234 cur_i[chan] * (outrate - d)) /
1235 outrate;
1236 if (size == 1)
1237 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1238 else if (size == 2)
1239 *SHORTP(ncp, 0) = (short)(cur_o);
1240 else if (size == 4)
1241 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1242 ncp += size;
1243 }
1244 d -= inrate;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001245 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001247 exit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 if (prev_i != NULL)
1249 free(prev_i);
1250 if (cur_i != NULL)
1251 free(cur_i);
1252 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001253}
Guido van Rossum1851a671997-02-14 16:14:03 +00001254
Roger E. Massec905fff1997-01-17 18:12:04 +00001255static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001256audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 signed char *cp;
1259 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001260 Py_ssize_t len, i;
1261 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1265 &cp, &len, &size) )
1266 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if ( size != 1 && size != 2 && size != 4) {
1269 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1270 return 0;
1271 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 rv = PyBytes_FromStringAndSize(NULL, len/size);
1274 if ( rv == 0 )
1275 return 0;
1276 ncp = (unsigned char *)PyBytes_AsString(rv);
1277
1278 for ( i=0; i < len; i += size ) {
1279 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1280 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1281 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1282
1283 *ncp++ = st_14linear2ulaw(val);
1284 }
1285 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001286}
1287
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001288static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001289audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 unsigned char *cp;
1292 unsigned char cval;
1293 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001294 Py_ssize_t len, i;
1295 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 PyObject *rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1299 &cp, &len, &size) )
1300 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 if ( size != 1 && size != 2 && size != 4) {
1303 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1304 return 0;
1305 }
1306
Mark Dickinson81fece22010-05-11 13:34:35 +00001307 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyErr_SetString(PyExc_MemoryError,
1309 "not enough memory for output buffer");
1310 return 0;
1311 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001312 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 if ( rv == 0 )
1314 return 0;
1315 ncp = (signed char *)PyBytes_AsString(rv);
1316
Mark Dickinson85eacea2010-05-10 16:27:45 +00001317 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 cval = *cp++;
1319 val = st_ulaw2linear16(cval);
1320
1321 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1322 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1323 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1324 }
1325 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001326}
1327
1328static PyObject *
1329audioop_lin2alaw(PyObject *self, PyObject *args)
1330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 signed char *cp;
1332 unsigned char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001333 Py_ssize_t len, i;
1334 int size, val = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1338 &cp, &len, &size) )
1339 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 if ( size != 1 && size != 2 && size != 4) {
1342 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1343 return 0;
1344 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 rv = PyBytes_FromStringAndSize(NULL, len/size);
1347 if ( rv == 0 )
1348 return 0;
1349 ncp = (unsigned char *)PyBytes_AsString(rv);
1350
1351 for ( i=0; i < len; i += size ) {
1352 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1353 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1354 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1355
1356 *ncp++ = st_linear2alaw(val);
1357 }
1358 return rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001359}
1360
1361static PyObject *
1362audioop_alaw2lin(PyObject *self, PyObject *args)
1363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 unsigned char *cp;
1365 unsigned char cval;
1366 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001367 Py_ssize_t len, i;
1368 int size, val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 PyObject *rv;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1372 &cp, &len, &size) )
1373 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 if ( size != 1 && size != 2 && size != 4) {
1376 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1377 return 0;
1378 }
1379
Mark Dickinson81fece22010-05-11 13:34:35 +00001380 if (len > PY_SSIZE_T_MAX/size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyErr_SetString(PyExc_MemoryError,
1382 "not enough memory for output buffer");
1383 return 0;
1384 }
Mark Dickinson85eacea2010-05-10 16:27:45 +00001385 rv = PyBytes_FromStringAndSize(NULL, len*size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 if ( rv == 0 )
1387 return 0;
1388 ncp = (signed char *)PyBytes_AsString(rv);
1389
Mark Dickinson85eacea2010-05-10 16:27:45 +00001390 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 cval = *cp++;
1392 val = st_alaw2linear16(cval);
1393
1394 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1395 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1396 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1397 }
1398 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001399}
1400
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001401static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001402audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 signed char *cp;
1405 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001406 Py_ssize_t len, i;
1407 int size, val = 0, step, valpred, delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 index, sign, vpdiff, diff;
1409 PyObject *rv, *state, *str;
Mark Dickinson81fece22010-05-11 13:34:35 +00001410 int outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1413 &cp, &len, &size, &state) )
1414 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416
1417 if ( size != 1 && size != 2 && size != 4) {
1418 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1419 return 0;
1420 }
1421
1422 str = PyBytes_FromStringAndSize(NULL, len/(size*2));
1423 if ( str == 0 )
1424 return 0;
1425 ncp = (signed char *)PyBytes_AsString(str);
1426
1427 /* Decode state, should have (value, step) */
1428 if ( state == Py_None ) {
1429 /* First time, it seems. Set defaults */
1430 valpred = 0;
1431 step = 7;
1432 index = 0;
1433 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1434 return 0;
1435
1436 step = stepsizeTable[index];
1437 bufferstep = 1;
1438
1439 for ( i=0; i < len; i += size ) {
1440 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1441 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1442 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1443
1444 /* Step 1 - compute difference with previous value */
1445 diff = val - valpred;
1446 sign = (diff < 0) ? 8 : 0;
1447 if ( sign ) diff = (-diff);
1448
1449 /* Step 2 - Divide and clamp */
1450 /* Note:
1451 ** This code *approximately* computes:
1452 ** delta = diff*4/step;
1453 ** vpdiff = (delta+0.5)*step/4;
1454 ** but in shift step bits are dropped. The net result of this
1455 ** is that even if you have fast mul/div hardware you cannot
1456 ** put it to good use since the fixup would be too expensive.
1457 */
1458 delta = 0;
1459 vpdiff = (step >> 3);
1460
1461 if ( diff >= step ) {
1462 delta = 4;
1463 diff -= step;
1464 vpdiff += step;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 step >>= 1;
1467 if ( diff >= step ) {
1468 delta |= 2;
1469 diff -= step;
1470 vpdiff += step;
1471 }
1472 step >>= 1;
1473 if ( diff >= step ) {
1474 delta |= 1;
1475 vpdiff += step;
1476 }
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 /* Step 3 - Update previous value */
1479 if ( sign )
1480 valpred -= vpdiff;
1481 else
1482 valpred += vpdiff;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 /* Step 4 - Clamp previous value to 16 bits */
1485 if ( valpred > 32767 )
1486 valpred = 32767;
1487 else if ( valpred < -32768 )
1488 valpred = -32768;
1489
1490 /* Step 5 - Assemble value, update index and step values */
1491 delta |= sign;
1492
1493 index += indexTable[delta];
1494 if ( index < 0 ) index = 0;
1495 if ( index > 88 ) index = 88;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001496 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 /* Step 6 - Output value */
1499 if ( bufferstep ) {
1500 outputbuffer = (delta << 4) & 0xf0;
1501 } else {
1502 *ncp++ = (delta & 0x0f) | outputbuffer;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001503 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 bufferstep = !bufferstep;
1505 }
1506 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1507 Py_DECREF(str);
1508 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001509}
1510
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001511static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001512audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 signed char *cp;
1515 signed char *ncp;
Mark Dickinson81fece22010-05-11 13:34:35 +00001516 Py_ssize_t len, i;
1517 int size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 PyObject *rv, *str, *state;
Mark Dickinson81fece22010-05-11 13:34:35 +00001519 int inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1522 &cp, &len, &size, &state) )
1523 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 if ( size != 1 && size != 2 && size != 4) {
1526 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1527 return 0;
1528 }
1529
1530 /* Decode state, should have (value, step) */
1531 if ( state == Py_None ) {
1532 /* First time, it seems. Set defaults */
1533 valpred = 0;
1534 step = 7;
1535 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}