blob: 68f4da3e33109e146f5c8991f01aef3505bd3946 [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{
Anthony Baxter17471432006-03-20 05:58:21 +000056 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +000057
Anthony Baxter17471432006-03-20 05:58:21 +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,
86 -8, 0, 32124, 31100, 30076, 29052, 28028,
87 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,
103 80, 72, 64, 56, 48, 40, 32,
104 24, 16, 8, 0
105};
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
140st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000141{
Anthony Baxter17471432006-03-20 05:58:21 +0000142 PyInt16 mask;
143 PyInt16 seg;
144 unsigned char uval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000145
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +0000160 /* Convert the scaled magnitude to segment number. */
161 seg = search(pcm_val, seg_uend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000162
Anthony Baxter17471432006-03-20 05:58:21 +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
237st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
Anthony Baxterfa869072006-03-20 05:21:58 +0000238{
Anthony Baxter17471432006-03-20 05:58:21 +0000239 PyInt16 mask;
240 short seg;
241 unsigned char aval;
Anthony Baxterfa869072006-03-20 05:21:58 +0000242
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +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
Anthony Baxter17471432006-03-20 05:58:21 +0000254 /* Convert the scaled magnitude to segment number. */
255 seg = search(pcm_val, seg_aend, 8);
Anthony Baxterfa869072006-03-20 05:21:58 +0000256
Anthony Baxter17471432006-03-20 05:58:21 +0000257 /* Combine the sign, segment, and quantization bits. */
Anthony Baxterfa869072006-03-20 05:21:58 +0000258
Anthony Baxter17471432006-03-20 05:58:21 +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] = {
Anthony Baxter17471432006-03-20 05:58:21 +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] = {
Anthony Baxter17471432006-03-20 05:58:21 +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};
289
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{
Anthony Baxter17471432006-03-20 05:58:21 +0000301 signed char *cp;
302 int len, size, val = 0;
303 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000304
Georg Brandl660222f2006-05-28 22:34:51 +0000305 if ( !PyArg_ParseTuple(args, "s#ii:getsample", &cp, &len, &size, &i) )
Anthony Baxter17471432006-03-20 05:58:21 +0000306 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000329 if ( !PyArg_ParseTuple(args, "s#i:max", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000330 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000353 if (!PyArg_ParseTuple(args, "s#i:minmax", &cp, &len, &size))
Anthony Baxter17471432006-03-20 05:58:21 +0000354 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000377 if ( !PyArg_ParseTuple(args, "s#i:avg", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000378 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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000404 if ( !PyArg_ParseTuple(args, "s#i:rms", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000405 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{
Anthony Baxter17471432006-03-20 05:58:21 +0000425 int i;
426 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000427
Anthony Baxter17471432006-03-20 05:58:21 +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{
Anthony Baxter17471432006-03-20 05:58:21 +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
Georg Brandl660222f2006-05-28 22:34:51 +0000475 if ( !PyArg_ParseTuple(args, "s#s#:findfit",
476 &cp1, &len1, &cp2, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000477 return 0;
478 if ( len1 & 1 || len2 & 1 ) {
479 PyErr_SetString(AudioopError, "Strings should be even-sized");
480 return 0;
481 }
482 len1 >>= 1;
483 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000484
Anthony Baxter17471432006-03-20 05:58:21 +0000485 if ( len1 < len2 ) {
486 PyErr_SetString(AudioopError, "First sample should be longer");
487 return 0;
488 }
489 sum_ri_2 = _sum2(cp2, cp2, len2);
490 sum_aij_2 = _sum2(cp1, cp1, len2);
491 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000492
Anthony Baxter17471432006-03-20 05:58:21 +0000493 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000494
Anthony Baxter17471432006-03-20 05:58:21 +0000495 best_result = result;
496 best_j = 0;
497 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000498
Anthony Baxter17471432006-03-20 05:58:21 +0000499 for ( j=1; j<=len1-len2; j++) {
500 aj_m1 = (double)cp1[j-1];
501 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502
Anthony Baxter17471432006-03-20 05:58:21 +0000503 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
504 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000505
Anthony Baxter17471432006-03-20 05:58:21 +0000506 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
507 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000508
Anthony Baxter17471432006-03-20 05:58:21 +0000509 if ( result < best_result ) {
510 best_result = result;
511 best_j = j;
512 }
513
514 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000515
Anthony Baxter17471432006-03-20 05:58:21 +0000516 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000517
Anthony Baxter17471432006-03-20 05:58:21 +0000518 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000519}
520
521/*
522** findfactor finds a factor f so that the energy in A-fB is minimal.
523** See the comment for findfit for details.
524*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000525static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000526audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000527{
Anthony Baxter17471432006-03-20 05:58:21 +0000528 short *cp1, *cp2;
529 int len1, len2;
530 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000531
Georg Brandl660222f2006-05-28 22:34:51 +0000532 if ( !PyArg_ParseTuple(args, "s#s#:findfactor",
533 &cp1, &len1, &cp2, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000534 return 0;
535 if ( len1 & 1 || len2 & 1 ) {
536 PyErr_SetString(AudioopError, "Strings should be even-sized");
537 return 0;
538 }
539 if ( len1 != len2 ) {
540 PyErr_SetString(AudioopError, "Samples should be same size");
541 return 0;
542 }
543 len2 >>= 1;
544 sum_ri_2 = _sum2(cp2, cp2, len2);
545 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000546
Anthony Baxter17471432006-03-20 05:58:21 +0000547 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000548
Anthony Baxter17471432006-03-20 05:58:21 +0000549 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000550}
551
552/*
553** findmax returns the index of the n-sized segment of the input sample
554** that contains the most energy.
555*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000556static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000557audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000558{
Anthony Baxter17471432006-03-20 05:58:21 +0000559 short *cp1;
560 int len1, len2;
561 int j, best_j;
562 double aj_m1, aj_lm1;
563 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000564
Georg Brandl660222f2006-05-28 22:34:51 +0000565 if ( !PyArg_ParseTuple(args, "s#i:findmax", &cp1, &len1, &len2) )
Anthony Baxter17471432006-03-20 05:58:21 +0000566 return 0;
567 if ( len1 & 1 ) {
568 PyErr_SetString(AudioopError, "Strings should be even-sized");
569 return 0;
570 }
571 len1 >>= 1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000572
Anthony Baxter17471432006-03-20 05:58:21 +0000573 if ( len1 < len2 ) {
574 PyErr_SetString(AudioopError, "Input sample should be longer");
575 return 0;
576 }
Jack Jansena90805f1993-02-17 14:29:28 +0000577
Anthony Baxter17471432006-03-20 05:58:21 +0000578 result = _sum2(cp1, cp1, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000579
Anthony Baxter17471432006-03-20 05:58:21 +0000580 best_result = result;
581 best_j = 0;
582 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000583
Anthony Baxter17471432006-03-20 05:58:21 +0000584 for ( j=1; j<=len1-len2; j++) {
585 aj_m1 = (double)cp1[j-1];
586 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000587
Anthony Baxter17471432006-03-20 05:58:21 +0000588 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000589
Anthony Baxter17471432006-03-20 05:58:21 +0000590 if ( result > best_result ) {
591 best_result = result;
592 best_j = j;
593 }
594
595 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000596
Anthony Baxter17471432006-03-20 05:58:21 +0000597 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000598}
599
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000601audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000602{
Anthony Baxter17471432006-03-20 05:58:21 +0000603 signed char *cp;
604 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
605 prevextreme = 0;
606 int i;
607 double avg = 0.0;
608 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000609
Georg Brandl660222f2006-05-28 22:34:51 +0000610 if ( !PyArg_ParseTuple(args, "s#i:avgpp", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000611 return 0;
612 if ( size != 1 && size != 2 && size != 4 ) {
613 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
614 return 0;
615 }
616 /* Compute first delta value ahead. Also automatically makes us
617 ** skip the first extreme value
618 */
619 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
620 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
621 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
622 if ( size == 1 ) val = (int)*CHARP(cp, size);
623 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
624 else if ( size == 4 ) val = (int)*LONGP(cp, size);
625 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000626
Anthony Baxter17471432006-03-20 05:58:21 +0000627 for ( i=size; i<len; i+= size) {
628 if ( size == 1 ) val = (int)*CHARP(cp, i);
629 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
630 else if ( size == 4 ) val = (int)*LONGP(cp, i);
631 diff = val - prevval;
632 if ( diff*prevdiff < 0 ) {
633 /* Derivative changed sign. Compute difference to last
634 ** extreme value and remember.
635 */
636 if ( prevextremevalid ) {
637 extremediff = prevval - prevextreme;
638 if ( extremediff < 0 )
639 extremediff = -extremediff;
640 avg += extremediff;
641 nextreme++;
642 }
643 prevextremevalid = 1;
644 prevextreme = prevval;
645 }
646 prevval = val;
647 if ( diff != 0 )
648 prevdiff = diff;
649 }
650 if ( nextreme == 0 )
651 val = 0;
652 else
653 val = (int)(avg / (double)nextreme);
654 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000655}
656
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000657static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000658audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000659{
Anthony Baxter17471432006-03-20 05:58:21 +0000660 signed char *cp;
661 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
662 prevextreme = 0;
663 int i;
664 int max = 0;
665 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000666
Georg Brandl660222f2006-05-28 22:34:51 +0000667 if ( !PyArg_ParseTuple(args, "s#i:maxpp", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000668 return 0;
669 if ( size != 1 && size != 2 && size != 4 ) {
670 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
671 return 0;
672 }
673 /* Compute first delta value ahead. Also automatically makes us
674 ** skip the first extreme value
675 */
676 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
677 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
678 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
679 if ( size == 1 ) val = (int)*CHARP(cp, size);
680 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
681 else if ( size == 4 ) val = (int)*LONGP(cp, size);
682 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683
Anthony Baxter17471432006-03-20 05:58:21 +0000684 for ( i=size; i<len; i+= size) {
685 if ( size == 1 ) val = (int)*CHARP(cp, i);
686 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
687 else if ( size == 4 ) val = (int)*LONGP(cp, i);
688 diff = val - prevval;
689 if ( diff*prevdiff < 0 ) {
690 /* Derivative changed sign. Compute difference to
691 ** last extreme value and remember.
692 */
693 if ( prevextremevalid ) {
694 extremediff = prevval - prevextreme;
695 if ( extremediff < 0 )
696 extremediff = -extremediff;
697 if ( extremediff > max )
698 max = extremediff;
699 }
700 prevextremevalid = 1;
701 prevextreme = prevval;
702 }
703 prevval = val;
704 if ( diff != 0 )
705 prevdiff = diff;
706 }
707 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000708}
709
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000710static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000711audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000712{
Anthony Baxter17471432006-03-20 05:58:21 +0000713 signed char *cp;
714 int len, size, val = 0;
715 int i;
716 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717
Georg Brandl660222f2006-05-28 22:34:51 +0000718 if ( !PyArg_ParseTuple(args, "s#i:cross", &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +0000719 return 0;
720 if ( size != 1 && size != 2 && size != 4 ) {
721 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
722 return 0;
723 }
724 ncross = -1;
725 prevval = 17; /* Anything <> 0,1 */
726 for ( i=0; i<len; i+= size) {
727 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
728 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
729 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
730 val = val & 1;
731 if ( val != prevval ) ncross++;
732 prevval = val;
733 }
734 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000735}
736
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000738audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000739{
Anthony Baxter17471432006-03-20 05:58:21 +0000740 signed char *cp, *ncp;
741 int len, size, val = 0;
742 double factor, fval, maxval;
743 PyObject *rv;
744 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745
Georg Brandl660222f2006-05-28 22:34:51 +0000746 if ( !PyArg_ParseTuple(args, "s#id:mul", &cp, &len, &size, &factor ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000747 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000748
Anthony Baxter17471432006-03-20 05:58:21 +0000749 if ( size == 1 ) maxval = (double) 0x7f;
750 else if ( size == 2 ) maxval = (double) 0x7fff;
751 else if ( size == 4 ) maxval = (double) 0x7fffffff;
752 else {
753 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
754 return 0;
755 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000756
Anthony Baxter17471432006-03-20 05:58:21 +0000757 rv = PyString_FromStringAndSize(NULL, len);
758 if ( rv == 0 )
759 return 0;
760 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
762
Anthony Baxter17471432006-03-20 05:58:21 +0000763 for ( i=0; i < len; i += size ) {
764 if ( size == 1 ) val = (int)*CHARP(cp, i);
765 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
766 else if ( size == 4 ) val = (int)*LONGP(cp, i);
767 fval = (double)val*factor;
768 if ( fval > maxval ) fval = maxval;
769 else if ( fval < -maxval ) fval = -maxval;
770 val = (int)fval;
771 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
772 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
773 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
774 }
775 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000776}
777
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000778static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000779audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000780{
Anthony Baxter17471432006-03-20 05:58:21 +0000781 signed char *cp, *ncp;
782 int len, size, val1 = 0, val2 = 0;
783 double fac1, fac2, fval, maxval;
784 PyObject *rv;
785 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000786
Georg Brandl660222f2006-05-28 22:34:51 +0000787 if ( !PyArg_ParseTuple(args, "s#idd:tomono",
788 &cp, &len, &size, &fac1, &fac2 ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000789 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790
Anthony Baxter17471432006-03-20 05:58:21 +0000791 if ( size == 1 ) maxval = (double) 0x7f;
792 else if ( size == 2 ) maxval = (double) 0x7fff;
793 else if ( size == 4 ) maxval = (double) 0x7fffffff;
794 else {
795 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
796 return 0;
797 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000798
Anthony Baxter17471432006-03-20 05:58:21 +0000799 rv = PyString_FromStringAndSize(NULL, len/2);
800 if ( rv == 0 )
801 return 0;
802 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803
804
Anthony Baxter17471432006-03-20 05:58:21 +0000805 for ( i=0; i < len; i += size*2 ) {
806 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
807 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
808 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
809 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
810 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
811 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
812 fval = (double)val1*fac1 + (double)val2*fac2;
813 if ( fval > maxval ) fval = maxval;
814 else if ( fval < -maxval ) fval = -maxval;
815 val1 = (int)fval;
816 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
817 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
818 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
819 }
820 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000821}
822
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000823static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000824audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000825{
Anthony Baxter17471432006-03-20 05:58:21 +0000826 signed char *cp, *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +0000827 int len, size, val1, val2, val = 0;
Anthony Baxter17471432006-03-20 05:58:21 +0000828 double fac1, fac2, fval, maxval;
829 PyObject *rv;
830 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831
Georg Brandl660222f2006-05-28 22:34:51 +0000832 if ( !PyArg_ParseTuple(args, "s#idd:tostereo",
833 &cp, &len, &size, &fac1, &fac2 ) )
Anthony Baxter17471432006-03-20 05:58:21 +0000834 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000835
Anthony Baxter17471432006-03-20 05:58:21 +0000836 if ( size == 1 ) maxval = (double) 0x7f;
837 else if ( size == 2 ) maxval = (double) 0x7fff;
838 else if ( size == 4 ) maxval = (double) 0x7fffffff;
839 else {
840 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
841 return 0;
842 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843
Matthias Klose192b7142010-10-17 10:28:49 +0000844 if (len > INT_MAX/2) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +0000845 PyErr_SetString(PyExc_MemoryError,
846 "not enough memory for output buffer");
847 return 0;
848 }
849
Matthias Klose192b7142010-10-17 10:28:49 +0000850 rv = PyString_FromStringAndSize(NULL, len*2);
Anthony Baxter17471432006-03-20 05:58:21 +0000851 if ( rv == 0 )
852 return 0;
853 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854
855
Anthony Baxter17471432006-03-20 05:58:21 +0000856 for ( i=0; i < len; i += size ) {
857 if ( size == 1 ) val = (int)*CHARP(cp, i);
858 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
859 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
Anthony Baxter17471432006-03-20 05:58:21 +0000861 fval = (double)val*fac1;
862 if ( fval > maxval ) fval = maxval;
863 else if ( fval < -maxval ) fval = -maxval;
864 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000865
Anthony Baxter17471432006-03-20 05:58:21 +0000866 fval = (double)val*fac2;
867 if ( fval > maxval ) fval = maxval;
868 else if ( fval < -maxval ) fval = -maxval;
869 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000870
Anthony Baxter17471432006-03-20 05:58:21 +0000871 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
872 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
873 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000874
Anthony Baxter17471432006-03-20 05:58:21 +0000875 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
876 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
877 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
878 }
879 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000880}
881
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000882static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000883audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000884{
Anthony Baxter17471432006-03-20 05:58:21 +0000885 signed char *cp1, *cp2, *ncp;
886 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
887 PyObject *rv;
888 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000889
Georg Brandl660222f2006-05-28 22:34:51 +0000890 if ( !PyArg_ParseTuple(args, "s#s#i:add",
Anthony Baxter17471432006-03-20 05:58:21 +0000891 &cp1, &len1, &cp2, &len2, &size ) )
892 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000893
Anthony Baxter17471432006-03-20 05:58:21 +0000894 if ( len1 != len2 ) {
895 PyErr_SetString(AudioopError, "Lengths should be the same");
896 return 0;
897 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000898
Anthony Baxter17471432006-03-20 05:58:21 +0000899 if ( size == 1 ) maxval = 0x7f;
900 else if ( size == 2 ) maxval = 0x7fff;
901 else if ( size == 4 ) maxval = 0x7fffffff;
902 else {
903 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
904 return 0;
905 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000906
Anthony Baxter17471432006-03-20 05:58:21 +0000907 rv = PyString_FromStringAndSize(NULL, len1);
908 if ( rv == 0 )
909 return 0;
910 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000911
Anthony Baxter17471432006-03-20 05:58:21 +0000912 for ( i=0; i < len1; i += size ) {
913 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
914 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
915 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
916
917 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
918 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
919 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000920
Anthony Baxter17471432006-03-20 05:58:21 +0000921 newval = val1 + val2;
922 /* truncate in case of overflow */
923 if (newval > maxval) newval = maxval;
924 else if (newval < -maxval) newval = -maxval;
925 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
926 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000927
Anthony Baxter17471432006-03-20 05:58:21 +0000928 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
929 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
930 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
931 }
932 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000933}
934
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000935static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000936audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000937{
Anthony Baxter17471432006-03-20 05:58:21 +0000938 signed char *cp, *ncp;
939 int len, size, val = 0;
940 PyObject *rv;
941 int i;
942 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000943
Georg Brandl660222f2006-05-28 22:34:51 +0000944 if ( !PyArg_ParseTuple(args, "s#ii:bias",
Anthony Baxter17471432006-03-20 05:58:21 +0000945 &cp, &len, &size , &bias) )
946 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000947
Anthony Baxter17471432006-03-20 05:58:21 +0000948 if ( size != 1 && size != 2 && size != 4) {
949 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
950 return 0;
951 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000952
Anthony Baxter17471432006-03-20 05:58:21 +0000953 rv = PyString_FromStringAndSize(NULL, len);
954 if ( rv == 0 )
955 return 0;
956 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000957
958
Anthony Baxter17471432006-03-20 05:58:21 +0000959 for ( i=0; i < len; i += size ) {
960 if ( size == 1 ) val = (int)*CHARP(cp, i);
961 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
962 else if ( size == 4 ) val = (int)*LONGP(cp, i);
963
964 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
965 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
966 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
967 }
968 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000969}
970
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000971static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000972audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000973{
Anthony Baxter17471432006-03-20 05:58:21 +0000974 signed char *cp;
975 unsigned char *ncp;
976 int len, size, val = 0;
977 PyObject *rv;
978 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000979
Georg Brandl660222f2006-05-28 22:34:51 +0000980 if ( !PyArg_ParseTuple(args, "s#i:reverse",
Anthony Baxter17471432006-03-20 05:58:21 +0000981 &cp, &len, &size) )
982 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000983
Anthony Baxter17471432006-03-20 05:58:21 +0000984 if ( size != 1 && size != 2 && size != 4 ) {
985 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
986 return 0;
987 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000988
Anthony Baxter17471432006-03-20 05:58:21 +0000989 rv = PyString_FromStringAndSize(NULL, len);
990 if ( rv == 0 )
991 return 0;
992 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000993
Anthony Baxter17471432006-03-20 05:58:21 +0000994 for ( i=0; i < len; i += size ) {
995 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
996 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
997 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000998
Anthony Baxter17471432006-03-20 05:58:21 +0000999 j = len - i - size;
1000
1001 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1002 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
1003 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1004 }
1005 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +00001006}
1007
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001008static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001009audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001010{
Anthony Baxter17471432006-03-20 05:58:21 +00001011 signed char *cp;
1012 unsigned char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001013 int len, size, size2, val = 0;
Anthony Baxter17471432006-03-20 05:58:21 +00001014 PyObject *rv;
1015 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001016
Georg Brandl660222f2006-05-28 22:34:51 +00001017 if ( !PyArg_ParseTuple(args, "s#ii:lin2lin",
Anthony Baxter17471432006-03-20 05:58:21 +00001018 &cp, &len, &size, &size2) )
1019 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001020
Anthony Baxter17471432006-03-20 05:58:21 +00001021 if ( (size != 1 && size != 2 && size != 4) ||
1022 (size2 != 1 && size2 != 2 && size2 != 4)) {
1023 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1024 return 0;
1025 }
Jack Jansena90805f1993-02-17 14:29:28 +00001026
Matthias Klose192b7142010-10-17 10:28:49 +00001027 if (len/size > INT_MAX/size2) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001028 PyErr_SetString(PyExc_MemoryError,
1029 "not enough memory for output buffer");
1030 return 0;
1031 }
Matthias Klose192b7142010-10-17 10:28:49 +00001032 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
Anthony Baxter17471432006-03-20 05:58:21 +00001033 if ( rv == 0 )
1034 return 0;
1035 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001036
Anthony Baxter17471432006-03-20 05:58:21 +00001037 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1038 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1039 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1040 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001041
Anthony Baxter17471432006-03-20 05:58:21 +00001042 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1043 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1044 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1045 }
1046 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001047}
1048
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001049static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001050gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001051{
Anthony Baxter17471432006-03-20 05:58:21 +00001052 while (b > 0) {
1053 int tmp = a % b;
1054 a = b;
1055 b = tmp;
1056 }
1057 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001058}
1059
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001060static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001061audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001062{
Anthony Baxter17471432006-03-20 05:58:21 +00001063 char *cp, *ncp;
1064 int len, size, nchannels, inrate, outrate, weightA, weightB;
1065 int chan, d, *prev_i, *cur_i, cur_o;
1066 PyObject *state, *samps, *str, *rv = NULL;
1067 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001068
Anthony Baxter17471432006-03-20 05:58:21 +00001069 weightA = 1;
1070 weightB = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001071 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size,
1072 &nchannels, &inrate, &outrate, &state,
1073 &weightA, &weightB))
Anthony Baxter17471432006-03-20 05:58:21 +00001074 return NULL;
1075 if (size != 1 && size != 2 && size != 4) {
1076 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1077 return NULL;
1078 }
1079 if (nchannels < 1) {
1080 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1081 return NULL;
1082 }
1083 bytes_per_frame = size * nchannels;
1084 if (bytes_per_frame / nchannels != size) {
1085 /* This overflow test is rigorously correct because
1086 both multiplicands are >= 1. Use the argument names
1087 from the docs for the error msg. */
1088 PyErr_SetString(PyExc_OverflowError,
1089 "width * nchannels too big for a C int");
1090 return NULL;
1091 }
1092 if (weightA < 1 || weightB < 0) {
1093 PyErr_SetString(AudioopError,
1094 "weightA should be >= 1, weightB should be >= 0");
1095 return NULL;
1096 }
1097 if (len % bytes_per_frame != 0) {
1098 PyErr_SetString(AudioopError, "not a whole number of frames");
1099 return NULL;
1100 }
1101 if (inrate <= 0 || outrate <= 0) {
1102 PyErr_SetString(AudioopError, "sampling rate not > 0");
1103 return NULL;
1104 }
1105 /* divide inrate and outrate by their greatest common divisor */
1106 d = gcd(inrate, outrate);
1107 inrate /= d;
1108 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001109
Matthias Klose192b7142010-10-17 10:28:49 +00001110 if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001111 PyErr_SetString(PyExc_MemoryError,
1112 "not enough memory for output buffer");
1113 return 0;
1114 }
Matthias Klose192b7142010-10-17 10:28:49 +00001115 prev_i = (int *) malloc(nchannels * sizeof(int));
1116 cur_i = (int *) malloc(nchannels * sizeof(int));
Anthony Baxter17471432006-03-20 05:58:21 +00001117 if (prev_i == NULL || cur_i == NULL) {
1118 (void) PyErr_NoMemory();
1119 goto exit;
1120 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001121
Anthony Baxter17471432006-03-20 05:58:21 +00001122 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001123
Anthony Baxter17471432006-03-20 05:58:21 +00001124 if (state == Py_None) {
1125 d = -outrate;
1126 for (chan = 0; chan < nchannels; chan++)
1127 prev_i[chan] = cur_i[chan] = 0;
1128 }
1129 else {
1130 if (!PyArg_ParseTuple(state,
1131 "iO!;audioop.ratecv: illegal state argument",
1132 &d, &PyTuple_Type, &samps))
1133 goto exit;
1134 if (PyTuple_Size(samps) != nchannels) {
1135 PyErr_SetString(AudioopError,
1136 "illegal state argument");
1137 goto exit;
1138 }
1139 for (chan = 0; chan < nchannels; chan++) {
1140 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Georg Brandl660222f2006-05-28 22:34:51 +00001141 "ii:ratecv", &prev_i[chan],
1142 &cur_i[chan]))
Anthony Baxter17471432006-03-20 05:58:21 +00001143 goto exit;
1144 }
1145 }
Tim Peters1691bd92001-12-05 06:05:07 +00001146
Anthony Baxter17471432006-03-20 05:58:21 +00001147 /* str <- Space for the output buffer. */
1148 {
1149 /* There are len input frames, so we need (mathematically)
1150 ceiling(len*outrate/inrate) output frames, and each frame
1151 requires bytes_per_frame bytes. Computing this
1152 without spurious overflow is the challenge; we can
1153 settle for a reasonable upper bound, though. */
1154 int ceiling; /* the number of output frames */
1155 int nbytes; /* the number of output bytes needed */
1156 int q = len / inrate;
1157 /* Now len = q * inrate + r exactly (with r = len % inrate),
1158 and this is less than q * inrate + inrate = (q+1)*inrate.
1159 So a reasonable upper bound on len*outrate/inrate is
1160 ((q+1)*inrate)*outrate/inrate =
1161 (q+1)*outrate.
1162 */
1163 ceiling = (q+1) * outrate;
1164 nbytes = ceiling * bytes_per_frame;
1165 /* See whether anything overflowed; if not, get the space. */
1166 if (q+1 < 0 ||
1167 ceiling / outrate != q+1 ||
1168 nbytes / bytes_per_frame != ceiling)
1169 str = NULL;
1170 else
1171 str = PyString_FromStringAndSize(NULL, nbytes);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001172
Anthony Baxter17471432006-03-20 05:58:21 +00001173 if (str == NULL) {
1174 PyErr_SetString(PyExc_MemoryError,
1175 "not enough memory for output buffer");
1176 goto exit;
1177 }
1178 }
1179 ncp = PyString_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001180
Anthony Baxter17471432006-03-20 05:58:21 +00001181 for (;;) {
1182 while (d < 0) {
1183 if (len == 0) {
1184 samps = PyTuple_New(nchannels);
1185 if (samps == NULL)
1186 goto exit;
1187 for (chan = 0; chan < nchannels; chan++)
1188 PyTuple_SetItem(samps, chan,
1189 Py_BuildValue("(ii)",
1190 prev_i[chan],
1191 cur_i[chan]));
1192 if (PyErr_Occurred())
1193 goto exit;
1194 /* We have checked before that the length
1195 * of the string fits into int. */
1196 len = (int)(ncp - PyString_AsString(str));
1197 if (len == 0) {
1198 /*don't want to resize to zero length*/
1199 rv = PyString_FromStringAndSize("", 0);
1200 Py_DECREF(str);
1201 str = rv;
1202 } else if (_PyString_Resize(&str, len) < 0)
1203 goto exit;
1204 rv = Py_BuildValue("(O(iO))", str, d, samps);
1205 Py_DECREF(samps);
1206 Py_DECREF(str);
1207 goto exit; /* return rv */
1208 }
1209 for (chan = 0; chan < nchannels; chan++) {
1210 prev_i[chan] = cur_i[chan];
1211 if (size == 1)
1212 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1213 else if (size == 2)
1214 cur_i[chan] = (int)*SHORTP(cp, 0);
1215 else if (size == 4)
1216 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1217 cp += size;
1218 /* implements a simple digital filter */
1219 cur_i[chan] =
1220 (weightA * cur_i[chan] +
1221 weightB * prev_i[chan]) /
1222 (weightA + weightB);
1223 }
1224 len--;
1225 d += outrate;
1226 }
1227 while (d >= 0) {
1228 for (chan = 0; chan < nchannels; chan++) {
1229 cur_o = (prev_i[chan] * d +
1230 cur_i[chan] * (outrate - d)) /
1231 outrate;
1232 if (size == 1)
1233 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1234 else if (size == 2)
1235 *SHORTP(ncp, 0) = (short)(cur_o);
1236 else if (size == 4)
1237 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1238 ncp += size;
1239 }
1240 d -= inrate;
1241 }
1242 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001243 exit:
Anthony Baxter17471432006-03-20 05:58:21 +00001244 if (prev_i != NULL)
1245 free(prev_i);
1246 if (cur_i != NULL)
1247 free(cur_i);
1248 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001249}
Guido van Rossum1851a671997-02-14 16:14:03 +00001250
Roger E. Massec905fff1997-01-17 18:12:04 +00001251static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001252audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001253{
Anthony Baxter17471432006-03-20 05:58:21 +00001254 signed char *cp;
1255 unsigned char *ncp;
1256 int len, size, val = 0;
1257 PyObject *rv;
1258 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001259
Georg Brandl660222f2006-05-28 22:34:51 +00001260 if ( !PyArg_ParseTuple(args, "s#i:lin2ulaw",
1261 &cp, &len, &size) )
1262 return 0 ;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001263
Anthony Baxter17471432006-03-20 05:58:21 +00001264 if ( size != 1 && size != 2 && size != 4) {
1265 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1266 return 0;
1267 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001268
Anthony Baxter17471432006-03-20 05:58:21 +00001269 rv = PyString_FromStringAndSize(NULL, len/size);
1270 if ( rv == 0 )
1271 return 0;
1272 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001273
Anthony Baxter17471432006-03-20 05:58:21 +00001274 for ( i=0; i < len; i += size ) {
1275 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1276 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1277 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001278
Anthony Baxter17471432006-03-20 05:58:21 +00001279 *ncp++ = st_14linear2ulaw(val);
1280 }
1281 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001282}
1283
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001284static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001285audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001286{
Anthony Baxter17471432006-03-20 05:58:21 +00001287 unsigned char *cp;
1288 unsigned char cval;
1289 signed char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001290 int len, size, val;
Anthony Baxter17471432006-03-20 05:58:21 +00001291 PyObject *rv;
1292 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001293
Georg Brandl660222f2006-05-28 22:34:51 +00001294 if ( !PyArg_ParseTuple(args, "s#i:ulaw2lin",
1295 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001296 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001297
Anthony Baxter17471432006-03-20 05:58:21 +00001298 if ( size != 1 && size != 2 && size != 4) {
1299 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1300 return 0;
1301 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001302
Matthias Klose192b7142010-10-17 10:28:49 +00001303 if (len > INT_MAX/size) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001304 PyErr_SetString(PyExc_MemoryError,
1305 "not enough memory for output buffer");
1306 return 0;
1307 }
Matthias Klose192b7142010-10-17 10:28:49 +00001308 rv = PyString_FromStringAndSize(NULL, len*size);
Anthony Baxter17471432006-03-20 05:58:21 +00001309 if ( rv == 0 )
1310 return 0;
1311 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001312
Matthias Klose192b7142010-10-17 10:28:49 +00001313 for ( i=0; i < len*size; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001314 cval = *cp++;
1315 val = st_ulaw2linear16(cval);
1316
1317 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1318 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1319 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1320 }
1321 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001322}
1323
1324static PyObject *
1325audioop_lin2alaw(PyObject *self, PyObject *args)
1326{
Anthony Baxter17471432006-03-20 05:58:21 +00001327 signed char *cp;
1328 unsigned char *ncp;
1329 int len, size, val = 0;
1330 PyObject *rv;
1331 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001332
Georg Brandl660222f2006-05-28 22:34:51 +00001333 if ( !PyArg_ParseTuple(args, "s#i:lin2alaw",
1334 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001335 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001336
Anthony Baxter17471432006-03-20 05:58:21 +00001337 if ( size != 1 && size != 2 && size != 4) {
1338 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1339 return 0;
1340 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001341
Anthony Baxter17471432006-03-20 05:58:21 +00001342 rv = PyString_FromStringAndSize(NULL, len/size);
1343 if ( rv == 0 )
1344 return 0;
1345 ncp = (unsigned char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001346
Anthony Baxter17471432006-03-20 05:58:21 +00001347 for ( i=0; i < len; i += size ) {
1348 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1349 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1350 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001351
Anthony Baxter17471432006-03-20 05:58:21 +00001352 *ncp++ = st_linear2alaw(val);
1353 }
1354 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001355}
1356
1357static PyObject *
1358audioop_alaw2lin(PyObject *self, PyObject *args)
1359{
Anthony Baxter17471432006-03-20 05:58:21 +00001360 unsigned char *cp;
1361 unsigned char cval;
1362 signed char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001363 int len, size, val;
Anthony Baxter17471432006-03-20 05:58:21 +00001364 PyObject *rv;
1365 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001366
Georg Brandl660222f2006-05-28 22:34:51 +00001367 if ( !PyArg_ParseTuple(args, "s#i:alaw2lin",
1368 &cp, &len, &size) )
Anthony Baxter17471432006-03-20 05:58:21 +00001369 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001370
Anthony Baxter17471432006-03-20 05:58:21 +00001371 if ( size != 1 && size != 2 && size != 4) {
1372 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1373 return 0;
1374 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001375
Matthias Klose192b7142010-10-17 10:28:49 +00001376 if (len > INT_MAX/size) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001377 PyErr_SetString(PyExc_MemoryError,
1378 "not enough memory for output buffer");
1379 return 0;
1380 }
Matthias Klose192b7142010-10-17 10:28:49 +00001381 rv = PyString_FromStringAndSize(NULL, len*size);
Anthony Baxter17471432006-03-20 05:58:21 +00001382 if ( rv == 0 )
1383 return 0;
1384 ncp = (signed char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001385
Matthias Klose192b7142010-10-17 10:28:49 +00001386 for ( i=0; i < len*size; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001387 cval = *cp++;
1388 val = st_alaw2linear16(cval);
1389
1390 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1391 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1392 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1393 }
1394 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001395}
1396
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001397static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001398audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001399{
Anthony Baxter17471432006-03-20 05:58:21 +00001400 signed char *cp;
1401 signed char *ncp;
1402 int len, size, val = 0, step, valpred, delta,
1403 index, sign, vpdiff, diff;
1404 PyObject *rv, *state, *str;
1405 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001406
Georg Brandl660222f2006-05-28 22:34:51 +00001407 if ( !PyArg_ParseTuple(args, "s#iO:lin2adpcm",
1408 &cp, &len, &size, &state) )
Anthony Baxter17471432006-03-20 05:58:21 +00001409 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001410
1411
Anthony Baxter17471432006-03-20 05:58:21 +00001412 if ( size != 1 && size != 2 && size != 4) {
1413 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1414 return 0;
1415 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001416
Anthony Baxter17471432006-03-20 05:58:21 +00001417 str = PyString_FromStringAndSize(NULL, len/(size*2));
1418 if ( str == 0 )
1419 return 0;
1420 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001421
Anthony Baxter17471432006-03-20 05:58:21 +00001422 /* Decode state, should have (value, step) */
1423 if ( state == Py_None ) {
1424 /* First time, it seems. Set defaults */
1425 valpred = 0;
1426 step = 7;
1427 index = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001428 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Anthony Baxter17471432006-03-20 05:58:21 +00001429 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001430
Anthony Baxter17471432006-03-20 05:58:21 +00001431 step = stepsizeTable[index];
1432 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001433
Anthony Baxter17471432006-03-20 05:58:21 +00001434 for ( i=0; i < len; i += size ) {
1435 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1436 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1437 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001438
Anthony Baxter17471432006-03-20 05:58:21 +00001439 /* Step 1 - compute difference with previous value */
1440 diff = val - valpred;
1441 sign = (diff < 0) ? 8 : 0;
1442 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001443
Anthony Baxter17471432006-03-20 05:58:21 +00001444 /* Step 2 - Divide and clamp */
1445 /* Note:
1446 ** This code *approximately* computes:
1447 ** delta = diff*4/step;
1448 ** vpdiff = (delta+0.5)*step/4;
1449 ** but in shift step bits are dropped. The net result of this
1450 ** is that even if you have fast mul/div hardware you cannot
1451 ** put it to good use since the fixup would be too expensive.
1452 */
1453 delta = 0;
1454 vpdiff = (step >> 3);
1455
1456 if ( diff >= step ) {
1457 delta = 4;
1458 diff -= step;
1459 vpdiff += step;
1460 }
1461 step >>= 1;
1462 if ( diff >= step ) {
1463 delta |= 2;
1464 diff -= step;
1465 vpdiff += step;
1466 }
1467 step >>= 1;
1468 if ( diff >= step ) {
1469 delta |= 1;
1470 vpdiff += step;
1471 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001472
Anthony Baxter17471432006-03-20 05:58:21 +00001473 /* Step 3 - Update previous value */
1474 if ( sign )
1475 valpred -= vpdiff;
1476 else
1477 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001478
Anthony Baxter17471432006-03-20 05:58:21 +00001479 /* Step 4 - Clamp previous value to 16 bits */
1480 if ( valpred > 32767 )
1481 valpred = 32767;
1482 else if ( valpred < -32768 )
1483 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001484
Anthony Baxter17471432006-03-20 05:58:21 +00001485 /* Step 5 - Assemble value, update index and step values */
1486 delta |= sign;
1487
1488 index += indexTable[delta];
1489 if ( index < 0 ) index = 0;
1490 if ( index > 88 ) index = 88;
1491 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001492
Anthony Baxter17471432006-03-20 05:58:21 +00001493 /* Step 6 - Output value */
1494 if ( bufferstep ) {
1495 outputbuffer = (delta << 4) & 0xf0;
1496 } else {
1497 *ncp++ = (delta & 0x0f) | outputbuffer;
1498 }
1499 bufferstep = !bufferstep;
1500 }
1501 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1502 Py_DECREF(str);
1503 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001504}
1505
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001506static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001507audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001508{
Anthony Baxter17471432006-03-20 05:58:21 +00001509 signed char *cp;
1510 signed char *ncp;
Matthias Klose192b7142010-10-17 10:28:49 +00001511 int len, size, valpred, step, delta, index, sign, vpdiff;
Anthony Baxter17471432006-03-20 05:58:21 +00001512 PyObject *rv, *str, *state;
1513 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001514
Georg Brandl660222f2006-05-28 22:34:51 +00001515 if ( !PyArg_ParseTuple(args, "s#iO:adpcm2lin",
1516 &cp, &len, &size, &state) )
Anthony Baxter17471432006-03-20 05:58:21 +00001517 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001518
Anthony Baxter17471432006-03-20 05:58:21 +00001519 if ( size != 1 && size != 2 && size != 4) {
1520 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1521 return 0;
1522 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001523
Anthony Baxter17471432006-03-20 05:58:21 +00001524 /* Decode state, should have (value, step) */
1525 if ( state == Py_None ) {
1526 /* First time, it seems. Set defaults */
1527 valpred = 0;
1528 step = 7;
1529 index = 0;
Georg Brandl660222f2006-05-28 22:34:51 +00001530 } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
Anthony Baxter17471432006-03-20 05:58:21 +00001531 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001532
Matthias Klose192b7142010-10-17 10:28:49 +00001533 if (len > (INT_MAX/2)/size) {
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001534 PyErr_SetString(PyExc_MemoryError,
1535 "not enough memory for output buffer");
1536 return 0;
1537 }
Matthias Klose192b7142010-10-17 10:28:49 +00001538 str = PyString_FromStringAndSize(NULL, len*size*2);
Anthony Baxter17471432006-03-20 05:58:21 +00001539 if ( str == 0 )
1540 return 0;
1541 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001542
Anthony Baxter17471432006-03-20 05:58:21 +00001543 step = stepsizeTable[index];
1544 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001545
Matthias Klose192b7142010-10-17 10:28:49 +00001546 for ( i=0; i < len*size*2; i += size ) {
Anthony Baxter17471432006-03-20 05:58:21 +00001547 /* Step 1 - get the delta value and compute next index */
1548 if ( bufferstep ) {
1549 delta = inputbuffer & 0xf;
1550 } else {
1551 inputbuffer = *cp++;
1552 delta = (inputbuffer >> 4) & 0xf;
1553 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001554
Anthony Baxter17471432006-03-20 05:58:21 +00001555 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001556
Anthony Baxter17471432006-03-20 05:58:21 +00001557 /* Step 2 - Find new index value (for later) */
1558 index += indexTable[delta];
1559 if ( index < 0 ) index = 0;
1560 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001561
Anthony Baxter17471432006-03-20 05:58:21 +00001562 /* Step 3 - Separate sign and magnitude */
1563 sign = delta & 8;
1564 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001565
Anthony Baxter17471432006-03-20 05:58:21 +00001566 /* Step 4 - Compute difference and new predicted value */
1567 /*
1568 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1569 ** in adpcm_coder.
1570 */
1571 vpdiff = step >> 3;
1572 if ( delta & 4 ) vpdiff += step;
1573 if ( delta & 2 ) vpdiff += step>>1;
1574 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001575
Anthony Baxter17471432006-03-20 05:58:21 +00001576 if ( sign )
1577 valpred -= vpdiff;
1578 else
1579 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001580
Anthony Baxter17471432006-03-20 05:58:21 +00001581 /* Step 5 - clamp output value */
1582 if ( valpred > 32767 )
1583 valpred = 32767;
1584 else if ( valpred < -32768 )
1585 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001586
Anthony Baxter17471432006-03-20 05:58:21 +00001587 /* Step 6 - Update step value */
1588 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001589
Anthony Baxter17471432006-03-20 05:58:21 +00001590 /* Step 6 - Output value */
1591 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1592 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1593 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1594 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001595
Anthony Baxter17471432006-03-20 05:58:21 +00001596 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1597 Py_DECREF(str);
1598 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001599}
1600
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001601static PyMethodDef audioop_methods[] = {
Georg Brandl660222f2006-05-28 22:34:51 +00001602 { "max", audioop_max, METH_VARARGS },
1603 { "minmax", audioop_minmax, METH_VARARGS },
1604 { "avg", audioop_avg, METH_VARARGS },
1605 { "maxpp", audioop_maxpp, METH_VARARGS },
1606 { "avgpp", audioop_avgpp, METH_VARARGS },
1607 { "rms", audioop_rms, METH_VARARGS },
1608 { "findfit", audioop_findfit, METH_VARARGS },
1609 { "findmax", audioop_findmax, METH_VARARGS },
1610 { "findfactor", audioop_findfactor, METH_VARARGS },
1611 { "cross", audioop_cross, METH_VARARGS },
1612 { "mul", audioop_mul, METH_VARARGS },
1613 { "add", audioop_add, METH_VARARGS },
1614 { "bias", audioop_bias, METH_VARARGS },
1615 { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS },
1616 { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS },
1617 { "alaw2lin", audioop_alaw2lin, METH_VARARGS },
1618 { "lin2alaw", audioop_lin2alaw, METH_VARARGS },
1619 { "lin2lin", audioop_lin2lin, METH_VARARGS },
1620 { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS },
1621 { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS },
1622 { "tomono", audioop_tomono, METH_VARARGS },
1623 { "tostereo", audioop_tostereo, METH_VARARGS },
1624 { "getsample", audioop_getsample, METH_VARARGS },
1625 { "reverse", audioop_reverse, METH_VARARGS },
Anthony Baxter17471432006-03-20 05:58:21 +00001626 { "ratecv", audioop_ratecv, METH_VARARGS },
1627 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001628};
1629
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001630PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001631initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001632{
Anthony Baxter17471432006-03-20 05:58:21 +00001633 PyObject *m, *d;
1634 m = Py_InitModule("audioop", audioop_methods);
1635 if (m == NULL)
1636 return;
1637 d = PyModule_GetDict(m);
Neal Norwitz49c65d02006-03-20 06:34:06 +00001638 if (d == NULL)
1639 return;
Anthony Baxter17471432006-03-20 05:58:21 +00001640 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1641 if (AudioopError != NULL)
1642 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001643}