blob: c6d9df5bcb98f121dfb16ca26bb4e1650c88b634 [file] [log] [blame]
Guido van Rossumb66efa01992-06-01 16:01:24 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumb66efa01992-06-01 16:01:24 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumb66efa01992-06-01 16:01:24 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumb66efa01992-06-01 16:01:24 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumb66efa01992-06-01 16:01:24 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumb66efa01992-06-01 16:01:24 +000029
30******************************************************************/
31
Guido van Rossumb6775db1994-08-01 11:34:53 +000032/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +000033
Roger E. Masseeaa6e111997-01-03 19:26:27 +000034#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +000035
Guido van Rossum7b1e9741994-08-29 10:46:42 +000036#if defined(__CHAR_UNSIGNED__)
37#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000038!ERROR!; READ THE SOURCE FILE!;
39/* This module currently does not work on systems where only unsigned
40 characters are available. Take it out of Setup. Sorry. */
41#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000042#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000043
Guido van Rossuma320fd31995-03-09 12:14:15 +000044#include "mymath.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000045
Jack Jansena90805f1993-02-17 14:29:28 +000046/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000047** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
48
49#define MINLIN -32768
50#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000051#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
52 else if ( x > MAXLIN ) x = MAXLIN; \
53 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000054
Guido van Rossumcd938fc1995-01-17 16:13:48 +000055static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000056
57/*
58** This macro converts from ulaw to 16 bit linear, faster.
59**
60** Jef Poskanzer
61** 23 October 1989
62**
63** Input: 8 bit ulaw sample
64** Output: signed 16 bit linear sample
65*/
66#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
67
68static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000069 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
70 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
71 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
72 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
73 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
74 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
75 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
76 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
77 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
78 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
79 -876, -844, -812, -780, -748, -716, -684, -652,
80 -620, -588, -556, -524, -492, -460, -428, -396,
81 -372, -356, -340, -324, -308, -292, -276, -260,
82 -244, -228, -212, -196, -180, -164, -148, -132,
83 -120, -112, -104, -96, -88, -80, -72, -64,
84 -56, -48, -40, -32, -24, -16, -8, 0,
85 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
86 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
87 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
88 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
89 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
90 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
91 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
92 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
93 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
94 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
95 876, 844, 812, 780, 748, 716, 684, 652,
96 620, 588, 556, 524, 492, 460, 428, 396,
97 372, 356, 340, 324, 308, 292, 276, 260,
98 244, 228, 212, 196, 180, 164, 148, 132,
99 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +0000100 56, 48, 40, 32, 24, 16, 8, 0 };
101
102#define ZEROTRAP /* turn on the trap as per the MIL-STD */
103#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
104#define CLIP 32635
105
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000106static unsigned char
Guido van Rossumb66efa01992-06-01 16:01:24 +0000107st_linear_to_ulaw( sample )
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000108 int sample;
109{
110 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
111 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
112 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
113 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
114 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
115 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
116 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
117 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
118 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
119 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
120 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
121 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
122 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
123 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
124 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
125 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
126 int sign, exponent, mantissa;
127 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000128
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000129 /* Get the sample into sign-magnitude. */
130 sign = (sample >> 8) & 0x80; /* set aside the sign */
131 if ( sign != 0 ) sample = -sample; /* get magnitude */
132 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000133
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000134 /* Convert from 16 bit linear to ulaw. */
135 sample = sample + BIAS;
136 exponent = exp_lut[( sample >> 7 ) & 0xFF];
137 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
138 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000139#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000140 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000141#endif
142
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000143 return ulawbyte;
144}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000145/* End of code taken from sox */
146
Guido van Rossumb64e6351992-07-06 14:21:56 +0000147/* Intel ADPCM step variation table */
148static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000149 -1, -1, -1, -1, 2, 4, 6, 8,
150 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000151};
152
153static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000154 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
155 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
156 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
157 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
158 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
159 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
160 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
161 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
162 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000163};
164
Guido van Rossumb66efa01992-06-01 16:01:24 +0000165#define CHARP(cp, i) ((signed char *)(cp+i))
166#define SHORTP(cp, i) ((short *)(cp+i))
167#define LONGP(cp, i) ((long *)(cp+i))
168
169
170
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000171static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000172
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000173static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000174audioop_getsample(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000175 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000176 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000177{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000178 signed char *cp;
179 int len, size, val = 0;
180 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000181
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000182 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
183 return 0;
184 if ( size != 1 && size != 2 && size != 4 ) {
185 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
186 return 0;
187 }
188 if ( i < 0 || i >= len/size ) {
189 PyErr_SetString(AudioopError, "Index out of range");
190 return 0;
191 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000192 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000193 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
194 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
195 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000196}
197
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000198static PyObject *
199audioop_max(self, args)
200 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000201 PyObject *args;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000202{
203 signed char *cp;
204 int len, size, val = 0;
205 int i;
206 int max = 0;
207
208 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
209 return 0;
210 if ( size != 1 && size != 2 && size != 4 ) {
211 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
212 return 0;
213 }
214 for ( i=0; i<len; i+= size) {
215 if ( size == 1 ) val = (int)*CHARP(cp, i);
216 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
217 else if ( size == 4 ) val = (int)*LONGP(cp, i);
218 if ( val < 0 ) val = (-val);
219 if ( val > max ) max = val;
220 }
221 return PyInt_FromLong(max);
222}
223
224static PyObject *
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000225audioop_minmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000226 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000227 PyObject *args;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000228{
229 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000230 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000231 int i;
232 int min = 0x7fffffff, max = -0x7fffffff;
233
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000234 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000235 return NULL;
236 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000237 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000238 return NULL;
239 }
240 for (i = 0; i < len; i += size) {
241 if (size == 1) val = (int) *CHARP(cp, i);
242 else if (size == 2) val = (int) *SHORTP(cp, i);
243 else if (size == 4) val = (int) *LONGP(cp, i);
244 if (val > max) max = val;
245 if (val < min) min = val;
246 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000247 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000248}
249
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000250static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000251audioop_avg(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000252 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000253 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000254{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000255 signed char *cp;
256 int len, size, val = 0;
257 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000258 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000259
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000260 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
261 return 0;
262 if ( size != 1 && size != 2 && size != 4 ) {
263 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
264 return 0;
265 }
266 for ( i=0; i<len; i+= size) {
267 if ( size == 1 ) val = (int)*CHARP(cp, i);
268 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
269 else if ( size == 4 ) val = (int)*LONGP(cp, i);
270 avg += val;
271 }
272 if ( len == 0 )
273 val = 0;
274 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000275 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000276 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000277}
278
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000279static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000280audioop_rms(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000281 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000282 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000283{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000284 signed char *cp;
285 int len, size, val = 0;
286 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000287 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000288
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000289 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
290 return 0;
291 if ( size != 1 && size != 2 && size != 4 ) {
292 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
293 return 0;
294 }
295 for ( i=0; i<len; i+= size) {
296 if ( size == 1 ) val = (int)*CHARP(cp, i);
297 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
298 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000299 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000300 }
301 if ( len == 0 )
302 val = 0;
303 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000304 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000305 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000306}
307
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000308static double _sum2(a, b, len)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000309 short *a;
Roger E. Massec905fff1997-01-17 18:12:04 +0000310 short *b;
311 int len;
Jack Jansena90805f1993-02-17 14:29:28 +0000312{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000313 int i;
314 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000315
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000316 for( i=0; i<len; i++) {
317 sum = sum + (double)a[i]*(double)b[i];
318 }
319 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000320}
321
322/*
323** Findfit tries to locate a sample within another sample. Its main use
324** is in echo-cancellation (to find the feedback of the output signal in
325** the input signal).
326** The method used is as follows:
327**
328** let R be the reference signal (length n) and A the input signal (length N)
329** with N > n, and let all sums be over i from 0 to n-1.
330**
331** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
332** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
333** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
334**
335** Next, we compute the relative distance between the original signal and
336** the modified signal and minimize that over j:
337** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
338** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
339**
340** In the code variables correspond as follows:
341** cp1 A
342** cp2 R
343** len1 N
344** len2 n
345** aj_m1 A[j-1]
346** aj_lm1 A[j+n-1]
347** sum_ri_2 sum(R[i]^2)
348** sum_aij_2 sum(A[i+j]^2)
349** sum_aij_ri sum(A[i+j]R[i])
350**
351** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
352** is completely recalculated each step.
353*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000354static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000355audioop_findfit(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000356 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000357 PyObject *args;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000358{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000359 short *cp1, *cp2;
360 int len1, len2;
361 int j, best_j;
362 double aj_m1, aj_lm1;
363 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000364
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000365 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
366 return 0;
367 if ( len1 & 1 || len2 & 1 ) {
368 PyErr_SetString(AudioopError, "Strings should be even-sized");
369 return 0;
370 }
371 len1 >>= 1;
372 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000373
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000374 if ( len1 < len2 ) {
375 PyErr_SetString(AudioopError, "First sample should be longer");
376 return 0;
377 }
378 sum_ri_2 = _sum2(cp2, cp2, len2);
379 sum_aij_2 = _sum2(cp1, cp1, len2);
380 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000381
382 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
383
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000384 best_result = result;
385 best_j = 0;
386 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000387
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000388 for ( j=1; j<=len1-len2; j++) {
389 aj_m1 = (double)cp1[j-1];
390 aj_lm1 = (double)cp1[j+len2-1];
391
392 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
393 sum_aij_ri = _sum2(cp1+j, cp2, len2);
394
395 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
396 / sum_aij_2;
397
398 if ( result < best_result ) {
399 best_result = result;
400 best_j = j;
401 }
402
403 }
404
405 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000406
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000407 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000408}
409
410/*
411** findfactor finds a factor f so that the energy in A-fB is minimal.
412** See the comment for findfit for details.
413*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000414static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000415audioop_findfactor(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000417 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000418{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000419 short *cp1, *cp2;
420 int len1, len2;
421 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000422
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000423 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
424 return 0;
425 if ( len1 & 1 || len2 & 1 ) {
426 PyErr_SetString(AudioopError, "Strings should be even-sized");
427 return 0;
428 }
429 if ( len1 != len2 ) {
430 PyErr_SetString(AudioopError, "Samples should be same size");
431 return 0;
432 }
433 len2 >>= 1;
434 sum_ri_2 = _sum2(cp2, cp2, len2);
435 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000436
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000437 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000438
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000439 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000440}
441
442/*
443** findmax returns the index of the n-sized segment of the input sample
444** that contains the most energy.
445*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000446static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000447audioop_findmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000448 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000449 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000450{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000451 short *cp1;
452 int len1, len2;
453 int j, best_j;
454 double aj_m1, aj_lm1;
455 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000456
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000457 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
458 return 0;
459 if ( len1 & 1 ) {
460 PyErr_SetString(AudioopError, "Strings should be even-sized");
461 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000462 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000463 len1 >>= 1;
464
465 if ( len1 < len2 ) {
466 PyErr_SetString(AudioopError, "Input sample should be longer");
467 return 0;
468 }
Jack Jansena90805f1993-02-17 14:29:28 +0000469
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000470 result = _sum2(cp1, cp1, len2);
471
472 best_result = result;
473 best_j = 0;
474 j = 0;
475
476 for ( j=1; j<=len1-len2; j++) {
477 aj_m1 = (double)cp1[j-1];
478 aj_lm1 = (double)cp1[j+len2-1];
479
480 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
481
482 if ( result > best_result ) {
483 best_result = result;
484 best_j = j;
485 }
486
487 }
488
489 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000490}
491
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000492static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000493audioop_avgpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000494 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000495 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000496{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000497 signed char *cp;
498 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
499 prevextreme = 0;
500 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000501 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000502 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000503
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000504 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
505 return 0;
506 if ( size != 1 && size != 2 && size != 4 ) {
507 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
508 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000509 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000510 /* Compute first delta value ahead. Also automatically makes us
511 ** skip the first extreme value
512 */
513 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
514 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
515 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
516 if ( size == 1 ) val = (int)*CHARP(cp, size);
517 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
518 else if ( size == 4 ) val = (int)*LONGP(cp, size);
519 prevdiff = val - prevval;
520
521 for ( i=size; i<len; i+= size) {
522 if ( size == 1 ) val = (int)*CHARP(cp, i);
523 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
524 else if ( size == 4 ) val = (int)*LONGP(cp, i);
525 diff = val - prevval;
526 if ( diff*prevdiff < 0 ) {
527 /* Derivative changed sign. Compute difference to last
528 ** extreme value and remember.
529 */
530 if ( prevextremevalid ) {
531 extremediff = prevval - prevextreme;
532 if ( extremediff < 0 )
533 extremediff = -extremediff;
534 avg += extremediff;
535 nextreme++;
536 }
537 prevextremevalid = 1;
538 prevextreme = prevval;
539 }
540 prevval = val;
541 if ( diff != 0 )
542 prevdiff = diff;
543 }
544 if ( nextreme == 0 )
545 val = 0;
546 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000547 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000548 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000549}
550
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000551static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000552audioop_maxpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000553 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000554 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000555{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000556 signed char *cp;
557 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
558 prevextreme = 0;
559 int i;
560 int max = 0;
561 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000562
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000563 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
564 return 0;
565 if ( size != 1 && size != 2 && size != 4 ) {
566 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
567 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000568 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000569 /* Compute first delta value ahead. Also automatically makes us
570 ** skip the first extreme value
571 */
572 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
573 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
574 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
575 if ( size == 1 ) val = (int)*CHARP(cp, size);
576 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
577 else if ( size == 4 ) val = (int)*LONGP(cp, size);
578 prevdiff = val - prevval;
579
580 for ( i=size; i<len; i+= size) {
581 if ( size == 1 ) val = (int)*CHARP(cp, i);
582 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
583 else if ( size == 4 ) val = (int)*LONGP(cp, i);
584 diff = val - prevval;
585 if ( diff*prevdiff < 0 ) {
586 /* Derivative changed sign. Compute difference to
587 ** last extreme value and remember.
588 */
589 if ( prevextremevalid ) {
590 extremediff = prevval - prevextreme;
591 if ( extremediff < 0 )
592 extremediff = -extremediff;
593 if ( extremediff > max )
594 max = extremediff;
595 }
596 prevextremevalid = 1;
597 prevextreme = prevval;
598 }
599 prevval = val;
600 if ( diff != 0 )
601 prevdiff = diff;
602 }
603 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000604}
605
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000606static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000607audioop_cross(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000608 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000609 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000610{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000611 signed char *cp;
612 int len, size, val = 0;
613 int i;
614 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000615
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000616 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
617 return 0;
618 if ( size != 1 && size != 2 && size != 4 ) {
619 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
620 return 0;
621 }
622 ncross = -1;
623 prevval = 17; /* Anything <> 0,1 */
624 for ( i=0; i<len; i+= size) {
625 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
626 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
627 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
628 val = val & 1;
629 if ( val != prevval ) ncross++;
630 prevval = val;
631 }
632 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000633}
634
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000635static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000636audioop_mul(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000638 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000639{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000640 signed char *cp, *ncp;
641 int len, size, val = 0;
642 double factor, fval, maxval;
643 PyObject *rv;
644 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000645
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000646 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
647 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000648
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000649 if ( size == 1 ) maxval = (double) 0x7f;
650 else if ( size == 2 ) maxval = (double) 0x7fff;
651 else if ( size == 4 ) maxval = (double) 0x7fffffff;
652 else {
653 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
654 return 0;
655 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000656
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000657 rv = PyString_FromStringAndSize(NULL, len);
658 if ( rv == 0 )
659 return 0;
660 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000661
662
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000663 for ( i=0; i < len; i += size ) {
664 if ( size == 1 ) val = (int)*CHARP(cp, i);
665 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
666 else if ( size == 4 ) val = (int)*LONGP(cp, i);
667 fval = (double)val*factor;
668 if ( fval > maxval ) fval = maxval;
669 else if ( fval < -maxval ) fval = -maxval;
670 val = (int)fval;
671 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
672 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
673 else if ( size == 4 ) *LONGP(ncp, i) = (long)val;
674 }
675 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000676}
677
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000678static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000679audioop_tomono(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000680 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000681 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000682{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000683 signed char *cp, *ncp;
684 int len, size, val1 = 0, val2 = 0;
685 double fac1, fac2, fval, maxval;
686 PyObject *rv;
687 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000688
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000689 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
690 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000691
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000692 if ( size == 1 ) maxval = (double) 0x7f;
693 else if ( size == 2 ) maxval = (double) 0x7fff;
694 else if ( size == 4 ) maxval = (double) 0x7fffffff;
695 else {
696 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
697 return 0;
698 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000699
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000700 rv = PyString_FromStringAndSize(NULL, len/2);
701 if ( rv == 0 )
702 return 0;
703 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000704
705
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000706 for ( i=0; i < len; i += size*2 ) {
707 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
708 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
709 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
710 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
711 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
712 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
713 fval = (double)val1*fac1 + (double)val2*fac2;
714 if ( fval > maxval ) fval = maxval;
715 else if ( fval < -maxval ) fval = -maxval;
716 val1 = (int)fval;
717 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
718 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
719 else if ( size == 4 ) *LONGP(ncp, i/2)= (long)val1;
720 }
721 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722}
723
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000724static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000725audioop_tostereo(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000726 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000727 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000728{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000729 signed char *cp, *ncp;
730 int len, size, val1, val2, val = 0;
731 double fac1, fac2, fval, maxval;
732 PyObject *rv;
733 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000734
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000735 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
736 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000737
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000738 if ( size == 1 ) maxval = (double) 0x7f;
739 else if ( size == 2 ) maxval = (double) 0x7fff;
740 else if ( size == 4 ) maxval = (double) 0x7fffffff;
741 else {
742 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
743 return 0;
744 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000745
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000746 rv = PyString_FromStringAndSize(NULL, len*2);
747 if ( rv == 0 )
748 return 0;
749 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000750
751
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000752 for ( i=0; i < len; i += size ) {
753 if ( size == 1 ) val = (int)*CHARP(cp, i);
754 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
755 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000756
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000757 fval = (double)val*fac1;
758 if ( fval > maxval ) fval = maxval;
759 else if ( fval < -maxval ) fval = -maxval;
760 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000761
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000762 fval = (double)val*fac2;
763 if ( fval > maxval ) fval = maxval;
764 else if ( fval < -maxval ) fval = -maxval;
765 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000766
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000767 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
768 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
769 else if ( size == 4 ) *LONGP(ncp, i*2) = (long)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000770
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000771 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
772 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
773 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (long)val2;
774 }
775 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000776}
777
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000778static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000779audioop_add(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000780 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000781 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000782{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000783 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000784 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000785 PyObject *rv;
786 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000787
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000788 if ( !PyArg_Parse(args, "(s#s#i)",
789 &cp1, &len1, &cp2, &len2, &size ) )
790 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000791
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000792 if ( len1 != len2 ) {
793 PyErr_SetString(AudioopError, "Lengths should be the same");
794 return 0;
795 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000796
Guido van Rossum1851a671997-02-14 16:14:03 +0000797 if ( size == 1 ) maxval = 0x7f;
798 else if ( size == 2 ) maxval = 0x7fff;
799 else if ( size == 4 ) maxval = 0x7fffffff;
800 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000801 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
802 return 0;
803 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000804
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000805 rv = PyString_FromStringAndSize(NULL, len1);
806 if ( rv == 0 )
807 return 0;
808 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000809
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000810 for ( i=0; i < len1; i += size ) {
811 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
812 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
813 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000814
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000815 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
816 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
817 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000818
Guido van Rossum1851a671997-02-14 16:14:03 +0000819 newval = val1 + val2;
820 /* truncate in case of overflow */
821 if (newval > maxval) newval = maxval;
822 else if (newval < -maxval) newval = -maxval;
823 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
824 newval = val1 > 0 ? maxval : - maxval;
825
826 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
827 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
828 else if ( size == 4 ) *LONGP(ncp, i) = (long)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000829 }
830 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831}
832
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000833static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834audioop_bias(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000835 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000836 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000837{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000838 signed char *cp, *ncp;
839 int len, size, val = 0;
840 PyObject *rv;
841 int i;
842 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000843
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000844 if ( !PyArg_Parse(args, "(s#ii)",
845 &cp, &len, &size , &bias) )
846 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000847
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000848 if ( size != 1 && size != 2 && size != 4) {
849 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
850 return 0;
851 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000852
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000853 rv = PyString_FromStringAndSize(NULL, len);
854 if ( rv == 0 )
855 return 0;
856 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000857
858
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000859 for ( i=0; i < len; i += size ) {
860 if ( size == 1 ) val = (int)*CHARP(cp, i);
861 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
862 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000863
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
865 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
866 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val+bias);
867 }
868 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000869}
870
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000871static PyObject *
Jack Jansen337b20e1993-02-23 13:39:57 +0000872audioop_reverse(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000874 PyObject *args;
Jack Jansen337b20e1993-02-23 13:39:57 +0000875{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000876 signed char *cp;
877 unsigned char *ncp;
878 int len, size, val = 0;
879 PyObject *rv;
880 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000881
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000882 if ( !PyArg_Parse(args, "(s#i)",
883 &cp, &len, &size) )
884 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000885
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000886 if ( size != 1 && size != 2 && size != 4 ) {
887 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
888 return 0;
889 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000890
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000891 rv = PyString_FromStringAndSize(NULL, len);
892 if ( rv == 0 )
893 return 0;
894 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000895
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000896 for ( i=0; i < len; i += size ) {
897 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
898 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
899 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000900
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000901 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000902
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
904 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
905 else if ( size == 4 ) *LONGP(ncp, j) = (long)(val<<16);
906 }
907 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000908}
909
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000910static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000911audioop_lin2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000912 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000913 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000914{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000915 signed char *cp;
916 unsigned char *ncp;
917 int len, size, size2, val = 0;
918 PyObject *rv;
919 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000920
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000921 if ( !PyArg_Parse(args, "(s#ii)",
922 &cp, &len, &size, &size2) )
923 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000924
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000925 if ( (size != 1 && size != 2 && size != 4) ||
926 (size2 != 1 && size2 != 2 && size2 != 4)) {
927 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
928 return 0;
929 }
Jack Jansena90805f1993-02-17 14:29:28 +0000930
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000931 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
932 if ( rv == 0 )
933 return 0;
934 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000935
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000936 for ( i=0, j=0; i < len; i += size, j += size2 ) {
937 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
938 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
939 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000940
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000941 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
942 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
943 else if ( size2 == 4 ) *LONGP(ncp, j) = (long)(val<<16);
944 }
945 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000946}
947
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000948static int
949gcd(a, b)
950 int a, b;
951{
952 while (b > 0) {
953 int tmp = a % b;
954 a = b;
955 b = tmp;
956 }
957 return a;
958}
959
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000960static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000961audioop_ratecv(self, args)
Guido van Rossum1851a671997-02-14 16:14:03 +0000962 PyObject *self;
963 PyObject *args;
Roger E. Massec905fff1997-01-17 18:12:04 +0000964{
Guido van Rossum1851a671997-02-14 16:14:03 +0000965 char *cp, *ncp;
966 int len, size, nchannels, inrate, outrate, weightA, weightB;
967 int chan, d, *prev_i, *cur_i, cur_o;
968 PyObject *state, *samps, *str, *rv;
969
970 weightA = 1;
971 weightB = 0;
972 if (!PyArg_ParseTuple(args, "s#iiiiO|ii", &cp, &len, &size, &nchannels,
973 &inrate, &outrate, &state, &weightA, &weightB))
974 return NULL;
975 if (size != 1 && size != 2 && size != 4) {
976 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
977 return NULL;
978 }
979 if (nchannels < 1) {
980 PyErr_SetString(AudioopError, "# of channels should be >= 1");
981 return NULL;
982 }
983 if (weightA < 1 || weightB < 0) {
984 PyErr_SetString(AudioopError,
985 "weightA should be >= 1, weightB should be >= 0");
986 return NULL;
987 }
988 if (len % (size * nchannels) != 0) {
989 PyErr_SetString(AudioopError, "not a whole number of frames");
990 return NULL;
991 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000992 if (inrate <= 0 || outrate <= 0) {
993 PyErr_SetString(AudioopError, "sampling rate not > 0");
994 return NULL;
995 }
996 /* divide inrate and outrate by their greatest common divisor */
997 d = gcd(inrate, outrate);
998 inrate /= d;
999 outrate /= d;
1000
Guido van Rossum1851a671997-02-14 16:14:03 +00001001 prev_i = malloc(nchannels * sizeof(int));
1002 cur_i = malloc(nchannels * sizeof(int));
1003 len /= size * nchannels; /* # of frames */
1004
1005 if (state == Py_None) {
1006 d = -outrate;
1007 for (chan = 0; chan < nchannels; chan++)
1008 prev_i[chan] = cur_i[chan] = 0;
1009 } else {
1010 if (!PyArg_ParseTuple(state,
1011 "iO!;audioop.ratecv: illegal state argument",
1012 &d, &PyTuple_Type, &samps))
1013 return NULL;
1014 if (PyTuple_Size(samps) != nchannels) {
1015 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +00001016 "illegal state argument");
Guido van Rossum1851a671997-02-14 16:14:03 +00001017 return NULL;
1018 }
1019 for (chan = 0; chan < nchannels; chan++) {
1020 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Roger E. Massec905fff1997-01-17 18:12:04 +00001021 "ii",&prev_i[chan],&cur_i[chan]))
Guido van Rossum1851a671997-02-14 16:14:03 +00001022 return NULL;
1023 }
1024 }
1025 str = PyString_FromStringAndSize(
1026 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
1027 if (str == NULL)
1028 return NULL;
1029 ncp = PyString_AsString(str);
1030
1031 for (;;) {
1032 while (d < 0) {
1033 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001034 samps = PyTuple_New(nchannels);
1035 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001036 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001037 Py_BuildValue("(ii)",
1038 prev_i[chan],
1039 cur_i[chan]));
1040 if (PyErr_Occurred())
1041 return NULL;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001042 len = ncp - PyString_AsString(str);
1043 if (len == 0) {
1044 /*don't want to resize to zero length*/
1045 rv = PyString_FromStringAndSize("", 0);
1046 Py_DECREF(str);
1047 str = rv;
1048 } else if (_PyString_Resize(&str, len) < 0)
Roger E. Massec905fff1997-01-17 18:12:04 +00001049 return NULL;
1050 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001051 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001052 Py_DECREF(str);
Guido van Rossum1851a671997-02-14 16:14:03 +00001053 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001054 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001055 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001056 prev_i[chan] = cur_i[chan];
1057 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001058 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001059 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001060 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001061 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001062 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001063 cp += size;
1064 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001065 cur_i[chan] =
1066 (weightA * cur_i[chan] +
1067 weightB * prev_i[chan]) /
1068 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001069 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001070 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001071 d += outrate;
1072 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001073 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001074 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001075 cur_o = (prev_i[chan] * d +
1076 cur_i[chan] * (outrate - d)) /
1077 outrate;
1078 if (size == 1)
1079 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001080 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001081 *SHORTP(ncp, 0) = (short)(cur_o);
1082 else if (size == 4)
1083 *LONGP(ncp, 0) = (long)(cur_o<<16);
1084 ncp += size;
1085 }
1086 d -= inrate;
1087 }
1088 }
Roger E. Massec905fff1997-01-17 18:12:04 +00001089}
Guido van Rossum1851a671997-02-14 16:14:03 +00001090
Roger E. Massec905fff1997-01-17 18:12:04 +00001091static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001092audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001093 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001094 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001095{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001096 signed char *cp;
1097 unsigned char *ncp;
1098 int len, size, val = 0;
1099 PyObject *rv;
1100 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001101
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001102 if ( !PyArg_Parse(args, "(s#i)",
1103 &cp, &len, &size) )
1104 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001105
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001106 if ( size != 1 && size != 2 && size != 4) {
1107 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1108 return 0;
1109 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001110
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001111 rv = PyString_FromStringAndSize(NULL, len/size);
1112 if ( rv == 0 )
1113 return 0;
1114 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001115
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001116 for ( i=0; i < len; i += size ) {
1117 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1118 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1119 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001120
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001121 *ncp++ = st_linear_to_ulaw(val);
1122 }
1123 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001124}
1125
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001126static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001127audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001128 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001129 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001130{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001131 unsigned char *cp;
1132 unsigned char cval;
1133 signed char *ncp;
1134 int len, size, val;
1135 PyObject *rv;
1136 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001137
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001138 if ( !PyArg_Parse(args, "(s#i)",
1139 &cp, &len, &size) )
1140 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001141
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001142 if ( size != 1 && size != 2 && size != 4) {
1143 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1144 return 0;
1145 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001146
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001147 rv = PyString_FromStringAndSize(NULL, len*size);
1148 if ( rv == 0 )
1149 return 0;
1150 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001151
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001152 for ( i=0; i < len*size; i += size ) {
1153 cval = *cp++;
1154 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001155
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001156 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1157 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
1158 else if ( size == 4 ) *LONGP(ncp, i) = (long)(val<<16);
1159 }
1160 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001161}
1162
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001163static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001164audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001165 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001166 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001167{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001168 signed char *cp;
1169 signed char *ncp;
1170 int len, size, val = 0, step, valpred, delta,
1171 index, sign, vpdiff, diff;
1172 PyObject *rv, *state, *str;
1173 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001174
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001175 if ( !PyArg_Parse(args, "(s#iO)",
1176 &cp, &len, &size, &state) )
1177 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001178
1179
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001180 if ( size != 1 && size != 2 && size != 4) {
1181 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1182 return 0;
1183 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001184
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001185 str = PyString_FromStringAndSize(NULL, len/(size*2));
1186 if ( str == 0 )
1187 return 0;
1188 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001189
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001190 /* Decode state, should have (value, step) */
1191 if ( state == Py_None ) {
1192 /* First time, it seems. Set defaults */
1193 valpred = 0;
1194 step = 7;
1195 index = 0;
1196 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1197 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001198
Guido van Rossumb64e6351992-07-06 14:21:56 +00001199 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001200 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001201
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001202 for ( i=0; i < len; i += size ) {
1203 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1204 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1205 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1206
1207 /* Step 1 - compute difference with previous value */
1208 diff = val - valpred;
1209 sign = (diff < 0) ? 8 : 0;
1210 if ( sign ) diff = (-diff);
1211
1212 /* Step 2 - Divide and clamp */
1213 /* Note:
1214 ** This code *approximately* computes:
1215 ** delta = diff*4/step;
1216 ** vpdiff = (delta+0.5)*step/4;
1217 ** but in shift step bits are dropped. The net result of this
1218 ** is that even if you have fast mul/div hardware you cannot
1219 ** put it to good use since the fixup would be too expensive.
1220 */
1221 delta = 0;
1222 vpdiff = (step >> 3);
1223
1224 if ( diff >= step ) {
1225 delta = 4;
1226 diff -= step;
1227 vpdiff += step;
1228 }
1229 step >>= 1;
1230 if ( diff >= step ) {
1231 delta |= 2;
1232 diff -= step;
1233 vpdiff += step;
1234 }
1235 step >>= 1;
1236 if ( diff >= step ) {
1237 delta |= 1;
1238 vpdiff += step;
1239 }
1240
1241 /* Step 3 - Update previous value */
1242 if ( sign )
1243 valpred -= vpdiff;
1244 else
1245 valpred += vpdiff;
1246
1247 /* Step 4 - Clamp previous value to 16 bits */
1248 if ( valpred > 32767 )
1249 valpred = 32767;
1250 else if ( valpred < -32768 )
1251 valpred = -32768;
1252
1253 /* Step 5 - Assemble value, update index and step values */
1254 delta |= sign;
1255
1256 index += indexTable[delta];
1257 if ( index < 0 ) index = 0;
1258 if ( index > 88 ) index = 88;
1259 step = stepsizeTable[index];
1260
1261 /* Step 6 - Output value */
1262 if ( bufferstep ) {
1263 outputbuffer = (delta << 4) & 0xf0;
1264 } else {
1265 *ncp++ = (delta & 0x0f) | outputbuffer;
1266 }
1267 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001268 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001269 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1270 Py_DECREF(str);
1271 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001272}
1273
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001274static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001275audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001276 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001277 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001278{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001279 signed char *cp;
1280 signed char *ncp;
1281 int len, size, valpred, step, delta, index, sign, vpdiff;
1282 PyObject *rv, *str, *state;
1283 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001284
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001285 if ( !PyArg_Parse(args, "(s#iO)",
1286 &cp, &len, &size, &state) )
1287 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001288
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001289 if ( size != 1 && size != 2 && size != 4) {
1290 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1291 return 0;
1292 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001293
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001294 /* Decode state, should have (value, step) */
1295 if ( state == Py_None ) {
1296 /* First time, it seems. Set defaults */
1297 valpred = 0;
1298 step = 7;
1299 index = 0;
1300 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1301 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001302
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001303 str = PyString_FromStringAndSize(NULL, len*size*2);
1304 if ( str == 0 )
1305 return 0;
1306 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001307
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001308 step = stepsizeTable[index];
1309 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001310
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001311 for ( i=0; i < len*size*2; i += size ) {
1312 /* Step 1 - get the delta value and compute next index */
1313 if ( bufferstep ) {
1314 delta = inputbuffer & 0xf;
1315 } else {
1316 inputbuffer = *cp++;
1317 delta = (inputbuffer >> 4) & 0xf;
1318 }
1319
1320 bufferstep = !bufferstep;
1321
1322 /* Step 2 - Find new index value (for later) */
1323 index += indexTable[delta];
1324 if ( index < 0 ) index = 0;
1325 if ( index > 88 ) index = 88;
1326
1327 /* Step 3 - Separate sign and magnitude */
1328 sign = delta & 8;
1329 delta = delta & 7;
1330
1331 /* Step 4 - Compute difference and new predicted value */
1332 /*
1333 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1334 ** in adpcm_coder.
1335 */
1336 vpdiff = step >> 3;
1337 if ( delta & 4 ) vpdiff += step;
1338 if ( delta & 2 ) vpdiff += step>>1;
1339 if ( delta & 1 ) vpdiff += step>>2;
1340
1341 if ( sign )
1342 valpred -= vpdiff;
1343 else
1344 valpred += vpdiff;
1345
1346 /* Step 5 - clamp output value */
1347 if ( valpred > 32767 )
1348 valpred = 32767;
1349 else if ( valpred < -32768 )
1350 valpred = -32768;
1351
1352 /* Step 6 - Update step value */
1353 step = stepsizeTable[index];
1354
1355 /* Step 6 - Output value */
1356 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1357 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
1358 else if ( size == 4 ) *LONGP(ncp, i) = (long)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001359 }
1360
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001361 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1362 Py_DECREF(str);
1363 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001364}
1365
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001366static PyMethodDef audioop_methods[] = {
1367 { "max", audioop_max },
1368 { "minmax", audioop_minmax },
1369 { "avg", audioop_avg },
1370 { "maxpp", audioop_maxpp },
1371 { "avgpp", audioop_avgpp },
1372 { "rms", audioop_rms },
1373 { "findfit", audioop_findfit },
1374 { "findmax", audioop_findmax },
1375 { "findfactor", audioop_findfactor },
1376 { "cross", audioop_cross },
1377 { "mul", audioop_mul },
1378 { "add", audioop_add },
1379 { "bias", audioop_bias },
1380 { "ulaw2lin", audioop_ulaw2lin },
1381 { "lin2ulaw", audioop_lin2ulaw },
1382 { "lin2lin", audioop_lin2lin },
1383 { "adpcm2lin", audioop_adpcm2lin },
1384 { "lin2adpcm", audioop_lin2adpcm },
1385 { "tomono", audioop_tomono },
1386 { "tostereo", audioop_tostereo },
1387 { "getsample", audioop_getsample },
1388 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001389 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001390 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001391};
1392
Guido van Rossumb66efa01992-06-01 16:01:24 +00001393void
1394initaudioop()
1395{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001396 PyObject *m, *d;
1397 m = Py_InitModule("audioop", audioop_methods);
1398 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001399 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1400 if (AudioopError != NULL)
1401 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001402}