blob: 471f851fa2aae8581cffd02dbc4ff53bf025a431 [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;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000258 double 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
Guido van Rossum644a12b1997-04-09 19:24:53 +0000275 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000276 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;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000287 double 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);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000299 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000300 }
301 if ( len == 0 )
302 val = 0;
303 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000304 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000305 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;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000501 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502 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
Guido van Rossum644a12b1997-04-09 19:24:53 +0000547 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000548 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;
Guido van Rossum1851a671997-02-14 16:14:03 +0000784 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000785 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
Guido van Rossum1851a671997-02-14 16:14:03 +0000797 if ( size == 1 ) maxval = 0x7f;
798 else if ( size == 2 ) maxval = 0x7fff;
799 else if ( size == 4 ) maxval = 0x7fffffff;
800 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000801 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
802 return 0;
803 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000804
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000805 rv = PyString_FromStringAndSize(NULL, len1);
806 if ( rv == 0 )
807 return 0;
808 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000809
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000810 for ( i=0; i < len1; i += size ) {
811 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
812 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
813 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000814
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000815 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
816 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
817 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000818
Guido van Rossum1851a671997-02-14 16:14:03 +0000819 newval = val1 + val2;
820 /* truncate in case of overflow */
821 if (newval > maxval) newval = maxval;
822 else if (newval < -maxval) newval = -maxval;
823 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
824 newval = val1 > 0 ? maxval : - maxval;
825
826 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
827 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
828 else if ( size == 4 ) *LONGP(ncp, i) = (long)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000829 }
830 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831}
832
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000833static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834audioop_bias(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000835 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000836 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000837{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000838 signed char *cp, *ncp;
839 int len, size, val = 0;
840 PyObject *rv;
841 int i;
842 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000844 if ( !PyArg_Parse(args, "(s#ii)",
845 &cp, &len, &size , &bias) )
846 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000847
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000848 if ( size != 1 && size != 2 && size != 4) {
849 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
850 return 0;
851 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000852
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000853 rv = PyString_FromStringAndSize(NULL, len);
854 if ( rv == 0 )
855 return 0;
856 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000857
858
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000859 for ( i=0; i < len; i += size ) {
860 if ( size == 1 ) val = (int)*CHARP(cp, i);
861 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
862 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000863
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
865 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
866 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val+bias);
867 }
868 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000869}
870
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000871static PyObject *
Jack Jansen337b20e1993-02-23 13:39:57 +0000872audioop_reverse(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000874 PyObject *args;
Jack Jansen337b20e1993-02-23 13:39:57 +0000875{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000876 signed char *cp;
877 unsigned char *ncp;
878 int len, size, val = 0;
879 PyObject *rv;
880 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000881
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000882 if ( !PyArg_Parse(args, "(s#i)",
883 &cp, &len, &size) )
884 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000885
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000886 if ( size != 1 && size != 2 && size != 4 ) {
887 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
888 return 0;
889 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000890
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000891 rv = PyString_FromStringAndSize(NULL, len);
892 if ( rv == 0 )
893 return 0;
894 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000895
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000896 for ( i=0; i < len; i += size ) {
897 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
898 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
899 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000900
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000901 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000902
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
904 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
905 else if ( size == 4 ) *LONGP(ncp, j) = (long)(val<<16);
906 }
907 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000908}
909
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000910static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000911audioop_lin2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000912 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000913 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000914{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000915 signed char *cp;
916 unsigned char *ncp;
917 int len, size, size2, val = 0;
918 PyObject *rv;
919 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000920
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000921 if ( !PyArg_Parse(args, "(s#ii)",
922 &cp, &len, &size, &size2) )
923 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000924
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000925 if ( (size != 1 && size != 2 && size != 4) ||
926 (size2 != 1 && size2 != 2 && size2 != 4)) {
927 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
928 return 0;
929 }
Jack Jansena90805f1993-02-17 14:29:28 +0000930
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000931 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
932 if ( rv == 0 )
933 return 0;
934 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000935
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000936 for ( i=0, j=0; i < len; i += size, j += size2 ) {
937 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
938 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
939 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000940
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000941 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
942 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
943 else if ( size2 == 4 ) *LONGP(ncp, j) = (long)(val<<16);
944 }
945 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000946}
947
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000948static int
949gcd(a, b)
950 int a, b;
951{
952 while (b > 0) {
953 int tmp = a % b;
954 a = b;
955 b = tmp;
956 }
957 return a;
958}
959
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000960static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000961audioop_ratecv(self, args)
Guido van Rossum1851a671997-02-14 16:14:03 +0000962 PyObject *self;
963 PyObject *args;
Roger E. Massec905fff1997-01-17 18:12:04 +0000964{
Guido van Rossum1851a671997-02-14 16:14:03 +0000965 char *cp, *ncp;
966 int len, size, nchannels, inrate, outrate, weightA, weightB;
967 int chan, d, *prev_i, *cur_i, cur_o;
968 PyObject *state, *samps, *str, *rv;
969
970 weightA = 1;
971 weightB = 0;
972 if (!PyArg_ParseTuple(args, "s#iiiiO|ii", &cp, &len, &size, &nchannels,
973 &inrate, &outrate, &state, &weightA, &weightB))
974 return NULL;
975 if (size != 1 && size != 2 && size != 4) {
976 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
977 return NULL;
978 }
979 if (nchannels < 1) {
980 PyErr_SetString(AudioopError, "# of channels should be >= 1");
981 return NULL;
982 }
983 if (weightA < 1 || weightB < 0) {
984 PyErr_SetString(AudioopError,
985 "weightA should be >= 1, weightB should be >= 0");
986 return NULL;
987 }
988 if (len % (size * nchannels) != 0) {
989 PyErr_SetString(AudioopError, "not a whole number of frames");
990 return NULL;
991 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000992 if (inrate <= 0 || outrate <= 0) {
993 PyErr_SetString(AudioopError, "sampling rate not > 0");
994 return NULL;
995 }
996 /* divide inrate and outrate by their greatest common divisor */
997 d = gcd(inrate, outrate);
998 inrate /= d;
999 outrate /= d;
1000
Guido van Rossum1851a671997-02-14 16:14:03 +00001001 prev_i = malloc(nchannels * sizeof(int));
1002 cur_i = malloc(nchannels * sizeof(int));
1003 len /= size * nchannels; /* # of frames */
1004
1005 if (state == Py_None) {
1006 d = -outrate;
1007 for (chan = 0; chan < nchannels; chan++)
1008 prev_i[chan] = cur_i[chan] = 0;
1009 } else {
1010 if (!PyArg_ParseTuple(state,
1011 "iO!;audioop.ratecv: illegal state argument",
1012 &d, &PyTuple_Type, &samps))
1013 return NULL;
1014 if (PyTuple_Size(samps) != nchannels) {
1015 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +00001016 "illegal state argument");
Guido van Rossum1851a671997-02-14 16:14:03 +00001017 return NULL;
1018 }
1019 for (chan = 0; chan < nchannels; chan++) {
1020 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Roger E. Massec905fff1997-01-17 18:12:04 +00001021 "ii",&prev_i[chan],&cur_i[chan]))
Guido van Rossum1851a671997-02-14 16:14:03 +00001022 return NULL;
1023 }
1024 }
1025 str = PyString_FromStringAndSize(
1026 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
1027 if (str == NULL)
1028 return NULL;
1029 ncp = PyString_AsString(str);
1030
1031 for (;;) {
1032 while (d < 0) {
1033 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001034 samps = PyTuple_New(nchannels);
1035 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001036 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001037 Py_BuildValue("(ii)",
1038 prev_i[chan],
1039 cur_i[chan]));
1040 if (PyErr_Occurred())
1041 return NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +00001042 if (_PyString_Resize(&str,
1043 ncp - PyString_AsString(str)) < 0)
Roger E. Massec905fff1997-01-17 18:12:04 +00001044 return NULL;
1045 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001046 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001047 Py_DECREF(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001048 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001049 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001050 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001051 prev_i[chan] = cur_i[chan];
1052 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001053 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001054 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001055 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001056 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001057 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001058 cp += size;
1059 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001060 cur_i[chan] =
1061 (weightA * cur_i[chan] +
1062 weightB * prev_i[chan]) /
1063 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001064 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001065 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001066 d += outrate;
1067 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001068 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001069 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001070 cur_o = (prev_i[chan] * d +
1071 cur_i[chan] * (outrate - d)) /
1072 outrate;
1073 if (size == 1)
1074 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001075 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001076 *SHORTP(ncp, 0) = (short)(cur_o);
1077 else if (size == 4)
1078 *LONGP(ncp, 0) = (long)(cur_o<<16);
1079 ncp += size;
1080 }
1081 d -= inrate;
1082 }
1083 }
Roger E. Massec905fff1997-01-17 18:12:04 +00001084}
Guido van Rossum1851a671997-02-14 16:14:03 +00001085
Roger E. Massec905fff1997-01-17 18:12:04 +00001086static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001087audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001088 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001089 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001090{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001091 signed char *cp;
1092 unsigned char *ncp;
1093 int len, size, val = 0;
1094 PyObject *rv;
1095 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001096
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001097 if ( !PyArg_Parse(args, "(s#i)",
1098 &cp, &len, &size) )
1099 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001100
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001101 if ( size != 1 && size != 2 && size != 4) {
1102 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1103 return 0;
1104 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001105
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001106 rv = PyString_FromStringAndSize(NULL, len/size);
1107 if ( rv == 0 )
1108 return 0;
1109 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001110
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001111 for ( i=0; i < len; i += size ) {
1112 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1113 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1114 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001115
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116 *ncp++ = st_linear_to_ulaw(val);
1117 }
1118 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001119}
1120
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001121static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001122audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001123 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001124 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001125{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001126 unsigned char *cp;
1127 unsigned char cval;
1128 signed char *ncp;
1129 int len, size, val;
1130 PyObject *rv;
1131 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001132
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001133 if ( !PyArg_Parse(args, "(s#i)",
1134 &cp, &len, &size) )
1135 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001136
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001137 if ( size != 1 && size != 2 && size != 4) {
1138 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1139 return 0;
1140 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001141
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001142 rv = PyString_FromStringAndSize(NULL, len*size);
1143 if ( rv == 0 )
1144 return 0;
1145 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001146
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001147 for ( i=0; i < len*size; i += size ) {
1148 cval = *cp++;
1149 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001150
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001151 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1152 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1153 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val<<16);
1154 }
1155 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001156}
1157
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001158static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001159audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001160 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001161 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001162{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001163 signed char *cp;
1164 signed char *ncp;
1165 int len, size, val = 0, step, valpred, delta,
1166 index, sign, vpdiff, diff;
1167 PyObject *rv, *state, *str;
1168 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001169
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001170 if ( !PyArg_Parse(args, "(s#iO)",
1171 &cp, &len, &size, &state) )
1172 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001173
1174
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001175 if ( size != 1 && size != 2 && size != 4) {
1176 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1177 return 0;
1178 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001179
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001180 str = PyString_FromStringAndSize(NULL, len/(size*2));
1181 if ( str == 0 )
1182 return 0;
1183 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001184
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001185 /* Decode state, should have (value, step) */
1186 if ( state == Py_None ) {
1187 /* First time, it seems. Set defaults */
1188 valpred = 0;
1189 step = 7;
1190 index = 0;
1191 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1192 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001193
Guido van Rossumb64e6351992-07-06 14:21:56 +00001194 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001195 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001196
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001197 for ( i=0; i < len; i += size ) {
1198 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1199 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1200 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1201
1202 /* Step 1 - compute difference with previous value */
1203 diff = val - valpred;
1204 sign = (diff < 0) ? 8 : 0;
1205 if ( sign ) diff = (-diff);
1206
1207 /* Step 2 - Divide and clamp */
1208 /* Note:
1209 ** This code *approximately* computes:
1210 ** delta = diff*4/step;
1211 ** vpdiff = (delta+0.5)*step/4;
1212 ** but in shift step bits are dropped. The net result of this
1213 ** is that even if you have fast mul/div hardware you cannot
1214 ** put it to good use since the fixup would be too expensive.
1215 */
1216 delta = 0;
1217 vpdiff = (step >> 3);
1218
1219 if ( diff >= step ) {
1220 delta = 4;
1221 diff -= step;
1222 vpdiff += step;
1223 }
1224 step >>= 1;
1225 if ( diff >= step ) {
1226 delta |= 2;
1227 diff -= step;
1228 vpdiff += step;
1229 }
1230 step >>= 1;
1231 if ( diff >= step ) {
1232 delta |= 1;
1233 vpdiff += step;
1234 }
1235
1236 /* Step 3 - Update previous value */
1237 if ( sign )
1238 valpred -= vpdiff;
1239 else
1240 valpred += vpdiff;
1241
1242 /* Step 4 - Clamp previous value to 16 bits */
1243 if ( valpred > 32767 )
1244 valpred = 32767;
1245 else if ( valpred < -32768 )
1246 valpred = -32768;
1247
1248 /* Step 5 - Assemble value, update index and step values */
1249 delta |= sign;
1250
1251 index += indexTable[delta];
1252 if ( index < 0 ) index = 0;
1253 if ( index > 88 ) index = 88;
1254 step = stepsizeTable[index];
1255
1256 /* Step 6 - Output value */
1257 if ( bufferstep ) {
1258 outputbuffer = (delta << 4) & 0xf0;
1259 } else {
1260 *ncp++ = (delta & 0x0f) | outputbuffer;
1261 }
1262 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001263 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001264 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1265 Py_DECREF(str);
1266 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001267}
1268
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001269static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001270audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001271 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001272 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001273{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001274 signed char *cp;
1275 signed char *ncp;
1276 int len, size, valpred, step, delta, index, sign, vpdiff;
1277 PyObject *rv, *str, *state;
1278 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001279
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001280 if ( !PyArg_Parse(args, "(s#iO)",
1281 &cp, &len, &size, &state) )
1282 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001283
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001284 if ( size != 1 && size != 2 && size != 4) {
1285 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1286 return 0;
1287 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001288
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001289 /* Decode state, should have (value, step) */
1290 if ( state == Py_None ) {
1291 /* First time, it seems. Set defaults */
1292 valpred = 0;
1293 step = 7;
1294 index = 0;
1295 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1296 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001297
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001298 str = PyString_FromStringAndSize(NULL, len*size*2);
1299 if ( str == 0 )
1300 return 0;
1301 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001302
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001303 step = stepsizeTable[index];
1304 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001305
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001306 for ( i=0; i < len*size*2; i += size ) {
1307 /* Step 1 - get the delta value and compute next index */
1308 if ( bufferstep ) {
1309 delta = inputbuffer & 0xf;
1310 } else {
1311 inputbuffer = *cp++;
1312 delta = (inputbuffer >> 4) & 0xf;
1313 }
1314
1315 bufferstep = !bufferstep;
1316
1317 /* Step 2 - Find new index value (for later) */
1318 index += indexTable[delta];
1319 if ( index < 0 ) index = 0;
1320 if ( index > 88 ) index = 88;
1321
1322 /* Step 3 - Separate sign and magnitude */
1323 sign = delta & 8;
1324 delta = delta & 7;
1325
1326 /* Step 4 - Compute difference and new predicted value */
1327 /*
1328 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1329 ** in adpcm_coder.
1330 */
1331 vpdiff = step >> 3;
1332 if ( delta & 4 ) vpdiff += step;
1333 if ( delta & 2 ) vpdiff += step>>1;
1334 if ( delta & 1 ) vpdiff += step>>2;
1335
1336 if ( sign )
1337 valpred -= vpdiff;
1338 else
1339 valpred += vpdiff;
1340
1341 /* Step 5 - clamp output value */
1342 if ( valpred > 32767 )
1343 valpred = 32767;
1344 else if ( valpred < -32768 )
1345 valpred = -32768;
1346
1347 /* Step 6 - Update step value */
1348 step = stepsizeTable[index];
1349
1350 /* Step 6 - Output value */
1351 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1352 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1353 else if ( size == 4 ) *LONGP(ncp, i) = (long)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001354 }
1355
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001356 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1357 Py_DECREF(str);
1358 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001359}
1360
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001361static PyMethodDef audioop_methods[] = {
1362 { "max", audioop_max },
1363 { "minmax", audioop_minmax },
1364 { "avg", audioop_avg },
1365 { "maxpp", audioop_maxpp },
1366 { "avgpp", audioop_avgpp },
1367 { "rms", audioop_rms },
1368 { "findfit", audioop_findfit },
1369 { "findmax", audioop_findmax },
1370 { "findfactor", audioop_findfactor },
1371 { "cross", audioop_cross },
1372 { "mul", audioop_mul },
1373 { "add", audioop_add },
1374 { "bias", audioop_bias },
1375 { "ulaw2lin", audioop_ulaw2lin },
1376 { "lin2ulaw", audioop_lin2ulaw },
1377 { "lin2lin", audioop_lin2lin },
1378 { "adpcm2lin", audioop_adpcm2lin },
1379 { "lin2adpcm", audioop_lin2adpcm },
1380 { "tomono", audioop_tomono },
1381 { "tostereo", audioop_tostereo },
1382 { "getsample", audioop_getsample },
1383 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001384 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001385 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001386};
1387
Guido van Rossumb66efa01992-06-01 16:01:24 +00001388void
1389initaudioop()
1390{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001391 PyObject *m, *d;
1392 m = Py_InitModule("audioop", audioop_methods);
1393 d = PyModule_GetDict(m);
1394 AudioopError = PyString_FromString("audioop.error");
1395 if ( AudioopError == NULL
1396 || PyDict_SetItemString(d,"error",AudioopError) )
1397 Py_FatalError("can't define audioop.error");
Guido van Rossumb66efa01992-06-01 16:01:24 +00001398}