blob: 08e8fd43eb7964a449a21e4c111cec091f1569df [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
Guido van Rossuma320fd31995-03-09 12:14:15 +000034#include "mymath.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000035
Jack Jansena90805f1993-02-17 14:29:28 +000036/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000037** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
38
39#define MINLIN -32768
40#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000041#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
42 else if ( x > MAXLIN ) x = MAXLIN; \
43 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000044
Guido van Rossumcd938fc1995-01-17 16:13:48 +000045static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000046
47/*
48** This macro converts from ulaw to 16 bit linear, faster.
49**
50** Jef Poskanzer
51** 23 October 1989
52**
53** Input: 8 bit ulaw sample
54** Output: signed 16 bit linear sample
55*/
56#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
57
58static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000059 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
60 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
61 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
62 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
63 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
64 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
65 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
66 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
67 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
68 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
69 -876, -844, -812, -780, -748, -716, -684, -652,
70 -620, -588, -556, -524, -492, -460, -428, -396,
71 -372, -356, -340, -324, -308, -292, -276, -260,
72 -244, -228, -212, -196, -180, -164, -148, -132,
73 -120, -112, -104, -96, -88, -80, -72, -64,
74 -56, -48, -40, -32, -24, -16, -8, 0,
75 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
76 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
77 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
78 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
79 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
80 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
81 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
82 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
83 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
84 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
85 876, 844, 812, 780, 748, 716, 684, 652,
86 620, 588, 556, 524, 492, 460, 428, 396,
87 372, 356, 340, 324, 308, 292, 276, 260,
88 244, 228, 212, 196, 180, 164, 148, 132,
89 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000090 56, 48, 40, 32, 24, 16, 8, 0 };
91
Guido van Rossum7d64b482000-05-02 21:18:13 +000092/* #define ZEROTRAP /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +000093#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
94#define CLIP 32635
95
Guido van Rossumcd938fc1995-01-17 16:13:48 +000096static unsigned char
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000097st_linear_to_ulaw(int sample)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000098{
99 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
100 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
101 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
102 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
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 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 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 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 int sign, exponent, mantissa;
116 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000117
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000118 /* Get the sample into sign-magnitude. */
119 sign = (sample >> 8) & 0x80; /* set aside the sign */
120 if ( sign != 0 ) sample = -sample; /* get magnitude */
121 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000122
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000123 /* Convert from 16 bit linear to ulaw. */
124 sample = sample + BIAS;
125 exponent = exp_lut[( sample >> 7 ) & 0xFF];
126 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
127 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000128#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000129 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000130#endif
131
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000132 return ulawbyte;
133}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000134/* End of code taken from sox */
135
Guido van Rossumb64e6351992-07-06 14:21:56 +0000136/* Intel ADPCM step variation table */
137static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000138 -1, -1, -1, -1, 2, 4, 6, 8,
139 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000140};
141
142static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000143 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
144 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
145 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
146 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
147 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
148 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
149 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
150 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
151 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000152};
153
Guido van Rossumb66efa01992-06-01 16:01:24 +0000154#define CHARP(cp, i) ((signed char *)(cp+i))
155#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000156#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000157
158
159
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000160static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000161
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000162static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000163audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000164{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000165 signed char *cp;
166 int len, size, val = 0;
167 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000168
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000169 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
170 return 0;
171 if ( size != 1 && size != 2 && size != 4 ) {
172 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
173 return 0;
174 }
175 if ( i < 0 || i >= len/size ) {
176 PyErr_SetString(AudioopError, "Index out of range");
177 return 0;
178 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000179 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000180 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
181 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
182 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000183}
184
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000185static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000186audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000187{
188 signed char *cp;
189 int len, size, val = 0;
190 int i;
191 int max = 0;
192
193 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
194 return 0;
195 if ( size != 1 && size != 2 && size != 4 ) {
196 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
197 return 0;
198 }
199 for ( i=0; i<len; i+= size) {
200 if ( size == 1 ) val = (int)*CHARP(cp, i);
201 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
202 else if ( size == 4 ) val = (int)*LONGP(cp, i);
203 if ( val < 0 ) val = (-val);
204 if ( val > max ) max = val;
205 }
206 return PyInt_FromLong(max);
207}
208
209static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000210audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000211{
212 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000213 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000214 int i;
215 int min = 0x7fffffff, max = -0x7fffffff;
216
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000217 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000218 return NULL;
219 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000220 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000221 return NULL;
222 }
223 for (i = 0; i < len; i += size) {
224 if (size == 1) val = (int) *CHARP(cp, i);
225 else if (size == 2) val = (int) *SHORTP(cp, i);
226 else if (size == 4) val = (int) *LONGP(cp, i);
227 if (val > max) max = val;
228 if (val < min) min = val;
229 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000230 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000231}
232
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000233static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000234audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000235{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000236 signed char *cp;
237 int len, size, val = 0;
238 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000239 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000240
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000241 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
242 return 0;
243 if ( size != 1 && size != 2 && size != 4 ) {
244 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
245 return 0;
246 }
247 for ( i=0; i<len; i+= size) {
248 if ( size == 1 ) val = (int)*CHARP(cp, i);
249 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
250 else if ( size == 4 ) val = (int)*LONGP(cp, i);
251 avg += val;
252 }
253 if ( len == 0 )
254 val = 0;
255 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000256 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000257 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000258}
259
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000260static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000261audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000262{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000263 signed char *cp;
264 int len, size, val = 0;
265 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000266 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000267
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000268 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
269 return 0;
270 if ( size != 1 && size != 2 && size != 4 ) {
271 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
272 return 0;
273 }
274 for ( i=0; i<len; i+= size) {
275 if ( size == 1 ) val = (int)*CHARP(cp, i);
276 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
277 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000278 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000279 }
280 if ( len == 0 )
281 val = 0;
282 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000283 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000284 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000285}
286
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000287static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000288{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000289 int i;
290 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000291
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000292 for( i=0; i<len; i++) {
293 sum = sum + (double)a[i]*(double)b[i];
294 }
295 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000296}
297
298/*
299** Findfit tries to locate a sample within another sample. Its main use
300** is in echo-cancellation (to find the feedback of the output signal in
301** the input signal).
302** The method used is as follows:
303**
304** let R be the reference signal (length n) and A the input signal (length N)
305** with N > n, and let all sums be over i from 0 to n-1.
306**
307** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
308** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
309** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
310**
311** Next, we compute the relative distance between the original signal and
312** the modified signal and minimize that over j:
313** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
314** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
315**
316** In the code variables correspond as follows:
317** cp1 A
318** cp2 R
319** len1 N
320** len2 n
321** aj_m1 A[j-1]
322** aj_lm1 A[j+n-1]
323** sum_ri_2 sum(R[i]^2)
324** sum_aij_2 sum(A[i+j]^2)
325** sum_aij_ri sum(A[i+j]R[i])
326**
327** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
328** is completely recalculated each step.
329*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000330static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000331audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000332{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000333 short *cp1, *cp2;
334 int len1, len2;
335 int j, best_j;
336 double aj_m1, aj_lm1;
337 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000338
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000339 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
340 return 0;
341 if ( len1 & 1 || len2 & 1 ) {
342 PyErr_SetString(AudioopError, "Strings should be even-sized");
343 return 0;
344 }
345 len1 >>= 1;
346 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000347
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000348 if ( len1 < len2 ) {
349 PyErr_SetString(AudioopError, "First sample should be longer");
350 return 0;
351 }
352 sum_ri_2 = _sum2(cp2, cp2, len2);
353 sum_aij_2 = _sum2(cp1, cp1, len2);
354 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000355
356 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
357
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000358 best_result = result;
359 best_j = 0;
360 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000361
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000362 for ( j=1; j<=len1-len2; j++) {
363 aj_m1 = (double)cp1[j-1];
364 aj_lm1 = (double)cp1[j+len2-1];
365
366 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
367 sum_aij_ri = _sum2(cp1+j, cp2, len2);
368
369 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
370 / sum_aij_2;
371
372 if ( result < best_result ) {
373 best_result = result;
374 best_j = j;
375 }
376
377 }
378
379 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000380
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000381 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000382}
383
384/*
385** findfactor finds a factor f so that the energy in A-fB is minimal.
386** See the comment for findfit for details.
387*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000388static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000389audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000390{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000391 short *cp1, *cp2;
392 int len1, len2;
393 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000394
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000395 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
396 return 0;
397 if ( len1 & 1 || len2 & 1 ) {
398 PyErr_SetString(AudioopError, "Strings should be even-sized");
399 return 0;
400 }
401 if ( len1 != len2 ) {
402 PyErr_SetString(AudioopError, "Samples should be same size");
403 return 0;
404 }
405 len2 >>= 1;
406 sum_ri_2 = _sum2(cp2, cp2, len2);
407 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000408
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000409 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000410
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000412}
413
414/*
415** findmax returns the index of the n-sized segment of the input sample
416** that contains the most energy.
417*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000418static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000419audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000420{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000421 short *cp1;
422 int len1, len2;
423 int j, best_j;
424 double aj_m1, aj_lm1;
425 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000426
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000427 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
428 return 0;
429 if ( len1 & 1 ) {
430 PyErr_SetString(AudioopError, "Strings should be even-sized");
431 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000432 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000433 len1 >>= 1;
434
435 if ( len1 < len2 ) {
436 PyErr_SetString(AudioopError, "Input sample should be longer");
437 return 0;
438 }
Jack Jansena90805f1993-02-17 14:29:28 +0000439
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000440 result = _sum2(cp1, cp1, len2);
441
442 best_result = result;
443 best_j = 0;
444 j = 0;
445
446 for ( j=1; j<=len1-len2; j++) {
447 aj_m1 = (double)cp1[j-1];
448 aj_lm1 = (double)cp1[j+len2-1];
449
450 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
451
452 if ( result > best_result ) {
453 best_result = result;
454 best_j = j;
455 }
456
457 }
458
459 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000460}
461
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000462static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000463audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000464{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000465 signed char *cp;
466 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
467 prevextreme = 0;
468 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000469 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000470 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000471
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000472 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
473 return 0;
474 if ( size != 1 && size != 2 && size != 4 ) {
475 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
476 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000477 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000478 /* Compute first delta value ahead. Also automatically makes us
479 ** skip the first extreme value
480 */
481 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
482 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
483 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
484 if ( size == 1 ) val = (int)*CHARP(cp, size);
485 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
486 else if ( size == 4 ) val = (int)*LONGP(cp, size);
487 prevdiff = val - prevval;
488
489 for ( i=size; i<len; i+= size) {
490 if ( size == 1 ) val = (int)*CHARP(cp, i);
491 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
492 else if ( size == 4 ) val = (int)*LONGP(cp, i);
493 diff = val - prevval;
494 if ( diff*prevdiff < 0 ) {
495 /* Derivative changed sign. Compute difference to last
496 ** extreme value and remember.
497 */
498 if ( prevextremevalid ) {
499 extremediff = prevval - prevextreme;
500 if ( extremediff < 0 )
501 extremediff = -extremediff;
502 avg += extremediff;
503 nextreme++;
504 }
505 prevextremevalid = 1;
506 prevextreme = prevval;
507 }
508 prevval = val;
509 if ( diff != 0 )
510 prevdiff = diff;
511 }
512 if ( nextreme == 0 )
513 val = 0;
514 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000515 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000516 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000517}
518
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000520audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000521{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000522 signed char *cp;
523 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
524 prevextreme = 0;
525 int i;
526 int max = 0;
527 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000528
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000529 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
530 return 0;
531 if ( size != 1 && size != 2 && size != 4 ) {
532 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
533 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000534 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000535 /* Compute first delta value ahead. Also automatically makes us
536 ** skip the first extreme value
537 */
538 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
539 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
540 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
541 if ( size == 1 ) val = (int)*CHARP(cp, size);
542 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
543 else if ( size == 4 ) val = (int)*LONGP(cp, size);
544 prevdiff = val - prevval;
545
546 for ( i=size; i<len; i+= size) {
547 if ( size == 1 ) val = (int)*CHARP(cp, i);
548 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
549 else if ( size == 4 ) val = (int)*LONGP(cp, i);
550 diff = val - prevval;
551 if ( diff*prevdiff < 0 ) {
552 /* Derivative changed sign. Compute difference to
553 ** last extreme value and remember.
554 */
555 if ( prevextremevalid ) {
556 extremediff = prevval - prevextreme;
557 if ( extremediff < 0 )
558 extremediff = -extremediff;
559 if ( extremediff > max )
560 max = extremediff;
561 }
562 prevextremevalid = 1;
563 prevextreme = prevval;
564 }
565 prevval = val;
566 if ( diff != 0 )
567 prevdiff = diff;
568 }
569 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000570}
571
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000572static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000573audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000574{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000575 signed char *cp;
576 int len, size, val = 0;
577 int i;
578 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000579
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000580 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
581 return 0;
582 if ( size != 1 && size != 2 && size != 4 ) {
583 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
584 return 0;
585 }
586 ncross = -1;
587 prevval = 17; /* Anything <> 0,1 */
588 for ( i=0; i<len; i+= size) {
589 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
590 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
591 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
592 val = val & 1;
593 if ( val != prevval ) ncross++;
594 prevval = val;
595 }
596 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000597}
598
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000599static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000600audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000601{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000602 signed char *cp, *ncp;
603 int len, size, val = 0;
604 double factor, fval, maxval;
605 PyObject *rv;
606 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000607
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000608 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
609 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000610
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000611 if ( size == 1 ) maxval = (double) 0x7f;
612 else if ( size == 2 ) maxval = (double) 0x7fff;
613 else if ( size == 4 ) maxval = (double) 0x7fffffff;
614 else {
615 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
616 return 0;
617 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000618
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000619 rv = PyString_FromStringAndSize(NULL, len);
620 if ( rv == 0 )
621 return 0;
622 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000623
624
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000625 for ( i=0; i < len; i += size ) {
626 if ( size == 1 ) val = (int)*CHARP(cp, i);
627 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
628 else if ( size == 4 ) val = (int)*LONGP(cp, i);
629 fval = (double)val*factor;
630 if ( fval > maxval ) fval = maxval;
631 else if ( fval < -maxval ) fval = -maxval;
632 val = (int)fval;
633 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
634 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000635 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000636 }
637 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000638}
639
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000640static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000641audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000642{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000643 signed char *cp, *ncp;
644 int len, size, val1 = 0, val2 = 0;
645 double fac1, fac2, fval, maxval;
646 PyObject *rv;
647 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000648
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
650 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000651
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000652 if ( size == 1 ) maxval = (double) 0x7f;
653 else if ( size == 2 ) maxval = (double) 0x7fff;
654 else if ( size == 4 ) maxval = (double) 0x7fffffff;
655 else {
656 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
657 return 0;
658 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000659
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000660 rv = PyString_FromStringAndSize(NULL, len/2);
661 if ( rv == 0 )
662 return 0;
663 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000664
665
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000666 for ( i=0; i < len; i += size*2 ) {
667 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
668 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
669 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
670 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
671 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
672 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
673 fval = (double)val1*fac1 + (double)val2*fac2;
674 if ( fval > maxval ) fval = maxval;
675 else if ( fval < -maxval ) fval = -maxval;
676 val1 = (int)fval;
677 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
678 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000679 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000680 }
681 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000682}
683
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000684static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000685audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000686{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000687 signed char *cp, *ncp;
688 int len, size, val1, val2, val = 0;
689 double fac1, fac2, fval, maxval;
690 PyObject *rv;
691 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000692
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000693 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
694 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000695
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000696 if ( size == 1 ) maxval = (double) 0x7f;
697 else if ( size == 2 ) maxval = (double) 0x7fff;
698 else if ( size == 4 ) maxval = (double) 0x7fffffff;
699 else {
700 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
701 return 0;
702 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000703
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000704 rv = PyString_FromStringAndSize(NULL, len*2);
705 if ( rv == 0 )
706 return 0;
707 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000708
709
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000710 for ( i=0; i < len; i += size ) {
711 if ( size == 1 ) val = (int)*CHARP(cp, i);
712 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
713 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000714
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000715 fval = (double)val*fac1;
716 if ( fval > maxval ) fval = maxval;
717 else if ( fval < -maxval ) fval = -maxval;
718 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000719
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000720 fval = (double)val*fac2;
721 if ( fval > maxval ) fval = maxval;
722 else if ( fval < -maxval ) fval = -maxval;
723 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000724
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000725 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
726 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000727 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000728
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000729 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
730 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000731 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000732 }
733 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000734}
735
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000736static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000737audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000738{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000739 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000740 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000741 PyObject *rv;
742 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000743
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000744 if ( !PyArg_Parse(args, "(s#s#i)",
745 &cp1, &len1, &cp2, &len2, &size ) )
746 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000747
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000748 if ( len1 != len2 ) {
749 PyErr_SetString(AudioopError, "Lengths should be the same");
750 return 0;
751 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000752
Guido van Rossum1851a671997-02-14 16:14:03 +0000753 if ( size == 1 ) maxval = 0x7f;
754 else if ( size == 2 ) maxval = 0x7fff;
755 else if ( size == 4 ) maxval = 0x7fffffff;
756 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000757 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
758 return 0;
759 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000760
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000761 rv = PyString_FromStringAndSize(NULL, len1);
762 if ( rv == 0 )
763 return 0;
764 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000765
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000766 for ( i=0; i < len1; i += size ) {
767 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
768 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
769 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000770
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000771 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
772 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
773 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000774
Guido van Rossum1851a671997-02-14 16:14:03 +0000775 newval = val1 + val2;
776 /* truncate in case of overflow */
777 if (newval > maxval) newval = maxval;
778 else if (newval < -maxval) newval = -maxval;
779 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
780 newval = val1 > 0 ? maxval : - maxval;
781
782 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
783 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000784 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000785 }
786 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787}
788
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000789static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000790audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792 signed char *cp, *ncp;
793 int len, size, val = 0;
794 PyObject *rv;
795 int i;
796 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000797
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000798 if ( !PyArg_Parse(args, "(s#ii)",
799 &cp, &len, &size , &bias) )
800 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000801
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000802 if ( size != 1 && size != 2 && size != 4) {
803 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
804 return 0;
805 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000806
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000807 rv = PyString_FromStringAndSize(NULL, len);
808 if ( rv == 0 )
809 return 0;
810 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000811
812
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000813 for ( i=0; i < len; i += size ) {
814 if ( size == 1 ) val = (int)*CHARP(cp, i);
815 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
816 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000817
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000818 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
819 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000820 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000821 }
822 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000823}
824
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000825static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000826audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000827{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000828 signed char *cp;
829 unsigned char *ncp;
830 int len, size, val = 0;
831 PyObject *rv;
832 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000833
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000834 if ( !PyArg_Parse(args, "(s#i)",
835 &cp, &len, &size) )
836 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000837
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000838 if ( size != 1 && size != 2 && size != 4 ) {
839 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
840 return 0;
841 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000842
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000843 rv = PyString_FromStringAndSize(NULL, len);
844 if ( rv == 0 )
845 return 0;
846 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000847
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000848 for ( i=0; i < len; i += size ) {
849 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
850 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
851 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000852
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000853 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000854
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000855 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
856 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000857 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000858 }
859 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000860}
861
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000862static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000863audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000864{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000865 signed char *cp;
866 unsigned char *ncp;
867 int len, size, size2, val = 0;
868 PyObject *rv;
869 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000870
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000871 if ( !PyArg_Parse(args, "(s#ii)",
872 &cp, &len, &size, &size2) )
873 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000874
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000875 if ( (size != 1 && size != 2 && size != 4) ||
876 (size2 != 1 && size2 != 2 && size2 != 4)) {
877 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
878 return 0;
879 }
Jack Jansena90805f1993-02-17 14:29:28 +0000880
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000881 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
882 if ( rv == 0 )
883 return 0;
884 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000885
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000886 for ( i=0, j=0; i < len; i += size, j += size2 ) {
887 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
888 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
889 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000890
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000891 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
892 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000893 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000894 }
895 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000896}
897
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000898static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000899gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000900{
901 while (b > 0) {
902 int tmp = a % b;
903 a = b;
904 b = tmp;
905 }
906 return a;
907}
908
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000909static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000910audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +0000911{
Guido van Rossum1851a671997-02-14 16:14:03 +0000912 char *cp, *ncp;
913 int len, size, nchannels, inrate, outrate, weightA, weightB;
914 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000915 PyObject *state, *samps, *str, *rv = NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +0000916
917 weightA = 1;
918 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000919 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000920 &inrate, &outrate, &state, &weightA, &weightB))
921 return NULL;
922 if (size != 1 && size != 2 && size != 4) {
923 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
924 return NULL;
925 }
926 if (nchannels < 1) {
927 PyErr_SetString(AudioopError, "# of channels should be >= 1");
928 return NULL;
929 }
930 if (weightA < 1 || weightB < 0) {
931 PyErr_SetString(AudioopError,
932 "weightA should be >= 1, weightB should be >= 0");
933 return NULL;
934 }
935 if (len % (size * nchannels) != 0) {
936 PyErr_SetString(AudioopError, "not a whole number of frames");
937 return NULL;
938 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000939 if (inrate <= 0 || outrate <= 0) {
940 PyErr_SetString(AudioopError, "sampling rate not > 0");
941 return NULL;
942 }
943 /* divide inrate and outrate by their greatest common divisor */
944 d = gcd(inrate, outrate);
945 inrate /= d;
946 outrate /= d;
947
Guido van Rossum6345ac61997-10-31 20:32:13 +0000948 prev_i = (int *) malloc(nchannels * sizeof(int));
949 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +0000950 len /= size * nchannels; /* # of frames */
Guido van Rossum65bb3281999-09-07 14:24:05 +0000951 if (prev_i == NULL || cur_i == NULL) {
952 (void) PyErr_NoMemory();
953 goto exit;
954 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000955
956 if (state == Py_None) {
957 d = -outrate;
958 for (chan = 0; chan < nchannels; chan++)
959 prev_i[chan] = cur_i[chan] = 0;
960 } else {
961 if (!PyArg_ParseTuple(state,
962 "iO!;audioop.ratecv: illegal state argument",
963 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000964 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000965 if (PyTuple_Size(samps) != nchannels) {
966 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000967 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +0000968 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000969 }
970 for (chan = 0; chan < nchannels; chan++) {
971 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +0000972 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000973 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000974 }
975 }
976 str = PyString_FromStringAndSize(
977 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
978 if (str == NULL)
Guido van Rossum65bb3281999-09-07 14:24:05 +0000979 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000980 ncp = PyString_AsString(str);
981
982 for (;;) {
983 while (d < 0) {
984 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +0000985 samps = PyTuple_New(nchannels);
986 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +0000987 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +0000988 Py_BuildValue("(ii)",
989 prev_i[chan],
990 cur_i[chan]));
991 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +0000992 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +0000993 len = ncp - PyString_AsString(str);
994 if (len == 0) {
995 /*don't want to resize to zero length*/
996 rv = PyString_FromStringAndSize("", 0);
997 Py_DECREF(str);
998 str = rv;
999 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001000 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001001 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001002 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001003 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001004 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001005 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001006 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001007 prev_i[chan] = cur_i[chan];
1008 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001009 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001010 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001011 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001012 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001013 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001014 cp += size;
1015 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001016 cur_i[chan] =
1017 (weightA * cur_i[chan] +
1018 weightB * prev_i[chan]) /
1019 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001020 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001021 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001022 d += outrate;
1023 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001024 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001025 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001026 cur_o = (prev_i[chan] * d +
1027 cur_i[chan] * (outrate - d)) /
1028 outrate;
1029 if (size == 1)
1030 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001031 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001032 *SHORTP(ncp, 0) = (short)(cur_o);
1033 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001034 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001035 ncp += size;
1036 }
1037 d -= inrate;
1038 }
1039 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001040 exit:
1041 if (prev_i != NULL)
1042 free(prev_i);
1043 if (cur_i != NULL)
1044 free(cur_i);
1045 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001046}
Guido van Rossum1851a671997-02-14 16:14:03 +00001047
Roger E. Massec905fff1997-01-17 18:12:04 +00001048static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001049audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001050{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001051 signed char *cp;
1052 unsigned char *ncp;
1053 int len, size, val = 0;
1054 PyObject *rv;
1055 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001056
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001057 if ( !PyArg_Parse(args, "(s#i)",
1058 &cp, &len, &size) )
1059 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001060
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001061 if ( size != 1 && size != 2 && size != 4) {
1062 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1063 return 0;
1064 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001065
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001066 rv = PyString_FromStringAndSize(NULL, len/size);
1067 if ( rv == 0 )
1068 return 0;
1069 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001070
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001071 for ( i=0; i < len; i += size ) {
1072 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1073 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1074 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001075
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001076 *ncp++ = st_linear_to_ulaw(val);
1077 }
1078 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001079}
1080
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001081static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001082audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001083{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001084 unsigned char *cp;
1085 unsigned char cval;
1086 signed char *ncp;
1087 int len, size, val;
1088 PyObject *rv;
1089 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001090
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001091 if ( !PyArg_Parse(args, "(s#i)",
1092 &cp, &len, &size) )
1093 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001094
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001095 if ( size != 1 && size != 2 && size != 4) {
1096 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1097 return 0;
1098 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001099
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001100 rv = PyString_FromStringAndSize(NULL, len*size);
1101 if ( rv == 0 )
1102 return 0;
1103 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001104
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001105 for ( i=0; i < len*size; i += size ) {
1106 cval = *cp++;
1107 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001108
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001109 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1110 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001111 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001112 }
1113 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001114}
1115
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001117audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001118{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001119 signed char *cp;
1120 signed char *ncp;
1121 int len, size, val = 0, step, valpred, delta,
1122 index, sign, vpdiff, diff;
1123 PyObject *rv, *state, *str;
1124 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001125
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001126 if ( !PyArg_Parse(args, "(s#iO)",
1127 &cp, &len, &size, &state) )
1128 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001129
1130
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001131 if ( size != 1 && size != 2 && size != 4) {
1132 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1133 return 0;
1134 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001135
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001136 str = PyString_FromStringAndSize(NULL, len/(size*2));
1137 if ( str == 0 )
1138 return 0;
1139 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001140
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001141 /* Decode state, should have (value, step) */
1142 if ( state == Py_None ) {
1143 /* First time, it seems. Set defaults */
1144 valpred = 0;
1145 step = 7;
1146 index = 0;
1147 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1148 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001149
Guido van Rossumb64e6351992-07-06 14:21:56 +00001150 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001151 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001152
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001153 for ( i=0; i < len; i += size ) {
1154 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1155 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1156 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1157
1158 /* Step 1 - compute difference with previous value */
1159 diff = val - valpred;
1160 sign = (diff < 0) ? 8 : 0;
1161 if ( sign ) diff = (-diff);
1162
1163 /* Step 2 - Divide and clamp */
1164 /* Note:
1165 ** This code *approximately* computes:
1166 ** delta = diff*4/step;
1167 ** vpdiff = (delta+0.5)*step/4;
1168 ** but in shift step bits are dropped. The net result of this
1169 ** is that even if you have fast mul/div hardware you cannot
1170 ** put it to good use since the fixup would be too expensive.
1171 */
1172 delta = 0;
1173 vpdiff = (step >> 3);
1174
1175 if ( diff >= step ) {
1176 delta = 4;
1177 diff -= step;
1178 vpdiff += step;
1179 }
1180 step >>= 1;
1181 if ( diff >= step ) {
1182 delta |= 2;
1183 diff -= step;
1184 vpdiff += step;
1185 }
1186 step >>= 1;
1187 if ( diff >= step ) {
1188 delta |= 1;
1189 vpdiff += step;
1190 }
1191
1192 /* Step 3 - Update previous value */
1193 if ( sign )
1194 valpred -= vpdiff;
1195 else
1196 valpred += vpdiff;
1197
1198 /* Step 4 - Clamp previous value to 16 bits */
1199 if ( valpred > 32767 )
1200 valpred = 32767;
1201 else if ( valpred < -32768 )
1202 valpred = -32768;
1203
1204 /* Step 5 - Assemble value, update index and step values */
1205 delta |= sign;
1206
1207 index += indexTable[delta];
1208 if ( index < 0 ) index = 0;
1209 if ( index > 88 ) index = 88;
1210 step = stepsizeTable[index];
1211
1212 /* Step 6 - Output value */
1213 if ( bufferstep ) {
1214 outputbuffer = (delta << 4) & 0xf0;
1215 } else {
1216 *ncp++ = (delta & 0x0f) | outputbuffer;
1217 }
1218 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001219 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001220 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1221 Py_DECREF(str);
1222 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001223}
1224
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001225static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001226audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001227{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001228 signed char *cp;
1229 signed char *ncp;
1230 int len, size, valpred, step, delta, index, sign, vpdiff;
1231 PyObject *rv, *str, *state;
1232 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001233
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001234 if ( !PyArg_Parse(args, "(s#iO)",
1235 &cp, &len, &size, &state) )
1236 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001237
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001238 if ( size != 1 && size != 2 && size != 4) {
1239 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1240 return 0;
1241 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001242
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001243 /* Decode state, should have (value, step) */
1244 if ( state == Py_None ) {
1245 /* First time, it seems. Set defaults */
1246 valpred = 0;
1247 step = 7;
1248 index = 0;
1249 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1250 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001251
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001252 str = PyString_FromStringAndSize(NULL, len*size*2);
1253 if ( str == 0 )
1254 return 0;
1255 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001256
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001257 step = stepsizeTable[index];
1258 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001259
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001260 for ( i=0; i < len*size*2; i += size ) {
1261 /* Step 1 - get the delta value and compute next index */
1262 if ( bufferstep ) {
1263 delta = inputbuffer & 0xf;
1264 } else {
1265 inputbuffer = *cp++;
1266 delta = (inputbuffer >> 4) & 0xf;
1267 }
1268
1269 bufferstep = !bufferstep;
1270
1271 /* Step 2 - Find new index value (for later) */
1272 index += indexTable[delta];
1273 if ( index < 0 ) index = 0;
1274 if ( index > 88 ) index = 88;
1275
1276 /* Step 3 - Separate sign and magnitude */
1277 sign = delta & 8;
1278 delta = delta & 7;
1279
1280 /* Step 4 - Compute difference and new predicted value */
1281 /*
1282 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1283 ** in adpcm_coder.
1284 */
1285 vpdiff = step >> 3;
1286 if ( delta & 4 ) vpdiff += step;
1287 if ( delta & 2 ) vpdiff += step>>1;
1288 if ( delta & 1 ) vpdiff += step>>2;
1289
1290 if ( sign )
1291 valpred -= vpdiff;
1292 else
1293 valpred += vpdiff;
1294
1295 /* Step 5 - clamp output value */
1296 if ( valpred > 32767 )
1297 valpred = 32767;
1298 else if ( valpred < -32768 )
1299 valpred = -32768;
1300
1301 /* Step 6 - Update step value */
1302 step = stepsizeTable[index];
1303
1304 /* Step 6 - Output value */
1305 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1306 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001307 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001308 }
1309
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001310 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1311 Py_DECREF(str);
1312 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001313}
1314
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001315static PyMethodDef audioop_methods[] = {
1316 { "max", audioop_max },
1317 { "minmax", audioop_minmax },
1318 { "avg", audioop_avg },
1319 { "maxpp", audioop_maxpp },
1320 { "avgpp", audioop_avgpp },
1321 { "rms", audioop_rms },
1322 { "findfit", audioop_findfit },
1323 { "findmax", audioop_findmax },
1324 { "findfactor", audioop_findfactor },
1325 { "cross", audioop_cross },
1326 { "mul", audioop_mul },
1327 { "add", audioop_add },
1328 { "bias", audioop_bias },
1329 { "ulaw2lin", audioop_ulaw2lin },
1330 { "lin2ulaw", audioop_lin2ulaw },
1331 { "lin2lin", audioop_lin2lin },
1332 { "adpcm2lin", audioop_adpcm2lin },
1333 { "lin2adpcm", audioop_lin2adpcm },
1334 { "tomono", audioop_tomono },
1335 { "tostereo", audioop_tostereo },
1336 { "getsample", audioop_getsample },
1337 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001338 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001339 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001340};
1341
Guido van Rossum3886bb61998-12-04 18:50:17 +00001342DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001343initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001344{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001345 PyObject *m, *d;
1346 m = Py_InitModule("audioop", audioop_methods);
1347 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001348 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1349 if (AudioopError != NULL)
1350 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001351}