blob: ed70cdf48ab7d79b24c54bb8eabb22350c1d069f [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
Anthony Baxter17471432006-03-20 05:58:21 +0000305 if ( !PyArg_Parse(args, "(s#ii)", &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{
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
Anthony Baxter17471432006-03-20 05:58:21 +0000329 if ( !PyArg_Parse(args, "(s#i)", &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{
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
Anthony Baxter17471432006-03-20 05:58:21 +0000353 if (!PyArg_Parse(args, "(s#i)", &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{
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
Anthony Baxter17471432006-03-20 05:58:21 +0000377 if ( !PyArg_Parse(args, "(s#i)", &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{
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
Anthony Baxter17471432006-03-20 05:58:21 +0000404 if ( !PyArg_Parse(args, "(s#i)", &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{
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
Anthony Baxter17471432006-03-20 05:58:21 +0000475 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
476 return 0;
477 if ( len1 & 1 || len2 & 1 ) {
478 PyErr_SetString(AudioopError, "Strings should be even-sized");
479 return 0;
480 }
481 len1 >>= 1;
482 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000483
Anthony Baxter17471432006-03-20 05:58:21 +0000484 if ( len1 < len2 ) {
485 PyErr_SetString(AudioopError, "First sample should be longer");
486 return 0;
487 }
488 sum_ri_2 = _sum2(cp2, cp2, len2);
489 sum_aij_2 = _sum2(cp1, cp1, len2);
490 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000491
Anthony Baxter17471432006-03-20 05:58:21 +0000492 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000493
Anthony Baxter17471432006-03-20 05:58:21 +0000494 best_result = result;
495 best_j = 0;
496 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000497
Anthony Baxter17471432006-03-20 05:58:21 +0000498 for ( j=1; j<=len1-len2; j++) {
499 aj_m1 = (double)cp1[j-1];
500 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000501
Anthony Baxter17471432006-03-20 05:58:21 +0000502 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
503 sum_aij_ri = _sum2(cp1+j, cp2, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000504
Anthony Baxter17471432006-03-20 05:58:21 +0000505 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
506 / sum_aij_2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000507
Anthony Baxter17471432006-03-20 05:58:21 +0000508 if ( result < best_result ) {
509 best_result = result;
510 best_j = j;
511 }
512
513 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000514
Anthony Baxter17471432006-03-20 05:58:21 +0000515 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000516
Anthony Baxter17471432006-03-20 05:58:21 +0000517 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000518}
519
520/*
521** findfactor finds a factor f so that the energy in A-fB is minimal.
522** See the comment for findfit for details.
523*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000525audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000526{
Anthony Baxter17471432006-03-20 05:58:21 +0000527 short *cp1, *cp2;
528 int len1, len2;
529 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000530
Anthony Baxter17471432006-03-20 05:58:21 +0000531 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
532 return 0;
533 if ( len1 & 1 || len2 & 1 ) {
534 PyErr_SetString(AudioopError, "Strings should be even-sized");
535 return 0;
536 }
537 if ( len1 != len2 ) {
538 PyErr_SetString(AudioopError, "Samples should be same size");
539 return 0;
540 }
541 len2 >>= 1;
542 sum_ri_2 = _sum2(cp2, cp2, len2);
543 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000544
Anthony Baxter17471432006-03-20 05:58:21 +0000545 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000546
Anthony Baxter17471432006-03-20 05:58:21 +0000547 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000548}
549
550/*
551** findmax returns the index of the n-sized segment of the input sample
552** that contains the most energy.
553*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000554static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000555audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000556{
Anthony Baxter17471432006-03-20 05:58:21 +0000557 short *cp1;
558 int len1, len2;
559 int j, best_j;
560 double aj_m1, aj_lm1;
561 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000562
Anthony Baxter17471432006-03-20 05:58:21 +0000563 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
564 return 0;
565 if ( len1 & 1 ) {
566 PyErr_SetString(AudioopError, "Strings should be even-sized");
567 return 0;
568 }
569 len1 >>= 1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000570
Anthony Baxter17471432006-03-20 05:58:21 +0000571 if ( len1 < len2 ) {
572 PyErr_SetString(AudioopError, "Input sample should be longer");
573 return 0;
574 }
Jack Jansena90805f1993-02-17 14:29:28 +0000575
Anthony Baxter17471432006-03-20 05:58:21 +0000576 result = _sum2(cp1, cp1, len2);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000577
Anthony Baxter17471432006-03-20 05:58:21 +0000578 best_result = result;
579 best_j = 0;
580 j = 0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000581
Anthony Baxter17471432006-03-20 05:58:21 +0000582 for ( j=1; j<=len1-len2; j++) {
583 aj_m1 = (double)cp1[j-1];
584 aj_lm1 = (double)cp1[j+len2-1];
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000585
Anthony Baxter17471432006-03-20 05:58:21 +0000586 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000587
Anthony Baxter17471432006-03-20 05:58:21 +0000588 if ( result > best_result ) {
589 best_result = result;
590 best_j = j;
591 }
592
593 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000594
Anthony Baxter17471432006-03-20 05:58:21 +0000595 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000596}
597
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000598static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000599audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000600{
Anthony Baxter17471432006-03-20 05:58:21 +0000601 signed char *cp;
602 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
603 prevextreme = 0;
604 int i;
605 double avg = 0.0;
606 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000607
Anthony Baxter17471432006-03-20 05:58:21 +0000608 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
609 return 0;
610 if ( size != 1 && size != 2 && size != 4 ) {
611 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
612 return 0;
613 }
614 /* Compute first delta value ahead. Also automatically makes us
615 ** skip the first extreme value
616 */
617 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
618 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
619 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
620 if ( size == 1 ) val = (int)*CHARP(cp, size);
621 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
622 else if ( size == 4 ) val = (int)*LONGP(cp, size);
623 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000624
Anthony Baxter17471432006-03-20 05:58:21 +0000625 for ( i=size; i<len; i+= size) {
626 if ( size == 1 ) val = (int)*CHARP(cp, i);
627 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
628 else if ( size == 4 ) val = (int)*LONGP(cp, i);
629 diff = val - prevval;
630 if ( diff*prevdiff < 0 ) {
631 /* Derivative changed sign. Compute difference to last
632 ** extreme value and remember.
633 */
634 if ( prevextremevalid ) {
635 extremediff = prevval - prevextreme;
636 if ( extremediff < 0 )
637 extremediff = -extremediff;
638 avg += extremediff;
639 nextreme++;
640 }
641 prevextremevalid = 1;
642 prevextreme = prevval;
643 }
644 prevval = val;
645 if ( diff != 0 )
646 prevdiff = diff;
647 }
648 if ( nextreme == 0 )
649 val = 0;
650 else
651 val = (int)(avg / (double)nextreme);
652 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000653}
654
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000655static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000656audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000657{
Anthony Baxter17471432006-03-20 05:58:21 +0000658 signed char *cp;
659 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
660 prevextreme = 0;
661 int i;
662 int max = 0;
663 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000664
Anthony Baxter17471432006-03-20 05:58:21 +0000665 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
666 return 0;
667 if ( size != 1 && size != 2 && size != 4 ) {
668 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
669 return 0;
670 }
671 /* Compute first delta value ahead. Also automatically makes us
672 ** skip the first extreme value
673 */
674 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
675 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
676 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
677 if ( size == 1 ) val = (int)*CHARP(cp, size);
678 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
679 else if ( size == 4 ) val = (int)*LONGP(cp, size);
680 prevdiff = val - prevval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000681
Anthony Baxter17471432006-03-20 05:58:21 +0000682 for ( i=size; i<len; i+= size) {
683 if ( size == 1 ) val = (int)*CHARP(cp, i);
684 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
685 else if ( size == 4 ) val = (int)*LONGP(cp, i);
686 diff = val - prevval;
687 if ( diff*prevdiff < 0 ) {
688 /* Derivative changed sign. Compute difference to
689 ** last extreme value and remember.
690 */
691 if ( prevextremevalid ) {
692 extremediff = prevval - prevextreme;
693 if ( extremediff < 0 )
694 extremediff = -extremediff;
695 if ( extremediff > max )
696 max = extremediff;
697 }
698 prevextremevalid = 1;
699 prevextreme = prevval;
700 }
701 prevval = val;
702 if ( diff != 0 )
703 prevdiff = diff;
704 }
705 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000706}
707
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000708static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000709audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000710{
Anthony Baxter17471432006-03-20 05:58:21 +0000711 signed char *cp;
712 int len, size, val = 0;
713 int i;
714 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000715
Anthony Baxter17471432006-03-20 05:58:21 +0000716 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
717 return 0;
718 if ( size != 1 && size != 2 && size != 4 ) {
719 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
720 return 0;
721 }
722 ncross = -1;
723 prevval = 17; /* Anything <> 0,1 */
724 for ( i=0; i<len; i+= size) {
725 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
726 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
727 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
728 val = val & 1;
729 if ( val != prevval ) ncross++;
730 prevval = val;
731 }
732 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000733}
734
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000735static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000736audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000737{
Anthony Baxter17471432006-03-20 05:58:21 +0000738 signed char *cp, *ncp;
739 int len, size, val = 0;
740 double factor, fval, maxval;
741 PyObject *rv;
742 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000743
Anthony Baxter17471432006-03-20 05:58:21 +0000744 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
745 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000746
Anthony Baxter17471432006-03-20 05:58:21 +0000747 if ( size == 1 ) maxval = (double) 0x7f;
748 else if ( size == 2 ) maxval = (double) 0x7fff;
749 else if ( size == 4 ) maxval = (double) 0x7fffffff;
750 else {
751 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
752 return 0;
753 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000754
Anthony Baxter17471432006-03-20 05:58:21 +0000755 rv = PyString_FromStringAndSize(NULL, len);
756 if ( rv == 0 )
757 return 0;
758 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000759
760
Anthony Baxter17471432006-03-20 05:58:21 +0000761 for ( i=0; i < len; i += size ) {
762 if ( size == 1 ) val = (int)*CHARP(cp, i);
763 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
764 else if ( size == 4 ) val = (int)*LONGP(cp, i);
765 fval = (double)val*factor;
766 if ( fval > maxval ) fval = maxval;
767 else if ( fval < -maxval ) fval = -maxval;
768 val = (int)fval;
769 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
770 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
771 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
772 }
773 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000774}
775
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000776static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000777audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000778{
Anthony Baxter17471432006-03-20 05:58:21 +0000779 signed char *cp, *ncp;
780 int len, size, val1 = 0, val2 = 0;
781 double fac1, fac2, fval, maxval;
782 PyObject *rv;
783 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000784
Anthony Baxter17471432006-03-20 05:58:21 +0000785 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
786 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787
Anthony Baxter17471432006-03-20 05:58:21 +0000788 if ( size == 1 ) maxval = (double) 0x7f;
789 else if ( size == 2 ) maxval = (double) 0x7fff;
790 else if ( size == 4 ) maxval = (double) 0x7fffffff;
791 else {
792 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
793 return 0;
794 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Anthony Baxter17471432006-03-20 05:58:21 +0000796 rv = PyString_FromStringAndSize(NULL, len/2);
797 if ( rv == 0 )
798 return 0;
799 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000800
801
Anthony Baxter17471432006-03-20 05:58:21 +0000802 for ( i=0; i < len; i += size*2 ) {
803 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
804 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
805 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
806 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
807 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
808 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
809 fval = (double)val1*fac1 + (double)val2*fac2;
810 if ( fval > maxval ) fval = maxval;
811 else if ( fval < -maxval ) fval = -maxval;
812 val1 = (int)fval;
813 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
814 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
815 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
816 }
817 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000818}
819
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000820static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000821audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000822{
Anthony Baxter17471432006-03-20 05:58:21 +0000823 signed char *cp, *ncp;
824 int len, size, val1, val2, val = 0;
825 double fac1, fac2, fval, maxval;
826 PyObject *rv;
827 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000828
Anthony Baxter17471432006-03-20 05:58:21 +0000829 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
830 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831
Anthony Baxter17471432006-03-20 05:58:21 +0000832 if ( size == 1 ) maxval = (double) 0x7f;
833 else if ( size == 2 ) maxval = (double) 0x7fff;
834 else if ( size == 4 ) maxval = (double) 0x7fffffff;
835 else {
836 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
837 return 0;
838 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000839
Anthony Baxter17471432006-03-20 05:58:21 +0000840 rv = PyString_FromStringAndSize(NULL, len*2);
841 if ( rv == 0 )
842 return 0;
843 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000844
845
Anthony Baxter17471432006-03-20 05:58:21 +0000846 for ( i=0; i < len; i += size ) {
847 if ( size == 1 ) val = (int)*CHARP(cp, i);
848 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
849 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000850
Anthony Baxter17471432006-03-20 05:58:21 +0000851 fval = (double)val*fac1;
852 if ( fval > maxval ) fval = maxval;
853 else if ( fval < -maxval ) fval = -maxval;
854 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000855
Anthony Baxter17471432006-03-20 05:58:21 +0000856 fval = (double)val*fac2;
857 if ( fval > maxval ) fval = maxval;
858 else if ( fval < -maxval ) fval = -maxval;
859 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
Anthony Baxter17471432006-03-20 05:58:21 +0000861 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
862 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
863 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000864
Anthony Baxter17471432006-03-20 05:58:21 +0000865 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
866 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
867 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
868 }
869 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000870}
871
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000872static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000873audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000874{
Anthony Baxter17471432006-03-20 05:58:21 +0000875 signed char *cp1, *cp2, *ncp;
876 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
877 PyObject *rv;
878 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000879
Anthony Baxter17471432006-03-20 05:58:21 +0000880 if ( !PyArg_Parse(args, "(s#s#i)",
881 &cp1, &len1, &cp2, &len2, &size ) )
882 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000883
Anthony Baxter17471432006-03-20 05:58:21 +0000884 if ( len1 != len2 ) {
885 PyErr_SetString(AudioopError, "Lengths should be the same");
886 return 0;
887 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000888
Anthony Baxter17471432006-03-20 05:58:21 +0000889 if ( size == 1 ) maxval = 0x7f;
890 else if ( size == 2 ) maxval = 0x7fff;
891 else if ( size == 4 ) maxval = 0x7fffffff;
892 else {
893 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
894 return 0;
895 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000896
Anthony Baxter17471432006-03-20 05:58:21 +0000897 rv = PyString_FromStringAndSize(NULL, len1);
898 if ( rv == 0 )
899 return 0;
900 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000901
Anthony Baxter17471432006-03-20 05:58:21 +0000902 for ( i=0; i < len1; i += size ) {
903 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
904 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
905 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
906
907 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
908 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
909 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000910
Anthony Baxter17471432006-03-20 05:58:21 +0000911 newval = val1 + val2;
912 /* truncate in case of overflow */
913 if (newval > maxval) newval = maxval;
914 else if (newval < -maxval) newval = -maxval;
915 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
916 newval = val1 > 0 ? maxval : - maxval;
Guido van Rossum1851a671997-02-14 16:14:03 +0000917
Anthony Baxter17471432006-03-20 05:58:21 +0000918 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
919 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
920 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
921 }
922 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000923}
924
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000925static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000926audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000927{
Anthony Baxter17471432006-03-20 05:58:21 +0000928 signed char *cp, *ncp;
929 int len, size, val = 0;
930 PyObject *rv;
931 int i;
932 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000933
Anthony Baxter17471432006-03-20 05:58:21 +0000934 if ( !PyArg_Parse(args, "(s#ii)",
935 &cp, &len, &size , &bias) )
936 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000937
Anthony Baxter17471432006-03-20 05:58:21 +0000938 if ( size != 1 && size != 2 && size != 4) {
939 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
940 return 0;
941 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000942
Anthony Baxter17471432006-03-20 05:58:21 +0000943 rv = PyString_FromStringAndSize(NULL, len);
944 if ( rv == 0 )
945 return 0;
946 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000947
948
Anthony Baxter17471432006-03-20 05:58:21 +0000949 for ( i=0; i < len; i += size ) {
950 if ( size == 1 ) val = (int)*CHARP(cp, i);
951 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
952 else if ( size == 4 ) val = (int)*LONGP(cp, i);
953
954 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
955 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
956 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
957 }
958 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000959}
960
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000961static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000962audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000963{
Anthony Baxter17471432006-03-20 05:58:21 +0000964 signed char *cp;
965 unsigned char *ncp;
966 int len, size, val = 0;
967 PyObject *rv;
968 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000969
Anthony Baxter17471432006-03-20 05:58:21 +0000970 if ( !PyArg_Parse(args, "(s#i)",
971 &cp, &len, &size) )
972 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000973
Anthony Baxter17471432006-03-20 05:58:21 +0000974 if ( size != 1 && size != 2 && size != 4 ) {
975 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
976 return 0;
977 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000978
Anthony Baxter17471432006-03-20 05:58:21 +0000979 rv = PyString_FromStringAndSize(NULL, len);
980 if ( rv == 0 )
981 return 0;
982 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000983
Anthony Baxter17471432006-03-20 05:58:21 +0000984 for ( i=0; i < len; i += size ) {
985 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
986 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
987 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000988
Anthony Baxter17471432006-03-20 05:58:21 +0000989 j = len - i - size;
990
991 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
992 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
993 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
994 }
995 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000996}
997
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000998static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000999audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +00001000{
Anthony Baxter17471432006-03-20 05:58:21 +00001001 signed char *cp;
1002 unsigned char *ncp;
1003 int len, size, size2, val = 0;
1004 PyObject *rv;
1005 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +00001006
Anthony Baxter17471432006-03-20 05:58:21 +00001007 if ( !PyArg_Parse(args, "(s#ii)",
1008 &cp, &len, &size, &size2) )
1009 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +00001010
Anthony Baxter17471432006-03-20 05:58:21 +00001011 if ( (size != 1 && size != 2 && size != 4) ||
1012 (size2 != 1 && size2 != 2 && size2 != 4)) {
1013 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1014 return 0;
1015 }
Jack Jansena90805f1993-02-17 14:29:28 +00001016
Anthony Baxter17471432006-03-20 05:58:21 +00001017 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
1018 if ( rv == 0 )
1019 return 0;
1020 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +00001021
Anthony Baxter17471432006-03-20 05:58:21 +00001022 for ( i=0, j=0; i < len; i += size, j += size2 ) {
1023 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1024 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1025 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +00001026
Anthony Baxter17471432006-03-20 05:58:21 +00001027 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
1028 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
1029 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
1030 }
1031 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +00001032}
1033
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001034static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001035gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001036{
Anthony Baxter17471432006-03-20 05:58:21 +00001037 while (b > 0) {
1038 int tmp = a % b;
1039 a = b;
1040 b = tmp;
1041 }
1042 return a;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001043}
1044
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001045static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001046audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +00001047{
Anthony Baxter17471432006-03-20 05:58:21 +00001048 char *cp, *ncp;
1049 int len, size, nchannels, inrate, outrate, weightA, weightB;
1050 int chan, d, *prev_i, *cur_i, cur_o;
1051 PyObject *state, *samps, *str, *rv = NULL;
1052 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +00001053
Anthony Baxter17471432006-03-20 05:58:21 +00001054 weightA = 1;
1055 weightB = 0;
1056 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
1057 &inrate, &outrate, &state, &weightA, &weightB))
1058 return NULL;
1059 if (size != 1 && size != 2 && size != 4) {
1060 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1061 return NULL;
1062 }
1063 if (nchannels < 1) {
1064 PyErr_SetString(AudioopError, "# of channels should be >= 1");
1065 return NULL;
1066 }
1067 bytes_per_frame = size * nchannels;
1068 if (bytes_per_frame / nchannels != size) {
1069 /* This overflow test is rigorously correct because
1070 both multiplicands are >= 1. Use the argument names
1071 from the docs for the error msg. */
1072 PyErr_SetString(PyExc_OverflowError,
1073 "width * nchannels too big for a C int");
1074 return NULL;
1075 }
1076 if (weightA < 1 || weightB < 0) {
1077 PyErr_SetString(AudioopError,
1078 "weightA should be >= 1, weightB should be >= 0");
1079 return NULL;
1080 }
1081 if (len % bytes_per_frame != 0) {
1082 PyErr_SetString(AudioopError, "not a whole number of frames");
1083 return NULL;
1084 }
1085 if (inrate <= 0 || outrate <= 0) {
1086 PyErr_SetString(AudioopError, "sampling rate not > 0");
1087 return NULL;
1088 }
1089 /* divide inrate and outrate by their greatest common divisor */
1090 d = gcd(inrate, outrate);
1091 inrate /= d;
1092 outrate /= d;
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001093
Anthony Baxter17471432006-03-20 05:58:21 +00001094 prev_i = (int *) malloc(nchannels * sizeof(int));
1095 cur_i = (int *) malloc(nchannels * sizeof(int));
1096 if (prev_i == NULL || cur_i == NULL) {
1097 (void) PyErr_NoMemory();
1098 goto exit;
1099 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001100
Anthony Baxter17471432006-03-20 05:58:21 +00001101 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +00001102
Anthony Baxter17471432006-03-20 05:58:21 +00001103 if (state == Py_None) {
1104 d = -outrate;
1105 for (chan = 0; chan < nchannels; chan++)
1106 prev_i[chan] = cur_i[chan] = 0;
1107 }
1108 else {
1109 if (!PyArg_ParseTuple(state,
1110 "iO!;audioop.ratecv: illegal state argument",
1111 &d, &PyTuple_Type, &samps))
1112 goto exit;
1113 if (PyTuple_Size(samps) != nchannels) {
1114 PyErr_SetString(AudioopError,
1115 "illegal state argument");
1116 goto exit;
1117 }
1118 for (chan = 0; chan < nchannels; chan++) {
1119 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
1120 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
1121 goto exit;
1122 }
1123 }
Tim Peters1691bd92001-12-05 06:05:07 +00001124
Anthony Baxter17471432006-03-20 05:58:21 +00001125 /* str <- Space for the output buffer. */
1126 {
1127 /* There are len input frames, so we need (mathematically)
1128 ceiling(len*outrate/inrate) output frames, and each frame
1129 requires bytes_per_frame bytes. Computing this
1130 without spurious overflow is the challenge; we can
1131 settle for a reasonable upper bound, though. */
1132 int ceiling; /* the number of output frames */
1133 int nbytes; /* the number of output bytes needed */
1134 int q = len / inrate;
1135 /* Now len = q * inrate + r exactly (with r = len % inrate),
1136 and this is less than q * inrate + inrate = (q+1)*inrate.
1137 So a reasonable upper bound on len*outrate/inrate is
1138 ((q+1)*inrate)*outrate/inrate =
1139 (q+1)*outrate.
1140 */
1141 ceiling = (q+1) * outrate;
1142 nbytes = ceiling * bytes_per_frame;
1143 /* See whether anything overflowed; if not, get the space. */
1144 if (q+1 < 0 ||
1145 ceiling / outrate != q+1 ||
1146 nbytes / bytes_per_frame != ceiling)
1147 str = NULL;
1148 else
1149 str = PyString_FromStringAndSize(NULL, nbytes);
Tim Peterseb4b7ba2001-12-07 00:37:39 +00001150
Anthony Baxter17471432006-03-20 05:58:21 +00001151 if (str == NULL) {
1152 PyErr_SetString(PyExc_MemoryError,
1153 "not enough memory for output buffer");
1154 goto exit;
1155 }
1156 }
1157 ncp = PyString_AsString(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001158
Anthony Baxter17471432006-03-20 05:58:21 +00001159 for (;;) {
1160 while (d < 0) {
1161 if (len == 0) {
1162 samps = PyTuple_New(nchannels);
1163 if (samps == NULL)
1164 goto exit;
1165 for (chan = 0; chan < nchannels; chan++)
1166 PyTuple_SetItem(samps, chan,
1167 Py_BuildValue("(ii)",
1168 prev_i[chan],
1169 cur_i[chan]));
1170 if (PyErr_Occurred())
1171 goto exit;
1172 /* We have checked before that the length
1173 * of the string fits into int. */
1174 len = (int)(ncp - PyString_AsString(str));
1175 if (len == 0) {
1176 /*don't want to resize to zero length*/
1177 rv = PyString_FromStringAndSize("", 0);
1178 Py_DECREF(str);
1179 str = rv;
1180 } else if (_PyString_Resize(&str, len) < 0)
1181 goto exit;
1182 rv = Py_BuildValue("(O(iO))", str, d, samps);
1183 Py_DECREF(samps);
1184 Py_DECREF(str);
1185 goto exit; /* return rv */
1186 }
1187 for (chan = 0; chan < nchannels; chan++) {
1188 prev_i[chan] = cur_i[chan];
1189 if (size == 1)
1190 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
1191 else if (size == 2)
1192 cur_i[chan] = (int)*SHORTP(cp, 0);
1193 else if (size == 4)
1194 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
1195 cp += size;
1196 /* implements a simple digital filter */
1197 cur_i[chan] =
1198 (weightA * cur_i[chan] +
1199 weightB * prev_i[chan]) /
1200 (weightA + weightB);
1201 }
1202 len--;
1203 d += outrate;
1204 }
1205 while (d >= 0) {
1206 for (chan = 0; chan < nchannels; chan++) {
1207 cur_o = (prev_i[chan] * d +
1208 cur_i[chan] * (outrate - d)) /
1209 outrate;
1210 if (size == 1)
1211 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
1212 else if (size == 2)
1213 *SHORTP(ncp, 0) = (short)(cur_o);
1214 else if (size == 4)
1215 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
1216 ncp += size;
1217 }
1218 d -= inrate;
1219 }
1220 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001221 exit:
Anthony Baxter17471432006-03-20 05:58:21 +00001222 if (prev_i != NULL)
1223 free(prev_i);
1224 if (cur_i != NULL)
1225 free(cur_i);
1226 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001227}
Guido van Rossum1851a671997-02-14 16:14:03 +00001228
Roger E. Massec905fff1997-01-17 18:12:04 +00001229static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001230audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001231{
Anthony Baxter17471432006-03-20 05:58:21 +00001232 signed char *cp;
1233 unsigned char *ncp;
1234 int len, size, val = 0;
1235 PyObject *rv;
1236 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001237
Anthony Baxter17471432006-03-20 05:58:21 +00001238 if ( !PyArg_Parse(args, "(s#i)",
1239 &cp, &len, &size) )
1240 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001241
Anthony Baxter17471432006-03-20 05:58:21 +00001242 if ( size != 1 && size != 2 && size != 4) {
1243 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1244 return 0;
1245 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001246
Anthony Baxter17471432006-03-20 05:58:21 +00001247 rv = PyString_FromStringAndSize(NULL, len/size);
1248 if ( rv == 0 )
1249 return 0;
1250 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001251
Anthony Baxter17471432006-03-20 05:58:21 +00001252 for ( i=0; i < len; i += size ) {
1253 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1254 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1255 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001256
Anthony Baxter17471432006-03-20 05:58:21 +00001257 *ncp++ = st_14linear2ulaw(val);
1258 }
1259 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001260}
1261
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001262static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001263audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001264{
Anthony Baxter17471432006-03-20 05:58:21 +00001265 unsigned char *cp;
1266 unsigned char cval;
1267 signed char *ncp;
1268 int len, size, val;
1269 PyObject *rv;
1270 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001271
Anthony Baxter17471432006-03-20 05:58:21 +00001272 if ( !PyArg_Parse(args, "(s#i)",
1273 &cp, &len, &size) )
1274 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001275
Anthony Baxter17471432006-03-20 05:58:21 +00001276 if ( size != 1 && size != 2 && size != 4) {
1277 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1278 return 0;
1279 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001280
Anthony Baxter17471432006-03-20 05:58:21 +00001281 rv = PyString_FromStringAndSize(NULL, len*size);
1282 if ( rv == 0 )
1283 return 0;
1284 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001285
Anthony Baxter17471432006-03-20 05:58:21 +00001286 for ( i=0; i < len*size; i += size ) {
1287 cval = *cp++;
1288 val = st_ulaw2linear16(cval);
1289
1290 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1291 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1292 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1293 }
1294 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001295}
1296
1297static PyObject *
1298audioop_lin2alaw(PyObject *self, PyObject *args)
1299{
Anthony Baxter17471432006-03-20 05:58:21 +00001300 signed char *cp;
1301 unsigned char *ncp;
1302 int len, size, val = 0;
1303 PyObject *rv;
1304 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001305
Anthony Baxter17471432006-03-20 05:58:21 +00001306 if ( !PyArg_Parse(args, "(s#i)",
1307 &cp, &len, &size) )
1308 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001309
Anthony Baxter17471432006-03-20 05:58:21 +00001310 if ( size != 1 && size != 2 && size != 4) {
1311 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1312 return 0;
1313 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001314
Anthony Baxter17471432006-03-20 05:58:21 +00001315 rv = PyString_FromStringAndSize(NULL, len/size);
1316 if ( rv == 0 )
1317 return 0;
1318 ncp = (unsigned char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001319
Anthony Baxter17471432006-03-20 05:58:21 +00001320 for ( i=0; i < len; i += size ) {
1321 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1322 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1323 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Anthony Baxterfa869072006-03-20 05:21:58 +00001324
Anthony Baxter17471432006-03-20 05:58:21 +00001325 *ncp++ = st_linear2alaw(val);
1326 }
1327 return rv;
Anthony Baxterfa869072006-03-20 05:21:58 +00001328}
1329
1330static PyObject *
1331audioop_alaw2lin(PyObject *self, PyObject *args)
1332{
Anthony Baxter17471432006-03-20 05:58:21 +00001333 unsigned char *cp;
1334 unsigned char cval;
1335 signed char *ncp;
1336 int len, size, val;
1337 PyObject *rv;
1338 int i;
Anthony Baxterfa869072006-03-20 05:21:58 +00001339
Anthony Baxter17471432006-03-20 05:58:21 +00001340 if ( !PyArg_Parse(args, "(s#i)",
1341 &cp, &len, &size) )
1342 return 0;
Anthony Baxterfa869072006-03-20 05:21:58 +00001343
Anthony Baxter17471432006-03-20 05:58:21 +00001344 if ( size != 1 && size != 2 && size != 4) {
1345 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1346 return 0;
1347 }
Anthony Baxterfa869072006-03-20 05:21:58 +00001348
Anthony Baxter17471432006-03-20 05:58:21 +00001349 rv = PyString_FromStringAndSize(NULL, len*size);
1350 if ( rv == 0 )
1351 return 0;
1352 ncp = (signed char *)PyString_AsString(rv);
Anthony Baxterfa869072006-03-20 05:21:58 +00001353
Anthony Baxter17471432006-03-20 05:58:21 +00001354 for ( i=0; i < len*size; i += size ) {
1355 cval = *cp++;
1356 val = st_alaw2linear16(cval);
1357
1358 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1359 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1360 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
1361 }
1362 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001363}
1364
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001365static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001366audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001367{
Anthony Baxter17471432006-03-20 05:58:21 +00001368 signed char *cp;
1369 signed char *ncp;
1370 int len, size, val = 0, step, valpred, delta,
1371 index, sign, vpdiff, diff;
1372 PyObject *rv, *state, *str;
1373 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001374
Anthony Baxter17471432006-03-20 05:58:21 +00001375 if ( !PyArg_Parse(args, "(s#iO)",
1376 &cp, &len, &size, &state) )
1377 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001378
1379
Anthony Baxter17471432006-03-20 05:58:21 +00001380 if ( size != 1 && size != 2 && size != 4) {
1381 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1382 return 0;
1383 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001384
Anthony Baxter17471432006-03-20 05:58:21 +00001385 str = PyString_FromStringAndSize(NULL, len/(size*2));
1386 if ( str == 0 )
1387 return 0;
1388 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001389
Anthony Baxter17471432006-03-20 05:58:21 +00001390 /* Decode state, should have (value, step) */
1391 if ( state == Py_None ) {
1392 /* First time, it seems. Set defaults */
1393 valpred = 0;
1394 step = 7;
1395 index = 0;
1396 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1397 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001398
Anthony Baxter17471432006-03-20 05:58:21 +00001399 step = stepsizeTable[index];
1400 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001401
Anthony Baxter17471432006-03-20 05:58:21 +00001402 for ( i=0; i < len; i += size ) {
1403 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1404 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1405 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001406
Anthony Baxter17471432006-03-20 05:58:21 +00001407 /* Step 1 - compute difference with previous value */
1408 diff = val - valpred;
1409 sign = (diff < 0) ? 8 : 0;
1410 if ( sign ) diff = (-diff);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001411
Anthony Baxter17471432006-03-20 05:58:21 +00001412 /* Step 2 - Divide and clamp */
1413 /* Note:
1414 ** This code *approximately* computes:
1415 ** delta = diff*4/step;
1416 ** vpdiff = (delta+0.5)*step/4;
1417 ** but in shift step bits are dropped. The net result of this
1418 ** is that even if you have fast mul/div hardware you cannot
1419 ** put it to good use since the fixup would be too expensive.
1420 */
1421 delta = 0;
1422 vpdiff = (step >> 3);
1423
1424 if ( diff >= step ) {
1425 delta = 4;
1426 diff -= step;
1427 vpdiff += step;
1428 }
1429 step >>= 1;
1430 if ( diff >= step ) {
1431 delta |= 2;
1432 diff -= step;
1433 vpdiff += step;
1434 }
1435 step >>= 1;
1436 if ( diff >= step ) {
1437 delta |= 1;
1438 vpdiff += step;
1439 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001440
Anthony Baxter17471432006-03-20 05:58:21 +00001441 /* Step 3 - Update previous value */
1442 if ( sign )
1443 valpred -= vpdiff;
1444 else
1445 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001446
Anthony Baxter17471432006-03-20 05:58:21 +00001447 /* Step 4 - Clamp previous value to 16 bits */
1448 if ( valpred > 32767 )
1449 valpred = 32767;
1450 else if ( valpred < -32768 )
1451 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001452
Anthony Baxter17471432006-03-20 05:58:21 +00001453 /* Step 5 - Assemble value, update index and step values */
1454 delta |= sign;
1455
1456 index += indexTable[delta];
1457 if ( index < 0 ) index = 0;
1458 if ( index > 88 ) index = 88;
1459 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001460
Anthony Baxter17471432006-03-20 05:58:21 +00001461 /* Step 6 - Output value */
1462 if ( bufferstep ) {
1463 outputbuffer = (delta << 4) & 0xf0;
1464 } else {
1465 *ncp++ = (delta & 0x0f) | outputbuffer;
1466 }
1467 bufferstep = !bufferstep;
1468 }
1469 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1470 Py_DECREF(str);
1471 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001472}
1473
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001474static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001475audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001476{
Anthony Baxter17471432006-03-20 05:58:21 +00001477 signed char *cp;
1478 signed char *ncp;
1479 int len, size, valpred, step, delta, index, sign, vpdiff;
1480 PyObject *rv, *str, *state;
1481 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001482
Anthony Baxter17471432006-03-20 05:58:21 +00001483 if ( !PyArg_Parse(args, "(s#iO)",
1484 &cp, &len, &size, &state) )
1485 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001486
Anthony Baxter17471432006-03-20 05:58:21 +00001487 if ( size != 1 && size != 2 && size != 4) {
1488 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1489 return 0;
1490 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001491
Anthony Baxter17471432006-03-20 05:58:21 +00001492 /* Decode state, should have (value, step) */
1493 if ( state == Py_None ) {
1494 /* First time, it seems. Set defaults */
1495 valpred = 0;
1496 step = 7;
1497 index = 0;
1498 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1499 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001500
Anthony Baxter17471432006-03-20 05:58:21 +00001501 str = PyString_FromStringAndSize(NULL, len*size*2);
1502 if ( str == 0 )
1503 return 0;
1504 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001505
Anthony Baxter17471432006-03-20 05:58:21 +00001506 step = stepsizeTable[index];
1507 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001508
Anthony Baxter17471432006-03-20 05:58:21 +00001509 for ( i=0; i < len*size*2; i += size ) {
1510 /* Step 1 - get the delta value and compute next index */
1511 if ( bufferstep ) {
1512 delta = inputbuffer & 0xf;
1513 } else {
1514 inputbuffer = *cp++;
1515 delta = (inputbuffer >> 4) & 0xf;
1516 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001517
Anthony Baxter17471432006-03-20 05:58:21 +00001518 bufferstep = !bufferstep;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001519
Anthony Baxter17471432006-03-20 05:58:21 +00001520 /* Step 2 - Find new index value (for later) */
1521 index += indexTable[delta];
1522 if ( index < 0 ) index = 0;
1523 if ( index > 88 ) index = 88;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001524
Anthony Baxter17471432006-03-20 05:58:21 +00001525 /* Step 3 - Separate sign and magnitude */
1526 sign = delta & 8;
1527 delta = delta & 7;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001528
Anthony Baxter17471432006-03-20 05:58:21 +00001529 /* Step 4 - Compute difference and new predicted value */
1530 /*
1531 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1532 ** in adpcm_coder.
1533 */
1534 vpdiff = step >> 3;
1535 if ( delta & 4 ) vpdiff += step;
1536 if ( delta & 2 ) vpdiff += step>>1;
1537 if ( delta & 1 ) vpdiff += step>>2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001538
Anthony Baxter17471432006-03-20 05:58:21 +00001539 if ( sign )
1540 valpred -= vpdiff;
1541 else
1542 valpred += vpdiff;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001543
Anthony Baxter17471432006-03-20 05:58:21 +00001544 /* Step 5 - clamp output value */
1545 if ( valpred > 32767 )
1546 valpred = 32767;
1547 else if ( valpred < -32768 )
1548 valpred = -32768;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001549
Anthony Baxter17471432006-03-20 05:58:21 +00001550 /* Step 6 - Update step value */
1551 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001552
Anthony Baxter17471432006-03-20 05:58:21 +00001553 /* Step 6 - Output value */
1554 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1555 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1556 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
1557 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001558
Anthony Baxter17471432006-03-20 05:58:21 +00001559 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1560 Py_DECREF(str);
1561 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001562}
1563
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001564static PyMethodDef audioop_methods[] = {
Anthony Baxter17471432006-03-20 05:58:21 +00001565 { "max", audioop_max, METH_OLDARGS },
1566 { "minmax", audioop_minmax, METH_OLDARGS },
1567 { "avg", audioop_avg, METH_OLDARGS },
1568 { "maxpp", audioop_maxpp, METH_OLDARGS },
1569 { "avgpp", audioop_avgpp, METH_OLDARGS },
1570 { "rms", audioop_rms, METH_OLDARGS },
1571 { "findfit", audioop_findfit, METH_OLDARGS },
1572 { "findmax", audioop_findmax, METH_OLDARGS },
1573 { "findfactor", audioop_findfactor, METH_OLDARGS },
1574 { "cross", audioop_cross, METH_OLDARGS },
1575 { "mul", audioop_mul, METH_OLDARGS },
1576 { "add", audioop_add, METH_OLDARGS },
1577 { "bias", audioop_bias, METH_OLDARGS },
1578 { "ulaw2lin", audioop_ulaw2lin, METH_OLDARGS },
1579 { "lin2ulaw", audioop_lin2ulaw, METH_OLDARGS },
1580 { "alaw2lin", audioop_alaw2lin, METH_OLDARGS },
1581 { "lin2alaw", audioop_lin2alaw, METH_OLDARGS },
1582 { "lin2lin", audioop_lin2lin, METH_OLDARGS },
1583 { "adpcm2lin", audioop_adpcm2lin, METH_OLDARGS },
1584 { "lin2adpcm", audioop_lin2adpcm, METH_OLDARGS },
1585 { "tomono", audioop_tomono, METH_OLDARGS },
1586 { "tostereo", audioop_tostereo, METH_OLDARGS },
1587 { "getsample", audioop_getsample, METH_OLDARGS },
1588 { "reverse", audioop_reverse, METH_OLDARGS },
1589 { "ratecv", audioop_ratecv, METH_VARARGS },
1590 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001591};
1592
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001593PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001594initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001595{
Anthony Baxter17471432006-03-20 05:58:21 +00001596 PyObject *m, *d;
1597 m = Py_InitModule("audioop", audioop_methods);
1598 if (m == NULL)
1599 return;
1600 d = PyModule_GetDict(m);
Neal Norwitz49c65d02006-03-20 06:34:06 +00001601 if (d == NULL)
1602 return;
Anthony Baxter17471432006-03-20 05:58:21 +00001603 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1604 if (AudioopError != NULL)
1605 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001606}