blob: 01b37a1f74762e195fc75f5eb9e33018a233afa4 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumb66efa01992-06-01 16:01:24 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumb66efa01992-06-01 16:01:24 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumb66efa01992-06-01 16:01:24 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumb66efa01992-06-01 16:01:24 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumb66efa01992-06-01 16:01:24 +000029
30******************************************************************/
31
Guido van Rossumb6775db1994-08-01 11:34:53 +000032/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +000033
Roger E. Masseeaa6e111997-01-03 19:26:27 +000034#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +000035
Guido van Rossum7b1e9741994-08-29 10:46:42 +000036#if defined(__CHAR_UNSIGNED__)
37#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000038!ERROR!; READ THE SOURCE FILE!;
39/* This module currently does not work on systems where only unsigned
40 characters are available. Take it out of Setup. Sorry. */
41#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000042#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000043
Guido van Rossuma320fd31995-03-09 12:14:15 +000044#include "mymath.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000045
Jack Jansena90805f1993-02-17 14:29:28 +000046/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000047** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
48
49#define MINLIN -32768
50#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000051#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
52 else if ( x > MAXLIN ) x = MAXLIN; \
53 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000054
Guido van Rossumcd938fc1995-01-17 16:13:48 +000055static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000056
57/*
58** This macro converts from ulaw to 16 bit linear, faster.
59**
60** Jef Poskanzer
61** 23 October 1989
62**
63** Input: 8 bit ulaw sample
64** Output: signed 16 bit linear sample
65*/
66#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
67
68static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000069 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
70 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
71 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
72 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
73 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
74 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
75 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
76 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
77 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
78 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
79 -876, -844, -812, -780, -748, -716, -684, -652,
80 -620, -588, -556, -524, -492, -460, -428, -396,
81 -372, -356, -340, -324, -308, -292, -276, -260,
82 -244, -228, -212, -196, -180, -164, -148, -132,
83 -120, -112, -104, -96, -88, -80, -72, -64,
84 -56, -48, -40, -32, -24, -16, -8, 0,
85 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
86 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
87 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
88 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
89 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
90 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
91 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
92 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
93 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
94 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
95 876, 844, 812, 780, 748, 716, 684, 652,
96 620, 588, 556, 524, 492, 460, 428, 396,
97 372, 356, 340, 324, 308, 292, 276, 260,
98 244, 228, 212, 196, 180, 164, 148, 132,
99 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +0000100 56, 48, 40, 32, 24, 16, 8, 0 };
101
102#define ZEROTRAP /* turn on the trap as per the MIL-STD */
103#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
104#define CLIP 32635
105
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000106static unsigned char
Guido van Rossumb66efa01992-06-01 16:01:24 +0000107st_linear_to_ulaw( sample )
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000108 int sample;
109{
110 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
111 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
112 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
113 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
114 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
115 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
116 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
117 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
118 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
119 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
120 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
121 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
122 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
123 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
124 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
125 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
126 int sign, exponent, mantissa;
127 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000128
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000129 /* Get the sample into sign-magnitude. */
130 sign = (sample >> 8) & 0x80; /* set aside the sign */
131 if ( sign != 0 ) sample = -sample; /* get magnitude */
132 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000133
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000134 /* Convert from 16 bit linear to ulaw. */
135 sample = sample + BIAS;
136 exponent = exp_lut[( sample >> 7 ) & 0xFF];
137 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
138 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000139#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000140 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000141#endif
142
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000143 return ulawbyte;
144}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000145/* End of code taken from sox */
146
Guido van Rossumb64e6351992-07-06 14:21:56 +0000147/* Intel ADPCM step variation table */
148static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000149 -1, -1, -1, -1, 2, 4, 6, 8,
150 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000151};
152
153static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000154 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
155 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
156 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
157 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
158 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
159 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
160 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
161 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
162 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000163};
164
Guido van Rossumb66efa01992-06-01 16:01:24 +0000165#define CHARP(cp, i) ((signed char *)(cp+i))
166#define SHORTP(cp, i) ((short *)(cp+i))
167#define LONGP(cp, i) ((long *)(cp+i))
168
169
170
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000171static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000172
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000173static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000174audioop_getsample(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000175 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000176 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000177{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000178 signed char *cp;
179 int len, size, val = 0;
180 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000181
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000182 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
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 if ( i < 0 || i >= len/size ) {
189 PyErr_SetString(AudioopError, "Index out of range");
190 return 0;
191 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000192 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000193 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
194 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
195 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000196}
197
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000198static PyObject *
199audioop_max(self, args)
200 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000201 PyObject *args;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000202{
203 signed char *cp;
204 int len, size, val = 0;
205 int i;
206 int max = 0;
207
208 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
209 return 0;
210 if ( size != 1 && size != 2 && size != 4 ) {
211 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
212 return 0;
213 }
214 for ( i=0; i<len; i+= size) {
215 if ( size == 1 ) val = (int)*CHARP(cp, i);
216 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
217 else if ( size == 4 ) val = (int)*LONGP(cp, i);
218 if ( val < 0 ) val = (-val);
219 if ( val > max ) max = val;
220 }
221 return PyInt_FromLong(max);
222}
223
224static PyObject *
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000225audioop_minmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000226 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000227 PyObject *args;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000228{
229 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000230 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000231 int i;
232 int min = 0x7fffffff, max = -0x7fffffff;
233
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000234 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000235 return NULL;
236 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000237 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000238 return NULL;
239 }
240 for (i = 0; i < len; i += size) {
241 if (size == 1) val = (int) *CHARP(cp, i);
242 else if (size == 2) val = (int) *SHORTP(cp, i);
243 else if (size == 4) val = (int) *LONGP(cp, i);
244 if (val > max) max = val;
245 if (val < min) min = val;
246 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000247 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000248}
249
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000250static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000251audioop_avg(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000252 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000253 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000254{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000255 signed char *cp;
256 int len, size, val = 0;
257 int i;
258 float avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000259
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000260 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
261 return 0;
262 if ( size != 1 && size != 2 && size != 4 ) {
263 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
264 return 0;
265 }
266 for ( i=0; i<len; i+= size) {
267 if ( size == 1 ) val = (int)*CHARP(cp, i);
268 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
269 else if ( size == 4 ) val = (int)*LONGP(cp, i);
270 avg += val;
271 }
272 if ( len == 0 )
273 val = 0;
274 else
275 val = (int)(avg / (float)(len/size));
276 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000277}
278
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000279static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000280audioop_rms(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000281 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000282 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000283{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000284 signed char *cp;
285 int len, size, val = 0;
286 int i;
287 float sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000288
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000289 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
290 return 0;
291 if ( size != 1 && size != 2 && size != 4 ) {
292 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
293 return 0;
294 }
295 for ( i=0; i<len; i+= size) {
296 if ( size == 1 ) val = (int)*CHARP(cp, i);
297 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
298 else if ( size == 4 ) val = (int)*LONGP(cp, i);
299 sum_squares += (float)val*(float)val;
300 }
301 if ( len == 0 )
302 val = 0;
303 else
304 val = (int)sqrt(sum_squares / (float)(len/size));
305 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000306}
307
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000308static double _sum2(a, b, len)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000309 short *a;
Roger E. Massec905fff1997-01-17 18:12:04 +0000310 short *b;
311 int len;
Jack Jansena90805f1993-02-17 14:29:28 +0000312{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000313 int i;
314 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000315
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000316 for( i=0; i<len; i++) {
317 sum = sum + (double)a[i]*(double)b[i];
318 }
319 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000320}
321
322/*
323** Findfit tries to locate a sample within another sample. Its main use
324** is in echo-cancellation (to find the feedback of the output signal in
325** the input signal).
326** The method used is as follows:
327**
328** let R be the reference signal (length n) and A the input signal (length N)
329** with N > n, and let all sums be over i from 0 to n-1.
330**
331** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
332** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
333** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
334**
335** Next, we compute the relative distance between the original signal and
336** the modified signal and minimize that over j:
337** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
338** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
339**
340** In the code variables correspond as follows:
341** cp1 A
342** cp2 R
343** len1 N
344** len2 n
345** aj_m1 A[j-1]
346** aj_lm1 A[j+n-1]
347** sum_ri_2 sum(R[i]^2)
348** sum_aij_2 sum(A[i+j]^2)
349** sum_aij_ri sum(A[i+j]R[i])
350**
351** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
352** is completely recalculated each step.
353*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000354static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000355audioop_findfit(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000356 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000357 PyObject *args;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000358{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000359 short *cp1, *cp2;
360 int len1, len2;
361 int j, best_j;
362 double aj_m1, aj_lm1;
363 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000364
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000365 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
366 return 0;
367 if ( len1 & 1 || len2 & 1 ) {
368 PyErr_SetString(AudioopError, "Strings should be even-sized");
369 return 0;
370 }
371 len1 >>= 1;
372 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000373
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000374 if ( len1 < len2 ) {
375 PyErr_SetString(AudioopError, "First sample should be longer");
376 return 0;
377 }
378 sum_ri_2 = _sum2(cp2, cp2, len2);
379 sum_aij_2 = _sum2(cp1, cp1, len2);
380 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000381
382 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
383
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000384 best_result = result;
385 best_j = 0;
386 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000387
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000388 for ( j=1; j<=len1-len2; j++) {
389 aj_m1 = (double)cp1[j-1];
390 aj_lm1 = (double)cp1[j+len2-1];
391
392 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
393 sum_aij_ri = _sum2(cp1+j, cp2, len2);
394
395 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
396 / sum_aij_2;
397
398 if ( result < best_result ) {
399 best_result = result;
400 best_j = j;
401 }
402
403 }
404
405 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000406
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000408}
409
410/*
411** findfactor finds a factor f so that the energy in A-fB is minimal.
412** See the comment for findfit for details.
413*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000414static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000415audioop_findfactor(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000417 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000418{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000419 short *cp1, *cp2;
420 int len1, len2;
421 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000422
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000423 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
424 return 0;
425 if ( len1 & 1 || len2 & 1 ) {
426 PyErr_SetString(AudioopError, "Strings should be even-sized");
427 return 0;
428 }
429 if ( len1 != len2 ) {
430 PyErr_SetString(AudioopError, "Samples should be same size");
431 return 0;
432 }
433 len2 >>= 1;
434 sum_ri_2 = _sum2(cp2, cp2, len2);
435 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000436
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000437 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000438
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000439 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000440}
441
442/*
443** findmax returns the index of the n-sized segment of the input sample
444** that contains the most energy.
445*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000446static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000447audioop_findmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000448 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000449 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000450{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000451 short *cp1;
452 int len1, len2;
453 int j, best_j;
454 double aj_m1, aj_lm1;
455 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000456
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000457 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
458 return 0;
459 if ( len1 & 1 ) {
460 PyErr_SetString(AudioopError, "Strings should be even-sized");
461 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000462 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000463 len1 >>= 1;
464
465 if ( len1 < len2 ) {
466 PyErr_SetString(AudioopError, "Input sample should be longer");
467 return 0;
468 }
Jack Jansena90805f1993-02-17 14:29:28 +0000469
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000470 result = _sum2(cp1, cp1, len2);
471
472 best_result = result;
473 best_j = 0;
474 j = 0;
475
476 for ( j=1; j<=len1-len2; j++) {
477 aj_m1 = (double)cp1[j-1];
478 aj_lm1 = (double)cp1[j+len2-1];
479
480 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
481
482 if ( result > best_result ) {
483 best_result = result;
484 best_j = j;
485 }
486
487 }
488
489 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000490}
491
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000492static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000493audioop_avgpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000494 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000495 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000496{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000497 signed char *cp;
498 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
499 prevextreme = 0;
500 int i;
501 float avg = 0.0;
502 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000503
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000504 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
505 return 0;
506 if ( size != 1 && size != 2 && size != 4 ) {
507 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
508 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000509 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000510 /* Compute first delta value ahead. Also automatically makes us
511 ** skip the first extreme value
512 */
513 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
514 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
515 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
516 if ( size == 1 ) val = (int)*CHARP(cp, size);
517 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
518 else if ( size == 4 ) val = (int)*LONGP(cp, size);
519 prevdiff = val - prevval;
520
521 for ( i=size; i<len; i+= size) {
522 if ( size == 1 ) val = (int)*CHARP(cp, i);
523 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
524 else if ( size == 4 ) val = (int)*LONGP(cp, i);
525 diff = val - prevval;
526 if ( diff*prevdiff < 0 ) {
527 /* Derivative changed sign. Compute difference to last
528 ** extreme value and remember.
529 */
530 if ( prevextremevalid ) {
531 extremediff = prevval - prevextreme;
532 if ( extremediff < 0 )
533 extremediff = -extremediff;
534 avg += extremediff;
535 nextreme++;
536 }
537 prevextremevalid = 1;
538 prevextreme = prevval;
539 }
540 prevval = val;
541 if ( diff != 0 )
542 prevdiff = diff;
543 }
544 if ( nextreme == 0 )
545 val = 0;
546 else
547 val = (int)(avg / (float)nextreme);
548 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000549}
550
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000551static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000552audioop_maxpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000553 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000554 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000555{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000556 signed char *cp;
557 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
558 prevextreme = 0;
559 int i;
560 int max = 0;
561 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000562
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000563 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
564 return 0;
565 if ( size != 1 && size != 2 && size != 4 ) {
566 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
567 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000568 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000569 /* Compute first delta value ahead. Also automatically makes us
570 ** skip the first extreme value
571 */
572 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
573 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
574 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
575 if ( size == 1 ) val = (int)*CHARP(cp, size);
576 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
577 else if ( size == 4 ) val = (int)*LONGP(cp, size);
578 prevdiff = val - prevval;
579
580 for ( i=size; i<len; i+= size) {
581 if ( size == 1 ) val = (int)*CHARP(cp, i);
582 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
583 else if ( size == 4 ) val = (int)*LONGP(cp, i);
584 diff = val - prevval;
585 if ( diff*prevdiff < 0 ) {
586 /* Derivative changed sign. Compute difference to
587 ** last extreme value and remember.
588 */
589 if ( prevextremevalid ) {
590 extremediff = prevval - prevextreme;
591 if ( extremediff < 0 )
592 extremediff = -extremediff;
593 if ( extremediff > max )
594 max = extremediff;
595 }
596 prevextremevalid = 1;
597 prevextreme = prevval;
598 }
599 prevval = val;
600 if ( diff != 0 )
601 prevdiff = diff;
602 }
603 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000604}
605
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000606static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000607audioop_cross(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000608 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000609 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000610{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000611 signed char *cp;
612 int len, size, val = 0;
613 int i;
614 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000615
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000616 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
617 return 0;
618 if ( size != 1 && size != 2 && size != 4 ) {
619 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
620 return 0;
621 }
622 ncross = -1;
623 prevval = 17; /* Anything <> 0,1 */
624 for ( i=0; i<len; i+= size) {
625 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
626 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
627 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
628 val = val & 1;
629 if ( val != prevval ) ncross++;
630 prevval = val;
631 }
632 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000633}
634
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000635static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000636audioop_mul(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000638 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000639{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000640 signed char *cp, *ncp;
641 int len, size, val = 0;
642 double factor, fval, maxval;
643 PyObject *rv;
644 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000645
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000646 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
647 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000648
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649 if ( size == 1 ) maxval = (double) 0x7f;
650 else if ( size == 2 ) maxval = (double) 0x7fff;
651 else if ( size == 4 ) maxval = (double) 0x7fffffff;
652 else {
653 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
654 return 0;
655 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000656
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000657 rv = PyString_FromStringAndSize(NULL, len);
658 if ( rv == 0 )
659 return 0;
660 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000661
662
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000663 for ( i=0; i < len; i += size ) {
664 if ( size == 1 ) val = (int)*CHARP(cp, i);
665 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
666 else if ( size == 4 ) val = (int)*LONGP(cp, i);
667 fval = (double)val*factor;
668 if ( fval > maxval ) fval = maxval;
669 else if ( fval < -maxval ) fval = -maxval;
670 val = (int)fval;
671 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
672 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
673 else if ( size == 4 ) *LONGP(ncp, i) = (long)val;
674 }
675 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000676}
677
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000678static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000679audioop_tomono(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000680 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000681 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000682{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683 signed char *cp, *ncp;
684 int len, size, val1 = 0, val2 = 0;
685 double fac1, fac2, fval, maxval;
686 PyObject *rv;
687 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000688
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000689 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
690 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000691
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000692 if ( size == 1 ) maxval = (double) 0x7f;
693 else if ( size == 2 ) maxval = (double) 0x7fff;
694 else if ( size == 4 ) maxval = (double) 0x7fffffff;
695 else {
696 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
697 return 0;
698 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000699
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000700 rv = PyString_FromStringAndSize(NULL, len/2);
701 if ( rv == 0 )
702 return 0;
703 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000704
705
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000706 for ( i=0; i < len; i += size*2 ) {
707 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
708 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
709 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
710 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
711 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
712 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
713 fval = (double)val1*fac1 + (double)val2*fac2;
714 if ( fval > maxval ) fval = maxval;
715 else if ( fval < -maxval ) fval = -maxval;
716 val1 = (int)fval;
717 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
718 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
719 else if ( size == 4 ) *LONGP(ncp, i/2)= (long)val1;
720 }
721 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722}
723
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000724static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000725audioop_tostereo(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000726 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000727 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000728{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000729 signed char *cp, *ncp;
730 int len, size, val1, val2, val = 0;
731 double fac1, fac2, fval, maxval;
732 PyObject *rv;
733 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000734
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000735 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
736 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000737
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000738 if ( size == 1 ) maxval = (double) 0x7f;
739 else if ( size == 2 ) maxval = (double) 0x7fff;
740 else if ( size == 4 ) maxval = (double) 0x7fffffff;
741 else {
742 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
743 return 0;
744 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000746 rv = PyString_FromStringAndSize(NULL, len*2);
747 if ( rv == 0 )
748 return 0;
749 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
751
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000752 for ( i=0; i < len; i += size ) {
753 if ( size == 1 ) val = (int)*CHARP(cp, i);
754 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
755 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000756
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000757 fval = (double)val*fac1;
758 if ( fval > maxval ) fval = maxval;
759 else if ( fval < -maxval ) fval = -maxval;
760 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000762 fval = (double)val*fac2;
763 if ( fval > maxval ) fval = maxval;
764 else if ( fval < -maxval ) fval = -maxval;
765 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000766
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000767 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
768 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
769 else if ( size == 4 ) *LONGP(ncp, i*2) = (long)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000770
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000771 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
772 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
773 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (long)val2;
774 }
775 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000776}
777
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000778static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000779audioop_add(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000780 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000781 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000782{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783 signed char *cp1, *cp2, *ncp;
784 int len1, len2, size, val1 = 0, val2 = 0;
785 PyObject *rv;
786 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000788 if ( !PyArg_Parse(args, "(s#s#i)",
789 &cp1, &len1, &cp2, &len2, &size ) )
790 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792 if ( len1 != len2 ) {
793 PyErr_SetString(AudioopError, "Lengths should be the same");
794 return 0;
795 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000796
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000797 if ( size != 1 && size != 2 && size != 4) {
798 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
799 return 0;
800 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000801
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000802 rv = PyString_FromStringAndSize(NULL, len1);
803 if ( rv == 0 )
804 return 0;
805 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000806
807
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000808 for ( i=0; i < len1; i += size ) {
809 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
810 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
811 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000812
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000813 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
814 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
815 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000816
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000817 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val1+val2);
818 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val1+val2);
819 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val1+val2);
820 }
821 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000822}
823
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000824static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000825audioop_bias(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000826 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000827 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000828{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000829 signed char *cp, *ncp;
830 int len, size, val = 0;
831 PyObject *rv;
832 int i;
833 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000835 if ( !PyArg_Parse(args, "(s#ii)",
836 &cp, &len, &size , &bias) )
837 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000838
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000839 if ( size != 1 && size != 2 && size != 4) {
840 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
841 return 0;
842 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000844 rv = PyString_FromStringAndSize(NULL, len);
845 if ( rv == 0 )
846 return 0;
847 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000848
849
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000850 for ( i=0; i < len; i += size ) {
851 if ( size == 1 ) val = (int)*CHARP(cp, i);
852 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
853 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000855 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
856 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
857 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val+bias);
858 }
859 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860}
861
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000862static PyObject *
Jack Jansen337b20e1993-02-23 13:39:57 +0000863audioop_reverse(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000865 PyObject *args;
Jack Jansen337b20e1993-02-23 13:39:57 +0000866{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000867 signed char *cp;
868 unsigned char *ncp;
869 int len, size, val = 0;
870 PyObject *rv;
871 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000872
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873 if ( !PyArg_Parse(args, "(s#i)",
874 &cp, &len, &size) )
875 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000876
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000877 if ( size != 1 && size != 2 && size != 4 ) {
878 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
879 return 0;
880 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000881
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000882 rv = PyString_FromStringAndSize(NULL, len);
883 if ( rv == 0 )
884 return 0;
885 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000886
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000887 for ( i=0; i < len; i += size ) {
888 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
889 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
890 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000891
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000892 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000893
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000894 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
895 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
896 else if ( size == 4 ) *LONGP(ncp, j) = (long)(val<<16);
897 }
898 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000899}
900
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000901static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000902audioop_lin2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000904 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000905{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000906 signed char *cp;
907 unsigned char *ncp;
908 int len, size, size2, val = 0;
909 PyObject *rv;
910 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000911
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000912 if ( !PyArg_Parse(args, "(s#ii)",
913 &cp, &len, &size, &size2) )
914 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000915
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000916 if ( (size != 1 && size != 2 && size != 4) ||
917 (size2 != 1 && size2 != 2 && size2 != 4)) {
918 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
919 return 0;
920 }
Jack Jansena90805f1993-02-17 14:29:28 +0000921
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000922 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
923 if ( rv == 0 )
924 return 0;
925 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000926
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000927 for ( i=0, j=0; i < len; i += size, j += size2 ) {
928 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
929 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
930 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000931
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000932 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
933 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
934 else if ( size2 == 4 ) *LONGP(ncp, j) = (long)(val<<16);
935 }
936 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000937}
938
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000939static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000940audioop_ratecv(self, args)
941 PyObject *self;
942 PyObject *args;
943{
944 signed char *cp;
945 unsigned char *ncp;
946 int len, size, nchannels, inrate, outrate, weightA, weightB;
947 int chan, d, *prev_i, *cur_i, cur_o;
948 PyObject *state, *samps, *str, *rv;
949 weightA = 1;
950 weightB = 0;
951 if (!PyArg_ParseTuple(args, "s#iiiiO|ii", &cp, &len, &size, &nchannels,
952 &inrate, &outrate, &state, &weightA, &weightB))
953 return NULL;
954 if (size != 1 && size != 2 && size != 4) {
955 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
956 return NULL;
957 }
958 if (nchannels < 1) {
959 PyErr_SetString(AudioopError, "# of channels should be >= 1");
960 return NULL;
961 }
962 if (weightA < 1 || weightB < 0) {
963 PyErr_SetString(AudioopError,
964 "weightA should be >= 1, weightB should be >= 0");
965 return NULL;
966 }
967 prev_i = malloc(nchannels * sizeof(int));
968 cur_i = malloc(nchannels * sizeof(int));
969 len = len / size; /* # of frames */
970
971 if (state == Py_None) {
972 d = -outrate;
973 for (chan = 0; chan < nchannels; chan++)
974 prev_i[chan] = cur_i[chan] = 0;
975 } else {
976 if (!PyArg_ParseTuple(state,
977 "iO!;audioop.ratecv: illegal state argument",
978 &d, &PyTuple_Type, &samps))
979 return NULL;
980 if (PyTuple_Size(samps) != nchannels) {
981 PyErr_SetString(AudioopError,
982 "illegal state argument");
983 return NULL;
984 }
985 for (chan = 0; chan < nchannels; chan++) {
986 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
987 "ii",&prev_i[chan],&cur_i[chan]))
988 return NULL;
989 }
990 }
991 str = PyString_FromStringAndSize(NULL,
992 size * (len * outrate + inrate - 1) / inrate);
993 if (str == NULL)
994 return NULL;
995 ncp = PyString_AsString(str);
996
997 for (;;) {
998 while (d < 0) {
999 if (len == 0) {
1000 samps = PyTuple_New(nchannels);
1001 for (chan = 0; chan < nchannels; chan++)
1002 PyTuple_SetItem(samps, chan,
1003 Py_BuildValue("(ii)",
1004 prev_i[chan],
1005 cur_i[chan]));
1006 if (PyErr_Occurred())
1007 return NULL;
1008 if (_PyString_Resize(&str,
1009 ncp - (unsigned char *)
1010 PyString_AsString(str)) < 0)
1011 return NULL;
1012 rv = Py_BuildValue("(O(iO))", str, d, samps);
1013 Py_DECREF(samps);
1014 Py_DECREF(str);
1015 return rv;
1016 }
1017 for (chan = 0; chan < nchannels; chan++) {
1018 prev_i[chan] = cur_i[chan];
1019 if (size == 1)
1020 cur_i[chan] =
1021 ((int)*CHARP(cp, 0)) << 8;
1022 else if (size == 2)
1023 cur_i[chan] = (int)*SHORTP(cp, 0);
1024 else if (size == 4)
1025 cur_i[chan] =
1026 ((int)*LONGP(cp, 0)) >> 16;
1027 cp += size;
1028 /* implements a simple digital filter */
1029 cur_i[chan] = (weightA * cur_i[chan] +
1030 weightB * prev_i[chan])
1031 / (weightA + weightB);
1032 }
1033 len--;
1034 d += outrate;
1035 }
1036 while (d >= 0) {
1037 for (chan = 0; chan < nchannels; chan++) {
1038 cur_o = (prev_i[chan] * d + cur_i[chan]
1039 * (outrate - d)) / outrate;
1040 if (size == 1)
1041 *CHARP(ncp, 0) =
1042 (signed char)(cur_o >> 8);
1043 else if (size == 2)
1044 *SHORTP(ncp, 0) = (short)(cur_o);
1045 else if (size == 4)
1046 *LONGP(ncp, 0) = (long)(cur_o<<16);
1047 ncp += size;
1048 }
1049 d -= inrate;
1050 }
1051 }
1052}
1053
1054static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001055audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001056 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001057 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001058{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001059 signed char *cp;
1060 unsigned char *ncp;
1061 int len, size, val = 0;
1062 PyObject *rv;
1063 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001064
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001065 if ( !PyArg_Parse(args, "(s#i)",
1066 &cp, &len, &size) )
1067 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001068
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001069 if ( size != 1 && size != 2 && size != 4) {
1070 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1071 return 0;
1072 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001073
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001074 rv = PyString_FromStringAndSize(NULL, len/size);
1075 if ( rv == 0 )
1076 return 0;
1077 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001078
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001079 for ( i=0; i < len; i += size ) {
1080 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1081 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1082 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001083
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001084 *ncp++ = st_linear_to_ulaw(val);
1085 }
1086 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001087}
1088
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001089static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001090audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001091 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001092 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001093{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001094 unsigned char *cp;
1095 unsigned char cval;
1096 signed char *ncp;
1097 int len, size, val;
1098 PyObject *rv;
1099 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001100
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001101 if ( !PyArg_Parse(args, "(s#i)",
1102 &cp, &len, &size) )
1103 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001104
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001105 if ( size != 1 && size != 2 && size != 4) {
1106 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1107 return 0;
1108 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001109
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001110 rv = PyString_FromStringAndSize(NULL, len*size);
1111 if ( rv == 0 )
1112 return 0;
1113 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001114
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001115 for ( i=0; i < len*size; i += size ) {
1116 cval = *cp++;
1117 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001118
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001119 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1120 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1121 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val<<16);
1122 }
1123 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001124}
1125
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001126static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001127audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001128 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001129 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001130{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001131 signed char *cp;
1132 signed char *ncp;
1133 int len, size, val = 0, step, valpred, delta,
1134 index, sign, vpdiff, diff;
1135 PyObject *rv, *state, *str;
1136 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001137
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001138 if ( !PyArg_Parse(args, "(s#iO)",
1139 &cp, &len, &size, &state) )
1140 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001141
1142
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001143 if ( size != 1 && size != 2 && size != 4) {
1144 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1145 return 0;
1146 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001147
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001148 str = PyString_FromStringAndSize(NULL, len/(size*2));
1149 if ( str == 0 )
1150 return 0;
1151 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001152
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001153 /* Decode state, should have (value, step) */
1154 if ( state == Py_None ) {
1155 /* First time, it seems. Set defaults */
1156 valpred = 0;
1157 step = 7;
1158 index = 0;
1159 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1160 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001161
Guido van Rossumb64e6351992-07-06 14:21:56 +00001162 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001163 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001164
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001165 for ( i=0; i < len; i += size ) {
1166 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1167 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1168 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1169
1170 /* Step 1 - compute difference with previous value */
1171 diff = val - valpred;
1172 sign = (diff < 0) ? 8 : 0;
1173 if ( sign ) diff = (-diff);
1174
1175 /* Step 2 - Divide and clamp */
1176 /* Note:
1177 ** This code *approximately* computes:
1178 ** delta = diff*4/step;
1179 ** vpdiff = (delta+0.5)*step/4;
1180 ** but in shift step bits are dropped. The net result of this
1181 ** is that even if you have fast mul/div hardware you cannot
1182 ** put it to good use since the fixup would be too expensive.
1183 */
1184 delta = 0;
1185 vpdiff = (step >> 3);
1186
1187 if ( diff >= step ) {
1188 delta = 4;
1189 diff -= step;
1190 vpdiff += step;
1191 }
1192 step >>= 1;
1193 if ( diff >= step ) {
1194 delta |= 2;
1195 diff -= step;
1196 vpdiff += step;
1197 }
1198 step >>= 1;
1199 if ( diff >= step ) {
1200 delta |= 1;
1201 vpdiff += step;
1202 }
1203
1204 /* Step 3 - Update previous value */
1205 if ( sign )
1206 valpred -= vpdiff;
1207 else
1208 valpred += vpdiff;
1209
1210 /* Step 4 - Clamp previous value to 16 bits */
1211 if ( valpred > 32767 )
1212 valpred = 32767;
1213 else if ( valpred < -32768 )
1214 valpred = -32768;
1215
1216 /* Step 5 - Assemble value, update index and step values */
1217 delta |= sign;
1218
1219 index += indexTable[delta];
1220 if ( index < 0 ) index = 0;
1221 if ( index > 88 ) index = 88;
1222 step = stepsizeTable[index];
1223
1224 /* Step 6 - Output value */
1225 if ( bufferstep ) {
1226 outputbuffer = (delta << 4) & 0xf0;
1227 } else {
1228 *ncp++ = (delta & 0x0f) | outputbuffer;
1229 }
1230 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001231 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001232 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1233 Py_DECREF(str);
1234 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001235}
1236
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001237static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001238audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001239 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001240 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001241{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001242 signed char *cp;
1243 signed char *ncp;
1244 int len, size, valpred, step, delta, index, sign, vpdiff;
1245 PyObject *rv, *str, *state;
1246 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001247
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001248 if ( !PyArg_Parse(args, "(s#iO)",
1249 &cp, &len, &size, &state) )
1250 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001251
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001252 if ( size != 1 && size != 2 && size != 4) {
1253 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1254 return 0;
1255 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001256
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001257 /* Decode state, should have (value, step) */
1258 if ( state == Py_None ) {
1259 /* First time, it seems. Set defaults */
1260 valpred = 0;
1261 step = 7;
1262 index = 0;
1263 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1264 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001265
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001266 str = PyString_FromStringAndSize(NULL, len*size*2);
1267 if ( str == 0 )
1268 return 0;
1269 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001270
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001271 step = stepsizeTable[index];
1272 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001273
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001274 for ( i=0; i < len*size*2; i += size ) {
1275 /* Step 1 - get the delta value and compute next index */
1276 if ( bufferstep ) {
1277 delta = inputbuffer & 0xf;
1278 } else {
1279 inputbuffer = *cp++;
1280 delta = (inputbuffer >> 4) & 0xf;
1281 }
1282
1283 bufferstep = !bufferstep;
1284
1285 /* Step 2 - Find new index value (for later) */
1286 index += indexTable[delta];
1287 if ( index < 0 ) index = 0;
1288 if ( index > 88 ) index = 88;
1289
1290 /* Step 3 - Separate sign and magnitude */
1291 sign = delta & 8;
1292 delta = delta & 7;
1293
1294 /* Step 4 - Compute difference and new predicted value */
1295 /*
1296 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1297 ** in adpcm_coder.
1298 */
1299 vpdiff = step >> 3;
1300 if ( delta & 4 ) vpdiff += step;
1301 if ( delta & 2 ) vpdiff += step>>1;
1302 if ( delta & 1 ) vpdiff += step>>2;
1303
1304 if ( sign )
1305 valpred -= vpdiff;
1306 else
1307 valpred += vpdiff;
1308
1309 /* Step 5 - clamp output value */
1310 if ( valpred > 32767 )
1311 valpred = 32767;
1312 else if ( valpred < -32768 )
1313 valpred = -32768;
1314
1315 /* Step 6 - Update step value */
1316 step = stepsizeTable[index];
1317
1318 /* Step 6 - Output value */
1319 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1320 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1321 else if ( size == 4 ) *LONGP(ncp, i) = (long)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001322 }
1323
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001324 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1325 Py_DECREF(str);
1326 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001327}
1328
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001329static PyMethodDef audioop_methods[] = {
1330 { "max", audioop_max },
1331 { "minmax", audioop_minmax },
1332 { "avg", audioop_avg },
1333 { "maxpp", audioop_maxpp },
1334 { "avgpp", audioop_avgpp },
1335 { "rms", audioop_rms },
1336 { "findfit", audioop_findfit },
1337 { "findmax", audioop_findmax },
1338 { "findfactor", audioop_findfactor },
1339 { "cross", audioop_cross },
1340 { "mul", audioop_mul },
1341 { "add", audioop_add },
1342 { "bias", audioop_bias },
1343 { "ulaw2lin", audioop_ulaw2lin },
1344 { "lin2ulaw", audioop_lin2ulaw },
1345 { "lin2lin", audioop_lin2lin },
1346 { "adpcm2lin", audioop_adpcm2lin },
1347 { "lin2adpcm", audioop_lin2adpcm },
1348 { "tomono", audioop_tomono },
1349 { "tostereo", audioop_tostereo },
1350 { "getsample", audioop_getsample },
1351 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001352 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001353 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001354};
1355
Guido van Rossumb66efa01992-06-01 16:01:24 +00001356void
1357initaudioop()
1358{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001359 PyObject *m, *d;
1360 m = Py_InitModule("audioop", audioop_methods);
1361 d = PyModule_GetDict(m);
1362 AudioopError = PyString_FromString("audioop.error");
1363 if ( AudioopError == NULL
1364 || PyDict_SetItemString(d,"error",AudioopError) )
1365 Py_FatalError("can't define audioop.error");
Guido van Rossumb66efa01992-06-01 16:01:24 +00001366}