blob: 003f8af5cb7e69df13355329ed85dda83a00e206 [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
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000948static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000949audioop_ratecv(self, args)
Guido van Rossum1851a671997-02-14 16:14:03 +0000950 PyObject *self;
951 PyObject *args;
Roger E. Massec905fff1997-01-17 18:12:04 +0000952{
Guido van Rossum1851a671997-02-14 16:14:03 +0000953 char *cp, *ncp;
954 int len, size, nchannels, inrate, outrate, weightA, weightB;
955 int chan, d, *prev_i, *cur_i, cur_o;
956 PyObject *state, *samps, *str, *rv;
957
958 weightA = 1;
959 weightB = 0;
960 if (!PyArg_ParseTuple(args, "s#iiiiO|ii", &cp, &len, &size, &nchannels,
961 &inrate, &outrate, &state, &weightA, &weightB))
962 return NULL;
963 if (size != 1 && size != 2 && size != 4) {
964 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
965 return NULL;
966 }
967 if (nchannels < 1) {
968 PyErr_SetString(AudioopError, "# of channels should be >= 1");
969 return NULL;
970 }
971 if (weightA < 1 || weightB < 0) {
972 PyErr_SetString(AudioopError,
973 "weightA should be >= 1, weightB should be >= 0");
974 return NULL;
975 }
976 if (len % (size * nchannels) != 0) {
977 PyErr_SetString(AudioopError, "not a whole number of frames");
978 return NULL;
979 }
980 prev_i = malloc(nchannels * sizeof(int));
981 cur_i = malloc(nchannels * sizeof(int));
982 len /= size * nchannels; /* # of frames */
983
984 if (state == Py_None) {
985 d = -outrate;
986 for (chan = 0; chan < nchannels; chan++)
987 prev_i[chan] = cur_i[chan] = 0;
988 } else {
989 if (!PyArg_ParseTuple(state,
990 "iO!;audioop.ratecv: illegal state argument",
991 &d, &PyTuple_Type, &samps))
992 return NULL;
993 if (PyTuple_Size(samps) != nchannels) {
994 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +0000995 "illegal state argument");
Guido van Rossum1851a671997-02-14 16:14:03 +0000996 return NULL;
997 }
998 for (chan = 0; chan < nchannels; chan++) {
999 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Roger E. Massec905fff1997-01-17 18:12:04 +00001000 "ii",&prev_i[chan],&cur_i[chan]))
Guido van Rossum1851a671997-02-14 16:14:03 +00001001 return NULL;
1002 }
1003 }
1004 str = PyString_FromStringAndSize(
1005 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
1006 if (str == NULL)
1007 return NULL;
1008 ncp = PyString_AsString(str);
1009
1010 for (;;) {
1011 while (d < 0) {
1012 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001013 samps = PyTuple_New(nchannels);
1014 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001015 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001016 Py_BuildValue("(ii)",
1017 prev_i[chan],
1018 cur_i[chan]));
1019 if (PyErr_Occurred())
1020 return NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +00001021 if (_PyString_Resize(&str,
1022 ncp - PyString_AsString(str)) < 0)
Roger E. Massec905fff1997-01-17 18:12:04 +00001023 return NULL;
1024 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001025 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001026 Py_DECREF(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001027 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001028 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001029 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001030 prev_i[chan] = cur_i[chan];
1031 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001032 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001033 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001034 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001035 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001036 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001037 cp += size;
1038 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001039 cur_i[chan] =
1040 (weightA * cur_i[chan] +
1041 weightB * prev_i[chan]) /
1042 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001043 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001044 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001045 d += outrate;
1046 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001047 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001048 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001049 cur_o = (prev_i[chan] * d +
1050 cur_i[chan] * (outrate - d)) /
1051 outrate;
1052 if (size == 1)
1053 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001054 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001055 *SHORTP(ncp, 0) = (short)(cur_o);
1056 else if (size == 4)
1057 *LONGP(ncp, 0) = (long)(cur_o<<16);
1058 ncp += size;
1059 }
1060 d -= inrate;
1061 }
1062 }
Roger E. Massec905fff1997-01-17 18:12:04 +00001063}
Guido van Rossum1851a671997-02-14 16:14:03 +00001064
Roger E. Massec905fff1997-01-17 18:12:04 +00001065static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001066audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001067 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001068 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001069{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001070 signed char *cp;
1071 unsigned char *ncp;
1072 int len, size, val = 0;
1073 PyObject *rv;
1074 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001075
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001076 if ( !PyArg_Parse(args, "(s#i)",
1077 &cp, &len, &size) )
1078 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001079
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001080 if ( size != 1 && size != 2 && size != 4) {
1081 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1082 return 0;
1083 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001084
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001085 rv = PyString_FromStringAndSize(NULL, len/size);
1086 if ( rv == 0 )
1087 return 0;
1088 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001089
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001090 for ( i=0; i < len; i += size ) {
1091 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1092 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1093 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001094
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001095 *ncp++ = st_linear_to_ulaw(val);
1096 }
1097 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001098}
1099
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001100static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001101audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001102 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001103 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001104{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001105 unsigned char *cp;
1106 unsigned char cval;
1107 signed char *ncp;
1108 int len, size, val;
1109 PyObject *rv;
1110 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001111
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001112 if ( !PyArg_Parse(args, "(s#i)",
1113 &cp, &len, &size) )
1114 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001115
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116 if ( size != 1 && size != 2 && size != 4) {
1117 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1118 return 0;
1119 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001120
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001121 rv = PyString_FromStringAndSize(NULL, len*size);
1122 if ( rv == 0 )
1123 return 0;
1124 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001125
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001126 for ( i=0; i < len*size; i += size ) {
1127 cval = *cp++;
1128 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001129
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001130 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1131 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1132 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val<<16);
1133 }
1134 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001135}
1136
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001137static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001138audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001139 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001140 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001141{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001142 signed char *cp;
1143 signed char *ncp;
1144 int len, size, val = 0, step, valpred, delta,
1145 index, sign, vpdiff, diff;
1146 PyObject *rv, *state, *str;
1147 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001148
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001149 if ( !PyArg_Parse(args, "(s#iO)",
1150 &cp, &len, &size, &state) )
1151 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001152
1153
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001154 if ( size != 1 && size != 2 && size != 4) {
1155 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1156 return 0;
1157 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001158
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001159 str = PyString_FromStringAndSize(NULL, len/(size*2));
1160 if ( str == 0 )
1161 return 0;
1162 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001163
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001164 /* Decode state, should have (value, step) */
1165 if ( state == Py_None ) {
1166 /* First time, it seems. Set defaults */
1167 valpred = 0;
1168 step = 7;
1169 index = 0;
1170 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1171 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001172
Guido van Rossumb64e6351992-07-06 14:21:56 +00001173 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001174 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001175
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001176 for ( i=0; i < len; i += size ) {
1177 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1178 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1179 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1180
1181 /* Step 1 - compute difference with previous value */
1182 diff = val - valpred;
1183 sign = (diff < 0) ? 8 : 0;
1184 if ( sign ) diff = (-diff);
1185
1186 /* Step 2 - Divide and clamp */
1187 /* Note:
1188 ** This code *approximately* computes:
1189 ** delta = diff*4/step;
1190 ** vpdiff = (delta+0.5)*step/4;
1191 ** but in shift step bits are dropped. The net result of this
1192 ** is that even if you have fast mul/div hardware you cannot
1193 ** put it to good use since the fixup would be too expensive.
1194 */
1195 delta = 0;
1196 vpdiff = (step >> 3);
1197
1198 if ( diff >= step ) {
1199 delta = 4;
1200 diff -= step;
1201 vpdiff += step;
1202 }
1203 step >>= 1;
1204 if ( diff >= step ) {
1205 delta |= 2;
1206 diff -= step;
1207 vpdiff += step;
1208 }
1209 step >>= 1;
1210 if ( diff >= step ) {
1211 delta |= 1;
1212 vpdiff += step;
1213 }
1214
1215 /* Step 3 - Update previous value */
1216 if ( sign )
1217 valpred -= vpdiff;
1218 else
1219 valpred += vpdiff;
1220
1221 /* Step 4 - Clamp previous value to 16 bits */
1222 if ( valpred > 32767 )
1223 valpred = 32767;
1224 else if ( valpred < -32768 )
1225 valpred = -32768;
1226
1227 /* Step 5 - Assemble value, update index and step values */
1228 delta |= sign;
1229
1230 index += indexTable[delta];
1231 if ( index < 0 ) index = 0;
1232 if ( index > 88 ) index = 88;
1233 step = stepsizeTable[index];
1234
1235 /* Step 6 - Output value */
1236 if ( bufferstep ) {
1237 outputbuffer = (delta << 4) & 0xf0;
1238 } else {
1239 *ncp++ = (delta & 0x0f) | outputbuffer;
1240 }
1241 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001242 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001243 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1244 Py_DECREF(str);
1245 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001246}
1247
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001248static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001249audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001250 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001251 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001252{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001253 signed char *cp;
1254 signed char *ncp;
1255 int len, size, valpred, step, delta, index, sign, vpdiff;
1256 PyObject *rv, *str, *state;
1257 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001258
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001259 if ( !PyArg_Parse(args, "(s#iO)",
1260 &cp, &len, &size, &state) )
1261 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001262
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001263 if ( size != 1 && size != 2 && size != 4) {
1264 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1265 return 0;
1266 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001267
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001268 /* Decode state, should have (value, step) */
1269 if ( state == Py_None ) {
1270 /* First time, it seems. Set defaults */
1271 valpred = 0;
1272 step = 7;
1273 index = 0;
1274 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1275 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001276
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001277 str = PyString_FromStringAndSize(NULL, len*size*2);
1278 if ( str == 0 )
1279 return 0;
1280 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001281
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001282 step = stepsizeTable[index];
1283 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001284
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001285 for ( i=0; i < len*size*2; i += size ) {
1286 /* Step 1 - get the delta value and compute next index */
1287 if ( bufferstep ) {
1288 delta = inputbuffer & 0xf;
1289 } else {
1290 inputbuffer = *cp++;
1291 delta = (inputbuffer >> 4) & 0xf;
1292 }
1293
1294 bufferstep = !bufferstep;
1295
1296 /* Step 2 - Find new index value (for later) */
1297 index += indexTable[delta];
1298 if ( index < 0 ) index = 0;
1299 if ( index > 88 ) index = 88;
1300
1301 /* Step 3 - Separate sign and magnitude */
1302 sign = delta & 8;
1303 delta = delta & 7;
1304
1305 /* Step 4 - Compute difference and new predicted value */
1306 /*
1307 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1308 ** in adpcm_coder.
1309 */
1310 vpdiff = step >> 3;
1311 if ( delta & 4 ) vpdiff += step;
1312 if ( delta & 2 ) vpdiff += step>>1;
1313 if ( delta & 1 ) vpdiff += step>>2;
1314
1315 if ( sign )
1316 valpred -= vpdiff;
1317 else
1318 valpred += vpdiff;
1319
1320 /* Step 5 - clamp output value */
1321 if ( valpred > 32767 )
1322 valpred = 32767;
1323 else if ( valpred < -32768 )
1324 valpred = -32768;
1325
1326 /* Step 6 - Update step value */
1327 step = stepsizeTable[index];
1328
1329 /* Step 6 - Output value */
1330 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1331 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1332 else if ( size == 4 ) *LONGP(ncp, i) = (long)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001333 }
1334
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001335 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1336 Py_DECREF(str);
1337 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001338}
1339
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001340static PyMethodDef audioop_methods[] = {
1341 { "max", audioop_max },
1342 { "minmax", audioop_minmax },
1343 { "avg", audioop_avg },
1344 { "maxpp", audioop_maxpp },
1345 { "avgpp", audioop_avgpp },
1346 { "rms", audioop_rms },
1347 { "findfit", audioop_findfit },
1348 { "findmax", audioop_findmax },
1349 { "findfactor", audioop_findfactor },
1350 { "cross", audioop_cross },
1351 { "mul", audioop_mul },
1352 { "add", audioop_add },
1353 { "bias", audioop_bias },
1354 { "ulaw2lin", audioop_ulaw2lin },
1355 { "lin2ulaw", audioop_lin2ulaw },
1356 { "lin2lin", audioop_lin2lin },
1357 { "adpcm2lin", audioop_adpcm2lin },
1358 { "lin2adpcm", audioop_lin2adpcm },
1359 { "tomono", audioop_tomono },
1360 { "tostereo", audioop_tostereo },
1361 { "getsample", audioop_getsample },
1362 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001363 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001364 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001365};
1366
Guido van Rossumb66efa01992-06-01 16:01:24 +00001367void
1368initaudioop()
1369{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001370 PyObject *m, *d;
1371 m = Py_InitModule("audioop", audioop_methods);
1372 d = PyModule_GetDict(m);
1373 AudioopError = PyString_FromString("audioop.error");
1374 if ( AudioopError == NULL
1375 || PyDict_SetItemString(d,"error",AudioopError) )
1376 Py_FatalError("can't define audioop.error");
Guido van Rossumb66efa01992-06-01 16:01:24 +00001377}