blob: d9a398fc0bfa2272e3a5a136a7df8b96ee1bba9c [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;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001023 len = ncp - PyString_AsString(str);
1024 if (len == 0) {
1025 /*don't want to resize to zero length*/
1026 rv = PyString_FromStringAndSize("", 0);
1027 Py_DECREF(str);
1028 str = rv;
1029 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001030 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001031 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001032 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001033 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001034 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001035 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001036 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001037 prev_i[chan] = cur_i[chan];
1038 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001039 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001040 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001041 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001042 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001043 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001044 cp += size;
1045 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001046 cur_i[chan] =
1047 (weightA * cur_i[chan] +
1048 weightB * prev_i[chan]) /
1049 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001050 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001051 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001052 d += outrate;
1053 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001054 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001055 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001056 cur_o = (prev_i[chan] * d +
1057 cur_i[chan] * (outrate - d)) /
1058 outrate;
1059 if (size == 1)
1060 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001061 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001062 *SHORTP(ncp, 0) = (short)(cur_o);
1063 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001064 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001065 ncp += size;
1066 }
1067 d -= inrate;
1068 }
1069 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001070 exit:
1071 if (prev_i != NULL)
1072 free(prev_i);
1073 if (cur_i != NULL)
1074 free(cur_i);
1075 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001076}
Guido van Rossum1851a671997-02-14 16:14:03 +00001077
Roger E. Massec905fff1997-01-17 18:12:04 +00001078static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001079audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001080{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001081 signed char *cp;
1082 unsigned char *ncp;
1083 int len, size, val = 0;
1084 PyObject *rv;
1085 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001086
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001087 if ( !PyArg_Parse(args, "(s#i)",
1088 &cp, &len, &size) )
1089 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001090
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001091 if ( size != 1 && size != 2 && size != 4) {
1092 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1093 return 0;
1094 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001095
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001096 rv = PyString_FromStringAndSize(NULL, len/size);
1097 if ( rv == 0 )
1098 return 0;
1099 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001100
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001101 for ( i=0; i < len; i += size ) {
1102 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1103 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1104 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001105
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001106 *ncp++ = st_linear_to_ulaw(val);
1107 }
1108 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001109}
1110
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001111static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001112audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001113{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001114 unsigned char *cp;
1115 unsigned char cval;
1116 signed char *ncp;
1117 int len, size, val;
1118 PyObject *rv;
1119 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001120
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001121 if ( !PyArg_Parse(args, "(s#i)",
1122 &cp, &len, &size) )
1123 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001124
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001125 if ( size != 1 && size != 2 && size != 4) {
1126 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1127 return 0;
1128 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001129
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001130 rv = PyString_FromStringAndSize(NULL, len*size);
1131 if ( rv == 0 )
1132 return 0;
1133 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001134
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001135 for ( i=0; i < len*size; i += size ) {
1136 cval = *cp++;
1137 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001138
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001139 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1140 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001141 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001142 }
1143 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001144}
1145
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001146static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001147audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001148{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001149 signed char *cp;
1150 signed char *ncp;
1151 int len, size, val = 0, step, valpred, delta,
1152 index, sign, vpdiff, diff;
1153 PyObject *rv, *state, *str;
1154 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001155
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001156 if ( !PyArg_Parse(args, "(s#iO)",
1157 &cp, &len, &size, &state) )
1158 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001159
1160
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001161 if ( size != 1 && size != 2 && size != 4) {
1162 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1163 return 0;
1164 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001165
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001166 str = PyString_FromStringAndSize(NULL, len/(size*2));
1167 if ( str == 0 )
1168 return 0;
1169 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001170
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001171 /* Decode state, should have (value, step) */
1172 if ( state == Py_None ) {
1173 /* First time, it seems. Set defaults */
1174 valpred = 0;
1175 step = 7;
1176 index = 0;
1177 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1178 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001179
Guido van Rossumb64e6351992-07-06 14:21:56 +00001180 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001181 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001182
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001183 for ( i=0; i < len; i += size ) {
1184 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1185 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1186 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1187
1188 /* Step 1 - compute difference with previous value */
1189 diff = val - valpred;
1190 sign = (diff < 0) ? 8 : 0;
1191 if ( sign ) diff = (-diff);
1192
1193 /* Step 2 - Divide and clamp */
1194 /* Note:
1195 ** This code *approximately* computes:
1196 ** delta = diff*4/step;
1197 ** vpdiff = (delta+0.5)*step/4;
1198 ** but in shift step bits are dropped. The net result of this
1199 ** is that even if you have fast mul/div hardware you cannot
1200 ** put it to good use since the fixup would be too expensive.
1201 */
1202 delta = 0;
1203 vpdiff = (step >> 3);
1204
1205 if ( diff >= step ) {
1206 delta = 4;
1207 diff -= step;
1208 vpdiff += step;
1209 }
1210 step >>= 1;
1211 if ( diff >= step ) {
1212 delta |= 2;
1213 diff -= step;
1214 vpdiff += step;
1215 }
1216 step >>= 1;
1217 if ( diff >= step ) {
1218 delta |= 1;
1219 vpdiff += step;
1220 }
1221
1222 /* Step 3 - Update previous value */
1223 if ( sign )
1224 valpred -= vpdiff;
1225 else
1226 valpred += vpdiff;
1227
1228 /* Step 4 - Clamp previous value to 16 bits */
1229 if ( valpred > 32767 )
1230 valpred = 32767;
1231 else if ( valpred < -32768 )
1232 valpred = -32768;
1233
1234 /* Step 5 - Assemble value, update index and step values */
1235 delta |= sign;
1236
1237 index += indexTable[delta];
1238 if ( index < 0 ) index = 0;
1239 if ( index > 88 ) index = 88;
1240 step = stepsizeTable[index];
1241
1242 /* Step 6 - Output value */
1243 if ( bufferstep ) {
1244 outputbuffer = (delta << 4) & 0xf0;
1245 } else {
1246 *ncp++ = (delta & 0x0f) | outputbuffer;
1247 }
1248 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001249 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001250 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1251 Py_DECREF(str);
1252 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001253}
1254
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001255static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001256audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001257{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001258 signed char *cp;
1259 signed char *ncp;
1260 int len, size, valpred, step, delta, index, sign, vpdiff;
1261 PyObject *rv, *str, *state;
1262 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001263
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001264 if ( !PyArg_Parse(args, "(s#iO)",
1265 &cp, &len, &size, &state) )
1266 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001267
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001268 if ( size != 1 && size != 2 && size != 4) {
1269 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1270 return 0;
1271 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001272
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001273 /* Decode state, should have (value, step) */
1274 if ( state == Py_None ) {
1275 /* First time, it seems. Set defaults */
1276 valpred = 0;
1277 step = 7;
1278 index = 0;
1279 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1280 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001281
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001282 str = PyString_FromStringAndSize(NULL, len*size*2);
1283 if ( str == 0 )
1284 return 0;
1285 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001286
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001287 step = stepsizeTable[index];
1288 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001289
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001290 for ( i=0; i < len*size*2; i += size ) {
1291 /* Step 1 - get the delta value and compute next index */
1292 if ( bufferstep ) {
1293 delta = inputbuffer & 0xf;
1294 } else {
1295 inputbuffer = *cp++;
1296 delta = (inputbuffer >> 4) & 0xf;
1297 }
1298
1299 bufferstep = !bufferstep;
1300
1301 /* Step 2 - Find new index value (for later) */
1302 index += indexTable[delta];
1303 if ( index < 0 ) index = 0;
1304 if ( index > 88 ) index = 88;
1305
1306 /* Step 3 - Separate sign and magnitude */
1307 sign = delta & 8;
1308 delta = delta & 7;
1309
1310 /* Step 4 - Compute difference and new predicted value */
1311 /*
1312 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1313 ** in adpcm_coder.
1314 */
1315 vpdiff = step >> 3;
1316 if ( delta & 4 ) vpdiff += step;
1317 if ( delta & 2 ) vpdiff += step>>1;
1318 if ( delta & 1 ) vpdiff += step>>2;
1319
1320 if ( sign )
1321 valpred -= vpdiff;
1322 else
1323 valpred += vpdiff;
1324
1325 /* Step 5 - clamp output value */
1326 if ( valpred > 32767 )
1327 valpred = 32767;
1328 else if ( valpred < -32768 )
1329 valpred = -32768;
1330
1331 /* Step 6 - Update step value */
1332 step = stepsizeTable[index];
1333
1334 /* Step 6 - Output value */
1335 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1336 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001337 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001338 }
1339
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001340 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1341 Py_DECREF(str);
1342 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001343}
1344
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001345static PyMethodDef audioop_methods[] = {
1346 { "max", audioop_max },
1347 { "minmax", audioop_minmax },
1348 { "avg", audioop_avg },
1349 { "maxpp", audioop_maxpp },
1350 { "avgpp", audioop_avgpp },
1351 { "rms", audioop_rms },
1352 { "findfit", audioop_findfit },
1353 { "findmax", audioop_findmax },
1354 { "findfactor", audioop_findfactor },
1355 { "cross", audioop_cross },
1356 { "mul", audioop_mul },
1357 { "add", audioop_add },
1358 { "bias", audioop_bias },
1359 { "ulaw2lin", audioop_ulaw2lin },
1360 { "lin2ulaw", audioop_lin2ulaw },
1361 { "lin2lin", audioop_lin2lin },
1362 { "adpcm2lin", audioop_adpcm2lin },
1363 { "lin2adpcm", audioop_lin2adpcm },
1364 { "tomono", audioop_tomono },
1365 { "tostereo", audioop_tostereo },
1366 { "getsample", audioop_getsample },
1367 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001368 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001369 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001370};
1371
Guido van Rossum3886bb61998-12-04 18:50:17 +00001372DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001373initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001374{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001375 PyObject *m, *d;
1376 m = Py_InitModule("audioop", audioop_methods);
1377 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001378 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1379 if (AudioopError != NULL)
1380 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001381}