blob: d12642afb08a8c63df853cc0bd5001535fcb984c [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001
Guido van Rossumb6775db1994-08-01 11:34:53 +00002/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +00003
Roger E. Masseeaa6e111997-01-03 19:26:27 +00004#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +00005
Guido van Rossum69011961998-04-23 20:23:00 +00006#if SIZEOF_INT == 4
7typedef int Py_Int32;
8typedef unsigned int Py_UInt32;
9#else
10#if SIZEOF_LONG == 4
11typedef long Py_Int32;
12typedef unsigned long Py_UInt32;
13#else
14#error "No 4-byte integral type"
15#endif
16#endif
17
Guido van Rossum7b1e9741994-08-29 10:46:42 +000018#if defined(__CHAR_UNSIGNED__)
19#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000020/* This module currently does not work on systems where only unsigned
21 characters are available. Take it out of Setup. Sorry. */
22#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000023#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000024
Jack Jansena90805f1993-02-17 14:29:28 +000025/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000026** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
27
28#define MINLIN -32768
29#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000030#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
31 else if ( x > MAXLIN ) x = MAXLIN; \
32 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000033
Fred Drakec818d532000-08-31 05:07:19 +000034static unsigned char st_linear_to_ulaw(int sample);
Guido van Rossumb66efa01992-06-01 16:01:24 +000035
36/*
37** This macro converts from ulaw to 16 bit linear, faster.
38**
39** Jef Poskanzer
40** 23 October 1989
41**
42** Input: 8 bit ulaw sample
43** Output: signed 16 bit linear sample
44*/
45#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
46
47static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000048 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
49 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
50 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
51 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
52 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
53 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
54 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
55 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
56 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
57 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
58 -876, -844, -812, -780, -748, -716, -684, -652,
59 -620, -588, -556, -524, -492, -460, -428, -396,
60 -372, -356, -340, -324, -308, -292, -276, -260,
61 -244, -228, -212, -196, -180, -164, -148, -132,
62 -120, -112, -104, -96, -88, -80, -72, -64,
63 -56, -48, -40, -32, -24, -16, -8, 0,
64 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
65 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
66 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
67 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
68 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
69 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
70 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
71 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
72 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
73 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
74 876, 844, 812, 780, 748, 716, 684, 652,
75 620, 588, 556, 524, 492, 460, 428, 396,
76 372, 356, 340, 324, 308, 292, 276, 260,
77 244, 228, 212, 196, 180, 164, 148, 132,
78 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000079 56, 48, 40, 32, 24, 16, 8, 0 };
80
Moshe Zadka6a078ed2000-08-04 15:53:06 +000081/* #define ZEROTRAP */ /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +000082#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
83#define CLIP 32635
84
Guido van Rossumcd938fc1995-01-17 16:13:48 +000085static unsigned char
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000086st_linear_to_ulaw(int sample)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000087{
88 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
89 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
90 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
91 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
92 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
93 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
94 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
95 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
96 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
97 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
98 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
99 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
100 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
101 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
102 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
103 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
104 int sign, exponent, mantissa;
105 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000106
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000107 /* Get the sample into sign-magnitude. */
108 sign = (sample >> 8) & 0x80; /* set aside the sign */
109 if ( sign != 0 ) sample = -sample; /* get magnitude */
110 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000111
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000112 /* Convert from 16 bit linear to ulaw. */
113 sample = sample + BIAS;
114 exponent = exp_lut[( sample >> 7 ) & 0xFF];
115 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
116 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000117#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000118 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000119#endif
120
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000121 return ulawbyte;
122}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000123/* End of code taken from sox */
124
Guido van Rossumb64e6351992-07-06 14:21:56 +0000125/* Intel ADPCM step variation table */
126static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000127 -1, -1, -1, -1, 2, 4, 6, 8,
128 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000129};
130
131static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000132 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
133 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
134 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
135 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
136 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
137 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
138 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
139 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
140 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000141};
142
Guido van Rossumb66efa01992-06-01 16:01:24 +0000143#define CHARP(cp, i) ((signed char *)(cp+i))
144#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000145#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000146
147
148
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000149static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000150
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000151static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000152audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000153{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000154 signed char *cp;
155 int len, size, val = 0;
156 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000157
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000158 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
159 return 0;
160 if ( size != 1 && size != 2 && size != 4 ) {
161 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
162 return 0;
163 }
164 if ( i < 0 || i >= len/size ) {
165 PyErr_SetString(AudioopError, "Index out of range");
166 return 0;
167 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000168 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000169 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
170 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
171 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000172}
173
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000174static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000175audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000176{
177 signed char *cp;
178 int len, size, val = 0;
179 int i;
180 int max = 0;
181
182 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
183 return 0;
184 if ( size != 1 && size != 2 && size != 4 ) {
185 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
186 return 0;
187 }
188 for ( i=0; i<len; i+= size) {
189 if ( size == 1 ) val = (int)*CHARP(cp, i);
190 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
191 else if ( size == 4 ) val = (int)*LONGP(cp, i);
192 if ( val < 0 ) val = (-val);
193 if ( val > max ) max = val;
194 }
195 return PyInt_FromLong(max);
196}
197
198static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000199audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000200{
201 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000202 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000203 int i;
204 int min = 0x7fffffff, max = -0x7fffffff;
205
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000206 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000207 return NULL;
208 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000209 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000210 return NULL;
211 }
212 for (i = 0; i < len; i += size) {
213 if (size == 1) val = (int) *CHARP(cp, i);
214 else if (size == 2) val = (int) *SHORTP(cp, i);
215 else if (size == 4) val = (int) *LONGP(cp, i);
216 if (val > max) max = val;
217 if (val < min) min = val;
218 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000219 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000220}
221
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000222static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000223audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000224{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000225 signed char *cp;
226 int len, size, val = 0;
227 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000228 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000229
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000230 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
231 return 0;
232 if ( size != 1 && size != 2 && size != 4 ) {
233 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
234 return 0;
235 }
236 for ( i=0; i<len; i+= size) {
237 if ( size == 1 ) val = (int)*CHARP(cp, i);
238 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
239 else if ( size == 4 ) val = (int)*LONGP(cp, i);
240 avg += val;
241 }
242 if ( len == 0 )
243 val = 0;
244 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000245 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000246 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000247}
248
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000249static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000250audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000251{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000252 signed char *cp;
253 int len, size, val = 0;
254 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000255 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000256
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000257 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
258 return 0;
259 if ( size != 1 && size != 2 && size != 4 ) {
260 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
261 return 0;
262 }
263 for ( i=0; i<len; i+= size) {
264 if ( size == 1 ) val = (int)*CHARP(cp, i);
265 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
266 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000267 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000268 }
269 if ( len == 0 )
270 val = 0;
271 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000272 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000273 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000274}
275
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000276static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000277{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000278 int i;
279 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000280
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000281 for( i=0; i<len; i++) {
282 sum = sum + (double)a[i]*(double)b[i];
283 }
284 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000285}
286
287/*
288** Findfit tries to locate a sample within another sample. Its main use
289** is in echo-cancellation (to find the feedback of the output signal in
290** the input signal).
291** The method used is as follows:
292**
293** let R be the reference signal (length n) and A the input signal (length N)
294** with N > n, and let all sums be over i from 0 to n-1.
295**
296** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
297** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
298** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
299**
300** Next, we compute the relative distance between the original signal and
301** the modified signal and minimize that over j:
302** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
303** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
304**
305** In the code variables correspond as follows:
306** cp1 A
307** cp2 R
308** len1 N
309** len2 n
310** aj_m1 A[j-1]
311** aj_lm1 A[j+n-1]
312** sum_ri_2 sum(R[i]^2)
313** sum_aij_2 sum(A[i+j]^2)
314** sum_aij_ri sum(A[i+j]R[i])
315**
316** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
317** is completely recalculated each step.
318*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000319static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000320audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000321{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000322 short *cp1, *cp2;
323 int len1, len2;
324 int j, best_j;
325 double aj_m1, aj_lm1;
326 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000327
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
329 return 0;
330 if ( len1 & 1 || len2 & 1 ) {
331 PyErr_SetString(AudioopError, "Strings should be even-sized");
332 return 0;
333 }
334 len1 >>= 1;
335 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000336
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000337 if ( len1 < len2 ) {
338 PyErr_SetString(AudioopError, "First sample should be longer");
339 return 0;
340 }
341 sum_ri_2 = _sum2(cp2, cp2, len2);
342 sum_aij_2 = _sum2(cp1, cp1, len2);
343 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000344
345 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
346
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000347 best_result = result;
348 best_j = 0;
349 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000350
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000351 for ( j=1; j<=len1-len2; j++) {
352 aj_m1 = (double)cp1[j-1];
353 aj_lm1 = (double)cp1[j+len2-1];
354
355 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
356 sum_aij_ri = _sum2(cp1+j, cp2, len2);
357
358 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
359 / sum_aij_2;
360
361 if ( result < best_result ) {
362 best_result = result;
363 best_j = j;
364 }
365
366 }
367
368 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000369
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000370 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000371}
372
373/*
374** findfactor finds a factor f so that the energy in A-fB is minimal.
375** See the comment for findfit for details.
376*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000377static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000378audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000379{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000380 short *cp1, *cp2;
381 int len1, len2;
382 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000383
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000384 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
385 return 0;
386 if ( len1 & 1 || len2 & 1 ) {
387 PyErr_SetString(AudioopError, "Strings should be even-sized");
388 return 0;
389 }
390 if ( len1 != len2 ) {
391 PyErr_SetString(AudioopError, "Samples should be same size");
392 return 0;
393 }
394 len2 >>= 1;
395 sum_ri_2 = _sum2(cp2, cp2, len2);
396 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000397
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000398 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000399
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000400 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000401}
402
403/*
404** findmax returns the index of the n-sized segment of the input sample
405** that contains the most energy.
406*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000408audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000409{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000410 short *cp1;
411 int len1, len2;
412 int j, best_j;
413 double aj_m1, aj_lm1;
414 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000415
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
417 return 0;
418 if ( len1 & 1 ) {
419 PyErr_SetString(AudioopError, "Strings should be even-sized");
420 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000421 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000422 len1 >>= 1;
423
424 if ( len1 < len2 ) {
425 PyErr_SetString(AudioopError, "Input sample should be longer");
426 return 0;
427 }
Jack Jansena90805f1993-02-17 14:29:28 +0000428
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000429 result = _sum2(cp1, cp1, len2);
430
431 best_result = result;
432 best_j = 0;
433 j = 0;
434
435 for ( j=1; j<=len1-len2; j++) {
436 aj_m1 = (double)cp1[j-1];
437 aj_lm1 = (double)cp1[j+len2-1];
438
439 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
440
441 if ( result > best_result ) {
442 best_result = result;
443 best_j = j;
444 }
445
446 }
447
448 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000449}
450
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000451static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000452audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000453{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000454 signed char *cp;
455 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
456 prevextreme = 0;
457 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000458 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000459 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000460
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000461 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
462 return 0;
463 if ( size != 1 && size != 2 && size != 4 ) {
464 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
465 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000466 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000467 /* Compute first delta value ahead. Also automatically makes us
468 ** skip the first extreme value
469 */
470 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
471 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
472 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
473 if ( size == 1 ) val = (int)*CHARP(cp, size);
474 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
475 else if ( size == 4 ) val = (int)*LONGP(cp, size);
476 prevdiff = val - prevval;
477
478 for ( i=size; i<len; i+= size) {
479 if ( size == 1 ) val = (int)*CHARP(cp, i);
480 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
481 else if ( size == 4 ) val = (int)*LONGP(cp, i);
482 diff = val - prevval;
483 if ( diff*prevdiff < 0 ) {
484 /* Derivative changed sign. Compute difference to last
485 ** extreme value and remember.
486 */
487 if ( prevextremevalid ) {
488 extremediff = prevval - prevextreme;
489 if ( extremediff < 0 )
490 extremediff = -extremediff;
491 avg += extremediff;
492 nextreme++;
493 }
494 prevextremevalid = 1;
495 prevextreme = prevval;
496 }
497 prevval = val;
498 if ( diff != 0 )
499 prevdiff = diff;
500 }
501 if ( nextreme == 0 )
502 val = 0;
503 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000504 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000505 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000506}
507
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000508static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000509audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000510{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000511 signed char *cp;
512 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
513 prevextreme = 0;
514 int i;
515 int max = 0;
516 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000517
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000518 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
519 return 0;
520 if ( size != 1 && size != 2 && size != 4 ) {
521 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
522 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000523 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000524 /* Compute first delta value ahead. Also automatically makes us
525 ** skip the first extreme value
526 */
527 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
528 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
529 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
530 if ( size == 1 ) val = (int)*CHARP(cp, size);
531 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
532 else if ( size == 4 ) val = (int)*LONGP(cp, size);
533 prevdiff = val - prevval;
534
535 for ( i=size; i<len; i+= size) {
536 if ( size == 1 ) val = (int)*CHARP(cp, i);
537 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
538 else if ( size == 4 ) val = (int)*LONGP(cp, i);
539 diff = val - prevval;
540 if ( diff*prevdiff < 0 ) {
541 /* Derivative changed sign. Compute difference to
542 ** last extreme value and remember.
543 */
544 if ( prevextremevalid ) {
545 extremediff = prevval - prevextreme;
546 if ( extremediff < 0 )
547 extremediff = -extremediff;
548 if ( extremediff > max )
549 max = extremediff;
550 }
551 prevextremevalid = 1;
552 prevextreme = prevval;
553 }
554 prevval = val;
555 if ( diff != 0 )
556 prevdiff = diff;
557 }
558 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000559}
560
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000561static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000562audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000563{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000564 signed char *cp;
565 int len, size, val = 0;
566 int i;
567 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000568
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000569 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
570 return 0;
571 if ( size != 1 && size != 2 && size != 4 ) {
572 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
573 return 0;
574 }
575 ncross = -1;
576 prevval = 17; /* Anything <> 0,1 */
577 for ( i=0; i<len; i+= size) {
578 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
579 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
580 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
581 val = val & 1;
582 if ( val != prevval ) ncross++;
583 prevval = val;
584 }
585 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000586}
587
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000588static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000589audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000590{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000591 signed char *cp, *ncp;
592 int len, size, val = 0;
593 double factor, fval, maxval;
594 PyObject *rv;
595 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000596
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000597 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
598 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000599
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000600 if ( size == 1 ) maxval = (double) 0x7f;
601 else if ( size == 2 ) maxval = (double) 0x7fff;
602 else if ( size == 4 ) maxval = (double) 0x7fffffff;
603 else {
604 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
605 return 0;
606 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000607
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000608 rv = PyString_FromStringAndSize(NULL, len);
609 if ( rv == 0 )
610 return 0;
611 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000612
613
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000614 for ( i=0; i < len; i += size ) {
615 if ( size == 1 ) val = (int)*CHARP(cp, i);
616 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
617 else if ( size == 4 ) val = (int)*LONGP(cp, i);
618 fval = (double)val*factor;
619 if ( fval > maxval ) fval = maxval;
620 else if ( fval < -maxval ) fval = -maxval;
621 val = (int)fval;
622 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
623 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000624 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000625 }
626 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000627}
628
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000629static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000630audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000631{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000632 signed char *cp, *ncp;
633 int len, size, val1 = 0, val2 = 0;
634 double fac1, fac2, fval, maxval;
635 PyObject *rv;
636 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000637
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000638 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
639 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000640
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000641 if ( size == 1 ) maxval = (double) 0x7f;
642 else if ( size == 2 ) maxval = (double) 0x7fff;
643 else if ( size == 4 ) maxval = (double) 0x7fffffff;
644 else {
645 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
646 return 0;
647 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000648
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649 rv = PyString_FromStringAndSize(NULL, len/2);
650 if ( rv == 0 )
651 return 0;
652 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000653
654
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000655 for ( i=0; i < len; i += size*2 ) {
656 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
657 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
658 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
659 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
660 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
661 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
662 fval = (double)val1*fac1 + (double)val2*fac2;
663 if ( fval > maxval ) fval = maxval;
664 else if ( fval < -maxval ) fval = -maxval;
665 val1 = (int)fval;
666 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
667 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000668 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000669 }
670 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000671}
672
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000673static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000674audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000675{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000676 signed char *cp, *ncp;
677 int len, size, val1, val2, val = 0;
678 double fac1, fac2, fval, maxval;
679 PyObject *rv;
680 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000681
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000682 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
683 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000684
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000685 if ( size == 1 ) maxval = (double) 0x7f;
686 else if ( size == 2 ) maxval = (double) 0x7fff;
687 else if ( size == 4 ) maxval = (double) 0x7fffffff;
688 else {
689 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
690 return 0;
691 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000692
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000693 rv = PyString_FromStringAndSize(NULL, len*2);
694 if ( rv == 0 )
695 return 0;
696 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000697
698
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000699 for ( i=0; i < len; i += size ) {
700 if ( size == 1 ) val = (int)*CHARP(cp, i);
701 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
702 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000703
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000704 fval = (double)val*fac1;
705 if ( fval > maxval ) fval = maxval;
706 else if ( fval < -maxval ) fval = -maxval;
707 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000708
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000709 fval = (double)val*fac2;
710 if ( fval > maxval ) fval = maxval;
711 else if ( fval < -maxval ) fval = -maxval;
712 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000713
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000714 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
715 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000716 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000717
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000718 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
719 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000720 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000721 }
722 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000723}
724
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000725static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000726audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000727{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000728 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000729 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000730 PyObject *rv;
731 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000732
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000733 if ( !PyArg_Parse(args, "(s#s#i)",
734 &cp1, &len1, &cp2, &len2, &size ) )
735 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000736
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000737 if ( len1 != len2 ) {
738 PyErr_SetString(AudioopError, "Lengths should be the same");
739 return 0;
740 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000741
Guido van Rossum1851a671997-02-14 16:14:03 +0000742 if ( size == 1 ) maxval = 0x7f;
743 else if ( size == 2 ) maxval = 0x7fff;
744 else if ( size == 4 ) maxval = 0x7fffffff;
745 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000746 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
747 return 0;
748 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000749
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000750 rv = PyString_FromStringAndSize(NULL, len1);
751 if ( rv == 0 )
752 return 0;
753 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000754
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000755 for ( i=0; i < len1; i += size ) {
756 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
757 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
758 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000759
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000760 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
761 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
762 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000763
Guido van Rossum1851a671997-02-14 16:14:03 +0000764 newval = val1 + val2;
765 /* truncate in case of overflow */
766 if (newval > maxval) newval = maxval;
767 else if (newval < -maxval) newval = -maxval;
768 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
769 newval = val1 > 0 ? maxval : - maxval;
770
771 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
772 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000773 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000774 }
775 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000776}
777
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000778static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000779audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000780{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000781 signed char *cp, *ncp;
782 int len, size, val = 0;
783 PyObject *rv;
784 int i;
785 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000786
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000787 if ( !PyArg_Parse(args, "(s#ii)",
788 &cp, &len, &size , &bias) )
789 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000790
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000791 if ( size != 1 && size != 2 && size != 4) {
792 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
793 return 0;
794 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000795
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000796 rv = PyString_FromStringAndSize(NULL, len);
797 if ( rv == 0 )
798 return 0;
799 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000800
801
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000802 for ( i=0; i < len; i += size ) {
803 if ( size == 1 ) val = (int)*CHARP(cp, i);
804 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
805 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000806
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000807 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
808 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000809 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000810 }
811 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000812}
813
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000814static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000815audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000816{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000817 signed char *cp;
818 unsigned char *ncp;
819 int len, size, val = 0;
820 PyObject *rv;
821 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000822
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000823 if ( !PyArg_Parse(args, "(s#i)",
824 &cp, &len, &size) )
825 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000826
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000827 if ( size != 1 && size != 2 && size != 4 ) {
828 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
829 return 0;
830 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000831
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000832 rv = PyString_FromStringAndSize(NULL, len);
833 if ( rv == 0 )
834 return 0;
835 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000836
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000837 for ( i=0; i < len; i += size ) {
838 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
839 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
840 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000841
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000842 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000843
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000844 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
845 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000846 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000847 }
848 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000849}
850
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000851static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000852audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000853{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000854 signed char *cp;
855 unsigned char *ncp;
856 int len, size, size2, val = 0;
857 PyObject *rv;
858 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000859
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000860 if ( !PyArg_Parse(args, "(s#ii)",
861 &cp, &len, &size, &size2) )
862 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000863
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 if ( (size != 1 && size != 2 && size != 4) ||
865 (size2 != 1 && size2 != 2 && size2 != 4)) {
866 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
867 return 0;
868 }
Jack Jansena90805f1993-02-17 14:29:28 +0000869
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000870 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
871 if ( rv == 0 )
872 return 0;
873 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000874
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000875 for ( i=0, j=0; i < len; i += size, j += size2 ) {
876 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
877 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
878 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000879
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000880 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
881 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000882 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000883 }
884 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000885}
886
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000887static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000888gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000889{
890 while (b > 0) {
891 int tmp = a % b;
892 a = b;
893 b = tmp;
894 }
895 return a;
896}
897
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000898static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000899audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +0000900{
Guido van Rossum1851a671997-02-14 16:14:03 +0000901 char *cp, *ncp;
902 int len, size, nchannels, inrate, outrate, weightA, weightB;
903 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000904 PyObject *state, *samps, *str, *rv = NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +0000905
906 weightA = 1;
907 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000908 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000909 &inrate, &outrate, &state, &weightA, &weightB))
910 return NULL;
911 if (size != 1 && size != 2 && size != 4) {
912 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
913 return NULL;
914 }
915 if (nchannels < 1) {
916 PyErr_SetString(AudioopError, "# of channels should be >= 1");
917 return NULL;
918 }
919 if (weightA < 1 || weightB < 0) {
920 PyErr_SetString(AudioopError,
921 "weightA should be >= 1, weightB should be >= 0");
922 return NULL;
923 }
924 if (len % (size * nchannels) != 0) {
925 PyErr_SetString(AudioopError, "not a whole number of frames");
926 return NULL;
927 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000928 if (inrate <= 0 || outrate <= 0) {
929 PyErr_SetString(AudioopError, "sampling rate not > 0");
930 return NULL;
931 }
932 /* divide inrate and outrate by their greatest common divisor */
933 d = gcd(inrate, outrate);
934 inrate /= d;
935 outrate /= d;
936
Guido van Rossum6345ac61997-10-31 20:32:13 +0000937 prev_i = (int *) malloc(nchannels * sizeof(int));
938 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +0000939 len /= size * nchannels; /* # of frames */
Guido van Rossum65bb3281999-09-07 14:24:05 +0000940 if (prev_i == NULL || cur_i == NULL) {
941 (void) PyErr_NoMemory();
942 goto exit;
943 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000944
945 if (state == Py_None) {
946 d = -outrate;
947 for (chan = 0; chan < nchannels; chan++)
948 prev_i[chan] = cur_i[chan] = 0;
949 } else {
950 if (!PyArg_ParseTuple(state,
951 "iO!;audioop.ratecv: illegal state argument",
952 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000953 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000954 if (PyTuple_Size(samps) != nchannels) {
955 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000956 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +0000957 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000958 }
959 for (chan = 0; chan < nchannels; chan++) {
960 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +0000961 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000962 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000963 }
964 }
965 str = PyString_FromStringAndSize(
966 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
967 if (str == NULL)
Guido van Rossum65bb3281999-09-07 14:24:05 +0000968 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000969 ncp = PyString_AsString(str);
970
971 for (;;) {
972 while (d < 0) {
973 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +0000974 samps = PyTuple_New(nchannels);
975 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +0000976 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +0000977 Py_BuildValue("(ii)",
978 prev_i[chan],
979 cur_i[chan]));
980 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +0000981 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +0000982 len = ncp - PyString_AsString(str);
983 if (len == 0) {
984 /*don't want to resize to zero length*/
985 rv = PyString_FromStringAndSize("", 0);
986 Py_DECREF(str);
987 str = rv;
988 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +0000989 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +0000990 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +0000991 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +0000992 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +0000993 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +0000994 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000995 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +0000996 prev_i[chan] = cur_i[chan];
997 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +0000998 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +0000999 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001000 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001001 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001002 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001003 cp += size;
1004 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001005 cur_i[chan] =
1006 (weightA * cur_i[chan] +
1007 weightB * prev_i[chan]) /
1008 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001009 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001010 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001011 d += outrate;
1012 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001013 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001014 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001015 cur_o = (prev_i[chan] * d +
1016 cur_i[chan] * (outrate - d)) /
1017 outrate;
1018 if (size == 1)
1019 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001020 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001021 *SHORTP(ncp, 0) = (short)(cur_o);
1022 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001023 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001024 ncp += size;
1025 }
1026 d -= inrate;
1027 }
1028 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001029 exit:
1030 if (prev_i != NULL)
1031 free(prev_i);
1032 if (cur_i != NULL)
1033 free(cur_i);
1034 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001035}
Guido van Rossum1851a671997-02-14 16:14:03 +00001036
Roger E. Massec905fff1997-01-17 18:12:04 +00001037static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001038audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001039{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001040 signed char *cp;
1041 unsigned char *ncp;
1042 int len, size, val = 0;
1043 PyObject *rv;
1044 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001045
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001046 if ( !PyArg_Parse(args, "(s#i)",
1047 &cp, &len, &size) )
1048 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001049
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001050 if ( size != 1 && size != 2 && size != 4) {
1051 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1052 return 0;
1053 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001054
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001055 rv = PyString_FromStringAndSize(NULL, len/size);
1056 if ( rv == 0 )
1057 return 0;
1058 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001059
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001060 for ( i=0; i < len; i += size ) {
1061 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1062 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1063 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001064
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001065 *ncp++ = st_linear_to_ulaw(val);
1066 }
1067 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001068}
1069
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001070static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001071audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001072{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001073 unsigned char *cp;
1074 unsigned char cval;
1075 signed char *ncp;
1076 int len, size, val;
1077 PyObject *rv;
1078 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001079
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001080 if ( !PyArg_Parse(args, "(s#i)",
1081 &cp, &len, &size) )
1082 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001083
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001084 if ( size != 1 && size != 2 && size != 4) {
1085 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1086 return 0;
1087 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001088
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001089 rv = PyString_FromStringAndSize(NULL, len*size);
1090 if ( rv == 0 )
1091 return 0;
1092 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001093
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001094 for ( i=0; i < len*size; i += size ) {
1095 cval = *cp++;
1096 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001097
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001098 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1099 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001100 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001101 }
1102 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001103}
1104
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001105static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001106audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001107{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001108 signed char *cp;
1109 signed char *ncp;
1110 int len, size, val = 0, step, valpred, delta,
1111 index, sign, vpdiff, diff;
1112 PyObject *rv, *state, *str;
1113 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001114
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001115 if ( !PyArg_Parse(args, "(s#iO)",
1116 &cp, &len, &size, &state) )
1117 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001118
1119
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001120 if ( size != 1 && size != 2 && size != 4) {
1121 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1122 return 0;
1123 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001124
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001125 str = PyString_FromStringAndSize(NULL, len/(size*2));
1126 if ( str == 0 )
1127 return 0;
1128 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001129
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001130 /* Decode state, should have (value, step) */
1131 if ( state == Py_None ) {
1132 /* First time, it seems. Set defaults */
1133 valpred = 0;
1134 step = 7;
1135 index = 0;
1136 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1137 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001138
Guido van Rossumb64e6351992-07-06 14:21:56 +00001139 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001140 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001141
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001142 for ( i=0; i < len; i += size ) {
1143 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1144 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1145 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1146
1147 /* Step 1 - compute difference with previous value */
1148 diff = val - valpred;
1149 sign = (diff < 0) ? 8 : 0;
1150 if ( sign ) diff = (-diff);
1151
1152 /* Step 2 - Divide and clamp */
1153 /* Note:
1154 ** This code *approximately* computes:
1155 ** delta = diff*4/step;
1156 ** vpdiff = (delta+0.5)*step/4;
1157 ** but in shift step bits are dropped. The net result of this
1158 ** is that even if you have fast mul/div hardware you cannot
1159 ** put it to good use since the fixup would be too expensive.
1160 */
1161 delta = 0;
1162 vpdiff = (step >> 3);
1163
1164 if ( diff >= step ) {
1165 delta = 4;
1166 diff -= step;
1167 vpdiff += step;
1168 }
1169 step >>= 1;
1170 if ( diff >= step ) {
1171 delta |= 2;
1172 diff -= step;
1173 vpdiff += step;
1174 }
1175 step >>= 1;
1176 if ( diff >= step ) {
1177 delta |= 1;
1178 vpdiff += step;
1179 }
1180
1181 /* Step 3 - Update previous value */
1182 if ( sign )
1183 valpred -= vpdiff;
1184 else
1185 valpred += vpdiff;
1186
1187 /* Step 4 - Clamp previous value to 16 bits */
1188 if ( valpred > 32767 )
1189 valpred = 32767;
1190 else if ( valpred < -32768 )
1191 valpred = -32768;
1192
1193 /* Step 5 - Assemble value, update index and step values */
1194 delta |= sign;
1195
1196 index += indexTable[delta];
1197 if ( index < 0 ) index = 0;
1198 if ( index > 88 ) index = 88;
1199 step = stepsizeTable[index];
1200
1201 /* Step 6 - Output value */
1202 if ( bufferstep ) {
1203 outputbuffer = (delta << 4) & 0xf0;
1204 } else {
1205 *ncp++ = (delta & 0x0f) | outputbuffer;
1206 }
1207 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001208 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001209 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1210 Py_DECREF(str);
1211 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001212}
1213
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001214static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001215audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001216{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001217 signed char *cp;
1218 signed char *ncp;
1219 int len, size, valpred, step, delta, index, sign, vpdiff;
1220 PyObject *rv, *str, *state;
1221 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001222
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001223 if ( !PyArg_Parse(args, "(s#iO)",
1224 &cp, &len, &size, &state) )
1225 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001226
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001227 if ( size != 1 && size != 2 && size != 4) {
1228 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1229 return 0;
1230 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001231
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001232 /* Decode state, should have (value, step) */
1233 if ( state == Py_None ) {
1234 /* First time, it seems. Set defaults */
1235 valpred = 0;
1236 step = 7;
1237 index = 0;
1238 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1239 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001240
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001241 str = PyString_FromStringAndSize(NULL, len*size*2);
1242 if ( str == 0 )
1243 return 0;
1244 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001245
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001246 step = stepsizeTable[index];
1247 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001248
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001249 for ( i=0; i < len*size*2; i += size ) {
1250 /* Step 1 - get the delta value and compute next index */
1251 if ( bufferstep ) {
1252 delta = inputbuffer & 0xf;
1253 } else {
1254 inputbuffer = *cp++;
1255 delta = (inputbuffer >> 4) & 0xf;
1256 }
1257
1258 bufferstep = !bufferstep;
1259
1260 /* Step 2 - Find new index value (for later) */
1261 index += indexTable[delta];
1262 if ( index < 0 ) index = 0;
1263 if ( index > 88 ) index = 88;
1264
1265 /* Step 3 - Separate sign and magnitude */
1266 sign = delta & 8;
1267 delta = delta & 7;
1268
1269 /* Step 4 - Compute difference and new predicted value */
1270 /*
1271 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1272 ** in adpcm_coder.
1273 */
1274 vpdiff = step >> 3;
1275 if ( delta & 4 ) vpdiff += step;
1276 if ( delta & 2 ) vpdiff += step>>1;
1277 if ( delta & 1 ) vpdiff += step>>2;
1278
1279 if ( sign )
1280 valpred -= vpdiff;
1281 else
1282 valpred += vpdiff;
1283
1284 /* Step 5 - clamp output value */
1285 if ( valpred > 32767 )
1286 valpred = 32767;
1287 else if ( valpred < -32768 )
1288 valpred = -32768;
1289
1290 /* Step 6 - Update step value */
1291 step = stepsizeTable[index];
1292
1293 /* Step 6 - Output value */
1294 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1295 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001296 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001297 }
1298
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001299 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1300 Py_DECREF(str);
1301 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001302}
1303
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001304static PyMethodDef audioop_methods[] = {
1305 { "max", audioop_max },
1306 { "minmax", audioop_minmax },
1307 { "avg", audioop_avg },
1308 { "maxpp", audioop_maxpp },
1309 { "avgpp", audioop_avgpp },
1310 { "rms", audioop_rms },
1311 { "findfit", audioop_findfit },
1312 { "findmax", audioop_findmax },
1313 { "findfactor", audioop_findfactor },
1314 { "cross", audioop_cross },
1315 { "mul", audioop_mul },
1316 { "add", audioop_add },
1317 { "bias", audioop_bias },
1318 { "ulaw2lin", audioop_ulaw2lin },
1319 { "lin2ulaw", audioop_lin2ulaw },
1320 { "lin2lin", audioop_lin2lin },
1321 { "adpcm2lin", audioop_adpcm2lin },
1322 { "lin2adpcm", audioop_lin2adpcm },
1323 { "tomono", audioop_tomono },
1324 { "tostereo", audioop_tostereo },
1325 { "getsample", audioop_getsample },
1326 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001327 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001328 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001329};
1330
Guido van Rossum3886bb61998-12-04 18:50:17 +00001331DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001332initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001333{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001334 PyObject *m, *d;
1335 m = Py_InitModule("audioop", audioop_methods);
1336 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001337 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1338 if (AudioopError != NULL)
1339 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001340}