blob: 76fba98066b469d5d7796bc6e894e1fe1b50c4c8 [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 Rossum69011961998-04-23 20:23:00 +000036#if SIZEOF_INT == 4
37typedef int Py_Int32;
38typedef unsigned int Py_UInt32;
39#else
40#if SIZEOF_LONG == 4
41typedef long Py_Int32;
42typedef unsigned long Py_UInt32;
43#else
44#error "No 4-byte integral type"
45#endif
46#endif
47
Guido van Rossum7b1e9741994-08-29 10:46:42 +000048#if defined(__CHAR_UNSIGNED__)
49#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000050!ERROR!; READ THE SOURCE FILE!;
51/* This module currently does not work on systems where only unsigned
52 characters are available. Take it out of Setup. Sorry. */
53#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000054#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000055
Guido van Rossuma320fd31995-03-09 12:14:15 +000056#include "mymath.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000057
Jack Jansena90805f1993-02-17 14:29:28 +000058/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000059** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
60
61#define MINLIN -32768
62#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000063#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
64 else if ( x > MAXLIN ) x = MAXLIN; \
65 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000066
Guido van Rossumcd938fc1995-01-17 16:13:48 +000067static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000068
69/*
70** This macro converts from ulaw to 16 bit linear, faster.
71**
72** Jef Poskanzer
73** 23 October 1989
74**
75** Input: 8 bit ulaw sample
76** Output: signed 16 bit linear sample
77*/
78#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
79
80static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000081 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
82 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
83 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
84 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
85 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
86 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
87 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
88 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
89 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
90 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
91 -876, -844, -812, -780, -748, -716, -684, -652,
92 -620, -588, -556, -524, -492, -460, -428, -396,
93 -372, -356, -340, -324, -308, -292, -276, -260,
94 -244, -228, -212, -196, -180, -164, -148, -132,
95 -120, -112, -104, -96, -88, -80, -72, -64,
96 -56, -48, -40, -32, -24, -16, -8, 0,
97 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
98 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
99 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
100 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
101 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
102 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
103 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
104 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
105 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
106 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
107 876, 844, 812, 780, 748, 716, 684, 652,
108 620, 588, 556, 524, 492, 460, 428, 396,
109 372, 356, 340, 324, 308, 292, 276, 260,
110 244, 228, 212, 196, 180, 164, 148, 132,
111 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +0000112 56, 48, 40, 32, 24, 16, 8, 0 };
113
114#define ZEROTRAP /* turn on the trap as per the MIL-STD */
115#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
116#define CLIP 32635
117
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000118static unsigned char
Guido van Rossumb66efa01992-06-01 16:01:24 +0000119st_linear_to_ulaw( sample )
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000120 int sample;
121{
122 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
123 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
124 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
125 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
126 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
127 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
128 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
129 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
130 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
131 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
132 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
133 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
134 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
135 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
136 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
137 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
138 int sign, exponent, mantissa;
139 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000140
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000141 /* Get the sample into sign-magnitude. */
142 sign = (sample >> 8) & 0x80; /* set aside the sign */
143 if ( sign != 0 ) sample = -sample; /* get magnitude */
144 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000145
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000146 /* Convert from 16 bit linear to ulaw. */
147 sample = sample + BIAS;
148 exponent = exp_lut[( sample >> 7 ) & 0xFF];
149 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
150 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000151#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000152 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000153#endif
154
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000155 return ulawbyte;
156}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000157/* End of code taken from sox */
158
Guido van Rossumb64e6351992-07-06 14:21:56 +0000159/* Intel ADPCM step variation table */
160static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000161 -1, -1, -1, -1, 2, 4, 6, 8,
162 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000163};
164
165static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000166 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
167 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
168 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
169 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
170 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
171 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
172 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
173 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
174 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000175};
176
Guido van Rossumb66efa01992-06-01 16:01:24 +0000177#define CHARP(cp, i) ((signed char *)(cp+i))
178#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000179#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000180
181
182
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000183static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000184
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000185static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000186audioop_getsample(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000187 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000188 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000189{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000190 signed char *cp;
191 int len, size, val = 0;
192 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000193
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000194 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
195 return 0;
196 if ( size != 1 && size != 2 && size != 4 ) {
197 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
198 return 0;
199 }
200 if ( i < 0 || i >= len/size ) {
201 PyErr_SetString(AudioopError, "Index out of range");
202 return 0;
203 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000204 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000205 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
206 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
207 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000208}
209
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000210static PyObject *
211audioop_max(self, args)
212 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000213 PyObject *args;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000214{
215 signed char *cp;
216 int len, size, val = 0;
217 int i;
218 int max = 0;
219
220 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
221 return 0;
222 if ( size != 1 && size != 2 && size != 4 ) {
223 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
224 return 0;
225 }
226 for ( i=0; i<len; i+= size) {
227 if ( size == 1 ) val = (int)*CHARP(cp, i);
228 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
229 else if ( size == 4 ) val = (int)*LONGP(cp, i);
230 if ( val < 0 ) val = (-val);
231 if ( val > max ) max = val;
232 }
233 return PyInt_FromLong(max);
234}
235
236static PyObject *
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000237audioop_minmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000238 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000239 PyObject *args;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000240{
241 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000242 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000243 int i;
244 int min = 0x7fffffff, max = -0x7fffffff;
245
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000246 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000247 return NULL;
248 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000249 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000250 return NULL;
251 }
252 for (i = 0; i < len; i += size) {
253 if (size == 1) val = (int) *CHARP(cp, i);
254 else if (size == 2) val = (int) *SHORTP(cp, i);
255 else if (size == 4) val = (int) *LONGP(cp, i);
256 if (val > max) max = val;
257 if (val < min) min = val;
258 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000259 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000260}
261
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000262static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000263audioop_avg(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000264 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000265 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000266{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000267 signed char *cp;
268 int len, size, val = 0;
269 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000270 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000271
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000272 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
273 return 0;
274 if ( size != 1 && size != 2 && size != 4 ) {
275 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
276 return 0;
277 }
278 for ( i=0; i<len; i+= size) {
279 if ( size == 1 ) val = (int)*CHARP(cp, i);
280 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
281 else if ( size == 4 ) val = (int)*LONGP(cp, i);
282 avg += val;
283 }
284 if ( len == 0 )
285 val = 0;
286 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000287 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000288 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000289}
290
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000291static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000292audioop_rms(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000293 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000294 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000295{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000296 signed char *cp;
297 int len, size, val = 0;
298 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000299 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000300
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000301 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
302 return 0;
303 if ( size != 1 && size != 2 && size != 4 ) {
304 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
305 return 0;
306 }
307 for ( i=0; i<len; i+= size) {
308 if ( size == 1 ) val = (int)*CHARP(cp, i);
309 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
310 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000311 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000312 }
313 if ( len == 0 )
314 val = 0;
315 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000316 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000317 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000318}
319
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000320static double _sum2(a, b, len)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000321 short *a;
Roger E. Massec905fff1997-01-17 18:12:04 +0000322 short *b;
323 int len;
Jack Jansena90805f1993-02-17 14:29:28 +0000324{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000325 int i;
326 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000327
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000328 for( i=0; i<len; i++) {
329 sum = sum + (double)a[i]*(double)b[i];
330 }
331 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000332}
333
334/*
335** Findfit tries to locate a sample within another sample. Its main use
336** is in echo-cancellation (to find the feedback of the output signal in
337** the input signal).
338** The method used is as follows:
339**
340** let R be the reference signal (length n) and A the input signal (length N)
341** with N > n, and let all sums be over i from 0 to n-1.
342**
343** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
344** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
345** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
346**
347** Next, we compute the relative distance between the original signal and
348** the modified signal and minimize that over j:
349** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
350** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
351**
352** In the code variables correspond as follows:
353** cp1 A
354** cp2 R
355** len1 N
356** len2 n
357** aj_m1 A[j-1]
358** aj_lm1 A[j+n-1]
359** sum_ri_2 sum(R[i]^2)
360** sum_aij_2 sum(A[i+j]^2)
361** sum_aij_ri sum(A[i+j]R[i])
362**
363** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
364** is completely recalculated each step.
365*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000366static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000367audioop_findfit(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000368 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000369 PyObject *args;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000370{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000371 short *cp1, *cp2;
372 int len1, len2;
373 int j, best_j;
374 double aj_m1, aj_lm1;
375 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000376
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000377 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
378 return 0;
379 if ( len1 & 1 || len2 & 1 ) {
380 PyErr_SetString(AudioopError, "Strings should be even-sized");
381 return 0;
382 }
383 len1 >>= 1;
384 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000385
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000386 if ( len1 < len2 ) {
387 PyErr_SetString(AudioopError, "First sample should be longer");
388 return 0;
389 }
390 sum_ri_2 = _sum2(cp2, cp2, len2);
391 sum_aij_2 = _sum2(cp1, cp1, len2);
392 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000393
394 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
395
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000396 best_result = result;
397 best_j = 0;
398 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000399
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000400 for ( j=1; j<=len1-len2; j++) {
401 aj_m1 = (double)cp1[j-1];
402 aj_lm1 = (double)cp1[j+len2-1];
403
404 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
405 sum_aij_ri = _sum2(cp1+j, cp2, len2);
406
407 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
408 / sum_aij_2;
409
410 if ( result < best_result ) {
411 best_result = result;
412 best_j = j;
413 }
414
415 }
416
417 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000418
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000419 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000420}
421
422/*
423** findfactor finds a factor f so that the energy in A-fB is minimal.
424** See the comment for findfit for details.
425*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000426static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000427audioop_findfactor(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000428 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000429 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000430{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000431 short *cp1, *cp2;
432 int len1, len2;
433 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000434
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000435 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
436 return 0;
437 if ( len1 & 1 || len2 & 1 ) {
438 PyErr_SetString(AudioopError, "Strings should be even-sized");
439 return 0;
440 }
441 if ( len1 != len2 ) {
442 PyErr_SetString(AudioopError, "Samples should be same size");
443 return 0;
444 }
445 len2 >>= 1;
446 sum_ri_2 = _sum2(cp2, cp2, len2);
447 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000448
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000449 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000450
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000451 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000452}
453
454/*
455** findmax returns the index of the n-sized segment of the input sample
456** that contains the most energy.
457*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000458static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000459audioop_findmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000460 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000461 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000462{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000463 short *cp1;
464 int len1, len2;
465 int j, best_j;
466 double aj_m1, aj_lm1;
467 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000468
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000469 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
470 return 0;
471 if ( len1 & 1 ) {
472 PyErr_SetString(AudioopError, "Strings should be even-sized");
473 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000474 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000475 len1 >>= 1;
476
477 if ( len1 < len2 ) {
478 PyErr_SetString(AudioopError, "Input sample should be longer");
479 return 0;
480 }
Jack Jansena90805f1993-02-17 14:29:28 +0000481
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000482 result = _sum2(cp1, cp1, len2);
483
484 best_result = result;
485 best_j = 0;
486 j = 0;
487
488 for ( j=1; j<=len1-len2; j++) {
489 aj_m1 = (double)cp1[j-1];
490 aj_lm1 = (double)cp1[j+len2-1];
491
492 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
493
494 if ( result > best_result ) {
495 best_result = result;
496 best_j = j;
497 }
498
499 }
500
501 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000502}
503
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000504static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000505audioop_avgpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000506 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000507 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000508{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000509 signed char *cp;
510 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
511 prevextreme = 0;
512 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000513 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000514 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000515
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000516 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
517 return 0;
518 if ( size != 1 && size != 2 && size != 4 ) {
519 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
520 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000521 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000522 /* Compute first delta value ahead. Also automatically makes us
523 ** skip the first extreme value
524 */
525 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
526 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
527 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
528 if ( size == 1 ) val = (int)*CHARP(cp, size);
529 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
530 else if ( size == 4 ) val = (int)*LONGP(cp, size);
531 prevdiff = val - prevval;
532
533 for ( i=size; i<len; i+= size) {
534 if ( size == 1 ) val = (int)*CHARP(cp, i);
535 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
536 else if ( size == 4 ) val = (int)*LONGP(cp, i);
537 diff = val - prevval;
538 if ( diff*prevdiff < 0 ) {
539 /* Derivative changed sign. Compute difference to last
540 ** extreme value and remember.
541 */
542 if ( prevextremevalid ) {
543 extremediff = prevval - prevextreme;
544 if ( extremediff < 0 )
545 extremediff = -extremediff;
546 avg += extremediff;
547 nextreme++;
548 }
549 prevextremevalid = 1;
550 prevextreme = prevval;
551 }
552 prevval = val;
553 if ( diff != 0 )
554 prevdiff = diff;
555 }
556 if ( nextreme == 0 )
557 val = 0;
558 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000559 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000561}
562
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000563static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000564audioop_maxpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000565 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000566 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000567{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000568 signed char *cp;
569 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
570 prevextreme = 0;
571 int i;
572 int max = 0;
573 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000574
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000575 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
576 return 0;
577 if ( size != 1 && size != 2 && size != 4 ) {
578 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
579 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000580 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000581 /* Compute first delta value ahead. Also automatically makes us
582 ** skip the first extreme value
583 */
584 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
585 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
586 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
587 if ( size == 1 ) val = (int)*CHARP(cp, size);
588 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
589 else if ( size == 4 ) val = (int)*LONGP(cp, size);
590 prevdiff = val - prevval;
591
592 for ( i=size; i<len; i+= size) {
593 if ( size == 1 ) val = (int)*CHARP(cp, i);
594 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
595 else if ( size == 4 ) val = (int)*LONGP(cp, i);
596 diff = val - prevval;
597 if ( diff*prevdiff < 0 ) {
598 /* Derivative changed sign. Compute difference to
599 ** last extreme value and remember.
600 */
601 if ( prevextremevalid ) {
602 extremediff = prevval - prevextreme;
603 if ( extremediff < 0 )
604 extremediff = -extremediff;
605 if ( extremediff > max )
606 max = extremediff;
607 }
608 prevextremevalid = 1;
609 prevextreme = prevval;
610 }
611 prevval = val;
612 if ( diff != 0 )
613 prevdiff = diff;
614 }
615 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000616}
617
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000618static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000619audioop_cross(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000620 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000621 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000622{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000623 signed char *cp;
624 int len, size, val = 0;
625 int i;
626 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000627
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000628 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
629 return 0;
630 if ( size != 1 && size != 2 && size != 4 ) {
631 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
632 return 0;
633 }
634 ncross = -1;
635 prevval = 17; /* Anything <> 0,1 */
636 for ( i=0; i<len; i+= size) {
637 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
638 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
639 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
640 val = val & 1;
641 if ( val != prevval ) ncross++;
642 prevval = val;
643 }
644 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000645}
646
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000647static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000648audioop_mul(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000650 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000651{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000652 signed char *cp, *ncp;
653 int len, size, val = 0;
654 double factor, fval, maxval;
655 PyObject *rv;
656 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000657
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000658 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
659 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000660
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000661 if ( size == 1 ) maxval = (double) 0x7f;
662 else if ( size == 2 ) maxval = (double) 0x7fff;
663 else if ( size == 4 ) maxval = (double) 0x7fffffff;
664 else {
665 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
666 return 0;
667 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000668
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000669 rv = PyString_FromStringAndSize(NULL, len);
670 if ( rv == 0 )
671 return 0;
672 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000673
674
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000675 for ( i=0; i < len; i += size ) {
676 if ( size == 1 ) val = (int)*CHARP(cp, i);
677 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
678 else if ( size == 4 ) val = (int)*LONGP(cp, i);
679 fval = (double)val*factor;
680 if ( fval > maxval ) fval = maxval;
681 else if ( fval < -maxval ) fval = -maxval;
682 val = (int)fval;
683 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
684 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000685 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000686 }
687 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000688}
689
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000690static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000691audioop_tomono(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000692 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000693 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000694{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000695 signed char *cp, *ncp;
696 int len, size, val1 = 0, val2 = 0;
697 double fac1, fac2, fval, maxval;
698 PyObject *rv;
699 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000700
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000701 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
702 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000703
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000704 if ( size == 1 ) maxval = (double) 0x7f;
705 else if ( size == 2 ) maxval = (double) 0x7fff;
706 else if ( size == 4 ) maxval = (double) 0x7fffffff;
707 else {
708 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
709 return 0;
710 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000711
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000712 rv = PyString_FromStringAndSize(NULL, len/2);
713 if ( rv == 0 )
714 return 0;
715 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000716
717
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000718 for ( i=0; i < len; i += size*2 ) {
719 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
720 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
721 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
722 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
723 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
724 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
725 fval = (double)val1*fac1 + (double)val2*fac2;
726 if ( fval > maxval ) fval = maxval;
727 else if ( fval < -maxval ) fval = -maxval;
728 val1 = (int)fval;
729 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
730 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000731 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000732 }
733 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000734}
735
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000736static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000737audioop_tostereo(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000738 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000739 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000740{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000741 signed char *cp, *ncp;
742 int len, size, val1, val2, val = 0;
743 double fac1, fac2, fval, maxval;
744 PyObject *rv;
745 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000746
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000747 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
748 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000749
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000750 if ( size == 1 ) maxval = (double) 0x7f;
751 else if ( size == 2 ) maxval = (double) 0x7fff;
752 else if ( size == 4 ) maxval = (double) 0x7fffffff;
753 else {
754 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
755 return 0;
756 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000757
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000758 rv = PyString_FromStringAndSize(NULL, len*2);
759 if ( rv == 0 )
760 return 0;
761 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000762
763
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000764 for ( i=0; i < len; i += size ) {
765 if ( size == 1 ) val = (int)*CHARP(cp, i);
766 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
767 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000768
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000769 fval = (double)val*fac1;
770 if ( fval > maxval ) fval = maxval;
771 else if ( fval < -maxval ) fval = -maxval;
772 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000773
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000774 fval = (double)val*fac2;
775 if ( fval > maxval ) fval = maxval;
776 else if ( fval < -maxval ) fval = -maxval;
777 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000778
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000779 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
780 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000781 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000782
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
784 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000785 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000786 }
787 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000788}
789
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000790static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791audioop_add(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000793 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000794{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000795 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000796 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000797 PyObject *rv;
798 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000799
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000800 if ( !PyArg_Parse(args, "(s#s#i)",
801 &cp1, &len1, &cp2, &len2, &size ) )
802 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000803
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000804 if ( len1 != len2 ) {
805 PyErr_SetString(AudioopError, "Lengths should be the same");
806 return 0;
807 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000808
Guido van Rossum1851a671997-02-14 16:14:03 +0000809 if ( size == 1 ) maxval = 0x7f;
810 else if ( size == 2 ) maxval = 0x7fff;
811 else if ( size == 4 ) maxval = 0x7fffffff;
812 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000813 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
814 return 0;
815 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000816
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000817 rv = PyString_FromStringAndSize(NULL, len1);
818 if ( rv == 0 )
819 return 0;
820 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000821
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000822 for ( i=0; i < len1; i += size ) {
823 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
824 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
825 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000826
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000827 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
828 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
829 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000830
Guido van Rossum1851a671997-02-14 16:14:03 +0000831 newval = val1 + val2;
832 /* truncate in case of overflow */
833 if (newval > maxval) newval = maxval;
834 else if (newval < -maxval) newval = -maxval;
835 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
836 newval = val1 > 0 ? maxval : - maxval;
837
838 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
839 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000840 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000841 }
842 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843}
844
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000845static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000846audioop_bias(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000847 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000848 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000849{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000850 signed char *cp, *ncp;
851 int len, size, val = 0;
852 PyObject *rv;
853 int i;
854 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000855
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000856 if ( !PyArg_Parse(args, "(s#ii)",
857 &cp, &len, &size , &bias) )
858 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000859
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000860 if ( size != 1 && size != 2 && size != 4) {
861 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
862 return 0;
863 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000864
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000865 rv = PyString_FromStringAndSize(NULL, len);
866 if ( rv == 0 )
867 return 0;
868 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000869
870
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000871 for ( i=0; i < len; i += size ) {
872 if ( size == 1 ) val = (int)*CHARP(cp, i);
873 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
874 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000875
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000876 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
877 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000878 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000879 }
880 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000881}
882
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000883static PyObject *
Jack Jansen337b20e1993-02-23 13:39:57 +0000884audioop_reverse(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000885 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000886 PyObject *args;
Jack Jansen337b20e1993-02-23 13:39:57 +0000887{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000888 signed char *cp;
889 unsigned char *ncp;
890 int len, size, val = 0;
891 PyObject *rv;
892 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000893
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000894 if ( !PyArg_Parse(args, "(s#i)",
895 &cp, &len, &size) )
896 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000897
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000898 if ( size != 1 && size != 2 && size != 4 ) {
899 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
900 return 0;
901 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000902
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903 rv = PyString_FromStringAndSize(NULL, len);
904 if ( rv == 0 )
905 return 0;
906 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000907
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000908 for ( i=0; i < len; i += size ) {
909 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
910 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
911 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000912
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000913 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000914
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000915 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
916 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000917 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000918 }
919 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000920}
921
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000922static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000923audioop_lin2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000924 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000925 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000926{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000927 signed char *cp;
928 unsigned char *ncp;
929 int len, size, size2, val = 0;
930 PyObject *rv;
931 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000932
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000933 if ( !PyArg_Parse(args, "(s#ii)",
934 &cp, &len, &size, &size2) )
935 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000936
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000937 if ( (size != 1 && size != 2 && size != 4) ||
938 (size2 != 1 && size2 != 2 && size2 != 4)) {
939 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
940 return 0;
941 }
Jack Jansena90805f1993-02-17 14:29:28 +0000942
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000943 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
944 if ( rv == 0 )
945 return 0;
946 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000947
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000948 for ( i=0, j=0; i < len; i += size, j += size2 ) {
949 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
950 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
951 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000952
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000953 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
954 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000955 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000956 }
957 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000958}
959
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000960static int
961gcd(a, b)
962 int a, b;
963{
964 while (b > 0) {
965 int tmp = a % b;
966 a = b;
967 b = tmp;
968 }
969 return a;
970}
971
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000972static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000973audioop_ratecv(self, args)
Guido van Rossum1851a671997-02-14 16:14:03 +0000974 PyObject *self;
975 PyObject *args;
Roger E. Massec905fff1997-01-17 18:12:04 +0000976{
Guido van Rossum1851a671997-02-14 16:14:03 +0000977 char *cp, *ncp;
978 int len, size, nchannels, inrate, outrate, weightA, weightB;
979 int chan, d, *prev_i, *cur_i, cur_o;
980 PyObject *state, *samps, *str, *rv;
981
982 weightA = 1;
983 weightB = 0;
984 if (!PyArg_ParseTuple(args, "s#iiiiO|ii", &cp, &len, &size, &nchannels,
985 &inrate, &outrate, &state, &weightA, &weightB))
986 return NULL;
987 if (size != 1 && size != 2 && size != 4) {
988 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
989 return NULL;
990 }
991 if (nchannels < 1) {
992 PyErr_SetString(AudioopError, "# of channels should be >= 1");
993 return NULL;
994 }
995 if (weightA < 1 || weightB < 0) {
996 PyErr_SetString(AudioopError,
997 "weightA should be >= 1, weightB should be >= 0");
998 return NULL;
999 }
1000 if (len % (size * nchannels) != 0) {
1001 PyErr_SetString(AudioopError, "not a whole number of frames");
1002 return NULL;
1003 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +00001004 if (inrate <= 0 || outrate <= 0) {
1005 PyErr_SetString(AudioopError, "sampling rate not > 0");
1006 return NULL;
1007 }
1008 /* divide inrate and outrate by their greatest common divisor */
1009 d = gcd(inrate, outrate);
1010 inrate /= d;
1011 outrate /= d;
1012
Guido van Rossum6345ac61997-10-31 20:32:13 +00001013 prev_i = (int *) malloc(nchannels * sizeof(int));
1014 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +00001015 len /= size * nchannels; /* # of frames */
1016
1017 if (state == Py_None) {
1018 d = -outrate;
1019 for (chan = 0; chan < nchannels; chan++)
1020 prev_i[chan] = cur_i[chan] = 0;
1021 } else {
1022 if (!PyArg_ParseTuple(state,
1023 "iO!;audioop.ratecv: illegal state argument",
1024 &d, &PyTuple_Type, &samps))
1025 return NULL;
1026 if (PyTuple_Size(samps) != nchannels) {
1027 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +00001028 "illegal state argument");
Guido van Rossum1851a671997-02-14 16:14:03 +00001029 return NULL;
1030 }
1031 for (chan = 0; chan < nchannels; chan++) {
1032 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Roger E. Massec905fff1997-01-17 18:12:04 +00001033 "ii",&prev_i[chan],&cur_i[chan]))
Guido van Rossum1851a671997-02-14 16:14:03 +00001034 return NULL;
1035 }
1036 }
1037 str = PyString_FromStringAndSize(
1038 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
1039 if (str == NULL)
1040 return NULL;
1041 ncp = PyString_AsString(str);
1042
1043 for (;;) {
1044 while (d < 0) {
1045 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001046 samps = PyTuple_New(nchannels);
1047 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001048 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001049 Py_BuildValue("(ii)",
1050 prev_i[chan],
1051 cur_i[chan]));
1052 if (PyErr_Occurred())
1053 return NULL;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001054 len = ncp - PyString_AsString(str);
1055 if (len == 0) {
1056 /*don't want to resize to zero length*/
1057 rv = PyString_FromStringAndSize("", 0);
1058 Py_DECREF(str);
1059 str = rv;
1060 } else if (_PyString_Resize(&str, len) < 0)
Roger E. Massec905fff1997-01-17 18:12:04 +00001061 return NULL;
1062 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001063 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001064 Py_DECREF(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001065 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001066 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001067 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001068 prev_i[chan] = cur_i[chan];
1069 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001070 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001071 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001072 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001073 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001074 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001075 cp += size;
1076 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001077 cur_i[chan] =
1078 (weightA * cur_i[chan] +
1079 weightB * prev_i[chan]) /
1080 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001081 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001082 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001083 d += outrate;
1084 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001085 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001086 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001087 cur_o = (prev_i[chan] * d +
1088 cur_i[chan] * (outrate - d)) /
1089 outrate;
1090 if (size == 1)
1091 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001092 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001093 *SHORTP(ncp, 0) = (short)(cur_o);
1094 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001095 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001096 ncp += size;
1097 }
1098 d -= inrate;
1099 }
1100 }
Roger E. Massec905fff1997-01-17 18:12:04 +00001101}
Guido van Rossum1851a671997-02-14 16:14:03 +00001102
Roger E. Massec905fff1997-01-17 18:12:04 +00001103static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001104audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001105 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001106 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001107{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001108 signed char *cp;
1109 unsigned char *ncp;
1110 int len, size, val = 0;
1111 PyObject *rv;
1112 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001113
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001114 if ( !PyArg_Parse(args, "(s#i)",
1115 &cp, &len, &size) )
1116 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001117
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001118 if ( size != 1 && size != 2 && size != 4) {
1119 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1120 return 0;
1121 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001122
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001123 rv = PyString_FromStringAndSize(NULL, len/size);
1124 if ( rv == 0 )
1125 return 0;
1126 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001127
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001128 for ( i=0; i < len; i += size ) {
1129 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1130 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1131 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001132
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001133 *ncp++ = st_linear_to_ulaw(val);
1134 }
1135 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001136}
1137
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001138static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001139audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001140 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001141 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001142{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001143 unsigned char *cp;
1144 unsigned char cval;
1145 signed char *ncp;
1146 int len, size, val;
1147 PyObject *rv;
1148 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001149
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001150 if ( !PyArg_Parse(args, "(s#i)",
1151 &cp, &len, &size) )
1152 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001153
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 Rossumb66efa01992-06-01 16:01:24 +00001158
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001159 rv = PyString_FromStringAndSize(NULL, len*size);
1160 if ( rv == 0 )
1161 return 0;
1162 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001163
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001164 for ( i=0; i < len*size; i += size ) {
1165 cval = *cp++;
1166 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001167
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001168 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1169 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001170 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001171 }
1172 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001173}
1174
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001175static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001176audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001177 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001178 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001179{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001180 signed char *cp;
1181 signed char *ncp;
1182 int len, size, val = 0, step, valpred, delta,
1183 index, sign, vpdiff, diff;
1184 PyObject *rv, *state, *str;
1185 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001186
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001187 if ( !PyArg_Parse(args, "(s#iO)",
1188 &cp, &len, &size, &state) )
1189 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001190
1191
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001192 if ( size != 1 && size != 2 && size != 4) {
1193 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1194 return 0;
1195 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001196
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001197 str = PyString_FromStringAndSize(NULL, len/(size*2));
1198 if ( str == 0 )
1199 return 0;
1200 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001201
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001202 /* Decode state, should have (value, step) */
1203 if ( state == Py_None ) {
1204 /* First time, it seems. Set defaults */
1205 valpred = 0;
1206 step = 7;
1207 index = 0;
1208 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1209 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001210
Guido van Rossumb64e6351992-07-06 14:21:56 +00001211 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001212 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001213
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001214 for ( i=0; i < len; i += size ) {
1215 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1216 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1217 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1218
1219 /* Step 1 - compute difference with previous value */
1220 diff = val - valpred;
1221 sign = (diff < 0) ? 8 : 0;
1222 if ( sign ) diff = (-diff);
1223
1224 /* Step 2 - Divide and clamp */
1225 /* Note:
1226 ** This code *approximately* computes:
1227 ** delta = diff*4/step;
1228 ** vpdiff = (delta+0.5)*step/4;
1229 ** but in shift step bits are dropped. The net result of this
1230 ** is that even if you have fast mul/div hardware you cannot
1231 ** put it to good use since the fixup would be too expensive.
1232 */
1233 delta = 0;
1234 vpdiff = (step >> 3);
1235
1236 if ( diff >= step ) {
1237 delta = 4;
1238 diff -= step;
1239 vpdiff += step;
1240 }
1241 step >>= 1;
1242 if ( diff >= step ) {
1243 delta |= 2;
1244 diff -= step;
1245 vpdiff += step;
1246 }
1247 step >>= 1;
1248 if ( diff >= step ) {
1249 delta |= 1;
1250 vpdiff += step;
1251 }
1252
1253 /* Step 3 - Update previous value */
1254 if ( sign )
1255 valpred -= vpdiff;
1256 else
1257 valpred += vpdiff;
1258
1259 /* Step 4 - Clamp previous value to 16 bits */
1260 if ( valpred > 32767 )
1261 valpred = 32767;
1262 else if ( valpred < -32768 )
1263 valpred = -32768;
1264
1265 /* Step 5 - Assemble value, update index and step values */
1266 delta |= sign;
1267
1268 index += indexTable[delta];
1269 if ( index < 0 ) index = 0;
1270 if ( index > 88 ) index = 88;
1271 step = stepsizeTable[index];
1272
1273 /* Step 6 - Output value */
1274 if ( bufferstep ) {
1275 outputbuffer = (delta << 4) & 0xf0;
1276 } else {
1277 *ncp++ = (delta & 0x0f) | outputbuffer;
1278 }
1279 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001280 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001281 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1282 Py_DECREF(str);
1283 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001284}
1285
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001286static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001287audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001288 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001289 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001290{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001291 signed char *cp;
1292 signed char *ncp;
1293 int len, size, valpred, step, delta, index, sign, vpdiff;
1294 PyObject *rv, *str, *state;
1295 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001296
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001297 if ( !PyArg_Parse(args, "(s#iO)",
1298 &cp, &len, &size, &state) )
1299 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001300
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001301 if ( size != 1 && size != 2 && size != 4) {
1302 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1303 return 0;
1304 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001305
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001306 /* Decode state, should have (value, step) */
1307 if ( state == Py_None ) {
1308 /* First time, it seems. Set defaults */
1309 valpred = 0;
1310 step = 7;
1311 index = 0;
1312 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1313 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001314
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001315 str = PyString_FromStringAndSize(NULL, len*size*2);
1316 if ( str == 0 )
1317 return 0;
1318 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001319
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001320 step = stepsizeTable[index];
1321 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001322
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001323 for ( i=0; i < len*size*2; i += size ) {
1324 /* Step 1 - get the delta value and compute next index */
1325 if ( bufferstep ) {
1326 delta = inputbuffer & 0xf;
1327 } else {
1328 inputbuffer = *cp++;
1329 delta = (inputbuffer >> 4) & 0xf;
1330 }
1331
1332 bufferstep = !bufferstep;
1333
1334 /* Step 2 - Find new index value (for later) */
1335 index += indexTable[delta];
1336 if ( index < 0 ) index = 0;
1337 if ( index > 88 ) index = 88;
1338
1339 /* Step 3 - Separate sign and magnitude */
1340 sign = delta & 8;
1341 delta = delta & 7;
1342
1343 /* Step 4 - Compute difference and new predicted value */
1344 /*
1345 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1346 ** in adpcm_coder.
1347 */
1348 vpdiff = step >> 3;
1349 if ( delta & 4 ) vpdiff += step;
1350 if ( delta & 2 ) vpdiff += step>>1;
1351 if ( delta & 1 ) vpdiff += step>>2;
1352
1353 if ( sign )
1354 valpred -= vpdiff;
1355 else
1356 valpred += vpdiff;
1357
1358 /* Step 5 - clamp output value */
1359 if ( valpred > 32767 )
1360 valpred = 32767;
1361 else if ( valpred < -32768 )
1362 valpred = -32768;
1363
1364 /* Step 6 - Update step value */
1365 step = stepsizeTable[index];
1366
1367 /* Step 6 - Output value */
1368 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1369 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001370 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001371 }
1372
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001373 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1374 Py_DECREF(str);
1375 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001376}
1377
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001378static PyMethodDef audioop_methods[] = {
1379 { "max", audioop_max },
1380 { "minmax", audioop_minmax },
1381 { "avg", audioop_avg },
1382 { "maxpp", audioop_maxpp },
1383 { "avgpp", audioop_avgpp },
1384 { "rms", audioop_rms },
1385 { "findfit", audioop_findfit },
1386 { "findmax", audioop_findmax },
1387 { "findfactor", audioop_findfactor },
1388 { "cross", audioop_cross },
1389 { "mul", audioop_mul },
1390 { "add", audioop_add },
1391 { "bias", audioop_bias },
1392 { "ulaw2lin", audioop_ulaw2lin },
1393 { "lin2ulaw", audioop_lin2ulaw },
1394 { "lin2lin", audioop_lin2lin },
1395 { "adpcm2lin", audioop_adpcm2lin },
1396 { "lin2adpcm", audioop_lin2adpcm },
1397 { "tomono", audioop_tomono },
1398 { "tostereo", audioop_tostereo },
1399 { "getsample", audioop_getsample },
1400 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001401 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001402 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001403};
1404
Guido van Rossum3886bb61998-12-04 18:50:17 +00001405DL_EXPORT(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001406initaudioop()
1407{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001408 PyObject *m, *d;
1409 m = Py_InitModule("audioop", audioop_methods);
1410 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001411 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1412 if (AudioopError != NULL)
1413 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001414}