blob: 73612cbde762709a2fcd5c16c4f64bc269640948 [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
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000287static double _sum2(a, b, len)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000288 short *a;
Roger E. Massec905fff1997-01-17 18:12:04 +0000289 short *b;
290 int len;
Jack Jansena90805f1993-02-17 14:29:28 +0000291{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000292 int i;
293 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000294
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000295 for( i=0; i<len; i++) {
296 sum = sum + (double)a[i]*(double)b[i];
297 }
298 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000299}
300
301/*
302** Findfit tries to locate a sample within another sample. Its main use
303** is in echo-cancellation (to find the feedback of the output signal in
304** the input signal).
305** The method used is as follows:
306**
307** let R be the reference signal (length n) and A the input signal (length N)
308** with N > n, and let all sums be over i from 0 to n-1.
309**
310** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
311** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
312** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
313**
314** Next, we compute the relative distance between the original signal and
315** the modified signal and minimize that over j:
316** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
317** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
318**
319** In the code variables correspond as follows:
320** cp1 A
321** cp2 R
322** len1 N
323** len2 n
324** aj_m1 A[j-1]
325** aj_lm1 A[j+n-1]
326** sum_ri_2 sum(R[i]^2)
327** sum_aij_2 sum(A[i+j]^2)
328** sum_aij_ri sum(A[i+j]R[i])
329**
330** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
331** is completely recalculated each step.
332*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000333static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000334audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000335{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000336 short *cp1, *cp2;
337 int len1, len2;
338 int j, best_j;
339 double aj_m1, aj_lm1;
340 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000341
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000342 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
343 return 0;
344 if ( len1 & 1 || len2 & 1 ) {
345 PyErr_SetString(AudioopError, "Strings should be even-sized");
346 return 0;
347 }
348 len1 >>= 1;
349 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000350
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000351 if ( len1 < len2 ) {
352 PyErr_SetString(AudioopError, "First sample should be longer");
353 return 0;
354 }
355 sum_ri_2 = _sum2(cp2, cp2, len2);
356 sum_aij_2 = _sum2(cp1, cp1, len2);
357 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000358
359 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
360
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000361 best_result = result;
362 best_j = 0;
363 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000364
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000365 for ( j=1; j<=len1-len2; j++) {
366 aj_m1 = (double)cp1[j-1];
367 aj_lm1 = (double)cp1[j+len2-1];
368
369 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
370 sum_aij_ri = _sum2(cp1+j, cp2, len2);
371
372 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
373 / sum_aij_2;
374
375 if ( result < best_result ) {
376 best_result = result;
377 best_j = j;
378 }
379
380 }
381
382 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000383
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000384 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000385}
386
387/*
388** findfactor finds a factor f so that the energy in A-fB is minimal.
389** See the comment for findfit for details.
390*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000391static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000392audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000393{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000394 short *cp1, *cp2;
395 int len1, len2;
396 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000397
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000398 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
399 return 0;
400 if ( len1 & 1 || len2 & 1 ) {
401 PyErr_SetString(AudioopError, "Strings should be even-sized");
402 return 0;
403 }
404 if ( len1 != len2 ) {
405 PyErr_SetString(AudioopError, "Samples should be same size");
406 return 0;
407 }
408 len2 >>= 1;
409 sum_ri_2 = _sum2(cp2, cp2, len2);
410 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000411
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000412 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000413
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000414 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000415}
416
417/*
418** findmax returns the index of the n-sized segment of the input sample
419** that contains the most energy.
420*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000421static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000422audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000423{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000424 short *cp1;
425 int len1, len2;
426 int j, best_j;
427 double aj_m1, aj_lm1;
428 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000429
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000430 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
431 return 0;
432 if ( len1 & 1 ) {
433 PyErr_SetString(AudioopError, "Strings should be even-sized");
434 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000435 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000436 len1 >>= 1;
437
438 if ( len1 < len2 ) {
439 PyErr_SetString(AudioopError, "Input sample should be longer");
440 return 0;
441 }
Jack Jansena90805f1993-02-17 14:29:28 +0000442
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000443 result = _sum2(cp1, cp1, len2);
444
445 best_result = result;
446 best_j = 0;
447 j = 0;
448
449 for ( j=1; j<=len1-len2; j++) {
450 aj_m1 = (double)cp1[j-1];
451 aj_lm1 = (double)cp1[j+len2-1];
452
453 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
454
455 if ( result > best_result ) {
456 best_result = result;
457 best_j = j;
458 }
459
460 }
461
462 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000463}
464
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000465static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000466audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000467{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000468 signed char *cp;
469 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
470 prevextreme = 0;
471 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000472 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000473 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000474
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000475 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
476 return 0;
477 if ( size != 1 && size != 2 && size != 4 ) {
478 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
479 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000480 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000481 /* Compute first delta value ahead. Also automatically makes us
482 ** skip the first extreme value
483 */
484 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
485 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
486 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
487 if ( size == 1 ) val = (int)*CHARP(cp, size);
488 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
489 else if ( size == 4 ) val = (int)*LONGP(cp, size);
490 prevdiff = val - prevval;
491
492 for ( i=size; i<len; i+= size) {
493 if ( size == 1 ) val = (int)*CHARP(cp, i);
494 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
495 else if ( size == 4 ) val = (int)*LONGP(cp, i);
496 diff = val - prevval;
497 if ( diff*prevdiff < 0 ) {
498 /* Derivative changed sign. Compute difference to last
499 ** extreme value and remember.
500 */
501 if ( prevextremevalid ) {
502 extremediff = prevval - prevextreme;
503 if ( extremediff < 0 )
504 extremediff = -extremediff;
505 avg += extremediff;
506 nextreme++;
507 }
508 prevextremevalid = 1;
509 prevextreme = prevval;
510 }
511 prevval = val;
512 if ( diff != 0 )
513 prevdiff = diff;
514 }
515 if ( nextreme == 0 )
516 val = 0;
517 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000518 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000520}
521
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000522static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000523audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000524{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000525 signed char *cp;
526 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
527 prevextreme = 0;
528 int i;
529 int max = 0;
530 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000531
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000532 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
533 return 0;
534 if ( size != 1 && size != 2 && size != 4 ) {
535 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
536 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000537 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000538 /* Compute first delta value ahead. Also automatically makes us
539 ** skip the first extreme value
540 */
541 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
542 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
543 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
544 if ( size == 1 ) val = (int)*CHARP(cp, size);
545 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
546 else if ( size == 4 ) val = (int)*LONGP(cp, size);
547 prevdiff = val - prevval;
548
549 for ( i=size; i<len; i+= size) {
550 if ( size == 1 ) val = (int)*CHARP(cp, i);
551 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
552 else if ( size == 4 ) val = (int)*LONGP(cp, i);
553 diff = val - prevval;
554 if ( diff*prevdiff < 0 ) {
555 /* Derivative changed sign. Compute difference to
556 ** last extreme value and remember.
557 */
558 if ( prevextremevalid ) {
559 extremediff = prevval - prevextreme;
560 if ( extremediff < 0 )
561 extremediff = -extremediff;
562 if ( extremediff > max )
563 max = extremediff;
564 }
565 prevextremevalid = 1;
566 prevextreme = prevval;
567 }
568 prevval = val;
569 if ( diff != 0 )
570 prevdiff = diff;
571 }
572 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000573}
574
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000575static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000576audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000577{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000578 signed char *cp;
579 int len, size, val = 0;
580 int i;
581 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000582
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000583 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
584 return 0;
585 if ( size != 1 && size != 2 && size != 4 ) {
586 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
587 return 0;
588 }
589 ncross = -1;
590 prevval = 17; /* Anything <> 0,1 */
591 for ( i=0; i<len; i+= size) {
592 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
593 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
594 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
595 val = val & 1;
596 if ( val != prevval ) ncross++;
597 prevval = val;
598 }
599 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000600}
601
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000602static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000603audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000604{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605 signed char *cp, *ncp;
606 int len, size, val = 0;
607 double factor, fval, maxval;
608 PyObject *rv;
609 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000610
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000611 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
612 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000613
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614 if ( size == 1 ) maxval = (double) 0x7f;
615 else if ( size == 2 ) maxval = (double) 0x7fff;
616 else if ( size == 4 ) maxval = (double) 0x7fffffff;
617 else {
618 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
619 return 0;
620 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000621
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000622 rv = PyString_FromStringAndSize(NULL, len);
623 if ( rv == 0 )
624 return 0;
625 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000626
627
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000628 for ( i=0; i < len; i += size ) {
629 if ( size == 1 ) val = (int)*CHARP(cp, i);
630 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
631 else if ( size == 4 ) val = (int)*LONGP(cp, i);
632 fval = (double)val*factor;
633 if ( fval > maxval ) fval = maxval;
634 else if ( fval < -maxval ) fval = -maxval;
635 val = (int)fval;
636 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
637 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000638 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000639 }
640 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000641}
642
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000643static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000644audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000645{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000646 signed char *cp, *ncp;
647 int len, size, val1 = 0, val2 = 0;
648 double fac1, fac2, fval, maxval;
649 PyObject *rv;
650 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000651
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000652 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
653 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000654
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000655 if ( size == 1 ) maxval = (double) 0x7f;
656 else if ( size == 2 ) maxval = (double) 0x7fff;
657 else if ( size == 4 ) maxval = (double) 0x7fffffff;
658 else {
659 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
660 return 0;
661 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000662
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000663 rv = PyString_FromStringAndSize(NULL, len/2);
664 if ( rv == 0 )
665 return 0;
666 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000667
668
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000669 for ( i=0; i < len; i += size*2 ) {
670 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
671 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
672 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
673 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
674 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
675 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
676 fval = (double)val1*fac1 + (double)val2*fac2;
677 if ( fval > maxval ) fval = maxval;
678 else if ( fval < -maxval ) fval = -maxval;
679 val1 = (int)fval;
680 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
681 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000682 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683 }
684 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000685}
686
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000687static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000688audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000689{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000690 signed char *cp, *ncp;
691 int len, size, val1, val2, val = 0;
692 double fac1, fac2, fval, maxval;
693 PyObject *rv;
694 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000695
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000696 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
697 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000698
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000699 if ( size == 1 ) maxval = (double) 0x7f;
700 else if ( size == 2 ) maxval = (double) 0x7fff;
701 else if ( size == 4 ) maxval = (double) 0x7fffffff;
702 else {
703 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
704 return 0;
705 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000706
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000707 rv = PyString_FromStringAndSize(NULL, len*2);
708 if ( rv == 0 )
709 return 0;
710 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000711
712
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000713 for ( i=0; i < len; i += size ) {
714 if ( size == 1 ) val = (int)*CHARP(cp, i);
715 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
716 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000718 fval = (double)val*fac1;
719 if ( fval > maxval ) fval = maxval;
720 else if ( fval < -maxval ) fval = -maxval;
721 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000723 fval = (double)val*fac2;
724 if ( fval > maxval ) fval = maxval;
725 else if ( fval < -maxval ) fval = -maxval;
726 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000727
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000728 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
729 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000730 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000731
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000732 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
733 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000734 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000735 }
736 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000737}
738
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000739static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000740audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000741{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000742 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000743 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000744 PyObject *rv;
745 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000746
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000747 if ( !PyArg_Parse(args, "(s#s#i)",
748 &cp1, &len1, &cp2, &len2, &size ) )
749 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000751 if ( len1 != len2 ) {
752 PyErr_SetString(AudioopError, "Lengths should be the same");
753 return 0;
754 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000755
Guido van Rossum1851a671997-02-14 16:14:03 +0000756 if ( size == 1 ) maxval = 0x7f;
757 else if ( size == 2 ) maxval = 0x7fff;
758 else if ( size == 4 ) maxval = 0x7fffffff;
759 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000760 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
761 return 0;
762 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000763
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000764 rv = PyString_FromStringAndSize(NULL, len1);
765 if ( rv == 0 )
766 return 0;
767 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000768
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000769 for ( i=0; i < len1; i += size ) {
770 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
771 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
772 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000773
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000774 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
775 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
776 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000777
Guido van Rossum1851a671997-02-14 16:14:03 +0000778 newval = val1 + val2;
779 /* truncate in case of overflow */
780 if (newval > maxval) newval = maxval;
781 else if (newval < -maxval) newval = -maxval;
782 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
783 newval = val1 > 0 ? maxval : - maxval;
784
785 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
786 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000787 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000788 }
789 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790}
791
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000793audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000794{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000795 signed char *cp, *ncp;
796 int len, size, val = 0;
797 PyObject *rv;
798 int i;
799 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000800
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000801 if ( !PyArg_Parse(args, "(s#ii)",
802 &cp, &len, &size , &bias) )
803 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000804
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000805 if ( size != 1 && size != 2 && size != 4) {
806 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
807 return 0;
808 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000809
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000810 rv = PyString_FromStringAndSize(NULL, len);
811 if ( rv == 0 )
812 return 0;
813 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000814
815
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000816 for ( i=0; i < len; i += size ) {
817 if ( size == 1 ) val = (int)*CHARP(cp, i);
818 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
819 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000820
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000821 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
822 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000823 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000824 }
825 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000826}
827
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000828static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000829audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000830{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000831 signed char *cp;
832 unsigned char *ncp;
833 int len, size, val = 0;
834 PyObject *rv;
835 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000836
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000837 if ( !PyArg_Parse(args, "(s#i)",
838 &cp, &len, &size) )
839 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000840
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000841 if ( size != 1 && size != 2 && size != 4 ) {
842 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
843 return 0;
844 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000845
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000846 rv = PyString_FromStringAndSize(NULL, len);
847 if ( rv == 0 )
848 return 0;
849 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000850
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000851 for ( i=0; i < len; i += size ) {
852 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
853 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
854 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000855
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000856 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000857
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000858 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
859 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000860 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000861 }
862 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000863}
864
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000865static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000866audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000867{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000868 signed char *cp;
869 unsigned char *ncp;
870 int len, size, size2, val = 0;
871 PyObject *rv;
872 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000873
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000874 if ( !PyArg_Parse(args, "(s#ii)",
875 &cp, &len, &size, &size2) )
876 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000877
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000878 if ( (size != 1 && size != 2 && size != 4) ||
879 (size2 != 1 && size2 != 2 && size2 != 4)) {
880 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
881 return 0;
882 }
Jack Jansena90805f1993-02-17 14:29:28 +0000883
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000884 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
885 if ( rv == 0 )
886 return 0;
887 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000888
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000889 for ( i=0, j=0; i < len; i += size, j += size2 ) {
890 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
891 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
892 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000893
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000894 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
895 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000896 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000897 }
898 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000899}
900
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000901static int
902gcd(a, b)
903 int a, b;
904{
905 while (b > 0) {
906 int tmp = a % b;
907 a = b;
908 b = tmp;
909 }
910 return a;
911}
912
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000913static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000914audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +0000915{
Guido van Rossum1851a671997-02-14 16:14:03 +0000916 char *cp, *ncp;
917 int len, size, nchannels, inrate, outrate, weightA, weightB;
918 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000919 PyObject *state, *samps, *str, *rv = NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +0000920
921 weightA = 1;
922 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000923 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000924 &inrate, &outrate, &state, &weightA, &weightB))
925 return NULL;
926 if (size != 1 && size != 2 && size != 4) {
927 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
928 return NULL;
929 }
930 if (nchannels < 1) {
931 PyErr_SetString(AudioopError, "# of channels should be >= 1");
932 return NULL;
933 }
934 if (weightA < 1 || weightB < 0) {
935 PyErr_SetString(AudioopError,
936 "weightA should be >= 1, weightB should be >= 0");
937 return NULL;
938 }
939 if (len % (size * nchannels) != 0) {
940 PyErr_SetString(AudioopError, "not a whole number of frames");
941 return NULL;
942 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000943 if (inrate <= 0 || outrate <= 0) {
944 PyErr_SetString(AudioopError, "sampling rate not > 0");
945 return NULL;
946 }
947 /* divide inrate and outrate by their greatest common divisor */
948 d = gcd(inrate, outrate);
949 inrate /= d;
950 outrate /= d;
951
Guido van Rossum6345ac61997-10-31 20:32:13 +0000952 prev_i = (int *) malloc(nchannels * sizeof(int));
953 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +0000954 len /= size * nchannels; /* # of frames */
Guido van Rossum65bb3281999-09-07 14:24:05 +0000955 if (prev_i == NULL || cur_i == NULL) {
956 (void) PyErr_NoMemory();
957 goto exit;
958 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000959
960 if (state == Py_None) {
961 d = -outrate;
962 for (chan = 0; chan < nchannels; chan++)
963 prev_i[chan] = cur_i[chan] = 0;
964 } else {
965 if (!PyArg_ParseTuple(state,
966 "iO!;audioop.ratecv: illegal state argument",
967 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000968 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000969 if (PyTuple_Size(samps) != nchannels) {
970 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000971 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +0000972 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000973 }
974 for (chan = 0; chan < nchannels; chan++) {
975 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +0000976 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000977 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000978 }
979 }
980 str = PyString_FromStringAndSize(
981 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
982 if (str == NULL)
Guido van Rossum65bb3281999-09-07 14:24:05 +0000983 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000984 ncp = PyString_AsString(str);
985
986 for (;;) {
987 while (d < 0) {
988 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +0000989 samps = PyTuple_New(nchannels);
990 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +0000991 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +0000992 Py_BuildValue("(ii)",
993 prev_i[chan],
994 cur_i[chan]));
995 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +0000996 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +0000997 len = ncp - PyString_AsString(str);
998 if (len == 0) {
999 /*don't want to resize to zero length*/
1000 rv = PyString_FromStringAndSize("", 0);
1001 Py_DECREF(str);
1002 str = rv;
1003 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001004 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001005 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001006 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001007 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001008 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001009 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001010 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001011 prev_i[chan] = cur_i[chan];
1012 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001013 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001014 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001015 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001016 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001017 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001018 cp += size;
1019 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001020 cur_i[chan] =
1021 (weightA * cur_i[chan] +
1022 weightB * prev_i[chan]) /
1023 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001024 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001025 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001026 d += outrate;
1027 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001028 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001029 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001030 cur_o = (prev_i[chan] * d +
1031 cur_i[chan] * (outrate - d)) /
1032 outrate;
1033 if (size == 1)
1034 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001035 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001036 *SHORTP(ncp, 0) = (short)(cur_o);
1037 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001038 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001039 ncp += size;
1040 }
1041 d -= inrate;
1042 }
1043 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001044 exit:
1045 if (prev_i != NULL)
1046 free(prev_i);
1047 if (cur_i != NULL)
1048 free(cur_i);
1049 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001050}
Guido van Rossum1851a671997-02-14 16:14:03 +00001051
Roger E. Massec905fff1997-01-17 18:12:04 +00001052static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001053audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001054{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001055 signed char *cp;
1056 unsigned char *ncp;
1057 int len, size, val = 0;
1058 PyObject *rv;
1059 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001060
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001061 if ( !PyArg_Parse(args, "(s#i)",
1062 &cp, &len, &size) )
1063 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001064
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001065 if ( size != 1 && size != 2 && size != 4) {
1066 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1067 return 0;
1068 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001069
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001070 rv = PyString_FromStringAndSize(NULL, len/size);
1071 if ( rv == 0 )
1072 return 0;
1073 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001074
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001075 for ( i=0; i < len; i += size ) {
1076 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1077 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1078 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001079
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001080 *ncp++ = st_linear_to_ulaw(val);
1081 }
1082 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001083}
1084
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001085static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001086audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001087{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001088 unsigned char *cp;
1089 unsigned char cval;
1090 signed char *ncp;
1091 int len, size, val;
1092 PyObject *rv;
1093 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001094
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001095 if ( !PyArg_Parse(args, "(s#i)",
1096 &cp, &len, &size) )
1097 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001098
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001099 if ( size != 1 && size != 2 && size != 4) {
1100 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1101 return 0;
1102 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001103
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001104 rv = PyString_FromStringAndSize(NULL, len*size);
1105 if ( rv == 0 )
1106 return 0;
1107 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001108
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001109 for ( i=0; i < len*size; i += size ) {
1110 cval = *cp++;
1111 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001112
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001113 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1114 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001115 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116 }
1117 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001118}
1119
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001120static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001121audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001122{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001123 signed char *cp;
1124 signed char *ncp;
1125 int len, size, val = 0, step, valpred, delta,
1126 index, sign, vpdiff, diff;
1127 PyObject *rv, *state, *str;
1128 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001129
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001130 if ( !PyArg_Parse(args, "(s#iO)",
1131 &cp, &len, &size, &state) )
1132 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001133
1134
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001135 if ( size != 1 && size != 2 && size != 4) {
1136 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1137 return 0;
1138 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001139
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001140 str = PyString_FromStringAndSize(NULL, len/(size*2));
1141 if ( str == 0 )
1142 return 0;
1143 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001144
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001145 /* Decode state, should have (value, step) */
1146 if ( state == Py_None ) {
1147 /* First time, it seems. Set defaults */
1148 valpred = 0;
1149 step = 7;
1150 index = 0;
1151 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1152 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001153
Guido van Rossumb64e6351992-07-06 14:21:56 +00001154 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001155 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001156
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001157 for ( i=0; i < len; i += size ) {
1158 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1159 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1160 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1161
1162 /* Step 1 - compute difference with previous value */
1163 diff = val - valpred;
1164 sign = (diff < 0) ? 8 : 0;
1165 if ( sign ) diff = (-diff);
1166
1167 /* Step 2 - Divide and clamp */
1168 /* Note:
1169 ** This code *approximately* computes:
1170 ** delta = diff*4/step;
1171 ** vpdiff = (delta+0.5)*step/4;
1172 ** but in shift step bits are dropped. The net result of this
1173 ** is that even if you have fast mul/div hardware you cannot
1174 ** put it to good use since the fixup would be too expensive.
1175 */
1176 delta = 0;
1177 vpdiff = (step >> 3);
1178
1179 if ( diff >= step ) {
1180 delta = 4;
1181 diff -= step;
1182 vpdiff += step;
1183 }
1184 step >>= 1;
1185 if ( diff >= step ) {
1186 delta |= 2;
1187 diff -= step;
1188 vpdiff += step;
1189 }
1190 step >>= 1;
1191 if ( diff >= step ) {
1192 delta |= 1;
1193 vpdiff += step;
1194 }
1195
1196 /* Step 3 - Update previous value */
1197 if ( sign )
1198 valpred -= vpdiff;
1199 else
1200 valpred += vpdiff;
1201
1202 /* Step 4 - Clamp previous value to 16 bits */
1203 if ( valpred > 32767 )
1204 valpred = 32767;
1205 else if ( valpred < -32768 )
1206 valpred = -32768;
1207
1208 /* Step 5 - Assemble value, update index and step values */
1209 delta |= sign;
1210
1211 index += indexTable[delta];
1212 if ( index < 0 ) index = 0;
1213 if ( index > 88 ) index = 88;
1214 step = stepsizeTable[index];
1215
1216 /* Step 6 - Output value */
1217 if ( bufferstep ) {
1218 outputbuffer = (delta << 4) & 0xf0;
1219 } else {
1220 *ncp++ = (delta & 0x0f) | outputbuffer;
1221 }
1222 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001223 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001224 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1225 Py_DECREF(str);
1226 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001227}
1228
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001229static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001230audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001231{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001232 signed char *cp;
1233 signed char *ncp;
1234 int len, size, valpred, step, delta, index, sign, vpdiff;
1235 PyObject *rv, *str, *state;
1236 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001237
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001238 if ( !PyArg_Parse(args, "(s#iO)",
1239 &cp, &len, &size, &state) )
1240 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001241
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001242 if ( size != 1 && size != 2 && size != 4) {
1243 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1244 return 0;
1245 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001246
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001247 /* Decode state, should have (value, step) */
1248 if ( state == Py_None ) {
1249 /* First time, it seems. Set defaults */
1250 valpred = 0;
1251 step = 7;
1252 index = 0;
1253 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1254 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001255
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001256 str = PyString_FromStringAndSize(NULL, len*size*2);
1257 if ( str == 0 )
1258 return 0;
1259 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001260
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001261 step = stepsizeTable[index];
1262 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001263
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001264 for ( i=0; i < len*size*2; i += size ) {
1265 /* Step 1 - get the delta value and compute next index */
1266 if ( bufferstep ) {
1267 delta = inputbuffer & 0xf;
1268 } else {
1269 inputbuffer = *cp++;
1270 delta = (inputbuffer >> 4) & 0xf;
1271 }
1272
1273 bufferstep = !bufferstep;
1274
1275 /* Step 2 - Find new index value (for later) */
1276 index += indexTable[delta];
1277 if ( index < 0 ) index = 0;
1278 if ( index > 88 ) index = 88;
1279
1280 /* Step 3 - Separate sign and magnitude */
1281 sign = delta & 8;
1282 delta = delta & 7;
1283
1284 /* Step 4 - Compute difference and new predicted value */
1285 /*
1286 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1287 ** in adpcm_coder.
1288 */
1289 vpdiff = step >> 3;
1290 if ( delta & 4 ) vpdiff += step;
1291 if ( delta & 2 ) vpdiff += step>>1;
1292 if ( delta & 1 ) vpdiff += step>>2;
1293
1294 if ( sign )
1295 valpred -= vpdiff;
1296 else
1297 valpred += vpdiff;
1298
1299 /* Step 5 - clamp output value */
1300 if ( valpred > 32767 )
1301 valpred = 32767;
1302 else if ( valpred < -32768 )
1303 valpred = -32768;
1304
1305 /* Step 6 - Update step value */
1306 step = stepsizeTable[index];
1307
1308 /* Step 6 - Output value */
1309 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1310 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001311 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001312 }
1313
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001314 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1315 Py_DECREF(str);
1316 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001317}
1318
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001319static PyMethodDef audioop_methods[] = {
1320 { "max", audioop_max },
1321 { "minmax", audioop_minmax },
1322 { "avg", audioop_avg },
1323 { "maxpp", audioop_maxpp },
1324 { "avgpp", audioop_avgpp },
1325 { "rms", audioop_rms },
1326 { "findfit", audioop_findfit },
1327 { "findmax", audioop_findmax },
1328 { "findfactor", audioop_findfactor },
1329 { "cross", audioop_cross },
1330 { "mul", audioop_mul },
1331 { "add", audioop_add },
1332 { "bias", audioop_bias },
1333 { "ulaw2lin", audioop_ulaw2lin },
1334 { "lin2ulaw", audioop_lin2ulaw },
1335 { "lin2lin", audioop_lin2lin },
1336 { "adpcm2lin", audioop_adpcm2lin },
1337 { "lin2adpcm", audioop_lin2adpcm },
1338 { "tomono", audioop_tomono },
1339 { "tostereo", audioop_tostereo },
1340 { "getsample", audioop_getsample },
1341 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001342 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001343 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001344};
1345
Guido van Rossum3886bb61998-12-04 18:50:17 +00001346DL_EXPORT(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001347initaudioop()
1348{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001349 PyObject *m, *d;
1350 m = Py_InitModule("audioop", audioop_methods);
1351 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001352 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1353 if (AudioopError != NULL)
1354 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001355}