blob: cc5634de4717dfd1fddffb2389a53edb45ef9905 [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!ERROR!; READ THE SOURCE FILE!;
30/* This module currently does not work on systems where only unsigned
31 characters are available. Take it out of Setup. Sorry. */
32#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000033#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000034
Guido van Rossuma320fd31995-03-09 12:14:15 +000035#include "mymath.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000036
Jack Jansena90805f1993-02-17 14:29:28 +000037/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000038** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
39
40#define MINLIN -32768
41#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000042#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
43 else if ( x > MAXLIN ) x = MAXLIN; \
44 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000045
Guido van Rossumcd938fc1995-01-17 16:13:48 +000046static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000047
48/*
49** This macro converts from ulaw to 16 bit linear, faster.
50**
51** Jef Poskanzer
52** 23 October 1989
53**
54** Input: 8 bit ulaw sample
55** Output: signed 16 bit linear sample
56*/
57#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
58
59static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000060 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
61 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
62 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
63 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
64 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
65 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
66 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
67 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
68 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
69 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
70 -876, -844, -812, -780, -748, -716, -684, -652,
71 -620, -588, -556, -524, -492, -460, -428, -396,
72 -372, -356, -340, -324, -308, -292, -276, -260,
73 -244, -228, -212, -196, -180, -164, -148, -132,
74 -120, -112, -104, -96, -88, -80, -72, -64,
75 -56, -48, -40, -32, -24, -16, -8, 0,
76 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
77 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
78 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
79 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
80 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
81 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
82 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
83 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
84 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
85 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
86 876, 844, 812, 780, 748, 716, 684, 652,
87 620, 588, 556, 524, 492, 460, 428, 396,
88 372, 356, 340, 324, 308, 292, 276, 260,
89 244, 228, 212, 196, 180, 164, 148, 132,
90 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000091 56, 48, 40, 32, 24, 16, 8, 0 };
92
Guido van Rossum7d64b482000-05-02 21:18:13 +000093/* #define ZEROTRAP /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +000094#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
95#define CLIP 32635
96
Guido van Rossumcd938fc1995-01-17 16:13:48 +000097static unsigned char
Guido van Rossumb66efa01992-06-01 16:01:24 +000098st_linear_to_ulaw( sample )
Roger E. Masseeaa6e111997-01-03 19:26:27 +000099 int sample;
100{
101 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
102 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
103 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
104 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
105 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
106 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
107 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
108 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
114 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
115 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
116 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
117 int sign, exponent, mantissa;
118 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000119
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000120 /* Get the sample into sign-magnitude. */
121 sign = (sample >> 8) & 0x80; /* set aside the sign */
122 if ( sign != 0 ) sample = -sample; /* get magnitude */
123 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000124
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000125 /* Convert from 16 bit linear to ulaw. */
126 sample = sample + BIAS;
127 exponent = exp_lut[( sample >> 7 ) & 0xFF];
128 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
129 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000130#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000131 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000132#endif
133
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000134 return ulawbyte;
135}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000136/* End of code taken from sox */
137
Guido van Rossumb64e6351992-07-06 14:21:56 +0000138/* Intel ADPCM step variation table */
139static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000140 -1, -1, -1, -1, 2, 4, 6, 8,
141 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000142};
143
144static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000145 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
146 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
147 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
148 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
149 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
150 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
151 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
152 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
153 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000154};
155
Guido van Rossumb66efa01992-06-01 16:01:24 +0000156#define CHARP(cp, i) ((signed char *)(cp+i))
157#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000158#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000159
160
161
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000162static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000163
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000164static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000165audioop_getsample(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000166 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000167 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000168{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000169 signed char *cp;
170 int len, size, val = 0;
171 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000172
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000173 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
174 return 0;
175 if ( size != 1 && size != 2 && size != 4 ) {
176 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
177 return 0;
178 }
179 if ( i < 0 || i >= len/size ) {
180 PyErr_SetString(AudioopError, "Index out of range");
181 return 0;
182 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000183 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000184 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
185 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
186 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000187}
188
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000189static PyObject *
190audioop_max(self, args)
191 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000192 PyObject *args;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000193{
194 signed char *cp;
195 int len, size, val = 0;
196 int i;
197 int max = 0;
198
199 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
200 return 0;
201 if ( size != 1 && size != 2 && size != 4 ) {
202 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
203 return 0;
204 }
205 for ( i=0; i<len; i+= size) {
206 if ( size == 1 ) val = (int)*CHARP(cp, i);
207 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
208 else if ( size == 4 ) val = (int)*LONGP(cp, i);
209 if ( val < 0 ) val = (-val);
210 if ( val > max ) max = val;
211 }
212 return PyInt_FromLong(max);
213}
214
215static PyObject *
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000216audioop_minmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000217 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000218 PyObject *args;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000219{
220 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000221 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000222 int i;
223 int min = 0x7fffffff, max = -0x7fffffff;
224
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000225 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000226 return NULL;
227 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000228 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000229 return NULL;
230 }
231 for (i = 0; i < len; i += size) {
232 if (size == 1) val = (int) *CHARP(cp, i);
233 else if (size == 2) val = (int) *SHORTP(cp, i);
234 else if (size == 4) val = (int) *LONGP(cp, i);
235 if (val > max) max = val;
236 if (val < min) min = val;
237 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000238 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000239}
240
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000241static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000242audioop_avg(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000243 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000244 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000245{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000246 signed char *cp;
247 int len, size, val = 0;
248 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000249 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000250
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000251 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
252 return 0;
253 if ( size != 1 && size != 2 && size != 4 ) {
254 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
255 return 0;
256 }
257 for ( i=0; i<len; i+= size) {
258 if ( size == 1 ) val = (int)*CHARP(cp, i);
259 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
260 else if ( size == 4 ) val = (int)*LONGP(cp, i);
261 avg += val;
262 }
263 if ( len == 0 )
264 val = 0;
265 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000266 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000267 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000268}
269
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000270static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000271audioop_rms(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000272 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000273 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000274{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000275 signed char *cp;
276 int len, size, val = 0;
277 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000278 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000279
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000280 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
281 return 0;
282 if ( size != 1 && size != 2 && size != 4 ) {
283 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
284 return 0;
285 }
286 for ( i=0; i<len; i+= size) {
287 if ( size == 1 ) val = (int)*CHARP(cp, i);
288 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
289 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000290 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000291 }
292 if ( len == 0 )
293 val = 0;
294 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000295 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000296 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000297}
298
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000299static double _sum2(a, b, len)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000300 short *a;
Roger E. Massec905fff1997-01-17 18:12:04 +0000301 short *b;
302 int len;
Jack Jansena90805f1993-02-17 14:29:28 +0000303{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000304 int i;
305 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000306
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000307 for( i=0; i<len; i++) {
308 sum = sum + (double)a[i]*(double)b[i];
309 }
310 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000311}
312
313/*
314** Findfit tries to locate a sample within another sample. Its main use
315** is in echo-cancellation (to find the feedback of the output signal in
316** the input signal).
317** The method used is as follows:
318**
319** let R be the reference signal (length n) and A the input signal (length N)
320** with N > n, and let all sums be over i from 0 to n-1.
321**
322** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
323** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
324** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
325**
326** Next, we compute the relative distance between the original signal and
327** the modified signal and minimize that over j:
328** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
329** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
330**
331** In the code variables correspond as follows:
332** cp1 A
333** cp2 R
334** len1 N
335** len2 n
336** aj_m1 A[j-1]
337** aj_lm1 A[j+n-1]
338** sum_ri_2 sum(R[i]^2)
339** sum_aij_2 sum(A[i+j]^2)
340** sum_aij_ri sum(A[i+j]R[i])
341**
342** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
343** is completely recalculated each step.
344*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000345static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000346audioop_findfit(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000347 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000348 PyObject *args;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000349{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000350 short *cp1, *cp2;
351 int len1, len2;
352 int j, best_j;
353 double aj_m1, aj_lm1;
354 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000355
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000356 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
357 return 0;
358 if ( len1 & 1 || len2 & 1 ) {
359 PyErr_SetString(AudioopError, "Strings should be even-sized");
360 return 0;
361 }
362 len1 >>= 1;
363 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000364
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000365 if ( len1 < len2 ) {
366 PyErr_SetString(AudioopError, "First sample should be longer");
367 return 0;
368 }
369 sum_ri_2 = _sum2(cp2, cp2, len2);
370 sum_aij_2 = _sum2(cp1, cp1, len2);
371 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000372
373 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
374
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000375 best_result = result;
376 best_j = 0;
377 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000378
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000379 for ( j=1; j<=len1-len2; j++) {
380 aj_m1 = (double)cp1[j-1];
381 aj_lm1 = (double)cp1[j+len2-1];
382
383 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
384 sum_aij_ri = _sum2(cp1+j, cp2, len2);
385
386 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
387 / sum_aij_2;
388
389 if ( result < best_result ) {
390 best_result = result;
391 best_j = j;
392 }
393
394 }
395
396 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000397
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000398 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000399}
400
401/*
402** findfactor finds a factor f so that the energy in A-fB is minimal.
403** See the comment for findfit for details.
404*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000405static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000406audioop_findfactor(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000408 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000409{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000410 short *cp1, *cp2;
411 int len1, len2;
412 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000413
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000414 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
415 return 0;
416 if ( len1 & 1 || len2 & 1 ) {
417 PyErr_SetString(AudioopError, "Strings should be even-sized");
418 return 0;
419 }
420 if ( len1 != len2 ) {
421 PyErr_SetString(AudioopError, "Samples should be same size");
422 return 0;
423 }
424 len2 >>= 1;
425 sum_ri_2 = _sum2(cp2, cp2, len2);
426 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000427
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000428 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000429
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000430 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000431}
432
433/*
434** findmax returns the index of the n-sized segment of the input sample
435** that contains the most energy.
436*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000437static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000438audioop_findmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000439 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000440 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000441{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000442 short *cp1;
443 int len1, len2;
444 int j, best_j;
445 double aj_m1, aj_lm1;
446 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000447
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000448 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
449 return 0;
450 if ( len1 & 1 ) {
451 PyErr_SetString(AudioopError, "Strings should be even-sized");
452 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000453 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000454 len1 >>= 1;
455
456 if ( len1 < len2 ) {
457 PyErr_SetString(AudioopError, "Input sample should be longer");
458 return 0;
459 }
Jack Jansena90805f1993-02-17 14:29:28 +0000460
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000461 result = _sum2(cp1, cp1, len2);
462
463 best_result = result;
464 best_j = 0;
465 j = 0;
466
467 for ( j=1; j<=len1-len2; j++) {
468 aj_m1 = (double)cp1[j-1];
469 aj_lm1 = (double)cp1[j+len2-1];
470
471 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
472
473 if ( result > best_result ) {
474 best_result = result;
475 best_j = j;
476 }
477
478 }
479
480 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000481}
482
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000483static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000484audioop_avgpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000485 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000486 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000487{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000488 signed char *cp;
489 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
490 prevextreme = 0;
491 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000492 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000493 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000494
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000495 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
496 return 0;
497 if ( size != 1 && size != 2 && size != 4 ) {
498 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
499 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000500 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000501 /* Compute first delta value ahead. Also automatically makes us
502 ** skip the first extreme value
503 */
504 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
505 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
506 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
507 if ( size == 1 ) val = (int)*CHARP(cp, size);
508 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
509 else if ( size == 4 ) val = (int)*LONGP(cp, size);
510 prevdiff = val - prevval;
511
512 for ( i=size; i<len; i+= size) {
513 if ( size == 1 ) val = (int)*CHARP(cp, i);
514 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
515 else if ( size == 4 ) val = (int)*LONGP(cp, i);
516 diff = val - prevval;
517 if ( diff*prevdiff < 0 ) {
518 /* Derivative changed sign. Compute difference to last
519 ** extreme value and remember.
520 */
521 if ( prevextremevalid ) {
522 extremediff = prevval - prevextreme;
523 if ( extremediff < 0 )
524 extremediff = -extremediff;
525 avg += extremediff;
526 nextreme++;
527 }
528 prevextremevalid = 1;
529 prevextreme = prevval;
530 }
531 prevval = val;
532 if ( diff != 0 )
533 prevdiff = diff;
534 }
535 if ( nextreme == 0 )
536 val = 0;
537 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000538 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000539 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000540}
541
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000542static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000543audioop_maxpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000544 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000545 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000546{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000547 signed char *cp;
548 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
549 prevextreme = 0;
550 int i;
551 int max = 0;
552 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000553
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000554 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
555 return 0;
556 if ( size != 1 && size != 2 && size != 4 ) {
557 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
558 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000559 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560 /* Compute first delta value ahead. Also automatically makes us
561 ** skip the first extreme value
562 */
563 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
564 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
565 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
566 if ( size == 1 ) val = (int)*CHARP(cp, size);
567 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
568 else if ( size == 4 ) val = (int)*LONGP(cp, size);
569 prevdiff = val - prevval;
570
571 for ( i=size; i<len; i+= size) {
572 if ( size == 1 ) val = (int)*CHARP(cp, i);
573 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
574 else if ( size == 4 ) val = (int)*LONGP(cp, i);
575 diff = val - prevval;
576 if ( diff*prevdiff < 0 ) {
577 /* Derivative changed sign. Compute difference to
578 ** last extreme value and remember.
579 */
580 if ( prevextremevalid ) {
581 extremediff = prevval - prevextreme;
582 if ( extremediff < 0 )
583 extremediff = -extremediff;
584 if ( extremediff > max )
585 max = extremediff;
586 }
587 prevextremevalid = 1;
588 prevextreme = prevval;
589 }
590 prevval = val;
591 if ( diff != 0 )
592 prevdiff = diff;
593 }
594 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000595}
596
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000597static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000598audioop_cross(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000599 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000600 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000601{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000602 signed char *cp;
603 int len, size, val = 0;
604 int i;
605 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000606
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000607 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
608 return 0;
609 if ( size != 1 && size != 2 && size != 4 ) {
610 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
611 return 0;
612 }
613 ncross = -1;
614 prevval = 17; /* Anything <> 0,1 */
615 for ( i=0; i<len; i+= size) {
616 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
617 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
618 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
619 val = val & 1;
620 if ( val != prevval ) ncross++;
621 prevval = val;
622 }
623 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000624}
625
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000626static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000627audioop_mul(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000628 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000629 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000630{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000631 signed char *cp, *ncp;
632 int len, size, val = 0;
633 double factor, fval, maxval;
634 PyObject *rv;
635 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000636
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
638 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000639
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000640 if ( size == 1 ) maxval = (double) 0x7f;
641 else if ( size == 2 ) maxval = (double) 0x7fff;
642 else if ( size == 4 ) maxval = (double) 0x7fffffff;
643 else {
644 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
645 return 0;
646 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000647
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000648 rv = PyString_FromStringAndSize(NULL, len);
649 if ( rv == 0 )
650 return 0;
651 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000652
653
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000654 for ( i=0; i < len; i += size ) {
655 if ( size == 1 ) val = (int)*CHARP(cp, i);
656 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
657 else if ( size == 4 ) val = (int)*LONGP(cp, i);
658 fval = (double)val*factor;
659 if ( fval > maxval ) fval = maxval;
660 else if ( fval < -maxval ) fval = -maxval;
661 val = (int)fval;
662 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
663 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000664 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000665 }
666 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000667}
668
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000669static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000670audioop_tomono(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000671 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000672 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000673{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000674 signed char *cp, *ncp;
675 int len, size, val1 = 0, val2 = 0;
676 double fac1, fac2, fval, maxval;
677 PyObject *rv;
678 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000679
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000680 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
681 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000682
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683 if ( size == 1 ) maxval = (double) 0x7f;
684 else if ( size == 2 ) maxval = (double) 0x7fff;
685 else if ( size == 4 ) maxval = (double) 0x7fffffff;
686 else {
687 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
688 return 0;
689 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000690
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000691 rv = PyString_FromStringAndSize(NULL, len/2);
692 if ( rv == 0 )
693 return 0;
694 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000695
696
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000697 for ( i=0; i < len; i += size*2 ) {
698 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
699 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
700 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
701 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
702 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
703 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
704 fval = (double)val1*fac1 + (double)val2*fac2;
705 if ( fval > maxval ) fval = maxval;
706 else if ( fval < -maxval ) fval = -maxval;
707 val1 = (int)fval;
708 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
709 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000710 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000711 }
712 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000713}
714
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000715static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000716audioop_tostereo(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000717 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000718 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000719{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000720 signed char *cp, *ncp;
721 int len, size, val1, val2, val = 0;
722 double fac1, fac2, fval, maxval;
723 PyObject *rv;
724 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000725
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000726 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
727 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000728
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000729 if ( size == 1 ) maxval = (double) 0x7f;
730 else if ( size == 2 ) maxval = (double) 0x7fff;
731 else if ( size == 4 ) maxval = (double) 0x7fffffff;
732 else {
733 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
734 return 0;
735 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000736
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737 rv = PyString_FromStringAndSize(NULL, len*2);
738 if ( rv == 0 )
739 return 0;
740 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000741
742
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000743 for ( i=0; i < len; i += size ) {
744 if ( size == 1 ) val = (int)*CHARP(cp, i);
745 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
746 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000747
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000748 fval = (double)val*fac1;
749 if ( fval > maxval ) fval = maxval;
750 else if ( fval < -maxval ) fval = -maxval;
751 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000752
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000753 fval = (double)val*fac2;
754 if ( fval > maxval ) fval = maxval;
755 else if ( fval < -maxval ) fval = -maxval;
756 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000757
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000758 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
759 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000760 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000762 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
763 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000764 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000765 }
766 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000767}
768
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000769static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000770audioop_add(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000771 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000772 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000773{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000774 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000775 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000776 PyObject *rv;
777 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000778
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000779 if ( !PyArg_Parse(args, "(s#s#i)",
780 &cp1, &len1, &cp2, &len2, &size ) )
781 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000782
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783 if ( len1 != len2 ) {
784 PyErr_SetString(AudioopError, "Lengths should be the same");
785 return 0;
786 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787
Guido van Rossum1851a671997-02-14 16:14:03 +0000788 if ( size == 1 ) maxval = 0x7f;
789 else if ( size == 2 ) maxval = 0x7fff;
790 else if ( size == 4 ) maxval = 0x7fffffff;
791 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
793 return 0;
794 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000795
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000796 rv = PyString_FromStringAndSize(NULL, len1);
797 if ( rv == 0 )
798 return 0;
799 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000800
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000801 for ( i=0; i < len1; i += size ) {
802 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
803 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
804 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000805
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000806 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
807 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
808 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000809
Guido van Rossum1851a671997-02-14 16:14:03 +0000810 newval = val1 + val2;
811 /* truncate in case of overflow */
812 if (newval > maxval) newval = maxval;
813 else if (newval < -maxval) newval = -maxval;
814 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
815 newval = val1 > 0 ? maxval : - maxval;
816
817 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
818 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000819 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000820 }
821 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000822}
823
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000824static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000825audioop_bias(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000826 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000827 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000828{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000829 signed char *cp, *ncp;
830 int len, size, val = 0;
831 PyObject *rv;
832 int i;
833 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000835 if ( !PyArg_Parse(args, "(s#ii)",
836 &cp, &len, &size , &bias) )
837 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000838
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000839 if ( size != 1 && size != 2 && size != 4) {
840 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
841 return 0;
842 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000844 rv = PyString_FromStringAndSize(NULL, len);
845 if ( rv == 0 )
846 return 0;
847 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000848
849
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000850 for ( i=0; i < len; i += size ) {
851 if ( size == 1 ) val = (int)*CHARP(cp, i);
852 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
853 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000855 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
856 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000857 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000858 }
859 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860}
861
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000862static PyObject *
Jack Jansen337b20e1993-02-23 13:39:57 +0000863audioop_reverse(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000865 PyObject *args;
Jack Jansen337b20e1993-02-23 13:39:57 +0000866{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000867 signed char *cp;
868 unsigned char *ncp;
869 int len, size, val = 0;
870 PyObject *rv;
871 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000872
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873 if ( !PyArg_Parse(args, "(s#i)",
874 &cp, &len, &size) )
875 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000876
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000877 if ( size != 1 && size != 2 && size != 4 ) {
878 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
879 return 0;
880 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000881
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000882 rv = PyString_FromStringAndSize(NULL, len);
883 if ( rv == 0 )
884 return 0;
885 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000886
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000887 for ( i=0; i < len; i += size ) {
888 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
889 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
890 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000891
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000892 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000893
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000894 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
895 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000896 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000897 }
898 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000899}
900
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000901static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000902audioop_lin2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000904 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000905{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000906 signed char *cp;
907 unsigned char *ncp;
908 int len, size, size2, val = 0;
909 PyObject *rv;
910 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000911
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000912 if ( !PyArg_Parse(args, "(s#ii)",
913 &cp, &len, &size, &size2) )
914 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000915
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000916 if ( (size != 1 && size != 2 && size != 4) ||
917 (size2 != 1 && size2 != 2 && size2 != 4)) {
918 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
919 return 0;
920 }
Jack Jansena90805f1993-02-17 14:29:28 +0000921
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000922 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
923 if ( rv == 0 )
924 return 0;
925 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000926
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000927 for ( i=0, j=0; i < len; i += size, j += size2 ) {
928 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
929 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
930 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000931
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000932 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
933 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000934 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000935 }
936 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000937}
938
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000939static int
940gcd(a, b)
941 int a, b;
942{
943 while (b > 0) {
944 int tmp = a % b;
945 a = b;
946 b = tmp;
947 }
948 return a;
949}
950
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000951static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000952audioop_ratecv(self, args)
Guido van Rossum1851a671997-02-14 16:14:03 +0000953 PyObject *self;
954 PyObject *args;
Roger E. Massec905fff1997-01-17 18:12:04 +0000955{
Guido van Rossum1851a671997-02-14 16:14:03 +0000956 char *cp, *ncp;
957 int len, size, nchannels, inrate, outrate, weightA, weightB;
958 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000959 PyObject *state, *samps, *str, *rv = NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +0000960
961 weightA = 1;
962 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000963 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000964 &inrate, &outrate, &state, &weightA, &weightB))
965 return NULL;
966 if (size != 1 && size != 2 && size != 4) {
967 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
968 return NULL;
969 }
970 if (nchannels < 1) {
971 PyErr_SetString(AudioopError, "# of channels should be >= 1");
972 return NULL;
973 }
974 if (weightA < 1 || weightB < 0) {
975 PyErr_SetString(AudioopError,
976 "weightA should be >= 1, weightB should be >= 0");
977 return NULL;
978 }
979 if (len % (size * nchannels) != 0) {
980 PyErr_SetString(AudioopError, "not a whole number of frames");
981 return NULL;
982 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000983 if (inrate <= 0 || outrate <= 0) {
984 PyErr_SetString(AudioopError, "sampling rate not > 0");
985 return NULL;
986 }
987 /* divide inrate and outrate by their greatest common divisor */
988 d = gcd(inrate, outrate);
989 inrate /= d;
990 outrate /= d;
991
Guido van Rossum6345ac61997-10-31 20:32:13 +0000992 prev_i = (int *) malloc(nchannels * sizeof(int));
993 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +0000994 len /= size * nchannels; /* # of frames */
Guido van Rossum65bb3281999-09-07 14:24:05 +0000995 if (prev_i == NULL || cur_i == NULL) {
996 (void) PyErr_NoMemory();
997 goto exit;
998 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000999
1000 if (state == Py_None) {
1001 d = -outrate;
1002 for (chan = 0; chan < nchannels; chan++)
1003 prev_i[chan] = cur_i[chan] = 0;
1004 } else {
1005 if (!PyArg_ParseTuple(state,
1006 "iO!;audioop.ratecv: illegal state argument",
1007 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +00001008 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001009 if (PyTuple_Size(samps) != nchannels) {
1010 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +00001011 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +00001012 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001013 }
1014 for (chan = 0; chan < nchannels; chan++) {
1015 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +00001016 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +00001017 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001018 }
1019 }
1020 str = PyString_FromStringAndSize(
1021 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
1022 if (str == NULL)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001023 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001024 ncp = PyString_AsString(str);
1025
1026 for (;;) {
1027 while (d < 0) {
1028 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001029 samps = PyTuple_New(nchannels);
1030 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001031 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001032 Py_BuildValue("(ii)",
1033 prev_i[chan],
1034 cur_i[chan]));
1035 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +00001036 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001037 len = ncp - PyString_AsString(str);
1038 if (len == 0) {
1039 /*don't want to resize to zero length*/
1040 rv = PyString_FromStringAndSize("", 0);
1041 Py_DECREF(str);
1042 str = rv;
1043 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001044 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001045 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001046 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001047 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001048 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001049 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001050 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001051 prev_i[chan] = cur_i[chan];
1052 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001053 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001054 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001055 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001056 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001057 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001058 cp += size;
1059 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001060 cur_i[chan] =
1061 (weightA * cur_i[chan] +
1062 weightB * prev_i[chan]) /
1063 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001064 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001065 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001066 d += outrate;
1067 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001068 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001069 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001070 cur_o = (prev_i[chan] * d +
1071 cur_i[chan] * (outrate - d)) /
1072 outrate;
1073 if (size == 1)
1074 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001075 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001076 *SHORTP(ncp, 0) = (short)(cur_o);
1077 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001078 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001079 ncp += size;
1080 }
1081 d -= inrate;
1082 }
1083 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001084 exit:
1085 if (prev_i != NULL)
1086 free(prev_i);
1087 if (cur_i != NULL)
1088 free(cur_i);
1089 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001090}
Guido van Rossum1851a671997-02-14 16:14:03 +00001091
Roger E. Massec905fff1997-01-17 18:12:04 +00001092static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001093audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001094 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001095 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001096{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001097 signed char *cp;
1098 unsigned char *ncp;
1099 int len, size, val = 0;
1100 PyObject *rv;
1101 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001102
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001103 if ( !PyArg_Parse(args, "(s#i)",
1104 &cp, &len, &size) )
1105 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001106
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001107 if ( size != 1 && size != 2 && size != 4) {
1108 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1109 return 0;
1110 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001111
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001112 rv = PyString_FromStringAndSize(NULL, len/size);
1113 if ( rv == 0 )
1114 return 0;
1115 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001116
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001117 for ( i=0; i < len; i += size ) {
1118 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1119 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1120 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001121
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001122 *ncp++ = st_linear_to_ulaw(val);
1123 }
1124 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001125}
1126
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001127static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001128audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001129 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001130 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001131{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001132 unsigned char *cp;
1133 unsigned char cval;
1134 signed char *ncp;
1135 int len, size, val;
1136 PyObject *rv;
1137 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001138
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001139 if ( !PyArg_Parse(args, "(s#i)",
1140 &cp, &len, &size) )
1141 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001142
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001143 if ( size != 1 && size != 2 && size != 4) {
1144 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1145 return 0;
1146 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001147
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001148 rv = PyString_FromStringAndSize(NULL, len*size);
1149 if ( rv == 0 )
1150 return 0;
1151 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001152
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001153 for ( i=0; i < len*size; i += size ) {
1154 cval = *cp++;
1155 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001156
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001157 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1158 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001159 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001160 }
1161 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001162}
1163
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001164static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001165audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001166 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001167 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001168{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001169 signed char *cp;
1170 signed char *ncp;
1171 int len, size, val = 0, step, valpred, delta,
1172 index, sign, vpdiff, diff;
1173 PyObject *rv, *state, *str;
1174 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001175
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001176 if ( !PyArg_Parse(args, "(s#iO)",
1177 &cp, &len, &size, &state) )
1178 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001179
1180
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001181 if ( size != 1 && size != 2 && size != 4) {
1182 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1183 return 0;
1184 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001185
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001186 str = PyString_FromStringAndSize(NULL, len/(size*2));
1187 if ( str == 0 )
1188 return 0;
1189 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001190
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001191 /* Decode state, should have (value, step) */
1192 if ( state == Py_None ) {
1193 /* First time, it seems. Set defaults */
1194 valpred = 0;
1195 step = 7;
1196 index = 0;
1197 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1198 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001199
Guido van Rossumb64e6351992-07-06 14:21:56 +00001200 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001201 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001202
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001203 for ( i=0; i < len; i += size ) {
1204 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1205 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1206 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1207
1208 /* Step 1 - compute difference with previous value */
1209 diff = val - valpred;
1210 sign = (diff < 0) ? 8 : 0;
1211 if ( sign ) diff = (-diff);
1212
1213 /* Step 2 - Divide and clamp */
1214 /* Note:
1215 ** This code *approximately* computes:
1216 ** delta = diff*4/step;
1217 ** vpdiff = (delta+0.5)*step/4;
1218 ** but in shift step bits are dropped. The net result of this
1219 ** is that even if you have fast mul/div hardware you cannot
1220 ** put it to good use since the fixup would be too expensive.
1221 */
1222 delta = 0;
1223 vpdiff = (step >> 3);
1224
1225 if ( diff >= step ) {
1226 delta = 4;
1227 diff -= step;
1228 vpdiff += step;
1229 }
1230 step >>= 1;
1231 if ( diff >= step ) {
1232 delta |= 2;
1233 diff -= step;
1234 vpdiff += step;
1235 }
1236 step >>= 1;
1237 if ( diff >= step ) {
1238 delta |= 1;
1239 vpdiff += step;
1240 }
1241
1242 /* Step 3 - Update previous value */
1243 if ( sign )
1244 valpred -= vpdiff;
1245 else
1246 valpred += vpdiff;
1247
1248 /* Step 4 - Clamp previous value to 16 bits */
1249 if ( valpred > 32767 )
1250 valpred = 32767;
1251 else if ( valpred < -32768 )
1252 valpred = -32768;
1253
1254 /* Step 5 - Assemble value, update index and step values */
1255 delta |= sign;
1256
1257 index += indexTable[delta];
1258 if ( index < 0 ) index = 0;
1259 if ( index > 88 ) index = 88;
1260 step = stepsizeTable[index];
1261
1262 /* Step 6 - Output value */
1263 if ( bufferstep ) {
1264 outputbuffer = (delta << 4) & 0xf0;
1265 } else {
1266 *ncp++ = (delta & 0x0f) | outputbuffer;
1267 }
1268 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001269 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001270 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1271 Py_DECREF(str);
1272 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001273}
1274
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001275static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001276audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001277 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001278 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001279{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001280 signed char *cp;
1281 signed char *ncp;
1282 int len, size, valpred, step, delta, index, sign, vpdiff;
1283 PyObject *rv, *str, *state;
1284 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001285
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001286 if ( !PyArg_Parse(args, "(s#iO)",
1287 &cp, &len, &size, &state) )
1288 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001289
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001290 if ( size != 1 && size != 2 && size != 4) {
1291 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1292 return 0;
1293 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001294
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001295 /* Decode state, should have (value, step) */
1296 if ( state == Py_None ) {
1297 /* First time, it seems. Set defaults */
1298 valpred = 0;
1299 step = 7;
1300 index = 0;
1301 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1302 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001303
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001304 str = PyString_FromStringAndSize(NULL, len*size*2);
1305 if ( str == 0 )
1306 return 0;
1307 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001308
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001309 step = stepsizeTable[index];
1310 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001311
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001312 for ( i=0; i < len*size*2; i += size ) {
1313 /* Step 1 - get the delta value and compute next index */
1314 if ( bufferstep ) {
1315 delta = inputbuffer & 0xf;
1316 } else {
1317 inputbuffer = *cp++;
1318 delta = (inputbuffer >> 4) & 0xf;
1319 }
1320
1321 bufferstep = !bufferstep;
1322
1323 /* Step 2 - Find new index value (for later) */
1324 index += indexTable[delta];
1325 if ( index < 0 ) index = 0;
1326 if ( index > 88 ) index = 88;
1327
1328 /* Step 3 - Separate sign and magnitude */
1329 sign = delta & 8;
1330 delta = delta & 7;
1331
1332 /* Step 4 - Compute difference and new predicted value */
1333 /*
1334 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1335 ** in adpcm_coder.
1336 */
1337 vpdiff = step >> 3;
1338 if ( delta & 4 ) vpdiff += step;
1339 if ( delta & 2 ) vpdiff += step>>1;
1340 if ( delta & 1 ) vpdiff += step>>2;
1341
1342 if ( sign )
1343 valpred -= vpdiff;
1344 else
1345 valpred += vpdiff;
1346
1347 /* Step 5 - clamp output value */
1348 if ( valpred > 32767 )
1349 valpred = 32767;
1350 else if ( valpred < -32768 )
1351 valpred = -32768;
1352
1353 /* Step 6 - Update step value */
1354 step = stepsizeTable[index];
1355
1356 /* Step 6 - Output value */
1357 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1358 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001359 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001360 }
1361
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001362 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1363 Py_DECREF(str);
1364 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001365}
1366
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001367static PyMethodDef audioop_methods[] = {
1368 { "max", audioop_max },
1369 { "minmax", audioop_minmax },
1370 { "avg", audioop_avg },
1371 { "maxpp", audioop_maxpp },
1372 { "avgpp", audioop_avgpp },
1373 { "rms", audioop_rms },
1374 { "findfit", audioop_findfit },
1375 { "findmax", audioop_findmax },
1376 { "findfactor", audioop_findfactor },
1377 { "cross", audioop_cross },
1378 { "mul", audioop_mul },
1379 { "add", audioop_add },
1380 { "bias", audioop_bias },
1381 { "ulaw2lin", audioop_ulaw2lin },
1382 { "lin2ulaw", audioop_lin2ulaw },
1383 { "lin2lin", audioop_lin2lin },
1384 { "adpcm2lin", audioop_adpcm2lin },
1385 { "lin2adpcm", audioop_lin2adpcm },
1386 { "tomono", audioop_tomono },
1387 { "tostereo", audioop_tostereo },
1388 { "getsample", audioop_getsample },
1389 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001390 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001391 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001392};
1393
Guido van Rossum3886bb61998-12-04 18:50:17 +00001394DL_EXPORT(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001395initaudioop()
1396{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001397 PyObject *m, *d;
1398 m = Py_InitModule("audioop", audioop_methods);
1399 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001400 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1401 if (AudioopError != NULL)
1402 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001403}