blob: d23ee2aafc9ba8125252b96a6eb94ffca07c7412 [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"
Tim Peters1691bd92001-12-05 06:05:07 +00005#include <math.h>
Guido van Rossumb66efa01992-06-01 16:01:24 +00006
Guido van Rossum69011961998-04-23 20:23:00 +00007#if SIZEOF_INT == 4
8typedef int Py_Int32;
9typedef unsigned int Py_UInt32;
10#else
11#if SIZEOF_LONG == 4
12typedef long Py_Int32;
13typedef unsigned long Py_UInt32;
14#else
15#error "No 4-byte integral type"
16#endif
17#endif
18
Guido van Rossum7b1e9741994-08-29 10:46:42 +000019#if defined(__CHAR_UNSIGNED__)
20#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000021/* This module currently does not work on systems where only unsigned
22 characters are available. Take it out of Setup. Sorry. */
23#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000024#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000025
Jack Jansena90805f1993-02-17 14:29:28 +000026/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000027** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
28
29#define MINLIN -32768
30#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000031#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
32 else if ( x > MAXLIN ) x = MAXLIN; \
33 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000034
Fred Drakec818d532000-08-31 05:07:19 +000035static unsigned char st_linear_to_ulaw(int sample);
Guido van Rossumb66efa01992-06-01 16:01:24 +000036
37/*
38** This macro converts from ulaw to 16 bit linear, faster.
39**
40** Jef Poskanzer
41** 23 October 1989
42**
43** Input: 8 bit ulaw sample
44** Output: signed 16 bit linear sample
45*/
46#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
47
48static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000049 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
50 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
51 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
52 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
53 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
54 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
55 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
56 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
57 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
58 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
59 -876, -844, -812, -780, -748, -716, -684, -652,
60 -620, -588, -556, -524, -492, -460, -428, -396,
61 -372, -356, -340, -324, -308, -292, -276, -260,
62 -244, -228, -212, -196, -180, -164, -148, -132,
63 -120, -112, -104, -96, -88, -80, -72, -64,
64 -56, -48, -40, -32, -24, -16, -8, 0,
65 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
66 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
67 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
68 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
69 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
70 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
71 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
72 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
73 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
74 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
75 876, 844, 812, 780, 748, 716, 684, 652,
76 620, 588, 556, 524, 492, 460, 428, 396,
77 372, 356, 340, 324, 308, 292, 276, 260,
78 244, 228, 212, 196, 180, 164, 148, 132,
79 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000080 56, 48, 40, 32, 24, 16, 8, 0 };
81
Moshe Zadka6a078ed2000-08-04 15:53:06 +000082/* #define ZEROTRAP */ /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +000083#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
84#define CLIP 32635
85
Guido van Rossumcd938fc1995-01-17 16:13:48 +000086static unsigned char
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000087st_linear_to_ulaw(int sample)
Roger E. Masseeaa6e111997-01-03 19:26:27 +000088{
89 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
90 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
91 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
92 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
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 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
105 int sign, exponent, mantissa;
106 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000107
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000108 /* Get the sample into sign-magnitude. */
109 sign = (sample >> 8) & 0x80; /* set aside the sign */
110 if ( sign != 0 ) sample = -sample; /* get magnitude */
111 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000112
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000113 /* Convert from 16 bit linear to ulaw. */
114 sample = sample + BIAS;
115 exponent = exp_lut[( sample >> 7 ) & 0xFF];
116 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
117 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000118#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000119 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000120#endif
121
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000122 return ulawbyte;
123}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000124/* End of code taken from sox */
125
Guido van Rossumb64e6351992-07-06 14:21:56 +0000126/* Intel ADPCM step variation table */
127static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000128 -1, -1, -1, -1, 2, 4, 6, 8,
129 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000130};
131
132static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000133 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
134 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
135 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
136 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
137 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
138 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
139 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
140 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
141 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000142};
143
Guido van Rossumb66efa01992-06-01 16:01:24 +0000144#define CHARP(cp, i) ((signed char *)(cp+i))
145#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000146#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000147
148
149
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000150static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000151
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000152static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000153audioop_getsample(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000154{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000155 signed char *cp;
156 int len, size, val = 0;
157 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000158
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000159 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
160 return 0;
161 if ( size != 1 && size != 2 && size != 4 ) {
162 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
163 return 0;
164 }
165 if ( i < 0 || i >= len/size ) {
166 PyErr_SetString(AudioopError, "Index out of range");
167 return 0;
168 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000169 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000170 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
171 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
172 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000173}
174
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000175static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000176audioop_max(PyObject *self, PyObject *args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000177{
178 signed char *cp;
179 int len, size, val = 0;
180 int i;
181 int max = 0;
182
183 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
184 return 0;
185 if ( size != 1 && size != 2 && size != 4 ) {
186 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
187 return 0;
188 }
189 for ( i=0; i<len; i+= size) {
190 if ( size == 1 ) val = (int)*CHARP(cp, i);
191 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
192 else if ( size == 4 ) val = (int)*LONGP(cp, i);
193 if ( val < 0 ) val = (-val);
194 if ( val > max ) max = val;
195 }
196 return PyInt_FromLong(max);
197}
198
199static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000200audioop_minmax(PyObject *self, PyObject *args)
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000201{
202 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000203 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000204 int i;
205 int min = 0x7fffffff, max = -0x7fffffff;
206
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000207 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000208 return NULL;
209 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000210 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000211 return NULL;
212 }
213 for (i = 0; i < len; i += size) {
214 if (size == 1) val = (int) *CHARP(cp, i);
215 else if (size == 2) val = (int) *SHORTP(cp, i);
216 else if (size == 4) val = (int) *LONGP(cp, i);
217 if (val > max) max = val;
218 if (val < min) min = val;
219 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000220 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000221}
222
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000223static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000224audioop_avg(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000225{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000226 signed char *cp;
227 int len, size, val = 0;
228 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000229 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000230
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000231 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
232 return 0;
233 if ( size != 1 && size != 2 && size != 4 ) {
234 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
235 return 0;
236 }
237 for ( i=0; i<len; i+= size) {
238 if ( size == 1 ) val = (int)*CHARP(cp, i);
239 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
240 else if ( size == 4 ) val = (int)*LONGP(cp, i);
241 avg += val;
242 }
243 if ( len == 0 )
244 val = 0;
245 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000246 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000247 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000248}
249
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000250static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000251audioop_rms(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000252{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000253 signed char *cp;
254 int len, size, val = 0;
255 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000256 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000257
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000258 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
259 return 0;
260 if ( size != 1 && size != 2 && size != 4 ) {
261 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
262 return 0;
263 }
264 for ( i=0; i<len; i+= size) {
265 if ( size == 1 ) val = (int)*CHARP(cp, i);
266 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
267 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000268 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000269 }
270 if ( len == 0 )
271 val = 0;
272 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000273 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000274 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000275}
276
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000277static double _sum2(short *a, short *b, int len)
Jack Jansena90805f1993-02-17 14:29:28 +0000278{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000279 int i;
280 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000281
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000282 for( i=0; i<len; i++) {
283 sum = sum + (double)a[i]*(double)b[i];
284 }
285 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000286}
287
288/*
289** Findfit tries to locate a sample within another sample. Its main use
290** is in echo-cancellation (to find the feedback of the output signal in
291** the input signal).
292** The method used is as follows:
293**
294** let R be the reference signal (length n) and A the input signal (length N)
295** with N > n, and let all sums be over i from 0 to n-1.
296**
297** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
298** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
299** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
300**
301** Next, we compute the relative distance between the original signal and
302** the modified signal and minimize that over j:
303** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
304** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
305**
306** In the code variables correspond as follows:
307** cp1 A
308** cp2 R
309** len1 N
310** len2 n
311** aj_m1 A[j-1]
312** aj_lm1 A[j+n-1]
313** sum_ri_2 sum(R[i]^2)
314** sum_aij_2 sum(A[i+j]^2)
315** sum_aij_ri sum(A[i+j]R[i])
316**
317** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
318** is completely recalculated each step.
319*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000320static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000321audioop_findfit(PyObject *self, PyObject *args)
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000322{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000323 short *cp1, *cp2;
324 int len1, len2;
325 int j, best_j;
326 double aj_m1, aj_lm1;
327 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000328
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000329 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
330 return 0;
331 if ( len1 & 1 || len2 & 1 ) {
332 PyErr_SetString(AudioopError, "Strings should be even-sized");
333 return 0;
334 }
335 len1 >>= 1;
336 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000337
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000338 if ( len1 < len2 ) {
339 PyErr_SetString(AudioopError, "First sample should be longer");
340 return 0;
341 }
342 sum_ri_2 = _sum2(cp2, cp2, len2);
343 sum_aij_2 = _sum2(cp1, cp1, len2);
344 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000345
346 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
347
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000348 best_result = result;
349 best_j = 0;
350 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000351
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000352 for ( j=1; j<=len1-len2; j++) {
353 aj_m1 = (double)cp1[j-1];
354 aj_lm1 = (double)cp1[j+len2-1];
355
356 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
357 sum_aij_ri = _sum2(cp1+j, cp2, len2);
358
359 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
360 / sum_aij_2;
361
362 if ( result < best_result ) {
363 best_result = result;
364 best_j = j;
365 }
366
367 }
368
369 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000370
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000371 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000372}
373
374/*
375** findfactor finds a factor f so that the energy in A-fB is minimal.
376** See the comment for findfit for details.
377*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000378static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000379audioop_findfactor(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000380{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000381 short *cp1, *cp2;
382 int len1, len2;
383 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000384
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000385 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
386 return 0;
387 if ( len1 & 1 || len2 & 1 ) {
388 PyErr_SetString(AudioopError, "Strings should be even-sized");
389 return 0;
390 }
391 if ( len1 != len2 ) {
392 PyErr_SetString(AudioopError, "Samples should be same size");
393 return 0;
394 }
395 len2 >>= 1;
396 sum_ri_2 = _sum2(cp2, cp2, len2);
397 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000398
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000399 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000400
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000401 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000402}
403
404/*
405** findmax returns the index of the n-sized segment of the input sample
406** that contains the most energy.
407*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000408static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000409audioop_findmax(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000410{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411 short *cp1;
412 int len1, len2;
413 int j, best_j;
414 double aj_m1, aj_lm1;
415 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000416
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000417 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
418 return 0;
419 if ( len1 & 1 ) {
420 PyErr_SetString(AudioopError, "Strings should be even-sized");
421 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000422 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000423 len1 >>= 1;
424
425 if ( len1 < len2 ) {
426 PyErr_SetString(AudioopError, "Input sample should be longer");
427 return 0;
428 }
Jack Jansena90805f1993-02-17 14:29:28 +0000429
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000430 result = _sum2(cp1, cp1, len2);
431
432 best_result = result;
433 best_j = 0;
434 j = 0;
435
436 for ( j=1; j<=len1-len2; j++) {
437 aj_m1 = (double)cp1[j-1];
438 aj_lm1 = (double)cp1[j+len2-1];
439
440 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
441
442 if ( result > best_result ) {
443 best_result = result;
444 best_j = j;
445 }
446
447 }
448
449 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000450}
451
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000452static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000453audioop_avgpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000454{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000455 signed char *cp;
456 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
457 prevextreme = 0;
458 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000459 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000460 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000461
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000462 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
463 return 0;
464 if ( size != 1 && size != 2 && size != 4 ) {
465 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
466 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000467 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000468 /* Compute first delta value ahead. Also automatically makes us
469 ** skip the first extreme value
470 */
471 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
472 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
473 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
474 if ( size == 1 ) val = (int)*CHARP(cp, size);
475 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
476 else if ( size == 4 ) val = (int)*LONGP(cp, size);
477 prevdiff = val - prevval;
478
479 for ( i=size; i<len; i+= size) {
480 if ( size == 1 ) val = (int)*CHARP(cp, i);
481 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
482 else if ( size == 4 ) val = (int)*LONGP(cp, i);
483 diff = val - prevval;
484 if ( diff*prevdiff < 0 ) {
485 /* Derivative changed sign. Compute difference to last
486 ** extreme value and remember.
487 */
488 if ( prevextremevalid ) {
489 extremediff = prevval - prevextreme;
490 if ( extremediff < 0 )
491 extremediff = -extremediff;
492 avg += extremediff;
493 nextreme++;
494 }
495 prevextremevalid = 1;
496 prevextreme = prevval;
497 }
498 prevval = val;
499 if ( diff != 0 )
500 prevdiff = diff;
501 }
502 if ( nextreme == 0 )
503 val = 0;
504 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000505 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000506 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000507}
508
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000509static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000510audioop_maxpp(PyObject *self, PyObject *args)
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000511{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000512 signed char *cp;
513 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
514 prevextreme = 0;
515 int i;
516 int max = 0;
517 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000518
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000519 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
520 return 0;
521 if ( size != 1 && size != 2 && size != 4 ) {
522 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
523 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000524 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000525 /* Compute first delta value ahead. Also automatically makes us
526 ** skip the first extreme value
527 */
528 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
529 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
530 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
531 if ( size == 1 ) val = (int)*CHARP(cp, size);
532 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
533 else if ( size == 4 ) val = (int)*LONGP(cp, size);
534 prevdiff = val - prevval;
535
536 for ( i=size; i<len; i+= size) {
537 if ( size == 1 ) val = (int)*CHARP(cp, i);
538 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
539 else if ( size == 4 ) val = (int)*LONGP(cp, i);
540 diff = val - prevval;
541 if ( diff*prevdiff < 0 ) {
542 /* Derivative changed sign. Compute difference to
543 ** last extreme value and remember.
544 */
545 if ( prevextremevalid ) {
546 extremediff = prevval - prevextreme;
547 if ( extremediff < 0 )
548 extremediff = -extremediff;
549 if ( extremediff > max )
550 max = extremediff;
551 }
552 prevextremevalid = 1;
553 prevextreme = prevval;
554 }
555 prevval = val;
556 if ( diff != 0 )
557 prevdiff = diff;
558 }
559 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000560}
561
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000562static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000563audioop_cross(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000564{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000565 signed char *cp;
566 int len, size, val = 0;
567 int i;
568 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000569
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000570 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
571 return 0;
572 if ( size != 1 && size != 2 && size != 4 ) {
573 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
574 return 0;
575 }
576 ncross = -1;
577 prevval = 17; /* Anything <> 0,1 */
578 for ( i=0; i<len; i+= size) {
579 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
580 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
581 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
582 val = val & 1;
583 if ( val != prevval ) ncross++;
584 prevval = val;
585 }
586 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000587}
588
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000589static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000590audioop_mul(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000591{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000592 signed char *cp, *ncp;
593 int len, size, val = 0;
594 double factor, fval, maxval;
595 PyObject *rv;
596 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000597
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000598 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
599 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000600
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000601 if ( size == 1 ) maxval = (double) 0x7f;
602 else if ( size == 2 ) maxval = (double) 0x7fff;
603 else if ( size == 4 ) maxval = (double) 0x7fffffff;
604 else {
605 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
606 return 0;
607 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000608
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000609 rv = PyString_FromStringAndSize(NULL, len);
610 if ( rv == 0 )
611 return 0;
612 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000613
614
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000615 for ( i=0; i < len; i += size ) {
616 if ( size == 1 ) val = (int)*CHARP(cp, i);
617 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
618 else if ( size == 4 ) val = (int)*LONGP(cp, i);
619 fval = (double)val*factor;
620 if ( fval > maxval ) fval = maxval;
621 else if ( fval < -maxval ) fval = -maxval;
622 val = (int)fval;
623 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
624 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000625 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000626 }
627 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000628}
629
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000630static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000631audioop_tomono(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000632{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000633 signed char *cp, *ncp;
634 int len, size, val1 = 0, val2 = 0;
635 double fac1, fac2, fval, maxval;
636 PyObject *rv;
637 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000638
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000639 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
640 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000641
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000642 if ( size == 1 ) maxval = (double) 0x7f;
643 else if ( size == 2 ) maxval = (double) 0x7fff;
644 else if ( size == 4 ) maxval = (double) 0x7fffffff;
645 else {
646 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
647 return 0;
648 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000649
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000650 rv = PyString_FromStringAndSize(NULL, len/2);
651 if ( rv == 0 )
652 return 0;
653 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000654
655
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000656 for ( i=0; i < len; i += size*2 ) {
657 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
658 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
659 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
660 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
661 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
662 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
663 fval = (double)val1*fac1 + (double)val2*fac2;
664 if ( fval > maxval ) fval = maxval;
665 else if ( fval < -maxval ) fval = -maxval;
666 val1 = (int)fval;
667 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
668 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000669 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000670 }
671 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000672}
673
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000674static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000675audioop_tostereo(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000676{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000677 signed char *cp, *ncp;
678 int len, size, val1, val2, val = 0;
679 double fac1, fac2, fval, maxval;
680 PyObject *rv;
681 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000682
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
684 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000685
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000686 if ( size == 1 ) maxval = (double) 0x7f;
687 else if ( size == 2 ) maxval = (double) 0x7fff;
688 else if ( size == 4 ) maxval = (double) 0x7fffffff;
689 else {
690 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
691 return 0;
692 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000693
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000694 rv = PyString_FromStringAndSize(NULL, len*2);
695 if ( rv == 0 )
696 return 0;
697 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000698
699
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000700 for ( i=0; i < len; i += size ) {
701 if ( size == 1 ) val = (int)*CHARP(cp, i);
702 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
703 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000704
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000705 fval = (double)val*fac1;
706 if ( fval > maxval ) fval = maxval;
707 else if ( fval < -maxval ) fval = -maxval;
708 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000709
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000710 fval = (double)val*fac2;
711 if ( fval > maxval ) fval = maxval;
712 else if ( fval < -maxval ) fval = -maxval;
713 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000714
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000715 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
716 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000717 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000718
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000719 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
720 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000721 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000722 }
723 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000724}
725
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000726static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000727audioop_add(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000728{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000729 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000730 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000731 PyObject *rv;
732 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000733
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000734 if ( !PyArg_Parse(args, "(s#s#i)",
735 &cp1, &len1, &cp2, &len2, &size ) )
736 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000737
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000738 if ( len1 != len2 ) {
739 PyErr_SetString(AudioopError, "Lengths should be the same");
740 return 0;
741 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000742
Guido van Rossum1851a671997-02-14 16:14:03 +0000743 if ( size == 1 ) maxval = 0x7f;
744 else if ( size == 2 ) maxval = 0x7fff;
745 else if ( size == 4 ) maxval = 0x7fffffff;
746 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000747 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
748 return 0;
749 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000750
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000751 rv = PyString_FromStringAndSize(NULL, len1);
752 if ( rv == 0 )
753 return 0;
754 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000755
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000756 for ( i=0; i < len1; i += size ) {
757 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
758 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
759 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000760
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000761 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
762 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
763 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000764
Guido van Rossum1851a671997-02-14 16:14:03 +0000765 newval = val1 + val2;
766 /* truncate in case of overflow */
767 if (newval > maxval) newval = maxval;
768 else if (newval < -maxval) newval = -maxval;
769 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
770 newval = val1 > 0 ? maxval : - maxval;
771
772 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
773 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000774 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000775 }
776 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000777}
778
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000779static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000780audioop_bias(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +0000781{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000782 signed char *cp, *ncp;
783 int len, size, val = 0;
784 PyObject *rv;
785 int i;
786 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000788 if ( !PyArg_Parse(args, "(s#ii)",
789 &cp, &len, &size , &bias) )
790 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792 if ( size != 1 && size != 2 && size != 4) {
793 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
794 return 0;
795 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000796
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000797 rv = PyString_FromStringAndSize(NULL, len);
798 if ( rv == 0 )
799 return 0;
800 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000801
802
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000803 for ( i=0; i < len; i += size ) {
804 if ( size == 1 ) val = (int)*CHARP(cp, i);
805 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
806 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000807
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000808 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
809 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000810 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000811 }
812 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000813}
814
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000815static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000816audioop_reverse(PyObject *self, PyObject *args)
Jack Jansen337b20e1993-02-23 13:39:57 +0000817{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000818 signed char *cp;
819 unsigned char *ncp;
820 int len, size, val = 0;
821 PyObject *rv;
822 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000823
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000824 if ( !PyArg_Parse(args, "(s#i)",
825 &cp, &len, &size) )
826 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000827
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000828 if ( size != 1 && size != 2 && size != 4 ) {
829 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
830 return 0;
831 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000832
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000833 rv = PyString_FromStringAndSize(NULL, len);
834 if ( rv == 0 )
835 return 0;
836 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000837
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000838 for ( i=0; i < len; i += size ) {
839 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
840 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
841 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000842
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000843 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000844
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000845 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
846 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000847 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000848 }
849 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000850}
851
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000852static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000853audioop_lin2lin(PyObject *self, PyObject *args)
Jack Jansena90805f1993-02-17 14:29:28 +0000854{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000855 signed char *cp;
856 unsigned char *ncp;
857 int len, size, size2, val = 0;
858 PyObject *rv;
859 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000860
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000861 if ( !PyArg_Parse(args, "(s#ii)",
862 &cp, &len, &size, &size2) )
863 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000864
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000865 if ( (size != 1 && size != 2 && size != 4) ||
866 (size2 != 1 && size2 != 2 && size2 != 4)) {
867 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
868 return 0;
869 }
Jack Jansena90805f1993-02-17 14:29:28 +0000870
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000871 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
872 if ( rv == 0 )
873 return 0;
874 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000875
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000876 for ( i=0, j=0; i < len; i += size, j += size2 ) {
877 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
878 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
879 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000880
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000881 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
882 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000883 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000884 }
885 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000886}
887
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000888static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000889gcd(int a, int b)
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000890{
891 while (b > 0) {
892 int tmp = a % b;
893 a = b;
894 b = tmp;
895 }
896 return a;
897}
898
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000899static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000900audioop_ratecv(PyObject *self, PyObject *args)
Roger E. Massec905fff1997-01-17 18:12:04 +0000901{
Guido van Rossum1851a671997-02-14 16:14:03 +0000902 char *cp, *ncp;
903 int len, size, nchannels, inrate, outrate, weightA, weightB;
904 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000905 PyObject *state, *samps, *str, *rv = NULL;
Tim Peters3127c282001-12-05 22:30:21 +0000906 int bytes_per_frame;
Guido van Rossum1851a671997-02-14 16:14:03 +0000907
908 weightA = 1;
909 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000910 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000911 &inrate, &outrate, &state, &weightA, &weightB))
912 return NULL;
913 if (size != 1 && size != 2 && size != 4) {
914 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
915 return NULL;
916 }
917 if (nchannels < 1) {
918 PyErr_SetString(AudioopError, "# of channels should be >= 1");
919 return NULL;
920 }
Tim Peters3127c282001-12-05 22:30:21 +0000921 bytes_per_frame = size * nchannels;
922 if (bytes_per_frame / nchannels != size) {
923 /* This overflow test is rigorously correct because
924 both multiplicands are >= 1. Use the argument names
925 from the docs for the error msg. */
926 PyErr_SetString(PyExc_OverflowError,
927 "width * nchannels too big for a C int");
928 return NULL;
929 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000930 if (weightA < 1 || weightB < 0) {
931 PyErr_SetString(AudioopError,
932 "weightA should be >= 1, weightB should be >= 0");
933 return NULL;
934 }
Tim Peters3127c282001-12-05 22:30:21 +0000935 if (len % bytes_per_frame != 0) {
Guido van Rossum1851a671997-02-14 16:14:03 +0000936 PyErr_SetString(AudioopError, "not a whole number of frames");
937 return NULL;
938 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000939 if (inrate <= 0 || outrate <= 0) {
940 PyErr_SetString(AudioopError, "sampling rate not > 0");
941 return NULL;
942 }
943 /* divide inrate and outrate by their greatest common divisor */
944 d = gcd(inrate, outrate);
945 inrate /= d;
946 outrate /= d;
947
Guido van Rossum6345ac61997-10-31 20:32:13 +0000948 prev_i = (int *) malloc(nchannels * sizeof(int));
949 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum65bb3281999-09-07 14:24:05 +0000950 if (prev_i == NULL || cur_i == NULL) {
951 (void) PyErr_NoMemory();
952 goto exit;
953 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000954
Tim Peters3127c282001-12-05 22:30:21 +0000955 len /= bytes_per_frame; /* # of frames */
Tim Peters1691bd92001-12-05 06:05:07 +0000956
Guido van Rossum1851a671997-02-14 16:14:03 +0000957 if (state == Py_None) {
958 d = -outrate;
959 for (chan = 0; chan < nchannels; chan++)
960 prev_i[chan] = cur_i[chan] = 0;
Tim Peters1691bd92001-12-05 06:05:07 +0000961 }
962 else {
Guido van Rossum1851a671997-02-14 16:14:03 +0000963 if (!PyArg_ParseTuple(state,
964 "iO!;audioop.ratecv: illegal state argument",
965 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000966 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000967 if (PyTuple_Size(samps) != nchannels) {
968 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000969 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +0000970 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000971 }
972 for (chan = 0; chan < nchannels; chan++) {
973 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +0000974 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +0000975 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +0000976 }
977 }
Tim Peters1691bd92001-12-05 06:05:07 +0000978
979 /* str <- Space for the output buffer. */
980 {
981 /* There are len input frames, so we need (mathematically)
982 ceiling(len*outrate/inrate) output frames, and each frame
Tim Peters3127c282001-12-05 22:30:21 +0000983 requires bytes_per_frame bytes. Computing this
Tim Peters1691bd92001-12-05 06:05:07 +0000984 without spurious overflow is the challenge. */
985 int ceiling; /* the number of output frames, eventually */
986 int nbytes; /* the number of output bytes needed */
987 int q = len / inrate;
988 int r = len - q * inrate;
989 /* Now len = q * inrate + r exactly, so
990 len*outrate/inrate =
991 (q*inrate+r)*outrate/inrate =
992 (q*inrate*outrate + r*outrate)/inrate =
993 q*outrate + r*outrate/inrate exactly.
994 q*outrate is an exact integer, so the ceiling we're after is
995 q*outrate + ceiling(r*outrate/inrate). */
996 ceiling = q * outrate;
997 if (ceiling / outrate != q) {
998 PyErr_SetString(PyExc_MemoryError,
999 "not enough memory for output buffer");
1000 goto exit;
1001 }
1002 /* Since r = len % inrate, in particular r < inrate. So
1003 r * outrate / inrate = (r / inrate) * outrate < outrate,
1004 so ceiling(r * outrate / inrate) <= outrate: the final
1005 result fits in an int -- it can't overflow. */
1006 assert(r < inrate);
1007 q = (int)ceil((double)r * (double)outrate / (double)inrate);
1008 assert(q <= outrate);
1009 ceiling += q;
1010 if (ceiling < 0) {
1011 PyErr_SetString(PyExc_MemoryError,
1012 "not enough memory for output buffer");
1013 goto exit;
1014 }
Tim Peters3127c282001-12-05 22:30:21 +00001015 nbytes = ceiling * bytes_per_frame;
1016 if (nbytes / bytes_per_frame != ceiling) {
Tim Peters1691bd92001-12-05 06:05:07 +00001017 PyErr_SetString(PyExc_MemoryError,
1018 "not enough memory for output buffer");
1019 goto exit;
1020 }
1021 str = PyString_FromStringAndSize(NULL, nbytes);
1022 if (str == NULL)
1023 goto exit;
1024 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001025 ncp = PyString_AsString(str);
1026
1027 for (;;) {
1028 while (d < 0) {
1029 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001030 samps = PyTuple_New(nchannels);
1031 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001032 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001033 Py_BuildValue("(ii)",
1034 prev_i[chan],
1035 cur_i[chan]));
1036 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +00001037 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001038 len = ncp - PyString_AsString(str);
1039 if (len == 0) {
1040 /*don't want to resize to zero length*/
1041 rv = PyString_FromStringAndSize("", 0);
1042 Py_DECREF(str);
1043 str = rv;
1044 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001045 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001046 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001047 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001048 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001049 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001050 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001051 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001052 prev_i[chan] = cur_i[chan];
1053 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001054 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001055 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001056 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001057 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001058 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001059 cp += size;
1060 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001061 cur_i[chan] =
1062 (weightA * cur_i[chan] +
1063 weightB * prev_i[chan]) /
1064 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001065 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001066 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001067 d += outrate;
1068 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001069 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001070 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001071 cur_o = (prev_i[chan] * d +
1072 cur_i[chan] * (outrate - d)) /
1073 outrate;
1074 if (size == 1)
1075 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001076 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001077 *SHORTP(ncp, 0) = (short)(cur_o);
1078 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001079 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001080 ncp += size;
1081 }
1082 d -= inrate;
1083 }
1084 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001085 exit:
1086 if (prev_i != NULL)
1087 free(prev_i);
1088 if (cur_i != NULL)
1089 free(cur_i);
1090 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001091}
Guido van Rossum1851a671997-02-14 16:14:03 +00001092
Roger E. Massec905fff1997-01-17 18:12:04 +00001093static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001094audioop_lin2ulaw(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001095{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001096 signed char *cp;
1097 unsigned char *ncp;
1098 int len, size, val = 0;
1099 PyObject *rv;
1100 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001101
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001102 if ( !PyArg_Parse(args, "(s#i)",
1103 &cp, &len, &size) )
1104 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001105
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001106 if ( size != 1 && size != 2 && size != 4) {
1107 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1108 return 0;
1109 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001110
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001111 rv = PyString_FromStringAndSize(NULL, len/size);
1112 if ( rv == 0 )
1113 return 0;
1114 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001115
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116 for ( i=0; i < len; i += size ) {
1117 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1118 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1119 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001120
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001121 *ncp++ = st_linear_to_ulaw(val);
1122 }
1123 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001124}
1125
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001126static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001127audioop_ulaw2lin(PyObject *self, PyObject *args)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001128{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001129 unsigned char *cp;
1130 unsigned char cval;
1131 signed char *ncp;
1132 int len, size, val;
1133 PyObject *rv;
1134 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001135
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001136 if ( !PyArg_Parse(args, "(s#i)",
1137 &cp, &len, &size) )
1138 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001139
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001140 if ( size != 1 && size != 2 && size != 4) {
1141 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1142 return 0;
1143 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001144
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001145 rv = PyString_FromStringAndSize(NULL, len*size);
1146 if ( rv == 0 )
1147 return 0;
1148 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001149
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001150 for ( i=0; i < len*size; i += size ) {
1151 cval = *cp++;
1152 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001153
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001154 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1155 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001156 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001157 }
1158 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001159}
1160
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001161static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001162audioop_lin2adpcm(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001163{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001164 signed char *cp;
1165 signed char *ncp;
1166 int len, size, val = 0, step, valpred, delta,
1167 index, sign, vpdiff, diff;
1168 PyObject *rv, *state, *str;
1169 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001170
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001171 if ( !PyArg_Parse(args, "(s#iO)",
1172 &cp, &len, &size, &state) )
1173 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001174
1175
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001176 if ( size != 1 && size != 2 && size != 4) {
1177 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1178 return 0;
1179 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001180
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001181 str = PyString_FromStringAndSize(NULL, len/(size*2));
1182 if ( str == 0 )
1183 return 0;
1184 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001185
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001186 /* Decode state, should have (value, step) */
1187 if ( state == Py_None ) {
1188 /* First time, it seems. Set defaults */
1189 valpred = 0;
1190 step = 7;
1191 index = 0;
1192 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1193 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001194
Guido van Rossumb64e6351992-07-06 14:21:56 +00001195 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001196 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001197
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001198 for ( i=0; i < len; i += size ) {
1199 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1200 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1201 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1202
1203 /* Step 1 - compute difference with previous value */
1204 diff = val - valpred;
1205 sign = (diff < 0) ? 8 : 0;
1206 if ( sign ) diff = (-diff);
1207
1208 /* Step 2 - Divide and clamp */
1209 /* Note:
1210 ** This code *approximately* computes:
1211 ** delta = diff*4/step;
1212 ** vpdiff = (delta+0.5)*step/4;
1213 ** but in shift step bits are dropped. The net result of this
1214 ** is that even if you have fast mul/div hardware you cannot
1215 ** put it to good use since the fixup would be too expensive.
1216 */
1217 delta = 0;
1218 vpdiff = (step >> 3);
1219
1220 if ( diff >= step ) {
1221 delta = 4;
1222 diff -= step;
1223 vpdiff += step;
1224 }
1225 step >>= 1;
1226 if ( diff >= step ) {
1227 delta |= 2;
1228 diff -= step;
1229 vpdiff += step;
1230 }
1231 step >>= 1;
1232 if ( diff >= step ) {
1233 delta |= 1;
1234 vpdiff += step;
1235 }
1236
1237 /* Step 3 - Update previous value */
1238 if ( sign )
1239 valpred -= vpdiff;
1240 else
1241 valpred += vpdiff;
1242
1243 /* Step 4 - Clamp previous value to 16 bits */
1244 if ( valpred > 32767 )
1245 valpred = 32767;
1246 else if ( valpred < -32768 )
1247 valpred = -32768;
1248
1249 /* Step 5 - Assemble value, update index and step values */
1250 delta |= sign;
1251
1252 index += indexTable[delta];
1253 if ( index < 0 ) index = 0;
1254 if ( index > 88 ) index = 88;
1255 step = stepsizeTable[index];
1256
1257 /* Step 6 - Output value */
1258 if ( bufferstep ) {
1259 outputbuffer = (delta << 4) & 0xf0;
1260 } else {
1261 *ncp++ = (delta & 0x0f) | outputbuffer;
1262 }
1263 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001264 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001265 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1266 Py_DECREF(str);
1267 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001268}
1269
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001270static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +00001271audioop_adpcm2lin(PyObject *self, PyObject *args)
Guido van Rossumb64e6351992-07-06 14:21:56 +00001272{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001273 signed char *cp;
1274 signed char *ncp;
1275 int len, size, valpred, step, delta, index, sign, vpdiff;
1276 PyObject *rv, *str, *state;
1277 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001278
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001279 if ( !PyArg_Parse(args, "(s#iO)",
1280 &cp, &len, &size, &state) )
1281 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001282
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001283 if ( size != 1 && size != 2 && size != 4) {
1284 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1285 return 0;
1286 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001287
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001288 /* Decode state, should have (value, step) */
1289 if ( state == Py_None ) {
1290 /* First time, it seems. Set defaults */
1291 valpred = 0;
1292 step = 7;
1293 index = 0;
1294 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1295 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001296
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001297 str = PyString_FromStringAndSize(NULL, len*size*2);
1298 if ( str == 0 )
1299 return 0;
1300 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001301
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001302 step = stepsizeTable[index];
1303 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001304
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001305 for ( i=0; i < len*size*2; i += size ) {
1306 /* Step 1 - get the delta value and compute next index */
1307 if ( bufferstep ) {
1308 delta = inputbuffer & 0xf;
1309 } else {
1310 inputbuffer = *cp++;
1311 delta = (inputbuffer >> 4) & 0xf;
1312 }
1313
1314 bufferstep = !bufferstep;
1315
1316 /* Step 2 - Find new index value (for later) */
1317 index += indexTable[delta];
1318 if ( index < 0 ) index = 0;
1319 if ( index > 88 ) index = 88;
1320
1321 /* Step 3 - Separate sign and magnitude */
1322 sign = delta & 8;
1323 delta = delta & 7;
1324
1325 /* Step 4 - Compute difference and new predicted value */
1326 /*
1327 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1328 ** in adpcm_coder.
1329 */
1330 vpdiff = step >> 3;
1331 if ( delta & 4 ) vpdiff += step;
1332 if ( delta & 2 ) vpdiff += step>>1;
1333 if ( delta & 1 ) vpdiff += step>>2;
1334
1335 if ( sign )
1336 valpred -= vpdiff;
1337 else
1338 valpred += vpdiff;
1339
1340 /* Step 5 - clamp output value */
1341 if ( valpred > 32767 )
1342 valpred = 32767;
1343 else if ( valpred < -32768 )
1344 valpred = -32768;
1345
1346 /* Step 6 - Update step value */
1347 step = stepsizeTable[index];
1348
1349 /* Step 6 - Output value */
1350 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1351 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001352 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001353 }
1354
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001355 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1356 Py_DECREF(str);
1357 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001358}
1359
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001360static PyMethodDef audioop_methods[] = {
1361 { "max", audioop_max },
1362 { "minmax", audioop_minmax },
1363 { "avg", audioop_avg },
1364 { "maxpp", audioop_maxpp },
1365 { "avgpp", audioop_avgpp },
1366 { "rms", audioop_rms },
1367 { "findfit", audioop_findfit },
1368 { "findmax", audioop_findmax },
1369 { "findfactor", audioop_findfactor },
1370 { "cross", audioop_cross },
1371 { "mul", audioop_mul },
1372 { "add", audioop_add },
1373 { "bias", audioop_bias },
1374 { "ulaw2lin", audioop_ulaw2lin },
1375 { "lin2ulaw", audioop_lin2ulaw },
1376 { "lin2lin", audioop_lin2lin },
1377 { "adpcm2lin", audioop_adpcm2lin },
1378 { "lin2adpcm", audioop_lin2adpcm },
1379 { "tomono", audioop_tomono },
1380 { "tostereo", audioop_tostereo },
1381 { "getsample", audioop_getsample },
1382 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001383 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001384 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001385};
1386
Guido van Rossum3886bb61998-12-04 18:50:17 +00001387DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001388initaudioop(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001389{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001390 PyObject *m, *d;
1391 m = Py_InitModule("audioop", audioop_methods);
1392 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001393 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1394 if (AudioopError != NULL)
1395 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001396}