blob: 49cd8c95753143f37f6b98aac280ea2e92277225 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumb66efa01992-06-01 16:01:24 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumb66efa01992-06-01 16:01:24 +00009******************************************************************/
10
Guido van Rossumb6775db1994-08-01 11:34:53 +000011/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +000012
Roger E. Masseeaa6e111997-01-03 19:26:27 +000013#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +000014
Guido van Rossum69011961998-04-23 20:23:00 +000015#if SIZEOF_INT == 4
16typedef int Py_Int32;
17typedef unsigned int Py_UInt32;
18#else
19#if SIZEOF_LONG == 4
20typedef long Py_Int32;
21typedef unsigned long Py_UInt32;
22#else
23#error "No 4-byte integral type"
24#endif
25#endif
26
Guido van Rossum7b1e9741994-08-29 10:46:42 +000027#if defined(__CHAR_UNSIGNED__)
28#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000029/* This module currently does not work on systems where only unsigned
30 characters are available. Take it out of Setup. Sorry. */
31#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000032#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000033
Jack Jansena90805f1993-02-17 14:29:28 +000034/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000035** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
36
37#define MINLIN -32768
38#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000039#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
40 else if ( x > MAXLIN ) x = MAXLIN; \
41 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000042
Guido van Rossumcd938fc1995-01-17 16:13:48 +000043static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000044
45/*
46** This macro converts from ulaw to 16 bit linear, faster.
47**
48** Jef Poskanzer
49** 23 October 1989
50**
51** Input: 8 bit ulaw sample
52** Output: signed 16 bit linear sample
53*/
54#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
55
56static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000057 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
58 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
59 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
60 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
61 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
62 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
63 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
64 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
65 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
66 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
67 -876, -844, -812, -780, -748, -716, -684, -652,
68 -620, -588, -556, -524, -492, -460, -428, -396,
69 -372, -356, -340, -324, -308, -292, -276, -260,
70 -244, -228, -212, -196, -180, -164, -148, -132,
71 -120, -112, -104, -96, -88, -80, -72, -64,
72 -56, -48, -40, -32, -24, -16, -8, 0,
73 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
74 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
75 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
76 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
77 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
78 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
79 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
80 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
81 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
82 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
83 876, 844, 812, 780, 748, 716, 684, 652,
84 620, 588, 556, 524, 492, 460, 428, 396,
85 372, 356, 340, 324, 308, 292, 276, 260,
86 244, 228, 212, 196, 180, 164, 148, 132,
87 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000088 56, 48, 40, 32, 24, 16, 8, 0 };
89
Moshe Zadka6a078ed2000-08-04 15:53:06 +000090/* #define ZEROTRAP */ /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +000091#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
92#define CLIP 32635
93
Guido van Rossumcd938fc1995-01-17 16:13:48 +000094static unsigned char
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000095st_linear_to_ulaw(int sample)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000096{
97 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
98 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
99 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
100 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
101 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
102 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
103 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
104 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
105 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
106 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
107 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
110 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
111 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
112 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
113 int sign, exponent, mantissa;
114 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000115
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000116 /* Get the sample into sign-magnitude. */
117 sign = (sample >> 8) & 0x80; /* set aside the sign */
118 if ( sign != 0 ) sample = -sample; /* get magnitude */
119 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000120
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000121 /* Convert from 16 bit linear to ulaw. */
122 sample = sample + BIAS;
123 exponent = exp_lut[( sample >> 7 ) & 0xFF];
124 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
125 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000126#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000127 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000128#endif
129
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000130 return ulawbyte;
131}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000132/* End of code taken from sox */
133
Guido van Rossumb64e6351992-07-06 14:21:56 +0000134/* Intel ADPCM step variation table */
135static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000136 -1, -1, -1, -1, 2, 4, 6, 8,
137 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000138};
139
140static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000141 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
142 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
143 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
144 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
145 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
146 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
147 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
148 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
149 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000150};
151
Guido van Rossumb66efa01992-06-01 16:01:24 +0000152#define CHARP(cp, i) ((signed char *)(cp+i))
153#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000154#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000155
156
157
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000158static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000159
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000160static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000161audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000162{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000163 signed char *cp;
164 int len, size, val = 0;
165 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000166
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000167 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
168 return 0;
169 if ( size != 1 && size != 2 && size != 4 ) {
170 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
171 return 0;
172 }
173 if ( i < 0 || i >= len/size ) {
174 PyErr_SetString(AudioopError, "Index out of range");
175 return 0;
176 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000177 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000178 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
179 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
180 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000181}
182
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000183static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000184audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000185{
186 signed char *cp;
187 int len, size, val = 0;
188 int i;
189 int max = 0;
190
191 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
192 return 0;
193 if ( size != 1 && size != 2 && size != 4 ) {
194 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
195 return 0;
196 }
197 for ( i=0; i<len; i+= size) {
198 if ( size == 1 ) val = (int)*CHARP(cp, i);
199 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
200 else if ( size == 4 ) val = (int)*LONGP(cp, i);
201 if ( val < 0 ) val = (-val);
202 if ( val > max ) max = val;
203 }
204 return PyInt_FromLong(max);
205}
206
207static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000208audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000209{
210 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000211 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000212 int i;
213 int min = 0x7fffffff, max = -0x7fffffff;
214
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000215 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000216 return NULL;
217 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000218 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000219 return NULL;
220 }
221 for (i = 0; i < len; i += size) {
222 if (size == 1) val = (int) *CHARP(cp, i);
223 else if (size == 2) val = (int) *SHORTP(cp, i);
224 else if (size == 4) val = (int) *LONGP(cp, i);
225 if (val > max) max = val;
226 if (val < min) min = val;
227 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000228 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000229}
230
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000231static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000232audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000233{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000234 signed char *cp;
235 int len, size, val = 0;
236 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000237 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000238
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000239 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
240 return 0;
241 if ( size != 1 && size != 2 && size != 4 ) {
242 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
243 return 0;
244 }
245 for ( i=0; i<len; i+= size) {
246 if ( size == 1 ) val = (int)*CHARP(cp, i);
247 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
248 else if ( size == 4 ) val = (int)*LONGP(cp, i);
249 avg += val;
250 }
251 if ( len == 0 )
252 val = 0;
253 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000254 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000255 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000256}
257
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000258static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000259audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000260{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000261 signed char *cp;
262 int len, size, val = 0;
263 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000264 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000265
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000266 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
267 return 0;
268 if ( size != 1 && size != 2 && size != 4 ) {
269 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
270 return 0;
271 }
272 for ( i=0; i<len; i+= size) {
273 if ( size == 1 ) val = (int)*CHARP(cp, i);
274 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
275 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000276 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000277 }
278 if ( len == 0 )
279 val = 0;
280 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000281 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000282 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000283}
284
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000285static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000286{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000287 int i;
288 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000289
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000290 for( i=0; i<len; i++) {
291 sum = sum + (double)a[i]*(double)b[i];
292 }
293 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000294}
295
296/*
297** Findfit tries to locate a sample within another sample. Its main use
298** is in echo-cancellation (to find the feedback of the output signal in
299** the input signal).
300** The method used is as follows:
301**
302** let R be the reference signal (length n) and A the input signal (length N)
303** with N > n, and let all sums be over i from 0 to n-1.
304**
305** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
306** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
307** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
308**
309** Next, we compute the relative distance between the original signal and
310** the modified signal and minimize that over j:
311** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
312** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
313**
314** In the code variables correspond as follows:
315** cp1 A
316** cp2 R
317** len1 N
318** len2 n
319** aj_m1 A[j-1]
320** aj_lm1 A[j+n-1]
321** sum_ri_2 sum(R[i]^2)
322** sum_aij_2 sum(A[i+j]^2)
323** sum_aij_ri sum(A[i+j]R[i])
324**
325** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
326** is completely recalculated each step.
327*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000329audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000330{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000331 short *cp1, *cp2;
332 int len1, len2;
333 int j, best_j;
334 double aj_m1, aj_lm1;
335 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000336
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000337 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
338 return 0;
339 if ( len1 & 1 || len2 & 1 ) {
340 PyErr_SetString(AudioopError, "Strings should be even-sized");
341 return 0;
342 }
343 len1 >>= 1;
344 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000345
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000346 if ( len1 < len2 ) {
347 PyErr_SetString(AudioopError, "First sample should be longer");
348 return 0;
349 }
350 sum_ri_2 = _sum2(cp2, cp2, len2);
351 sum_aij_2 = _sum2(cp1, cp1, len2);
352 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000353
354 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
355
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000356 best_result = result;
357 best_j = 0;
358 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000359
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000360 for ( j=1; j<=len1-len2; j++) {
361 aj_m1 = (double)cp1[j-1];
362 aj_lm1 = (double)cp1[j+len2-1];
363
364 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
365 sum_aij_ri = _sum2(cp1+j, cp2, len2);
366
367 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
368 / sum_aij_2;
369
370 if ( result < best_result ) {
371 best_result = result;
372 best_j = j;
373 }
374
375 }
376
377 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000378
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000379 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000380}
381
382/*
383** findfactor finds a factor f so that the energy in A-fB is minimal.
384** See the comment for findfit for details.
385*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000386static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000387audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000388{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000389 short *cp1, *cp2;
390 int len1, len2;
391 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000392
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000393 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
394 return 0;
395 if ( len1 & 1 || len2 & 1 ) {
396 PyErr_SetString(AudioopError, "Strings should be even-sized");
397 return 0;
398 }
399 if ( len1 != len2 ) {
400 PyErr_SetString(AudioopError, "Samples should be same size");
401 return 0;
402 }
403 len2 >>= 1;
404 sum_ri_2 = _sum2(cp2, cp2, len2);
405 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000406
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000408
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000409 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000410}
411
412/*
413** findmax returns the index of the n-sized segment of the input sample
414** that contains the most energy.
415*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000417audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000418{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000419 short *cp1;
420 int len1, len2;
421 int j, best_j;
422 double aj_m1, aj_lm1;
423 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000424
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000425 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
426 return 0;
427 if ( len1 & 1 ) {
428 PyErr_SetString(AudioopError, "Strings should be even-sized");
429 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000430 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000431 len1 >>= 1;
432
433 if ( len1 < len2 ) {
434 PyErr_SetString(AudioopError, "Input sample should be longer");
435 return 0;
436 }
Jack Jansena90805f1993-02-17 14:29:28 +0000437
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000438 result = _sum2(cp1, cp1, len2);
439
440 best_result = result;
441 best_j = 0;
442 j = 0;
443
444 for ( j=1; j<=len1-len2; j++) {
445 aj_m1 = (double)cp1[j-1];
446 aj_lm1 = (double)cp1[j+len2-1];
447
448 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
449
450 if ( result > best_result ) {
451 best_result = result;
452 best_j = j;
453 }
454
455 }
456
457 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000458}
459
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000460static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000461audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000462{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000463 signed char *cp;
464 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
465 prevextreme = 0;
466 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000467 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000468 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000469
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000470 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
471 return 0;
472 if ( size != 1 && size != 2 && size != 4 ) {
473 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
474 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000475 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000476 /* Compute first delta value ahead. Also automatically makes us
477 ** skip the first extreme value
478 */
479 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
480 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
481 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
482 if ( size == 1 ) val = (int)*CHARP(cp, size);
483 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
484 else if ( size == 4 ) val = (int)*LONGP(cp, size);
485 prevdiff = val - prevval;
486
487 for ( i=size; i<len; i+= size) {
488 if ( size == 1 ) val = (int)*CHARP(cp, i);
489 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
490 else if ( size == 4 ) val = (int)*LONGP(cp, i);
491 diff = val - prevval;
492 if ( diff*prevdiff < 0 ) {
493 /* Derivative changed sign. Compute difference to last
494 ** extreme value and remember.
495 */
496 if ( prevextremevalid ) {
497 extremediff = prevval - prevextreme;
498 if ( extremediff < 0 )
499 extremediff = -extremediff;
500 avg += extremediff;
501 nextreme++;
502 }
503 prevextremevalid = 1;
504 prevextreme = prevval;
505 }
506 prevval = val;
507 if ( diff != 0 )
508 prevdiff = diff;
509 }
510 if ( nextreme == 0 )
511 val = 0;
512 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000513 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000514 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000515}
516
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000517static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000518audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000519{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000520 signed char *cp;
521 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
522 prevextreme = 0;
523 int i;
524 int max = 0;
525 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000526
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000527 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
528 return 0;
529 if ( size != 1 && size != 2 && size != 4 ) {
530 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
531 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000532 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000533 /* Compute first delta value ahead. Also automatically makes us
534 ** skip the first extreme value
535 */
536 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
537 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
538 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
539 if ( size == 1 ) val = (int)*CHARP(cp, size);
540 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
541 else if ( size == 4 ) val = (int)*LONGP(cp, size);
542 prevdiff = val - prevval;
543
544 for ( i=size; i<len; i+= size) {
545 if ( size == 1 ) val = (int)*CHARP(cp, i);
546 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
547 else if ( size == 4 ) val = (int)*LONGP(cp, i);
548 diff = val - prevval;
549 if ( diff*prevdiff < 0 ) {
550 /* Derivative changed sign. Compute difference to
551 ** last extreme value and remember.
552 */
553 if ( prevextremevalid ) {
554 extremediff = prevval - prevextreme;
555 if ( extremediff < 0 )
556 extremediff = -extremediff;
557 if ( extremediff > max )
558 max = extremediff;
559 }
560 prevextremevalid = 1;
561 prevextreme = prevval;
562 }
563 prevval = val;
564 if ( diff != 0 )
565 prevdiff = diff;
566 }
567 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000568}
569
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000570static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000571audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000572{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000573 signed char *cp;
574 int len, size, val = 0;
575 int i;
576 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000577
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000578 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
579 return 0;
580 if ( size != 1 && size != 2 && size != 4 ) {
581 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
582 return 0;
583 }
584 ncross = -1;
585 prevval = 17; /* Anything <> 0,1 */
586 for ( i=0; i<len; i+= size) {
587 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
588 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
589 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
590 val = val & 1;
591 if ( val != prevval ) ncross++;
592 prevval = val;
593 }
594 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000595}
596
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000597static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000598audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000599{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600 signed char *cp, *ncp;
601 int len, size, val = 0;
602 double factor, fval, maxval;
603 PyObject *rv;
604 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000605
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000606 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
607 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000608
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000609 if ( size == 1 ) maxval = (double) 0x7f;
610 else if ( size == 2 ) maxval = (double) 0x7fff;
611 else if ( size == 4 ) maxval = (double) 0x7fffffff;
612 else {
613 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
614 return 0;
615 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000616
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000617 rv = PyString_FromStringAndSize(NULL, len);
618 if ( rv == 0 )
619 return 0;
620 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000621
622
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000623 for ( i=0; i < len; i += size ) {
624 if ( size == 1 ) val = (int)*CHARP(cp, i);
625 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
626 else if ( size == 4 ) val = (int)*LONGP(cp, i);
627 fval = (double)val*factor;
628 if ( fval > maxval ) fval = maxval;
629 else if ( fval < -maxval ) fval = -maxval;
630 val = (int)fval;
631 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
632 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000633 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000634 }
635 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000636}
637
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000638static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000639audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000640{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000641 signed char *cp, *ncp;
642 int len, size, val1 = 0, val2 = 0;
643 double fac1, fac2, fval, maxval;
644 PyObject *rv;
645 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000646
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000647 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
648 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000649
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000650 if ( size == 1 ) maxval = (double) 0x7f;
651 else if ( size == 2 ) maxval = (double) 0x7fff;
652 else if ( size == 4 ) maxval = (double) 0x7fffffff;
653 else {
654 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
655 return 0;
656 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000657
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000658 rv = PyString_FromStringAndSize(NULL, len/2);
659 if ( rv == 0 )
660 return 0;
661 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000662
663
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000664 for ( i=0; i < len; i += size*2 ) {
665 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
666 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
667 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
668 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
669 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
670 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
671 fval = (double)val1*fac1 + (double)val2*fac2;
672 if ( fval > maxval ) fval = maxval;
673 else if ( fval < -maxval ) fval = -maxval;
674 val1 = (int)fval;
675 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
676 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000677 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000678 }
679 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000680}
681
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000682static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000683audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000684{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000685 signed char *cp, *ncp;
686 int len, size, val1, val2, val = 0;
687 double fac1, fac2, fval, maxval;
688 PyObject *rv;
689 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000690
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000691 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
692 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000693
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000694 if ( size == 1 ) maxval = (double) 0x7f;
695 else if ( size == 2 ) maxval = (double) 0x7fff;
696 else if ( size == 4 ) maxval = (double) 0x7fffffff;
697 else {
698 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
699 return 0;
700 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000701
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000702 rv = PyString_FromStringAndSize(NULL, len*2);
703 if ( rv == 0 )
704 return 0;
705 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000706
707
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000708 for ( i=0; i < len; i += size ) {
709 if ( size == 1 ) val = (int)*CHARP(cp, i);
710 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
711 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000712
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000713 fval = (double)val*fac1;
714 if ( fval > maxval ) fval = maxval;
715 else if ( fval < -maxval ) fval = -maxval;
716 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000718 fval = (double)val*fac2;
719 if ( fval > maxval ) fval = maxval;
720 else if ( fval < -maxval ) fval = -maxval;
721 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000723 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
724 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000725 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000726
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000727 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
728 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000729 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000730 }
731 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000732}
733
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000734static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000735audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000736{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000738 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000739 PyObject *rv;
740 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000741
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000742 if ( !PyArg_Parse(args, "(s#s#i)",
743 &cp1, &len1, &cp2, &len2, &size ) )
744 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000746 if ( len1 != len2 ) {
747 PyErr_SetString(AudioopError, "Lengths should be the same");
748 return 0;
749 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
Guido van Rossum1851a671997-02-14 16:14:03 +0000751 if ( size == 1 ) maxval = 0x7f;
752 else if ( size == 2 ) maxval = 0x7fff;
753 else if ( size == 4 ) maxval = 0x7fffffff;
754 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000755 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
756 return 0;
757 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000758
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000759 rv = PyString_FromStringAndSize(NULL, len1);
760 if ( rv == 0 )
761 return 0;
762 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000763
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000764 for ( i=0; i < len1; i += size ) {
765 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
766 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
767 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000768
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000769 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
770 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
771 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000772
Guido van Rossum1851a671997-02-14 16:14:03 +0000773 newval = val1 + val2;
774 /* truncate in case of overflow */
775 if (newval > maxval) newval = maxval;
776 else if (newval < -maxval) newval = -maxval;
777 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
778 newval = val1 > 0 ? maxval : - maxval;
779
780 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
781 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000782 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783 }
784 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000785}
786
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000787static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000788audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000789{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000790 signed char *cp, *ncp;
791 int len, size, val = 0;
792 PyObject *rv;
793 int i;
794 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000796 if ( !PyArg_Parse(args, "(s#ii)",
797 &cp, &len, &size , &bias) )
798 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000799
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000800 if ( size != 1 && size != 2 && size != 4) {
801 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
802 return 0;
803 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000804
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000805 rv = PyString_FromStringAndSize(NULL, len);
806 if ( rv == 0 )
807 return 0;
808 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000809
810
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000811 for ( i=0; i < len; i += size ) {
812 if ( size == 1 ) val = (int)*CHARP(cp, i);
813 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
814 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000815
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000816 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
817 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000818 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000819 }
820 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000821}
822
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000823static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000824audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000825{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000826 signed char *cp;
827 unsigned char *ncp;
828 int len, size, val = 0;
829 PyObject *rv;
830 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000831
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000832 if ( !PyArg_Parse(args, "(s#i)",
833 &cp, &len, &size) )
834 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000835
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000836 if ( size != 1 && size != 2 && size != 4 ) {
837 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
838 return 0;
839 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000840
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000841 rv = PyString_FromStringAndSize(NULL, len);
842 if ( rv == 0 )
843 return 0;
844 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000845
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000846 for ( i=0; i < len; i += size ) {
847 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
848 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
849 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000850
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000851 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000852
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000853 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
854 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000855 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000856 }
857 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000858}
859
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000860static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000861audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000862{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000863 signed char *cp;
864 unsigned char *ncp;
865 int len, size, size2, val = 0;
866 PyObject *rv;
867 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000868
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000869 if ( !PyArg_Parse(args, "(s#ii)",
870 &cp, &len, &size, &size2) )
871 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000872
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873 if ( (size != 1 && size != 2 && size != 4) ||
874 (size2 != 1 && size2 != 2 && size2 != 4)) {
875 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
876 return 0;
877 }
Jack Jansena90805f1993-02-17 14:29:28 +0000878
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000879 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
880 if ( rv == 0 )
881 return 0;
882 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000883
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000884 for ( i=0, j=0; i < len; i += size, j += size2 ) {
885 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
886 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
887 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000888
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000889 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
890 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000891 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000892 }
893 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000894}
895
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000896static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000897gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000898{
899 while (b > 0) {
900 int tmp = a % b;
901 a = b;
902 b = tmp;
903 }
904 return a;
905}
906
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000907static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000908audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +0000909{
Guido van Rossum1851a671997-02-14 16:14:03 +0000910 char *cp, *ncp;
911 int len, size, nchannels, inrate, outrate, weightA, weightB;
912 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000913 PyObject *state, *samps, *str, *rv = NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +0000914
915 weightA = 1;
916 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000917 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000918 &inrate, &outrate, &state, &weightA, &weightB))
919 return NULL;
920 if (size != 1 && size != 2 && size != 4) {
921 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
922 return NULL;
923 }
924 if (nchannels < 1) {
925 PyErr_SetString(AudioopError, "# of channels should be >= 1");
926 return NULL;
927 }
928 if (weightA < 1 || weightB < 0) {
929 PyErr_SetString(AudioopError,
930 "weightA should be >= 1, weightB should be >= 0");
931 return NULL;
932 }
933 if (len % (size * nchannels) != 0) {
934 PyErr_SetString(AudioopError, "not a whole number of frames");
935 return NULL;
936 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000937 if (inrate <= 0 || outrate <= 0) {
938 PyErr_SetString(AudioopError, "sampling rate not > 0");
939 return NULL;
940 }
941 /* divide inrate and outrate by their greatest common divisor */
942 d = gcd(inrate, outrate);
943 inrate /= d;
944 outrate /= d;
945
Guido van Rossum6345ac61997-10-31 20:32:13 +0000946 prev_i = (int *) malloc(nchannels * sizeof(int));
947 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +0000948 len /= size * nchannels; /* # of frames */
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
954 if (state == Py_None) {
955 d = -outrate;
956 for (chan = 0; chan < nchannels; chan++)
957 prev_i[chan] = cur_i[chan] = 0;
958 } else {
959 if (!PyArg_ParseTuple(state,
960 "iO!;audioop.ratecv: illegal state argument",
961 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000962 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000963 if (PyTuple_Size(samps) != nchannels) {
964 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000965 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +0000966 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000967 }
968 for (chan = 0; chan < nchannels; chan++) {
969 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +0000970 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000971 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000972 }
973 }
974 str = PyString_FromStringAndSize(
975 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
976 if (str == NULL)
Guido van Rossum65bb3281999-09-07 14:24:05 +0000977 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000978 ncp = PyString_AsString(str);
979
980 for (;;) {
981 while (d < 0) {
982 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +0000983 samps = PyTuple_New(nchannels);
984 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +0000985 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +0000986 Py_BuildValue("(ii)",
987 prev_i[chan],
988 cur_i[chan]));
989 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +0000990 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +0000991 len = ncp - PyString_AsString(str);
992 if (len == 0) {
993 /*don't want to resize to zero length*/
994 rv = PyString_FromStringAndSize("", 0);
995 Py_DECREF(str);
996 str = rv;
997 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +0000998 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +0000999 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001000 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001001 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001002 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001003 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001004 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001005 prev_i[chan] = cur_i[chan];
1006 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001007 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001008 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001009 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001010 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001011 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001012 cp += size;
1013 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001014 cur_i[chan] =
1015 (weightA * cur_i[chan] +
1016 weightB * prev_i[chan]) /
1017 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001018 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001019 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001020 d += outrate;
1021 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001022 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001023 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001024 cur_o = (prev_i[chan] * d +
1025 cur_i[chan] * (outrate - d)) /
1026 outrate;
1027 if (size == 1)
1028 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001029 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001030 *SHORTP(ncp, 0) = (short)(cur_o);
1031 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001032 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001033 ncp += size;
1034 }
1035 d -= inrate;
1036 }
1037 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001038 exit:
1039 if (prev_i != NULL)
1040 free(prev_i);
1041 if (cur_i != NULL)
1042 free(cur_i);
1043 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001044}
Guido van Rossum1851a671997-02-14 16:14:03 +00001045
Roger E. Massec905fff1997-01-17 18:12:04 +00001046static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001047audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001048{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001049 signed char *cp;
1050 unsigned char *ncp;
1051 int len, size, val = 0;
1052 PyObject *rv;
1053 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001054
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001055 if ( !PyArg_Parse(args, "(s#i)",
1056 &cp, &len, &size) )
1057 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001058
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001059 if ( size != 1 && size != 2 && size != 4) {
1060 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1061 return 0;
1062 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001063
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001064 rv = PyString_FromStringAndSize(NULL, len/size);
1065 if ( rv == 0 )
1066 return 0;
1067 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001068
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001069 for ( i=0; i < len; i += size ) {
1070 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1071 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1072 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001073
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001074 *ncp++ = st_linear_to_ulaw(val);
1075 }
1076 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001077}
1078
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001079static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001080audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001081{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001082 unsigned char *cp;
1083 unsigned char cval;
1084 signed char *ncp;
1085 int len, size, val;
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 = (signed 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*size; i += size ) {
1104 cval = *cp++;
1105 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001106
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001107 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1108 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001109 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001110 }
1111 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001112}
1113
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001114static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001115audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001116{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001117 signed char *cp;
1118 signed char *ncp;
1119 int len, size, val = 0, step, valpred, delta,
1120 index, sign, vpdiff, diff;
1121 PyObject *rv, *state, *str;
1122 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001123
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001124 if ( !PyArg_Parse(args, "(s#iO)",
1125 &cp, &len, &size, &state) )
1126 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001127
1128
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001129 if ( size != 1 && size != 2 && size != 4) {
1130 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1131 return 0;
1132 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001133
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001134 str = PyString_FromStringAndSize(NULL, len/(size*2));
1135 if ( str == 0 )
1136 return 0;
1137 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001138
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001139 /* Decode state, should have (value, step) */
1140 if ( state == Py_None ) {
1141 /* First time, it seems. Set defaults */
1142 valpred = 0;
1143 step = 7;
1144 index = 0;
1145 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1146 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001147
Guido van Rossumb64e6351992-07-06 14:21:56 +00001148 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001149 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001150
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001151 for ( i=0; i < len; i += size ) {
1152 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1153 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1154 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1155
1156 /* Step 1 - compute difference with previous value */
1157 diff = val - valpred;
1158 sign = (diff < 0) ? 8 : 0;
1159 if ( sign ) diff = (-diff);
1160
1161 /* Step 2 - Divide and clamp */
1162 /* Note:
1163 ** This code *approximately* computes:
1164 ** delta = diff*4/step;
1165 ** vpdiff = (delta+0.5)*step/4;
1166 ** but in shift step bits are dropped. The net result of this
1167 ** is that even if you have fast mul/div hardware you cannot
1168 ** put it to good use since the fixup would be too expensive.
1169 */
1170 delta = 0;
1171 vpdiff = (step >> 3);
1172
1173 if ( diff >= step ) {
1174 delta = 4;
1175 diff -= step;
1176 vpdiff += step;
1177 }
1178 step >>= 1;
1179 if ( diff >= step ) {
1180 delta |= 2;
1181 diff -= step;
1182 vpdiff += step;
1183 }
1184 step >>= 1;
1185 if ( diff >= step ) {
1186 delta |= 1;
1187 vpdiff += step;
1188 }
1189
1190 /* Step 3 - Update previous value */
1191 if ( sign )
1192 valpred -= vpdiff;
1193 else
1194 valpred += vpdiff;
1195
1196 /* Step 4 - Clamp previous value to 16 bits */
1197 if ( valpred > 32767 )
1198 valpred = 32767;
1199 else if ( valpred < -32768 )
1200 valpred = -32768;
1201
1202 /* Step 5 - Assemble value, update index and step values */
1203 delta |= sign;
1204
1205 index += indexTable[delta];
1206 if ( index < 0 ) index = 0;
1207 if ( index > 88 ) index = 88;
1208 step = stepsizeTable[index];
1209
1210 /* Step 6 - Output value */
1211 if ( bufferstep ) {
1212 outputbuffer = (delta << 4) & 0xf0;
1213 } else {
1214 *ncp++ = (delta & 0x0f) | outputbuffer;
1215 }
1216 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001217 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001218 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1219 Py_DECREF(str);
1220 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001221}
1222
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001223static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001224audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001225{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001226 signed char *cp;
1227 signed char *ncp;
1228 int len, size, valpred, step, delta, index, sign, vpdiff;
1229 PyObject *rv, *str, *state;
1230 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001231
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001232 if ( !PyArg_Parse(args, "(s#iO)",
1233 &cp, &len, &size, &state) )
1234 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001235
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001236 if ( size != 1 && size != 2 && size != 4) {
1237 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1238 return 0;
1239 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001240
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001241 /* Decode state, should have (value, step) */
1242 if ( state == Py_None ) {
1243 /* First time, it seems. Set defaults */
1244 valpred = 0;
1245 step = 7;
1246 index = 0;
1247 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1248 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001249
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001250 str = PyString_FromStringAndSize(NULL, len*size*2);
1251 if ( str == 0 )
1252 return 0;
1253 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001254
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001255 step = stepsizeTable[index];
1256 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001257
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001258 for ( i=0; i < len*size*2; i += size ) {
1259 /* Step 1 - get the delta value and compute next index */
1260 if ( bufferstep ) {
1261 delta = inputbuffer & 0xf;
1262 } else {
1263 inputbuffer = *cp++;
1264 delta = (inputbuffer >> 4) & 0xf;
1265 }
1266
1267 bufferstep = !bufferstep;
1268
1269 /* Step 2 - Find new index value (for later) */
1270 index += indexTable[delta];
1271 if ( index < 0 ) index = 0;
1272 if ( index > 88 ) index = 88;
1273
1274 /* Step 3 - Separate sign and magnitude */
1275 sign = delta & 8;
1276 delta = delta & 7;
1277
1278 /* Step 4 - Compute difference and new predicted value */
1279 /*
1280 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1281 ** in adpcm_coder.
1282 */
1283 vpdiff = step >> 3;
1284 if ( delta & 4 ) vpdiff += step;
1285 if ( delta & 2 ) vpdiff += step>>1;
1286 if ( delta & 1 ) vpdiff += step>>2;
1287
1288 if ( sign )
1289 valpred -= vpdiff;
1290 else
1291 valpred += vpdiff;
1292
1293 /* Step 5 - clamp output value */
1294 if ( valpred > 32767 )
1295 valpred = 32767;
1296 else if ( valpred < -32768 )
1297 valpred = -32768;
1298
1299 /* Step 6 - Update step value */
1300 step = stepsizeTable[index];
1301
1302 /* Step 6 - Output value */
1303 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1304 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001305 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001306 }
1307
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001308 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1309 Py_DECREF(str);
1310 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001311}
1312
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001313static PyMethodDef audioop_methods[] = {
1314 { "max", audioop_max },
1315 { "minmax", audioop_minmax },
1316 { "avg", audioop_avg },
1317 { "maxpp", audioop_maxpp },
1318 { "avgpp", audioop_avgpp },
1319 { "rms", audioop_rms },
1320 { "findfit", audioop_findfit },
1321 { "findmax", audioop_findmax },
1322 { "findfactor", audioop_findfactor },
1323 { "cross", audioop_cross },
1324 { "mul", audioop_mul },
1325 { "add", audioop_add },
1326 { "bias", audioop_bias },
1327 { "ulaw2lin", audioop_ulaw2lin },
1328 { "lin2ulaw", audioop_lin2ulaw },
1329 { "lin2lin", audioop_lin2lin },
1330 { "adpcm2lin", audioop_adpcm2lin },
1331 { "lin2adpcm", audioop_lin2adpcm },
1332 { "tomono", audioop_tomono },
1333 { "tostereo", audioop_tostereo },
1334 { "getsample", audioop_getsample },
1335 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001336 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001337 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001338};
1339
Guido van Rossum3886bb61998-12-04 18:50:17 +00001340DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001341initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001342{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001343 PyObject *m, *d;
1344 m = Py_InitModule("audioop", audioop_methods);
1345 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001346 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1347 if (AudioopError != NULL)
1348 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001349}