blob: 5e285f41f2e869061a26f9475289a8805485c869 [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
Guido van Rossum7b1e9741994-08-29 10:46:42 +000018#if defined(__CHAR_UNSIGNED__)
19#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000020/* This module currently does not work on systems where only unsigned
21 characters are available. Take it out of Setup. Sorry. */
22#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000023#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000024
Jack Jansena90805f1993-02-17 14:29:28 +000025/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000026** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
27
28#define MINLIN -32768
29#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000030#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
31 else if ( x > MAXLIN ) x = MAXLIN; \
32 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000033
Fred Drakec818d532000-08-31 05:07:19 +000034static unsigned char st_linear_to_ulaw(int sample);
Guido van Rossumb66efa01992-06-01 16:01:24 +000035
36/*
37** This macro converts from ulaw to 16 bit linear, faster.
38**
39** Jef Poskanzer
40** 23 October 1989
41**
42** Input: 8 bit ulaw sample
43** Output: signed 16 bit linear sample
44*/
45#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
46
47static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000048 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
49 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
50 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
51 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
52 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
53 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
54 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
55 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
56 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
57 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
58 -876, -844, -812, -780, -748, -716, -684, -652,
59 -620, -588, -556, -524, -492, -460, -428, -396,
60 -372, -356, -340, -324, -308, -292, -276, -260,
61 -244, -228, -212, -196, -180, -164, -148, -132,
62 -120, -112, -104, -96, -88, -80, -72, -64,
63 -56, -48, -40, -32, -24, -16, -8, 0,
64 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
65 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
66 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
67 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
68 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
69 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
70 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
71 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
72 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
73 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
74 876, 844, 812, 780, 748, 716, 684, 652,
75 620, 588, 556, 524, 492, 460, 428, 396,
76 372, 356, 340, 324, 308, 292, 276, 260,
77 244, 228, 212, 196, 180, 164, 148, 132,
78 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000079 56, 48, 40, 32, 24, 16, 8, 0 };
80
Moshe Zadka6a078ed2000-08-04 15:53:06 +000081/* #define ZEROTRAP */ /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +000082#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
83#define CLIP 32635
84
Guido van Rossumcd938fc1995-01-17 16:13:48 +000085static unsigned char
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000086st_linear_to_ulaw(int sample)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000087{
88 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
89 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
90 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
91 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
92 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
93 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
94 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
95 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
96 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
97 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
98 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
99 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
100 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
101 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
102 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
103 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
104 int sign, exponent, mantissa;
105 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000107 /* Get the sample into sign-magnitude. */
108 sign = (sample >> 8) & 0x80; /* set aside the sign */
109 if ( sign != 0 ) sample = -sample; /* get magnitude */
110 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000111
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000112 /* Convert from 16 bit linear to ulaw. */
113 sample = sample + BIAS;
114 exponent = exp_lut[( sample >> 7 ) & 0xFF];
115 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
116 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000117#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000118 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000119#endif
120
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000121 return ulawbyte;
122}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000123/* End of code taken from sox */
124
Guido van Rossumb64e6351992-07-06 14:21:56 +0000125/* Intel ADPCM step variation table */
126static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000127 -1, -1, -1, -1, 2, 4, 6, 8,
128 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000129};
130
131static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000132 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
133 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
134 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
135 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
136 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
137 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
138 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
139 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
140 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000141};
142
Guido van Rossumb66efa01992-06-01 16:01:24 +0000143#define CHARP(cp, i) ((signed char *)(cp+i))
144#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000145#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000146
147
148
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000149static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000150
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000151static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000152audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000153{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000154 signed char *cp;
155 int len, size, val = 0;
156 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000157
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000158 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
159 return 0;
160 if ( size != 1 && size != 2 && size != 4 ) {
161 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
162 return 0;
163 }
164 if ( i < 0 || i >= len/size ) {
165 PyErr_SetString(AudioopError, "Index out of range");
166 return 0;
167 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000168 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000169 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
170 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
171 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000172}
173
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000174static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000175audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000176{
177 signed char *cp;
178 int len, size, val = 0;
179 int i;
180 int max = 0;
181
182 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
183 return 0;
184 if ( size != 1 && size != 2 && size != 4 ) {
185 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
186 return 0;
187 }
188 for ( i=0; i<len; i+= size) {
189 if ( size == 1 ) val = (int)*CHARP(cp, i);
190 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
191 else if ( size == 4 ) val = (int)*LONGP(cp, i);
192 if ( val < 0 ) val = (-val);
193 if ( val > max ) max = val;
194 }
195 return PyInt_FromLong(max);
196}
197
198static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000199audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000200{
201 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000202 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000203 int i;
204 int min = 0x7fffffff, max = -0x7fffffff;
205
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000206 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000207 return NULL;
208 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000209 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000210 return NULL;
211 }
212 for (i = 0; i < len; i += size) {
213 if (size == 1) val = (int) *CHARP(cp, i);
214 else if (size == 2) val = (int) *SHORTP(cp, i);
215 else if (size == 4) val = (int) *LONGP(cp, i);
216 if (val > max) max = val;
217 if (val < min) min = val;
218 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000219 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000220}
221
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000222static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000223audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000224{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000225 signed char *cp;
226 int len, size, val = 0;
227 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000228 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000229
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000230 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
231 return 0;
232 if ( size != 1 && size != 2 && size != 4 ) {
233 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
234 return 0;
235 }
236 for ( i=0; i<len; i+= size) {
237 if ( size == 1 ) val = (int)*CHARP(cp, i);
238 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
239 else if ( size == 4 ) val = (int)*LONGP(cp, i);
240 avg += val;
241 }
242 if ( len == 0 )
243 val = 0;
244 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000245 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000246 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000247}
248
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000249static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000250audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000251{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000252 signed char *cp;
253 int len, size, val = 0;
254 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000255 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000256
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000257 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
258 return 0;
259 if ( size != 1 && size != 2 && size != 4 ) {
260 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
261 return 0;
262 }
263 for ( i=0; i<len; i+= size) {
264 if ( size == 1 ) val = (int)*CHARP(cp, i);
265 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
266 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000267 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000268 }
269 if ( len == 0 )
270 val = 0;
271 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000272 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000273 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000274}
275
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000276static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000277{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000278 int i;
279 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000280
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000281 for( i=0; i<len; i++) {
282 sum = sum + (double)a[i]*(double)b[i];
283 }
284 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000285}
286
287/*
288** Findfit tries to locate a sample within another sample. Its main use
289** is in echo-cancellation (to find the feedback of the output signal in
290** the input signal).
291** The method used is as follows:
292**
293** let R be the reference signal (length n) and A the input signal (length N)
294** with N > n, and let all sums be over i from 0 to n-1.
295**
296** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
297** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
298** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
299**
300** Next, we compute the relative distance between the original signal and
301** the modified signal and minimize that over j:
302** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
303** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
304**
305** In the code variables correspond as follows:
306** cp1 A
307** cp2 R
308** len1 N
309** len2 n
310** aj_m1 A[j-1]
311** aj_lm1 A[j+n-1]
312** sum_ri_2 sum(R[i]^2)
313** sum_aij_2 sum(A[i+j]^2)
314** sum_aij_ri sum(A[i+j]R[i])
315**
316** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
317** is completely recalculated each step.
318*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000319static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000320audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000321{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000322 short *cp1, *cp2;
323 int len1, len2;
324 int j, best_j;
325 double aj_m1, aj_lm1;
326 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000327
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
329 return 0;
330 if ( len1 & 1 || len2 & 1 ) {
331 PyErr_SetString(AudioopError, "Strings should be even-sized");
332 return 0;
333 }
334 len1 >>= 1;
335 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000336
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000337 if ( len1 < len2 ) {
338 PyErr_SetString(AudioopError, "First sample should be longer");
339 return 0;
340 }
341 sum_ri_2 = _sum2(cp2, cp2, len2);
342 sum_aij_2 = _sum2(cp1, cp1, len2);
343 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000344
345 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
346
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000347 best_result = result;
348 best_j = 0;
349 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000350
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000351 for ( j=1; j<=len1-len2; j++) {
352 aj_m1 = (double)cp1[j-1];
353 aj_lm1 = (double)cp1[j+len2-1];
354
355 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
356 sum_aij_ri = _sum2(cp1+j, cp2, len2);
357
358 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
359 / sum_aij_2;
360
361 if ( result < best_result ) {
362 best_result = result;
363 best_j = j;
364 }
365
366 }
367
368 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000369
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000370 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000371}
372
373/*
374** findfactor finds a factor f so that the energy in A-fB is minimal.
375** See the comment for findfit for details.
376*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000377static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000378audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000379{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000380 short *cp1, *cp2;
381 int len1, len2;
382 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000383
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000384 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
385 return 0;
386 if ( len1 & 1 || len2 & 1 ) {
387 PyErr_SetString(AudioopError, "Strings should be even-sized");
388 return 0;
389 }
390 if ( len1 != len2 ) {
391 PyErr_SetString(AudioopError, "Samples should be same size");
392 return 0;
393 }
394 len2 >>= 1;
395 sum_ri_2 = _sum2(cp2, cp2, len2);
396 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000397
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000398 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000399
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000400 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000401}
402
403/*
404** findmax returns the index of the n-sized segment of the input sample
405** that contains the most energy.
406*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000408audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000409{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000410 short *cp1;
411 int len1, len2;
412 int j, best_j;
413 double aj_m1, aj_lm1;
414 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000415
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
417 return 0;
418 if ( len1 & 1 ) {
419 PyErr_SetString(AudioopError, "Strings should be even-sized");
420 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000421 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000422 len1 >>= 1;
423
424 if ( len1 < len2 ) {
425 PyErr_SetString(AudioopError, "Input sample should be longer");
426 return 0;
427 }
Jack Jansena90805f1993-02-17 14:29:28 +0000428
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000429 result = _sum2(cp1, cp1, len2);
430
431 best_result = result;
432 best_j = 0;
433 j = 0;
434
435 for ( j=1; j<=len1-len2; j++) {
436 aj_m1 = (double)cp1[j-1];
437 aj_lm1 = (double)cp1[j+len2-1];
438
439 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
440
441 if ( result > best_result ) {
442 best_result = result;
443 best_j = j;
444 }
445
446 }
447
448 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000449}
450
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000451static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000452audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000453{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000454 signed char *cp;
455 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
456 prevextreme = 0;
457 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000458 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000459 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000460
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000461 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
462 return 0;
463 if ( size != 1 && size != 2 && size != 4 ) {
464 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
465 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000466 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000467 /* Compute first delta value ahead. Also automatically makes us
468 ** skip the first extreme value
469 */
470 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
471 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
472 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
473 if ( size == 1 ) val = (int)*CHARP(cp, size);
474 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
475 else if ( size == 4 ) val = (int)*LONGP(cp, size);
476 prevdiff = val - prevval;
477
478 for ( i=size; i<len; i+= size) {
479 if ( size == 1 ) val = (int)*CHARP(cp, i);
480 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
481 else if ( size == 4 ) val = (int)*LONGP(cp, i);
482 diff = val - prevval;
483 if ( diff*prevdiff < 0 ) {
484 /* Derivative changed sign. Compute difference to last
485 ** extreme value and remember.
486 */
487 if ( prevextremevalid ) {
488 extremediff = prevval - prevextreme;
489 if ( extremediff < 0 )
490 extremediff = -extremediff;
491 avg += extremediff;
492 nextreme++;
493 }
494 prevextremevalid = 1;
495 prevextreme = prevval;
496 }
497 prevval = val;
498 if ( diff != 0 )
499 prevdiff = diff;
500 }
501 if ( nextreme == 0 )
502 val = 0;
503 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000504 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000505 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000506}
507
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000508static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000509audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000510{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000511 signed char *cp;
512 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
513 prevextreme = 0;
514 int i;
515 int max = 0;
516 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000517
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000518 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
519 return 0;
520 if ( size != 1 && size != 2 && size != 4 ) {
521 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
522 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000523 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524 /* Compute first delta value ahead. Also automatically makes us
525 ** skip the first extreme value
526 */
527 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
528 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
529 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
530 if ( size == 1 ) val = (int)*CHARP(cp, size);
531 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
532 else if ( size == 4 ) val = (int)*LONGP(cp, size);
533 prevdiff = val - prevval;
534
535 for ( i=size; i<len; i+= size) {
536 if ( size == 1 ) val = (int)*CHARP(cp, i);
537 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
538 else if ( size == 4 ) val = (int)*LONGP(cp, i);
539 diff = val - prevval;
540 if ( diff*prevdiff < 0 ) {
541 /* Derivative changed sign. Compute difference to
542 ** last extreme value and remember.
543 */
544 if ( prevextremevalid ) {
545 extremediff = prevval - prevextreme;
546 if ( extremediff < 0 )
547 extremediff = -extremediff;
548 if ( extremediff > max )
549 max = extremediff;
550 }
551 prevextremevalid = 1;
552 prevextreme = prevval;
553 }
554 prevval = val;
555 if ( diff != 0 )
556 prevdiff = diff;
557 }
558 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000559}
560
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000561static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000562audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000563{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000564 signed char *cp;
565 int len, size, val = 0;
566 int i;
567 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000568
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000569 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
570 return 0;
571 if ( size != 1 && size != 2 && size != 4 ) {
572 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
573 return 0;
574 }
575 ncross = -1;
576 prevval = 17; /* Anything <> 0,1 */
577 for ( i=0; i<len; i+= size) {
578 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
579 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
580 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
581 val = val & 1;
582 if ( val != prevval ) ncross++;
583 prevval = val;
584 }
585 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000586}
587
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000588static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000589audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000590{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000591 signed char *cp, *ncp;
592 int len, size, val = 0;
593 double factor, fval, maxval;
594 PyObject *rv;
595 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000596
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000597 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
598 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000599
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600 if ( size == 1 ) maxval = (double) 0x7f;
601 else if ( size == 2 ) maxval = (double) 0x7fff;
602 else if ( size == 4 ) maxval = (double) 0x7fffffff;
603 else {
604 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
605 return 0;
606 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000607
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000608 rv = PyString_FromStringAndSize(NULL, len);
609 if ( rv == 0 )
610 return 0;
611 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000612
613
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614 for ( i=0; i < len; i += size ) {
615 if ( size == 1 ) val = (int)*CHARP(cp, i);
616 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
617 else if ( size == 4 ) val = (int)*LONGP(cp, i);
618 fval = (double)val*factor;
619 if ( fval > maxval ) fval = maxval;
620 else if ( fval < -maxval ) fval = -maxval;
621 val = (int)fval;
622 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
623 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000624 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000625 }
626 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000627}
628
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000629static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000630audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000631{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000632 signed char *cp, *ncp;
633 int len, size, val1 = 0, val2 = 0;
634 double fac1, fac2, fval, maxval;
635 PyObject *rv;
636 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000637
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000638 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
639 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000640
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000641 if ( size == 1 ) maxval = (double) 0x7f;
642 else if ( size == 2 ) maxval = (double) 0x7fff;
643 else if ( size == 4 ) maxval = (double) 0x7fffffff;
644 else {
645 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
646 return 0;
647 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000648
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649 rv = PyString_FromStringAndSize(NULL, len/2);
650 if ( rv == 0 )
651 return 0;
652 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000653
654
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000655 for ( i=0; i < len; i += size*2 ) {
656 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
657 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
658 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
659 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
660 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
661 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
662 fval = (double)val1*fac1 + (double)val2*fac2;
663 if ( fval > maxval ) fval = maxval;
664 else if ( fval < -maxval ) fval = -maxval;
665 val1 = (int)fval;
666 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
667 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000668 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000669 }
670 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000671}
672
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000673static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000674audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000675{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000676 signed char *cp, *ncp;
677 int len, size, val1, val2, val = 0;
678 double fac1, fac2, fval, maxval;
679 PyObject *rv;
680 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000681
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000682 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
683 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000684
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000685 if ( size == 1 ) maxval = (double) 0x7f;
686 else if ( size == 2 ) maxval = (double) 0x7fff;
687 else if ( size == 4 ) maxval = (double) 0x7fffffff;
688 else {
689 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
690 return 0;
691 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000692
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000693 rv = PyString_FromStringAndSize(NULL, len*2);
694 if ( rv == 0 )
695 return 0;
696 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000697
698
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000699 for ( i=0; i < len; i += size ) {
700 if ( size == 1 ) val = (int)*CHARP(cp, i);
701 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
702 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000703
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000704 fval = (double)val*fac1;
705 if ( fval > maxval ) fval = maxval;
706 else if ( fval < -maxval ) fval = -maxval;
707 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000708
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000709 fval = (double)val*fac2;
710 if ( fval > maxval ) fval = maxval;
711 else if ( fval < -maxval ) fval = -maxval;
712 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000713
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000714 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
715 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000716 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000718 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
719 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000720 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000721 }
722 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000723}
724
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000725static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000726audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000727{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000728 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000729 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000730 PyObject *rv;
731 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000732
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000733 if ( !PyArg_Parse(args, "(s#s#i)",
734 &cp1, &len1, &cp2, &len2, &size ) )
735 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000736
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737 if ( len1 != len2 ) {
738 PyErr_SetString(AudioopError, "Lengths should be the same");
739 return 0;
740 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000741
Guido van Rossum1851a671997-02-14 16:14:03 +0000742 if ( size == 1 ) maxval = 0x7f;
743 else if ( size == 2 ) maxval = 0x7fff;
744 else if ( size == 4 ) maxval = 0x7fffffff;
745 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000746 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
747 return 0;
748 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000749
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000750 rv = PyString_FromStringAndSize(NULL, len1);
751 if ( rv == 0 )
752 return 0;
753 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000754
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000755 for ( i=0; i < len1; i += size ) {
756 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
757 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
758 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000759
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000760 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
761 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
762 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000763
Guido van Rossum1851a671997-02-14 16:14:03 +0000764 newval = val1 + val2;
765 /* truncate in case of overflow */
766 if (newval > maxval) newval = maxval;
767 else if (newval < -maxval) newval = -maxval;
768 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
769 newval = val1 > 0 ? maxval : - maxval;
770
771 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
772 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000773 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000774 }
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_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000780{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000781 signed char *cp, *ncp;
782 int len, size, val = 0;
783 PyObject *rv;
784 int i;
785 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000786
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000787 if ( !PyArg_Parse(args, "(s#ii)",
788 &cp, &len, &size , &bias) )
789 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000791 if ( size != 1 && size != 2 && size != 4) {
792 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
793 return 0;
794 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000796 rv = PyString_FromStringAndSize(NULL, len);
797 if ( rv == 0 )
798 return 0;
799 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000800
801
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000802 for ( i=0; i < len; i += size ) {
803 if ( size == 1 ) val = (int)*CHARP(cp, i);
804 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
805 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000806
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000807 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
808 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000809 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000810 }
811 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000812}
813
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000814static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000815audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000816{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000817 signed char *cp;
818 unsigned char *ncp;
819 int len, size, val = 0;
820 PyObject *rv;
821 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000822
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000823 if ( !PyArg_Parse(args, "(s#i)",
824 &cp, &len, &size) )
825 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000826
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000827 if ( size != 1 && size != 2 && size != 4 ) {
828 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
829 return 0;
830 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000831
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000832 rv = PyString_FromStringAndSize(NULL, len);
833 if ( rv == 0 )
834 return 0;
835 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000836
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000837 for ( i=0; i < len; i += size ) {
838 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
839 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
840 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000841
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000842 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000843
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000844 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
845 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000846 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000847 }
848 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000849}
850
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000851static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000852audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000853{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000854 signed char *cp;
855 unsigned char *ncp;
856 int len, size, size2, val = 0;
857 PyObject *rv;
858 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000859
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000860 if ( !PyArg_Parse(args, "(s#ii)",
861 &cp, &len, &size, &size2) )
862 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000863
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 if ( (size != 1 && size != 2 && size != 4) ||
865 (size2 != 1 && size2 != 2 && size2 != 4)) {
866 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
867 return 0;
868 }
Jack Jansena90805f1993-02-17 14:29:28 +0000869
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000870 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
871 if ( rv == 0 )
872 return 0;
873 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000874
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000875 for ( i=0, j=0; i < len; i += size, j += size2 ) {
876 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
877 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
878 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000879
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000880 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
881 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000882 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000883 }
884 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000885}
886
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000887static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000888gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000889{
890 while (b > 0) {
891 int tmp = a % b;
892 a = b;
893 b = tmp;
894 }
895 return a;
896}
897
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000898static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000899audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +0000900{
Guido van Rossum1851a671997-02-14 16:14:03 +0000901 char *cp, *ncp;
902 int len, size, nchannels, inrate, outrate, weightA, weightB;
903 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000904 PyObject *state, *samps, *str, *rv = NULL;
Tim Peters3127c282001-12-05 22:30:21 +0000905 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +0000906
907 weightA = 1;
908 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000909 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000910 &inrate, &outrate, &state, &weightA, &weightB))
911 return NULL;
912 if (size != 1 && size != 2 && size != 4) {
913 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
914 return NULL;
915 }
916 if (nchannels < 1) {
917 PyErr_SetString(AudioopError, "# of channels should be >= 1");
918 return NULL;
919 }
Tim Peters3127c282001-12-05 22:30:21 +0000920 bytes_per_frame = size * nchannels;
921 if (bytes_per_frame / nchannels != size) {
922 /* This overflow test is rigorously correct because
923 both multiplicands are >= 1. Use the argument names
924 from the docs for the error msg. */
925 PyErr_SetString(PyExc_OverflowError,
926 "width * nchannels too big for a C int");
927 return NULL;
928 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000929 if (weightA < 1 || weightB < 0) {
930 PyErr_SetString(AudioopError,
931 "weightA should be >= 1, weightB should be >= 0");
932 return NULL;
933 }
Tim Peters3127c282001-12-05 22:30:21 +0000934 if (len % bytes_per_frame != 0) {
Guido van Rossum1851a671997-02-14 16:14:03 +0000935 PyErr_SetString(AudioopError, "not a whole number of frames");
936 return NULL;
937 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000938 if (inrate <= 0 || outrate <= 0) {
939 PyErr_SetString(AudioopError, "sampling rate not > 0");
940 return NULL;
941 }
942 /* divide inrate and outrate by their greatest common divisor */
943 d = gcd(inrate, outrate);
944 inrate /= d;
945 outrate /= d;
946
Guido van Rossum6345ac61997-10-31 20:32:13 +0000947 prev_i = (int *) malloc(nchannels * sizeof(int));
948 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum65bb3281999-09-07 14:24:05 +0000949 if (prev_i == NULL || cur_i == NULL) {
950 (void) PyErr_NoMemory();
951 goto exit;
952 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000953
Tim Peters3127c282001-12-05 22:30:21 +0000954 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +0000955
Guido van Rossum1851a671997-02-14 16:14:03 +0000956 if (state == Py_None) {
957 d = -outrate;
958 for (chan = 0; chan < nchannels; chan++)
959 prev_i[chan] = cur_i[chan] = 0;
Tim Peters1691bd92001-12-05 06:05:07 +0000960 }
961 else {
Guido van Rossum1851a671997-02-14 16:14:03 +0000962 if (!PyArg_ParseTuple(state,
963 "iO!;audioop.ratecv: illegal state argument",
964 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000965 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000966 if (PyTuple_Size(samps) != nchannels) {
967 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000968 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +0000969 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000970 }
971 for (chan = 0; chan < nchannels; chan++) {
972 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +0000973 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000974 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000975 }
976 }
Tim Peters1691bd92001-12-05 06:05:07 +0000977
978 /* str <- Space for the output buffer. */
979 {
980 /* There are len input frames, so we need (mathematically)
981 ceiling(len*outrate/inrate) output frames, and each frame
Tim Peters3127c282001-12-05 22:30:21 +0000982 requires bytes_per_frame bytes. Computing this
Tim Peterseb4b7ba2001-12-07 00:37:39 +0000983 without spurious overflow is the challenge; we can
984 settle for a reasonable upper bound, though. */
985 int ceiling; /* the number of output frames */
Tim Peters1691bd92001-12-05 06:05:07 +0000986 int nbytes; /* the number of output bytes needed */
987 int q = len / inrate;
Tim Peterseb4b7ba2001-12-07 00:37:39 +0000988 /* Now len = q * inrate + r exactly (with r = len % inrate),
989 and this is less than q * inrate + inrate = (q+1)*inrate.
990 So a reasonable upper bound on len*outrate/inrate is
991 ((q+1)*inrate)*outrate/inrate =
992 (q+1)*outrate.
993 */
994 ceiling = (q+1) * outrate;
Tim Peters3127c282001-12-05 22:30:21 +0000995 nbytes = ceiling * bytes_per_frame;
Tim Peterseb4b7ba2001-12-07 00:37:39 +0000996 /* See whether anything overflowed; if not, get the space. */
997 if (q+1 < 0 ||
998 ceiling / outrate != q+1 ||
999 nbytes / bytes_per_frame != ceiling)
1000 str = NULL;
1001 else
1002 str = PyString_FromStringAndSize(NULL, nbytes);
1003
1004 if (str == NULL) {
Tim Peters1691bd92001-12-05 06:05:07 +00001005 PyErr_SetString(PyExc_MemoryError,
1006 "not enough memory for output buffer");
1007 goto exit;
1008 }
Tim Peters1691bd92001-12-05 06:05:07 +00001009 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001010 ncp = PyString_AsString(str);
1011
1012 for (;;) {
1013 while (d < 0) {
1014 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001015 samps = PyTuple_New(nchannels);
1016 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001017 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001018 Py_BuildValue("(ii)",
1019 prev_i[chan],
1020 cur_i[chan]));
1021 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +00001022 goto exit;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001023 /* We have checked before that the length
1024 * of the string fits into int. */
1025 len = (int)(ncp - PyString_AsString(str));
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001026 if (len == 0) {
1027 /*don't want to resize to zero length*/
1028 rv = PyString_FromStringAndSize("", 0);
1029 Py_DECREF(str);
1030 str = rv;
1031 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001032 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001033 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001034 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001035 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001036 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001037 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001038 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001039 prev_i[chan] = cur_i[chan];
1040 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001041 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001042 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001043 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001044 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001045 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001046 cp += size;
1047 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001048 cur_i[chan] =
1049 (weightA * cur_i[chan] +
1050 weightB * prev_i[chan]) /
1051 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001052 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001053 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001054 d += outrate;
1055 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001056 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001057 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001058 cur_o = (prev_i[chan] * d +
1059 cur_i[chan] * (outrate - d)) /
1060 outrate;
1061 if (size == 1)
1062 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001063 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001064 *SHORTP(ncp, 0) = (short)(cur_o);
1065 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001066 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001067 ncp += size;
1068 }
1069 d -= inrate;
1070 }
1071 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001072 exit:
1073 if (prev_i != NULL)
1074 free(prev_i);
1075 if (cur_i != NULL)
1076 free(cur_i);
1077 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001078}
Guido van Rossum1851a671997-02-14 16:14:03 +00001079
Roger E. Massec905fff1997-01-17 18:12:04 +00001080static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001081audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001082{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001083 signed char *cp;
1084 unsigned char *ncp;
1085 int len, size, val = 0;
1086 PyObject *rv;
1087 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001088
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001089 if ( !PyArg_Parse(args, "(s#i)",
1090 &cp, &len, &size) )
1091 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001092
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001093 if ( size != 1 && size != 2 && size != 4) {
1094 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1095 return 0;
1096 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001097
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001098 rv = PyString_FromStringAndSize(NULL, len/size);
1099 if ( rv == 0 )
1100 return 0;
1101 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001102
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001103 for ( i=0; i < len; i += size ) {
1104 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1105 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1106 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001107
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001108 *ncp++ = st_linear_to_ulaw(val);
1109 }
1110 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001111}
1112
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001113static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001114audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001115{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116 unsigned char *cp;
1117 unsigned char cval;
1118 signed char *ncp;
1119 int len, size, val;
1120 PyObject *rv;
1121 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001122
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001123 if ( !PyArg_Parse(args, "(s#i)",
1124 &cp, &len, &size) )
1125 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001126
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001127 if ( size != 1 && size != 2 && size != 4) {
1128 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1129 return 0;
1130 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001131
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001132 rv = PyString_FromStringAndSize(NULL, len*size);
1133 if ( rv == 0 )
1134 return 0;
1135 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001136
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001137 for ( i=0; i < len*size; i += size ) {
1138 cval = *cp++;
1139 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001140
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001141 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1142 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001143 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001144 }
1145 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001146}
1147
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001148static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001149audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001150{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001151 signed char *cp;
1152 signed char *ncp;
1153 int len, size, val = 0, step, valpred, delta,
1154 index, sign, vpdiff, diff;
1155 PyObject *rv, *state, *str;
1156 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001157
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001158 if ( !PyArg_Parse(args, "(s#iO)",
1159 &cp, &len, &size, &state) )
1160 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001161
1162
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001163 if ( size != 1 && size != 2 && size != 4) {
1164 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1165 return 0;
1166 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001167
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001168 str = PyString_FromStringAndSize(NULL, len/(size*2));
1169 if ( str == 0 )
1170 return 0;
1171 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001172
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001173 /* Decode state, should have (value, step) */
1174 if ( state == Py_None ) {
1175 /* First time, it seems. Set defaults */
1176 valpred = 0;
1177 step = 7;
1178 index = 0;
1179 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1180 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001181
Guido van Rossumb64e6351992-07-06 14:21:56 +00001182 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001183 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001184
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001185 for ( i=0; i < len; i += size ) {
1186 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1187 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1188 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1189
1190 /* Step 1 - compute difference with previous value */
1191 diff = val - valpred;
1192 sign = (diff < 0) ? 8 : 0;
1193 if ( sign ) diff = (-diff);
1194
1195 /* Step 2 - Divide and clamp */
1196 /* Note:
1197 ** This code *approximately* computes:
1198 ** delta = diff*4/step;
1199 ** vpdiff = (delta+0.5)*step/4;
1200 ** but in shift step bits are dropped. The net result of this
1201 ** is that even if you have fast mul/div hardware you cannot
1202 ** put it to good use since the fixup would be too expensive.
1203 */
1204 delta = 0;
1205 vpdiff = (step >> 3);
1206
1207 if ( diff >= step ) {
1208 delta = 4;
1209 diff -= step;
1210 vpdiff += step;
1211 }
1212 step >>= 1;
1213 if ( diff >= step ) {
1214 delta |= 2;
1215 diff -= step;
1216 vpdiff += step;
1217 }
1218 step >>= 1;
1219 if ( diff >= step ) {
1220 delta |= 1;
1221 vpdiff += step;
1222 }
1223
1224 /* Step 3 - Update previous value */
1225 if ( sign )
1226 valpred -= vpdiff;
1227 else
1228 valpred += vpdiff;
1229
1230 /* Step 4 - Clamp previous value to 16 bits */
1231 if ( valpred > 32767 )
1232 valpred = 32767;
1233 else if ( valpred < -32768 )
1234 valpred = -32768;
1235
1236 /* Step 5 - Assemble value, update index and step values */
1237 delta |= sign;
1238
1239 index += indexTable[delta];
1240 if ( index < 0 ) index = 0;
1241 if ( index > 88 ) index = 88;
1242 step = stepsizeTable[index];
1243
1244 /* Step 6 - Output value */
1245 if ( bufferstep ) {
1246 outputbuffer = (delta << 4) & 0xf0;
1247 } else {
1248 *ncp++ = (delta & 0x0f) | outputbuffer;
1249 }
1250 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001251 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001252 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1253 Py_DECREF(str);
1254 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001255}
1256
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001257static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001258audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001259{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001260 signed char *cp;
1261 signed char *ncp;
1262 int len, size, valpred, step, delta, index, sign, vpdiff;
1263 PyObject *rv, *str, *state;
1264 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001265
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001266 if ( !PyArg_Parse(args, "(s#iO)",
1267 &cp, &len, &size, &state) )
1268 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001269
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001270 if ( size != 1 && size != 2 && size != 4) {
1271 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1272 return 0;
1273 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001274
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001275 /* Decode state, should have (value, step) */
1276 if ( state == Py_None ) {
1277 /* First time, it seems. Set defaults */
1278 valpred = 0;
1279 step = 7;
1280 index = 0;
1281 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1282 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001283
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001284 str = PyString_FromStringAndSize(NULL, len*size*2);
1285 if ( str == 0 )
1286 return 0;
1287 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001288
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001289 step = stepsizeTable[index];
1290 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001291
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001292 for ( i=0; i < len*size*2; i += size ) {
1293 /* Step 1 - get the delta value and compute next index */
1294 if ( bufferstep ) {
1295 delta = inputbuffer & 0xf;
1296 } else {
1297 inputbuffer = *cp++;
1298 delta = (inputbuffer >> 4) & 0xf;
1299 }
1300
1301 bufferstep = !bufferstep;
1302
1303 /* Step 2 - Find new index value (for later) */
1304 index += indexTable[delta];
1305 if ( index < 0 ) index = 0;
1306 if ( index > 88 ) index = 88;
1307
1308 /* Step 3 - Separate sign and magnitude */
1309 sign = delta & 8;
1310 delta = delta & 7;
1311
1312 /* Step 4 - Compute difference and new predicted value */
1313 /*
1314 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1315 ** in adpcm_coder.
1316 */
1317 vpdiff = step >> 3;
1318 if ( delta & 4 ) vpdiff += step;
1319 if ( delta & 2 ) vpdiff += step>>1;
1320 if ( delta & 1 ) vpdiff += step>>2;
1321
1322 if ( sign )
1323 valpred -= vpdiff;
1324 else
1325 valpred += vpdiff;
1326
1327 /* Step 5 - clamp output value */
1328 if ( valpred > 32767 )
1329 valpred = 32767;
1330 else if ( valpred < -32768 )
1331 valpred = -32768;
1332
1333 /* Step 6 - Update step value */
1334 step = stepsizeTable[index];
1335
1336 /* Step 6 - Output value */
1337 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1338 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001339 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001340 }
1341
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001342 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1343 Py_DECREF(str);
1344 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001345}
1346
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001347static PyMethodDef audioop_methods[] = {
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001348 { "max", audioop_max, METH_OLDARGS },
1349 { "minmax", audioop_minmax, METH_OLDARGS },
1350 { "avg", audioop_avg, METH_OLDARGS },
1351 { "maxpp", audioop_maxpp, METH_OLDARGS },
1352 { "avgpp", audioop_avgpp, METH_OLDARGS },
1353 { "rms", audioop_rms, METH_OLDARGS },
1354 { "findfit", audioop_findfit, METH_OLDARGS },
1355 { "findmax", audioop_findmax, METH_OLDARGS },
1356 { "findfactor", audioop_findfactor, METH_OLDARGS },
1357 { "cross", audioop_cross, METH_OLDARGS },
1358 { "mul", audioop_mul, METH_OLDARGS },
1359 { "add", audioop_add, METH_OLDARGS },
1360 { "bias", audioop_bias, METH_OLDARGS },
1361 { "ulaw2lin", audioop_ulaw2lin, METH_OLDARGS },
1362 { "lin2ulaw", audioop_lin2ulaw, METH_OLDARGS },
1363 { "lin2lin", audioop_lin2lin, METH_OLDARGS },
1364 { "adpcm2lin", audioop_adpcm2lin, METH_OLDARGS },
1365 { "lin2adpcm", audioop_lin2adpcm, METH_OLDARGS },
1366 { "tomono", audioop_tomono, METH_OLDARGS },
1367 { "tostereo", audioop_tostereo, METH_OLDARGS },
1368 { "getsample", audioop_getsample, METH_OLDARGS },
1369 { "reverse", audioop_reverse, METH_OLDARGS },
1370 { "ratecv", audioop_ratecv, METH_VARARGS },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001371 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001372};
1373
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001374PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001375initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001376{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001377 PyObject *m, *d;
1378 m = Py_InitModule("audioop", audioop_methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001379 if (m == NULL)
1380 return;
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001381 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001382 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1383 if (AudioopError != NULL)
1384 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001385}