blob: e5ff5ad682f8fc5771dc36dc05c63355e43715b0 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Anthony Baxter17471432006-03-20 05:58:21 +000018typedef short PyInt16;
19
Guido van Rossum7b1e9741994-08-29 10:46:42 +000020#if defined(__CHAR_UNSIGNED__)
21#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000022/* This module currently does not work on systems where only unsigned
23 characters are available. Take it out of Setup. Sorry. */
24#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000026
Anthony Baxterfa869072006-03-20 05:21:58 +000027/* Code shamelessly stolen from sox, 12.17.7, g711.c
Guido van Rossumb66efa01992-06-01 16:01:24 +000028** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
29
Anthony Baxterfa869072006-03-20 05:21:58 +000030/* From g711.c:
31 *
32 * December 30, 1994:
33 * Functions linear2alaw, linear2ulaw have been updated to correctly
34 * convert unquantized 16 bit values.
35 * Tables for direct u- to A-law and A- to u-law conversions have been
36 * corrected.
37 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
38 * bli@cpk.auc.dk
39 *
40 */
Guido van Rossumb66efa01992-06-01 16:01:24 +000041#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
42#define CLIP 32635
Anthony Baxter17471432006-03-20 05:58:21 +000043#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
44#define QUANT_MASK (0xf) /* Quantization field mask. */
45#define SEG_SHIFT (4) /* Left shift for segment number. */
46#define SEG_MASK (0x70) /* Segment field mask. */
Guido van Rossumb66efa01992-06-01 16:01:24 +000047
Anthony Baxter17471432006-03-20 05:58:21 +000048static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
49 0x1FF, 0x3FF, 0x7FF, 0xFFF};
50static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
51 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
Anthony Baxterfa869072006-03-20 05:21:58 +000052
Neal Norwitz49c65d02006-03-20 06:34:06 +000053static PyInt16
54search(PyInt16 val, PyInt16 *table, int size)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000055{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000058 for (i = 0; i < size; i++) {
59 if (val <= *table++)
60 return (i);
61 }
62 return (size);
Anthony Baxterfa869072006-03-20 05:21:58 +000063}
64#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
65#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
Guido van Rossumb66efa01992-06-01 16:01:24 +000066
Neal Norwitz49c65d02006-03-20 06:34:06 +000067static PyInt16 _st_ulaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +000068 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
69 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
70 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
71 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
72 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
73 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
74 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
75 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
76 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
77 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
78 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
79 -1052, -988, -924, -876, -844, -812, -780,
80 -748, -716, -684, -652, -620, -588, -556,
81 -524, -492, -460, -428, -396, -372, -356,
82 -340, -324, -308, -292, -276, -260, -244,
83 -228, -212, -196, -180, -164, -148, -132,
84 -120, -112, -104, -96, -88, -80, -72,
85 -64, -56, -48, -40, -32, -24, -16,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000086 -8, 0, 32124, 31100, 30076, 29052, 28028,
Anthony Baxterfa869072006-03-20 05:21:58 +000087 27004, 25980, 24956, 23932, 22908, 21884, 20860,
88 19836, 18812, 17788, 16764, 15996, 15484, 14972,
89 14460, 13948, 13436, 12924, 12412, 11900, 11388,
90 10876, 10364, 9852, 9340, 8828, 8316, 7932,
91 7676, 7420, 7164, 6908, 6652, 6396, 6140,
92 5884, 5628, 5372, 5116, 4860, 4604, 4348,
93 4092, 3900, 3772, 3644, 3516, 3388, 3260,
94 3132, 3004, 2876, 2748, 2620, 2492, 2364,
95 2236, 2108, 1980, 1884, 1820, 1756, 1692,
96 1628, 1564, 1500, 1436, 1372, 1308, 1244,
97 1180, 1116, 1052, 988, 924, 876, 844,
98 812, 780, 748, 716, 684, 652, 620,
99 588, 556, 524, 492, 460, 428, 396,
100 372, 356, 340, 324, 308, 292, 276,
101 260, 244, 228, 212, 196, 180, 164,
102 148, 132, 120, 112, 104, 96, 88,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
Anthony Baxterfa869072006-03-20 05:21:58 +0000105};
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Anthony Baxterfa869072006-03-20 05:21:58 +0000107/*
108 * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
109 * stored in a unsigned char. This function should only be called with
110 * the data shifted such that it only contains information in the lower
111 * 14-bits.
112 *
113 * In order to simplify the encoding process, the original linear magnitude
114 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
115 * (33 - 8191). The result can be seen in the following encoding table:
116 *
Anthony Baxter17471432006-03-20 05:58:21 +0000117 * Biased Linear Input Code Compressed Code
118 * ------------------------ ---------------
119 * 00000001wxyza 000wxyz
120 * 0000001wxyzab 001wxyz
121 * 000001wxyzabc 010wxyz
122 * 00001wxyzabcd 011wxyz
123 * 0001wxyzabcde 100wxyz
124 * 001wxyzabcdef 101wxyz
125 * 01wxyzabcdefg 110wxyz
126 * 1wxyzabcdefgh 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000127 *
128 * Each biased linear code has a leading 1 which identifies the segment
129 * number. The value of the segment number is equal to 7 minus the number
130 * of leading 0's. The quantization interval is directly available as the
131 * four bits wxyz. * The trailing bits (a - h) are ignored.
132 *
133 * Ordinarily the complement of the resulting code word is used for
134 * transmission, and so the code word is complemented before it is returned.
135 *
136 * For further information see John C. Bellamy's Digital Telephony, 1982,
137 * John Wiley & Sons, pps 98-111 and 472-476.
138 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000139static unsigned char
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000141{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000145
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000146 /* The original sox code does this in the calling function, not here */
147 pcm_val = pcm_val >> 2;
Anthony Baxterfa869072006-03-20 05:21:58 +0000148
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000149 /* u-law inverts all bits */
150 /* Get the sign and the magnitude of the value. */
151 if (pcm_val < 0) {
152 pcm_val = -pcm_val;
153 mask = 0x7F;
154 } else {
155 mask = 0xFF;
156 }
157 if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
158 pcm_val += (BIAS >> 2);
Anthony Baxterfa869072006-03-20 05:21:58 +0000159
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000162
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000163 /*
164 * Combine the sign, segment, quantization bits;
165 * and complement the code word.
166 */
167 if (seg >= 8) /* out of range, return maximum value. */
168 return (unsigned char) (0x7F ^ mask);
169 else {
170 uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
171 return (uval ^ mask);
172 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000173
174}
175
Neal Norwitz49c65d02006-03-20 06:34:06 +0000176static PyInt16 _st_alaw2linear16[256] = {
Anthony Baxterfa869072006-03-20 05:21:58 +0000177 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
178 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
179 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
180 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
181 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
182 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
183 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
184 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
185 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
186 -13568, -344, -328, -376, -360, -280, -264,
187 -312, -296, -472, -456, -504, -488, -408,
188 -392, -440, -424, -88, -72, -120, -104,
189 -24, -8, -56, -40, -216, -200, -248,
190 -232, -152, -136, -184, -168, -1376, -1312,
191 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
192 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
193 -688, -656, -752, -720, -560, -528, -624,
194 -592, -944, -912, -1008, -976, -816, -784,
195 -880, -848, 5504, 5248, 6016, 5760, 4480,
196 4224, 4992, 4736, 7552, 7296, 8064, 7808,
197 6528, 6272, 7040, 6784, 2752, 2624, 3008,
198 2880, 2240, 2112, 2496, 2368, 3776, 3648,
199 4032, 3904, 3264, 3136, 3520, 3392, 22016,
200 20992, 24064, 23040, 17920, 16896, 19968, 18944,
201 30208, 29184, 32256, 31232, 26112, 25088, 28160,
202 27136, 11008, 10496, 12032, 11520, 8960, 8448,
203 9984, 9472, 15104, 14592, 16128, 15616, 13056,
204 12544, 14080, 13568, 344, 328, 376, 360,
205 280, 264, 312, 296, 472, 456, 504,
206 488, 408, 392, 440, 424, 88, 72,
207 120, 104, 24, 8, 56, 40, 216,
208 200, 248, 232, 152, 136, 184, 168,
209 1376, 1312, 1504, 1440, 1120, 1056, 1248,
210 1184, 1888, 1824, 2016, 1952, 1632, 1568,
211 1760, 1696, 688, 656, 752, 720, 560,
212 528, 624, 592, 944, 912, 1008, 976,
213 816, 784, 880, 848
214};
215
216/*
217 * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
218 * stored in a unsigned char. This function should only be called with
219 * the data shifted such that it only contains information in the lower
220 * 13-bits.
221 *
Anthony Baxter17471432006-03-20 05:58:21 +0000222 * Linear Input Code Compressed Code
223 * ------------------------ ---------------
224 * 0000000wxyza 000wxyz
225 * 0000001wxyza 001wxyz
226 * 000001wxyzab 010wxyz
227 * 00001wxyzabc 011wxyz
228 * 0001wxyzabcd 100wxyz
229 * 001wxyzabcde 101wxyz
230 * 01wxyzabcdef 110wxyz
231 * 1wxyzabcdefg 111wxyz
Anthony Baxterfa869072006-03-20 05:21:58 +0000232 *
233 * For further information see John C. Bellamy's Digital Telephony, 1982,
234 * John Wiley & Sons, pps 98-111 and 472-476.
235 */
Neal Norwitz49c65d02006-03-20 06:34:06 +0000236static unsigned char
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000238{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000242
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000243 /* The original sox code does this in the calling function, not here */
244 pcm_val = pcm_val >> 3;
Anthony Baxterfa869072006-03-20 05:21:58 +0000245
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000246 /* A-law using even bit inversion */
247 if (pcm_val >= 0) {
248 mask = 0xD5; /* sign (7th) bit = 1 */
249 } else {
250 mask = 0x55; /* sign bit = 0 */
251 pcm_val = -pcm_val - 1;
252 }
Anthony Baxterfa869072006-03-20 05:21:58 +0000253
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000256
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000257 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000258
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000259 if (seg >= 8) /* out of range, return maximum value. */
260 return (unsigned char) (0x7F ^ mask);
261 else {
262 aval = (unsigned char) seg << SEG_SHIFT;
263 if (seg < 2)
264 aval |= (pcm_val >> 1) & QUANT_MASK;
265 else
266 aval |= (pcm_val >> seg) & QUANT_MASK;
267 return (aval ^ mask);
268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000270/* End of code taken from sox */
271
Guido van Rossumb64e6351992-07-06 14:21:56 +0000272/* Intel ADPCM step variation table */
273static int indexTable[16] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000274 -1, -1, -1, -1, 2, 4, 6, 8,
275 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000276};
277
278static int stepsizeTable[89] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000279 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
280 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
281 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
282 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
283 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
284 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
285 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
286 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
287 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000288};
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000289
Guido van Rossumb66efa01992-06-01 16:01:24 +0000290#define CHARP(cp, i) ((signed char *)(cp+i))
291#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000292#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000293
294
295
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000296static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000297
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000298static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000299audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000300{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000301 signed char *cp;
302 int len, size, val = 0;
303 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000304
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000305 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
306 return 0;
307 if ( size != 1 && size != 2 && size != 4 ) {
308 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
309 return 0;
310 }
311 if ( i < 0 || i >= len/size ) {
312 PyErr_SetString(AudioopError, "Index out of range");
313 return 0;
314 }
315 if ( size == 1 ) val = (int)*CHARP(cp, i);
316 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
317 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
318 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000319}
320
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000321static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000322audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000324 signed char *cp;
325 int len, size, val = 0;
326 int i;
327 int max = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000329 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
330 return 0;
331 if ( size != 1 && size != 2 && size != 4 ) {
332 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
333 return 0;
334 }
335 for ( i=0; i<len; i+= size) {
336 if ( size == 1 ) val = (int)*CHARP(cp, i);
337 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
338 else if ( size == 4 ) val = (int)*LONGP(cp, i);
339 if ( val < 0 ) val = (-val);
340 if ( val > max ) max = val;
341 }
342 return PyInt_FromLong(max);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000343}
344
345static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000346audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000347{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000348 signed char *cp;
349 int len, size, val = 0;
350 int i;
351 int min = 0x7fffffff, max = -0x7fffffff;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000352
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000353 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
354 return NULL;
355 if (size != 1 && size != 2 && size != 4) {
356 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
357 return NULL;
358 }
359 for (i = 0; i < len; i += size) {
360 if (size == 1) val = (int) *CHARP(cp, i);
361 else if (size == 2) val = (int) *SHORTP(cp, i);
362 else if (size == 4) val = (int) *LONGP(cp, i);
363 if (val > max) max = val;
364 if (val < min) min = val;
365 }
366 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000367}
368
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000369static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000370audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000371{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000372 signed char *cp;
373 int len, size, val = 0;
374 int i;
375 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000376
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000377 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
378 return 0;
379 if ( size != 1 && size != 2 && size != 4 ) {
380 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
381 return 0;
382 }
383 for ( i=0; i<len; i+= size) {
384 if ( size == 1 ) val = (int)*CHARP(cp, i);
385 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
386 else if ( size == 4 ) val = (int)*LONGP(cp, i);
387 avg += val;
388 }
389 if ( len == 0 )
390 val = 0;
391 else
392 val = (int)(avg / (double)(len/size));
393 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000394}
395
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000396static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000397audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000398{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000399 signed char *cp;
400 int len, size, val = 0;
401 int i;
402 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000403
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000404 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
405 return 0;
406 if ( size != 1 && size != 2 && size != 4 ) {
407 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
408 return 0;
409 }
410 for ( i=0; i<len; i+= size) {
411 if ( size == 1 ) val = (int)*CHARP(cp, i);
412 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
413 else if ( size == 4 ) val = (int)*LONGP(cp, i);
414 sum_squares += (double)val*(double)val;
415 }
416 if ( len == 0 )
417 val = 0;
418 else
419 val = (int)sqrt(sum_squares / (double)(len/size));
420 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000421}
422
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000423static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000424{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000425 int i;
426 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000427
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000428 for( i=0; i<len; i++) {
429 sum = sum + (double)a[i]*(double)b[i];
430 }
431 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000432}
433
434/*
435** Findfit tries to locate a sample within another sample. Its main use
436** is in echo-cancellation (to find the feedback of the output signal in
437** the input signal).
438** The method used is as follows:
439**
440** let R be the reference signal (length n) and A the input signal (length N)
441** with N > n, and let all sums be over i from 0 to n-1.
442**
443** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
444** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
445** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
446**
447** Next, we compute the relative distance between the original signal and
448** the modified signal and minimize that over j:
449** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
450** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
451**
452** In the code variables correspond as follows:
Anthony Baxter17471432006-03-20 05:58:21 +0000453** cp1 A
454** cp2 R
455** len1 N
456** len2 n
457** aj_m1 A[j-1]
458** aj_lm1 A[j+n-1]
459** sum_ri_2 sum(R[i]^2)
460** sum_aij_2 sum(A[i+j]^2)
461** sum_aij_ri sum(A[i+j]R[i])
Jack Jansena90805f1993-02-17 14:29:28 +0000462**
463** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
464** is completely recalculated each step.
465*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000466static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000467audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000468{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000469 short *cp1, *cp2;
470 int len1, len2;
471 int j, best_j;
472 double aj_m1, aj_lm1;
473 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000474
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000475 /* Passing a short** for an 's' argument is correct only
476 if the string contents is aligned for interpretation
477 as short[]. Due to the definition of PyStringObject,
478 this is currently (Python 2.6) the case. */
479 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
480 (char**)&cp1, &len1, (char**)&cp2, &len2) )
481 return 0;
482 if ( len1 & 1 || len2 & 1 ) {
483 PyErr_SetString(AudioopError, "Strings should be even-sized");
484 return 0;
485 }
486 len1 >>= 1;
487 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000488
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000489 if ( len1 < len2 ) {
490 PyErr_SetString(AudioopError, "First sample should be longer");
491 return 0;
492 }
493 sum_ri_2 = _sum2(cp2, cp2, len2);
494 sum_aij_2 = _sum2(cp1, cp1, len2);
495 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000496
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000497 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000498
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000499 best_result = result;
500 best_j = 0;
501 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000503 for ( j=1; j<=len1-len2; j++) {
504 aj_m1 = (double)cp1[j-1];
505 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000506
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000507 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
508 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000509
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000510 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
511 / sum_aij_2;
512
513 if ( result < best_result ) {
514 best_result = result;
515 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000516 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000517
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000518 }
519
520 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
521
522 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000523}
524
525/*
526** findfactor finds a factor f so that the energy in A-fB is minimal.
527** See the comment for findfit for details.
528*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000529static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000530audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000531{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000532 short *cp1, *cp2;
533 int len1, len2;
534 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000535
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000536 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
537 (char**)&cp1, &len1, (char**)&cp2, &len2) )
538 return 0;
539 if ( len1 & 1 || len2 & 1 ) {
540 PyErr_SetString(AudioopError, "Strings should be even-sized");
541 return 0;
542 }
543 if ( len1 != len2 ) {
544 PyErr_SetString(AudioopError, "Samples should be same size");
545 return 0;
546 }
547 len2 >>= 1;
548 sum_ri_2 = _sum2(cp2, cp2, len2);
549 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000550
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000551 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000552
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000553 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000554}
555
556/*
557** findmax returns the index of the n-sized segment of the input sample
558** that contains the most energy.
559*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000561audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000562{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000563 short *cp1;
564 int len1, len2;
565 int j, best_j;
566 double aj_m1, aj_lm1;
567 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000568
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000569 if ( !PyArg_ParseTuple(args, "s#i:findmax",
570 (char**)&cp1, &len1, &len2) )
571 return 0;
572 if ( len1 & 1 ) {
573 PyErr_SetString(AudioopError, "Strings should be even-sized");
574 return 0;
575 }
576 len1 >>= 1;
577
578 if ( len2 < 0 || len1 < len2 ) {
579 PyErr_SetString(AudioopError, "Input sample should be longer");
580 return 0;
581 }
582
583 result = _sum2(cp1, cp1, len2);
584
585 best_result = result;
586 best_j = 0;
587 j = 0;
588
589 for ( j=1; j<=len1-len2; j++) {
590 aj_m1 = (double)cp1[j-1];
591 aj_lm1 = (double)cp1[j+len2-1];
592
593 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
594
595 if ( result > best_result ) {
596 best_result = result;
597 best_j = j;
Anthony Baxter17471432006-03-20 05:58:21 +0000598 }
Jack Jansena90805f1993-02-17 14:29:28 +0000599
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000600 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000601
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000602 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000603}
604
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000606audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000607{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000608 signed char *cp;
609 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
610 prevextreme = 0;
611 int i;
612 double avg = 0.0;
613 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000614
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000615 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
616 return 0;
617 if ( size != 1 && size != 2 && size != 4 ) {
618 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
619 return 0;
620 }
621 /* Compute first delta value ahead. Also automatically makes us
622 ** skip the first extreme value
623 */
624 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
625 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
626 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
627 if ( size == 1 ) val = (int)*CHARP(cp, size);
628 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
629 else if ( size == 4 ) val = (int)*LONGP(cp, size);
630 prevdiff = val - prevval;
631
632 for ( i=size; i<len; i+= size) {
633 if ( size == 1 ) val = (int)*CHARP(cp, i);
634 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
635 else if ( size == 4 ) val = (int)*LONGP(cp, i);
636 diff = val - prevval;
637 if ( diff*prevdiff < 0 ) {
638 /* Derivative changed sign. Compute difference to last
639 ** extreme value and remember.
640 */
641 if ( prevextremevalid ) {
642 extremediff = prevval - prevextreme;
643 if ( extremediff < 0 )
644 extremediff = -extremediff;
645 avg += extremediff;
646 nextreme++;
647 }
648 prevextremevalid = 1;
649 prevextreme = prevval;
Anthony Baxter17471432006-03-20 05:58:21 +0000650 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000651 prevval = val;
652 if ( diff != 0 )
653 prevdiff = diff;
654 }
655 if ( nextreme == 0 )
656 val = 0;
657 else
658 val = (int)(avg / (double)nextreme);
659 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000660}
661
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000662static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000663audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000664{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000665 signed char *cp;
666 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
667 prevextreme = 0;
668 int i;
669 int max = 0;
670 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000671
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000672 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
673 return 0;
674 if ( size != 1 && size != 2 && size != 4 ) {
675 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
676 return 0;
677 }
678 /* Compute first delta value ahead. Also automatically makes us
679 ** skip the first extreme value
680 */
681 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
682 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
683 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
684 if ( size == 1 ) val = (int)*CHARP(cp, size);
685 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
686 else if ( size == 4 ) val = (int)*LONGP(cp, size);
687 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000688
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000689 for ( i=size; i<len; i+= size) {
690 if ( size == 1 ) val = (int)*CHARP(cp, i);
691 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
692 else if ( size == 4 ) val = (int)*LONGP(cp, i);
693 diff = val - prevval;
694 if ( diff*prevdiff < 0 ) {
695 /* Derivative changed sign. Compute difference to
696 ** last extreme value and remember.
697 */
698 if ( prevextremevalid ) {
699 extremediff = prevval - prevextreme;
700 if ( extremediff < 0 )
701 extremediff = -extremediff;
702 if ( extremediff > max )
703 max = extremediff;
704 }
705 prevextremevalid = 1;
706 prevextreme = prevval;
Anthony Baxter17471432006-03-20 05:58:21 +0000707 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000708 prevval = val;
709 if ( diff != 0 )
710 prevdiff = diff;
711 }
712 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000713}
714
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000715static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000716audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000718 signed char *cp;
719 int len, size, val = 0;
720 int i;
721 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000723 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
724 return 0;
725 if ( size != 1 && size != 2 && size != 4 ) {
726 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
727 return 0;
728 }
729 ncross = -1;
730 prevval = 17; /* Anything <> 0,1 */
731 for ( i=0; i<len; i+= size) {
732 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
733 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
734 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
735 val = val & 1;
736 if ( val != prevval ) ncross++;
737 prevval = val;
738 }
739 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000740}
741
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000742static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000743audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000744{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000745 signed char *cp, *ncp;
746 int len, size, val = 0;
747 double factor, fval, maxval;
748 PyObject *rv;
749 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000751 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
752 return 0;
753
754 if ( size == 1 ) maxval = (double) 0x7f;
755 else if ( size == 2 ) maxval = (double) 0x7fff;
756 else if ( size == 4 ) maxval = (double) 0x7fffffff;
757 else {
758 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
759 return 0;
760 }
761
762 rv = PyString_FromStringAndSize(NULL, len);
763 if ( rv == 0 )
764 return 0;
765 ncp = (signed char *)PyString_AsString(rv);
766
767
768 for ( i=0; i < len; i += size ) {
769 if ( size == 1 ) val = (int)*CHARP(cp, i);
770 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
771 else if ( size == 4 ) val = (int)*LONGP(cp, i);
772 fval = (double)val*factor;
773 if ( fval > maxval ) fval = maxval;
774 else if ( fval < -maxval ) fval = -maxval;
775 val = (int)fval;
776 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
777 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
778 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
779 }
780 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000781}
782
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000784audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000785{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000786 signed char *cp, *ncp;
787 int len, size, val1 = 0, val2 = 0;
788 double fac1, fac2, fval, maxval;
789 PyObject *rv;
790 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000792 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
793 &cp, &len, &size, &fac1, &fac2 ) )
794 return 0;
795
796 if ( size == 1 ) maxval = (double) 0x7f;
797 else if ( size == 2 ) maxval = (double) 0x7fff;
798 else if ( size == 4 ) maxval = (double) 0x7fffffff;
799 else {
800 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
801 return 0;
802 }
803
804 rv = PyString_FromStringAndSize(NULL, len/2);
805 if ( rv == 0 )
806 return 0;
807 ncp = (signed char *)PyString_AsString(rv);
808
809
810 for ( i=0; i < len; i += size*2 ) {
811 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
812 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
813 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
814 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
815 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
816 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
817 fval = (double)val1*fac1 + (double)val2*fac2;
818 if ( fval > maxval ) fval = maxval;
819 else if ( fval < -maxval ) fval = -maxval;
820 val1 = (int)fval;
821 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
822 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
823 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
824 }
825 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000826}
827
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000828static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000829audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000830{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000831 signed char *cp, *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +0000832 int len, size, val1, val2, val = 0;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000833 double fac1, fac2, fval, maxval;
834 PyObject *rv;
835 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000836
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000837 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
838 &cp, &len, &size, &fac1, &fac2 ) )
839 return 0;
Gregory P. Smith9d534572008-06-11 07:41:16 +0000840
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000841 if ( size == 1 ) maxval = (double) 0x7f;
842 else if ( size == 2 ) maxval = (double) 0x7fff;
843 else if ( size == 4 ) maxval = (double) 0x7fffffff;
844 else {
845 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
846 return 0;
847 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000848
Mark Dickinson47e3bf22010-05-10 16:16:52 +0000849 if (len > INT_MAX/2) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000850 PyErr_SetString(PyExc_MemoryError,
851 "not enough memory for output buffer");
852 return 0;
853 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854
Mark Dickinson47e3bf22010-05-10 16:16:52 +0000855 rv = PyString_FromStringAndSize(NULL, len*2);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000856 if ( rv == 0 )
857 return 0;
858 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000859
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000861 for ( i=0; i < len; i += size ) {
862 if ( size == 1 ) val = (int)*CHARP(cp, i);
863 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
864 else if ( size == 4 ) val = (int)*LONGP(cp, i);
865
866 fval = (double)val*fac1;
867 if ( fval > maxval ) fval = maxval;
868 else if ( fval < -maxval ) fval = -maxval;
869 val1 = (int)fval;
870
871 fval = (double)val*fac2;
872 if ( fval > maxval ) fval = maxval;
873 else if ( fval < -maxval ) fval = -maxval;
874 val2 = (int)fval;
875
876 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
877 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
878 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
879
880 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
881 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
882 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
883 }
884 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000885}
886
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000887static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000888audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000889{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000890 signed char *cp1, *cp2, *ncp;
891 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
892 PyObject *rv;
893 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000894
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000895 if ( !PyArg_ParseTuple(args, "s#s#i:add",
896 &cp1, &len1, &cp2, &len2, &size ) )
897 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000898
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000899 if ( len1 != len2 ) {
900 PyErr_SetString(AudioopError, "Lengths should be the same");
901 return 0;
902 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000903
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000904 if ( size == 1 ) maxval = 0x7f;
905 else if ( size == 2 ) maxval = 0x7fff;
906 else if ( size == 4 ) maxval = 0x7fffffff;
907 else {
908 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
909 return 0;
910 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000911
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000912 rv = PyString_FromStringAndSize(NULL, len1);
913 if ( rv == 0 )
914 return 0;
915 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000916
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000917 for ( i=0; i < len1; i += size ) {
918 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
919 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
920 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossum1851a671997-02-14 16:14:03 +0000921
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000922 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
923 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
924 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
925
926 newval = val1 + val2;
927 /* truncate in case of overflow */
928 if (newval > maxval) newval = maxval;
929 else if (newval < -maxval) newval = -maxval;
930 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
931 newval = val1 > 0 ? maxval : - maxval;
932
933 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
934 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
935 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
936 }
937 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000938}
939
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000940static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000941audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000942{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000943 signed char *cp, *ncp;
944 int len, size, val = 0;
945 PyObject *rv;
946 int i;
947 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000948
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000949 if ( !PyArg_ParseTuple(args, "s#ii:bias",
950 &cp, &len, &size , &bias) )
951 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000952
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000953 if ( size != 1 && size != 2 && size != 4) {
954 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
955 return 0;
956 }
957
958 rv = PyString_FromStringAndSize(NULL, len);
959 if ( rv == 0 )
960 return 0;
961 ncp = (signed char *)PyString_AsString(rv);
962
963
964 for ( i=0; i < len; i += size ) {
965 if ( size == 1 ) val = (int)*CHARP(cp, i);
966 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
967 else if ( size == 4 ) val = (int)*LONGP(cp, i);
968
969 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
970 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
971 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
972 }
973 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000974}
975
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000976static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000977audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000978{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000979 signed char *cp;
980 unsigned char *ncp;
981 int len, size, val = 0;
982 PyObject *rv;
983 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000984
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000985 if ( !PyArg_ParseTuple(args, "s#i:reverse",
986 &cp, &len, &size) )
987 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000988
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000989 if ( size != 1 && size != 2 && size != 4 ) {
990 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
991 return 0;
992 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000993
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000994 rv = PyString_FromStringAndSize(NULL, len);
995 if ( rv == 0 )
996 return 0;
997 ncp = (unsigned char *)PyString_AsString(rv);
998
999 for ( i=0; i < len; i += size ) {
1000 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1001 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1002 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1003
1004 j = len - i - size;
1005
1006 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1007 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1008 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1009 }
1010 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001011}
1012
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001013static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001014audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001015{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001016 signed char *cp;
1017 unsigned char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001018 int len, size, size2, val = 0;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001019 PyObject *rv;
1020 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001021
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001022 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
1023 &cp, &len, &size, &size2) )
1024 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001025
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001026 if ( (size != 1 && size != 2 && size != 4) ||
1027 (size2 != 1 && size2 != 2 && size2 != 4)) {
1028 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1029 return 0;
1030 }
Jack Jansena90805f1993-02-17 14:29:28 +00001031
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001032 if (len/size > INT_MAX/size2) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001033 PyErr_SetString(PyExc_MemoryError,
1034 "not enough memory for output buffer");
1035 return 0;
1036 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001037 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001038 if ( rv == 0 )
1039 return 0;
1040 ncp = (unsigned char *)PyString_AsString(rv);
1041
1042 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1043 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1044 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1045 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1046
1047 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1048 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1049 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1050 }
1051 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001052}
1053
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001054static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001055gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001056{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001057 while (b > 0) {
1058 int tmp = a % b;
1059 a = b;
1060 b = tmp;
1061 }
1062 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001063}
1064
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001065static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001066audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001067{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001068 char *cp, *ncp;
1069 int len, size, nchannels, inrate, outrate, weightA, weightB;
1070 int chan, d, *prev_i, *cur_i, cur_o;
1071 PyObject *state, *samps, *str, *rv = NULL;
1072 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001073
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001074 weightA = 1;
1075 weightB = 0;
1076 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1077 &nchannels, &inrate, &outrate, &state,
1078 &weightA, &weightB))
1079 return NULL;
1080 if (size != 1 && size != 2 && size != 4) {
1081 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1082 return NULL;
1083 }
1084 if (nchannels < 1) {
1085 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1086 return NULL;
1087 }
1088 bytes_per_frame = size * nchannels;
1089 if (bytes_per_frame / nchannels != size) {
1090 /* This overflow test is rigorously correct because
1091 both multiplicands are >= 1. Use the argument names
1092 from the docs for the error msg. */
1093 PyErr_SetString(PyExc_OverflowError,
1094 "width * nchannels too big for a C int");
1095 return NULL;
1096 }
1097 if (weightA < 1 || weightB < 0) {
1098 PyErr_SetString(AudioopError,
1099 "weightA should be >= 1, weightB should be >= 0");
1100 return NULL;
1101 }
1102 if (len % bytes_per_frame != 0) {
1103 PyErr_SetString(AudioopError, "not a whole number of frames");
1104 return NULL;
1105 }
1106 if (inrate <= 0 || outrate <= 0) {
1107 PyErr_SetString(AudioopError, "sampling rate not > 0");
1108 return NULL;
1109 }
1110 /* divide inrate and outrate by their greatest common divisor */
1111 d = gcd(inrate, outrate);
1112 inrate /= d;
1113 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001114
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001115 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001116 PyErr_SetString(PyExc_MemoryError,
1117 "not enough memory for output buffer");
1118 return 0;
1119 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001120 prev_i = (int *) malloc(nchannels * sizeof(int));
1121 cur_i = (int *) malloc(nchannels * sizeof(int));
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001122 if (prev_i == NULL || cur_i == NULL) {
1123 (void) PyErr_NoMemory();
1124 goto exit;
1125 }
1126
1127 len /= bytes_per_frame; /* # of frames */
1128
1129 if (state == Py_None) {
1130 d = -outrate;
1131 for (chan = 0; chan < nchannels; chan++)
1132 prev_i[chan] = cur_i[chan] = 0;
1133 }
1134 else {
1135 if (!PyArg_ParseTuple(state,
1136 "iO!;audioop.ratecv: illegal state argument",
1137 &d, &PyTuple_Type, &samps))
1138 goto exit;
1139 if (PyTuple_Size(samps) != nchannels) {
1140 PyErr_SetString(AudioopError,
1141 "illegal state argument");
1142 goto exit;
Gregory P. Smith9d534572008-06-11 07:41:16 +00001143 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001144 for (chan = 0; chan < nchannels; chan++) {
1145 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1146 "ii:ratecv", &prev_i[chan],
1147 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001148 goto exit;
1149 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001150 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001151
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001152 /* str <- Space for the output buffer. */
1153 {
1154 /* There are len input frames, so we need (mathematically)
1155 ceiling(len*outrate/inrate) output frames, and each frame
1156 requires bytes_per_frame bytes. Computing this
1157 without spurious overflow is the challenge; we can
1158 settle for a reasonable upper bound, though. */
1159 int ceiling; /* the number of output frames */
1160 int nbytes; /* the number of output bytes needed */
1161 int q = len / inrate;
1162 /* Now len = q * inrate + r exactly (with r = len % inrate),
1163 and this is less than q * inrate + inrate = (q+1)*inrate.
1164 So a reasonable upper bound on len*outrate/inrate is
1165 ((q+1)*inrate)*outrate/inrate =
1166 (q+1)*outrate.
1167 */
1168 ceiling = (q+1) * outrate;
1169 nbytes = ceiling * bytes_per_frame;
1170 /* See whether anything overflowed; if not, get the space. */
1171 if (q+1 < 0 ||
1172 ceiling / outrate != q+1 ||
1173 nbytes / bytes_per_frame != ceiling)
1174 str = NULL;
1175 else
1176 str = PyString_FromStringAndSize(NULL, nbytes);
Tim Peters1691bd92001-12-05 06:05:07 +00001177
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001178 if (str == NULL) {
1179 PyErr_SetString(PyExc_MemoryError,
1180 "not enough memory for output buffer");
1181 goto exit;
1182 }
1183 }
1184 ncp = PyString_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;
Anthony Baxter17471432006-03-20 05:58:21 +00001192 for (chan = 0; chan < nchannels; chan++)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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. */
1201 len = (int)(ncp - PyString_AsString(str));
1202 if (len == 0) {
1203 /*don't want to resize to zero length*/
1204 rv = PyString_FromStringAndSize("", 0);
1205 Py_DECREF(str);
1206 str = rv;
1207 } else if (_PyString_Resize(&str, len) < 0)
1208 goto exit;
1209 rv = Py_BuildValue("(O(iO))", str, d, samps);
1210 Py_DECREF(samps);
1211 Py_DECREF(str);
1212 goto exit; /* return rv */
1213 }
1214 for (chan = 0; chan < nchannels; chan++) {
1215 prev_i[chan] = cur_i[chan];
1216 if (size == 1)
1217 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1218 else if (size == 2)
1219 cur_i[chan] = (int)*SHORTP(cp, 0);
1220 else if (size == 4)
1221 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1222 cp += size;
1223 /* implements a simple digital filter */
1224 cur_i[chan] =
1225 (weightA * cur_i[chan] +
1226 weightB * prev_i[chan]) /
1227 (weightA + weightB);
1228 }
1229 len--;
1230 d += outrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001231 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001232 while (d >= 0) {
1233 for (chan = 0; chan < nchannels; chan++) {
1234 cur_o = (prev_i[chan] * d +
1235 cur_i[chan] * (outrate - d)) /
1236 outrate;
1237 if (size == 1)
1238 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1239 else if (size == 2)
1240 *SHORTP(ncp, 0) = (short)(cur_o);
1241 else if (size == 4)
1242 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1243 ncp += size;
1244 }
1245 d -= inrate;
Anthony Baxter17471432006-03-20 05:58:21 +00001246 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001247 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001248 exit:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001249 if (prev_i != NULL)
1250 free(prev_i);
1251 if (cur_i != NULL)
1252 free(cur_i);
1253 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001254}
Guido van Rossum1851a671997-02-14 16:14:03 +00001255
Roger E. Massec905fff1997-01-17 18:12:04 +00001256static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001257audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001258{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001259 signed char *cp;
1260 unsigned char *ncp;
1261 int len, size, val = 0;
1262 PyObject *rv;
1263 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001264
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001265 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1266 &cp, &len, &size) )
1267 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001268
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001269 if ( size != 1 && size != 2 && size != 4) {
1270 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1271 return 0;
1272 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001273
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001274 rv = PyString_FromStringAndSize(NULL, len/size);
1275 if ( rv == 0 )
1276 return 0;
1277 ncp = (unsigned char *)PyString_AsString(rv);
1278
1279 for ( i=0; i < len; i += size ) {
1280 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1281 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1282 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1283
1284 *ncp++ = st_14linear2ulaw(val);
1285 }
1286 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001287}
1288
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001289static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001290audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001291{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001292 unsigned char *cp;
1293 unsigned char cval;
1294 signed char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001295 int len, size, val;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001296 PyObject *rv;
1297 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001298
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001299 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1300 &cp, &len, &size) )
1301 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001303 if ( size != 1 && size != 2 && size != 4) {
1304 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1305 return 0;
1306 }
1307
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001308 if (len > INT_MAX/size) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001309 PyErr_SetString(PyExc_MemoryError,
1310 "not enough memory for output buffer");
1311 return 0;
1312 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001313 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001314 if ( rv == 0 )
1315 return 0;
1316 ncp = (signed char *)PyString_AsString(rv);
1317
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001318 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001319 cval = *cp++;
1320 val = st_ulaw2linear16(cval);
1321
1322 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1323 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1324 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1325 }
1326 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001327}
1328
1329static PyObject *
1330audioop_lin2alaw(PyObject *self, PyObject *args)
1331{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001332 signed char *cp;
1333 unsigned char *ncp;
1334 int len, size, val = 0;
1335 PyObject *rv;
1336 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001337
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001338 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1339 &cp, &len, &size) )
1340 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001341
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001342 if ( size != 1 && size != 2 && size != 4) {
1343 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1344 return 0;
1345 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001346
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001347 rv = PyString_FromStringAndSize(NULL, len/size);
1348 if ( rv == 0 )
1349 return 0;
1350 ncp = (unsigned char *)PyString_AsString(rv);
1351
1352 for ( i=0; i < len; i += size ) {
1353 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1354 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1355 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1356
1357 *ncp++ = st_linear2alaw(val);
1358 }
1359 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001360}
1361
1362static PyObject *
1363audioop_alaw2lin(PyObject *self, PyObject *args)
1364{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001365 unsigned char *cp;
1366 unsigned char cval;
1367 signed char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001368 int len, size, val;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001369 PyObject *rv;
1370 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001371
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001372 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1373 &cp, &len, &size) )
1374 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001375
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001376 if ( size != 1 && size != 2 && size != 4) {
1377 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1378 return 0;
1379 }
1380
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001381 if (len > INT_MAX/size) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001382 PyErr_SetString(PyExc_MemoryError,
1383 "not enough memory for output buffer");
1384 return 0;
1385 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001386 rv = PyString_FromStringAndSize(NULL, len*size);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001387 if ( rv == 0 )
1388 return 0;
1389 ncp = (signed char *)PyString_AsString(rv);
1390
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001391 for ( i=0; i < len*size; i += size ) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001392 cval = *cp++;
1393 val = st_alaw2linear16(cval);
1394
1395 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1396 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1397 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1398 }
1399 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001400}
1401
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001402static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001403audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001404{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001405 signed char *cp;
1406 signed char *ncp;
1407 int len, size, val = 0, step, valpred, delta,
1408 index, sign, vpdiff, diff;
1409 PyObject *rv, *state, *str;
1410 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001411
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 = PyString_FromStringAndSize(NULL, len/(size*2));
1423 if ( str == 0 )
1424 return 0;
1425 ncp = (signed char *)PyString_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;
Anthony Baxter17471432006-03-20 05:58:21 +00001465 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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;
Anthony Baxter17471432006-03-20 05:58:21 +00001496 step = stepsizeTable[index];
Guido van Rossumb64e6351992-07-06 14:21:56 +00001497
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001498 /* Step 6 - Output value */
1499 if ( bufferstep ) {
1500 outputbuffer = (delta << 4) & 0xf0;
1501 } else {
1502 *ncp++ = (delta & 0x0f) | outputbuffer;
Anthony Baxter17471432006-03-20 05:58:21 +00001503 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001514 signed char *cp;
1515 signed char *ncp;
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001516 int len, size, valpred, step, delta, index, sign, vpdiff;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001517 PyObject *rv, *str, *state;
1518 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001519
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001520 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1521 &cp, &len, &size, &state) )
1522 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001523
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001524 if ( size != 1 && size != 2 && size != 4) {
1525 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1526 return 0;
1527 }
1528
1529 /* Decode state, should have (value, step) */
1530 if ( state == Py_None ) {
1531 /* First time, it seems. Set defaults */
1532 valpred = 0;
1533 step = 7;
1534 index = 0;
1535 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
1536 return 0;
1537
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001538 if (len > (INT_MAX/2)/size) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001539 PyErr_SetString(PyExc_MemoryError,
1540 "not enough memory for output buffer");
1541 return 0;
1542 }
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001543 str = PyString_FromStringAndSize(NULL, len*size*2);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001544 if ( str == 0 )
1545 return 0;
1546 ncp = (signed char *)PyString_AsString(str);
1547
1548 step = stepsizeTable[index];
1549 bufferstep = 0;
1550
Mark Dickinson47e3bf22010-05-10 16:16:52 +00001551 for ( i=0; i < len*size*2; i += size ) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001552 /* Step 1 - get the delta value and compute next index */
1553 if ( bufferstep ) {
1554 delta = inputbuffer & 0xf;
1555 } else {
1556 inputbuffer = *cp++;
1557 delta = (inputbuffer >> 4) & 0xf;
Anthony Baxter17471432006-03-20 05:58:21 +00001558 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001559
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001560 bufferstep = !bufferstep;
1561
1562 /* Step 2 - Find new index value (for later) */
1563 index += indexTable[delta];
1564 if ( index < 0 ) index = 0;
1565 if ( index > 88 ) index = 88;
1566
1567 /* Step 3 - Separate sign and magnitude */
1568 sign = delta & 8;
1569 delta = delta & 7;
1570
1571 /* Step 4 - Compute difference and new predicted value */
1572 /*
1573 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1574 ** in adpcm_coder.
1575 */
1576 vpdiff = step >> 3;
1577 if ( delta & 4 ) vpdiff += step;
1578 if ( delta & 2 ) vpdiff += step>>1;
1579 if ( delta & 1 ) vpdiff += step>>2;
1580
1581 if ( sign )
1582 valpred -= vpdiff;
1583 else
1584 valpred += vpdiff;
1585
1586 /* Step 5 - clamp output value */
1587 if ( valpred > 32767 )
1588 valpred = 32767;
1589 else if ( valpred < -32768 )
1590 valpred = -32768;
1591
1592 /* Step 6 - Update step value */
Anthony Baxter17471432006-03-20 05:58:21 +00001593 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001594
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001595 /* Step 6 - Output value */
1596 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1597 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1598 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1599 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001600
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001601 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1602 Py_DECREF(str);
1603 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001604}
1605
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001606static PyMethodDef audioop_methods[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001607 { "max", audioop_max, METH_VARARGS },
1608 { "minmax", audioop_minmax, METH_VARARGS },
1609 { "avg", audioop_avg, METH_VARARGS },
1610 { "maxpp", audioop_maxpp, METH_VARARGS },
1611 { "avgpp", audioop_avgpp, METH_VARARGS },
1612 { "rms", audioop_rms, METH_VARARGS },
1613 { "findfit", audioop_findfit, METH_VARARGS },
1614 { "findmax", audioop_findmax, METH_VARARGS },
1615 { "findfactor", audioop_findfactor, METH_VARARGS },
1616 { "cross", audioop_cross, METH_VARARGS },
1617 { "mul", audioop_mul, METH_VARARGS },
1618 { "add", audioop_add, METH_VARARGS },
1619 { "bias", audioop_bias, METH_VARARGS },
1620 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1621 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1622 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1623 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1624 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1625 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1626 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1627 { "tomono", audioop_tomono, METH_VARARGS },
1628 { "tostereo", audioop_tostereo, METH_VARARGS },
1629 { "getsample", audioop_getsample, METH_VARARGS },
1630 { "reverse", audioop_reverse, METH_VARARGS },
1631 { "ratecv", audioop_ratecv, METH_VARARGS },
1632 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001633};
1634
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001635PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001636initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001637{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001638 PyObject *m, *d;
1639 m = Py_InitModule("audioop", audioop_methods);
1640 if (m == NULL)
1641 return;
1642 d = PyModule_GetDict(m);
1643 if (d == NULL)
1644 return;
1645 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1646 if (AudioopError != NULL)
1647 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001648}