blob: 43824b286b9a143e34b65dd2fe7ce1cff5e514d7 [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 Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossumb66efa01992-06-01 16:01:24 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumb66efa01992-06-01 16:01:24 +000014
15******************************************************************/
16
Guido van Rossumb6775db1994-08-01 11:34:53 +000017/* audioopmodule - Module to detect peak values in arrays */
Jack Jansene1b4d7c1992-08-24 14:36:31 +000018
Roger E. Masseeaa6e111997-01-03 19:26:27 +000019#include "Python.h"
Guido van Rossumb66efa01992-06-01 16:01:24 +000020
Guido van Rossum69011961998-04-23 20:23:00 +000021#if SIZEOF_INT == 4
22typedef int Py_Int32;
23typedef unsigned int Py_UInt32;
24#else
25#if SIZEOF_LONG == 4
26typedef long Py_Int32;
27typedef unsigned long Py_UInt32;
28#else
29#error "No 4-byte integral type"
30#endif
31#endif
32
Guido van Rossum7b1e9741994-08-29 10:46:42 +000033#if defined(__CHAR_UNSIGNED__)
34#if defined(signed)
Guido van Rossumb6775db1994-08-01 11:34:53 +000035!ERROR!; READ THE SOURCE FILE!;
36/* This module currently does not work on systems where only unsigned
37 characters are available. Take it out of Setup. Sorry. */
38#endif
Guido van Rossum7b1e9741994-08-29 10:46:42 +000039#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000040
Guido van Rossuma320fd31995-03-09 12:14:15 +000041#include "mymath.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000042
Jack Jansena90805f1993-02-17 14:29:28 +000043/* Code shamelessly stolen from sox,
Guido van Rossumb66efa01992-06-01 16:01:24 +000044** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
45
46#define MINLIN -32768
47#define MAXLIN 32767
Roger E. Masseeaa6e111997-01-03 19:26:27 +000048#define LINCLIP(x) do { if ( x < MINLIN ) x = MINLIN ; \
49 else if ( x > MAXLIN ) x = MAXLIN; \
50 } while ( 0 )
Guido van Rossumb66efa01992-06-01 16:01:24 +000051
Guido van Rossumcd938fc1995-01-17 16:13:48 +000052static unsigned char st_linear_to_ulaw( /* int sample */ );
Guido van Rossumb66efa01992-06-01 16:01:24 +000053
54/*
55** This macro converts from ulaw to 16 bit linear, faster.
56**
57** Jef Poskanzer
58** 23 October 1989
59**
60** Input: 8 bit ulaw sample
61** Output: signed 16 bit linear sample
62*/
63#define st_ulaw_to_linear(ulawbyte) ulaw_table[ulawbyte]
64
65static int ulaw_table[256] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +000066 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
67 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
68 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
69 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
70 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
71 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
72 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
73 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
74 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
75 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
76 -876, -844, -812, -780, -748, -716, -684, -652,
77 -620, -588, -556, -524, -492, -460, -428, -396,
78 -372, -356, -340, -324, -308, -292, -276, -260,
79 -244, -228, -212, -196, -180, -164, -148, -132,
80 -120, -112, -104, -96, -88, -80, -72, -64,
81 -56, -48, -40, -32, -24, -16, -8, 0,
82 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
83 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
84 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
85 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
86 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
87 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
88 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
89 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
90 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
91 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
92 876, 844, 812, 780, 748, 716, 684, 652,
93 620, 588, 556, 524, 492, 460, 428, 396,
94 372, 356, 340, 324, 308, 292, 276, 260,
95 244, 228, 212, 196, 180, 164, 148, 132,
96 120, 112, 104, 96, 88, 80, 72, 64,
Guido van Rossumb66efa01992-06-01 16:01:24 +000097 56, 48, 40, 32, 24, 16, 8, 0 };
98
Guido van Rossum7d64b482000-05-02 21:18:13 +000099/* #define ZEROTRAP /* turn on the trap as per the MIL-STD */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000100#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
101#define CLIP 32635
102
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000103static unsigned char
Guido van Rossumb66efa01992-06-01 16:01:24 +0000104st_linear_to_ulaw( sample )
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000105 int sample;
106{
107 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
108 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
109 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
110 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
111 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
112 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
113 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
114 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
115 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
116 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
117 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
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 int sign, exponent, mantissa;
124 unsigned char ulawbyte;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000125
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000126 /* Get the sample into sign-magnitude. */
127 sign = (sample >> 8) & 0x80; /* set aside the sign */
128 if ( sign != 0 ) sample = -sample; /* get magnitude */
129 if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000130
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000131 /* Convert from 16 bit linear to ulaw. */
132 sample = sample + BIAS;
133 exponent = exp_lut[( sample >> 7 ) & 0xFF];
134 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
135 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
Guido van Rossumb66efa01992-06-01 16:01:24 +0000136#ifdef ZEROTRAP
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000137 if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
Guido van Rossumb66efa01992-06-01 16:01:24 +0000138#endif
139
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000140 return ulawbyte;
141}
Guido van Rossumb66efa01992-06-01 16:01:24 +0000142/* End of code taken from sox */
143
Guido van Rossumb64e6351992-07-06 14:21:56 +0000144/* Intel ADPCM step variation table */
145static int indexTable[16] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000146 -1, -1, -1, -1, 2, 4, 6, 8,
147 -1, -1, -1, -1, 2, 4, 6, 8,
Guido van Rossumb64e6351992-07-06 14:21:56 +0000148};
149
150static int stepsizeTable[89] = {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000151 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
152 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
153 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
154 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
155 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
156 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
157 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
158 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
159 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
Guido van Rossumb64e6351992-07-06 14:21:56 +0000160};
161
Guido van Rossumb66efa01992-06-01 16:01:24 +0000162#define CHARP(cp, i) ((signed char *)(cp+i))
163#define SHORTP(cp, i) ((short *)(cp+i))
Guido van Rossum69011961998-04-23 20:23:00 +0000164#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
Guido van Rossumb66efa01992-06-01 16:01:24 +0000165
166
167
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000168static PyObject *AudioopError;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000169
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000170static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000171audioop_getsample(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000172 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000173 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000174{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000175 signed char *cp;
176 int len, size, val = 0;
177 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000178
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000179 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &size, &i) )
180 return 0;
181 if ( size != 1 && size != 2 && size != 4 ) {
182 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
183 return 0;
184 }
185 if ( i < 0 || i >= len/size ) {
186 PyErr_SetString(AudioopError, "Index out of range");
187 return 0;
188 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000189 if ( size == 1 ) val = (int)*CHARP(cp, i);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000190 else if ( size == 2 ) val = (int)*SHORTP(cp, i*2);
191 else if ( size == 4 ) val = (int)*LONGP(cp, i*4);
192 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000193}
194
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000195static PyObject *
196audioop_max(self, args)
197 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000198 PyObject *args;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000199{
200 signed char *cp;
201 int len, size, val = 0;
202 int i;
203 int max = 0;
204
205 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
206 return 0;
207 if ( size != 1 && size != 2 && size != 4 ) {
208 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
209 return 0;
210 }
211 for ( i=0; i<len; i+= size) {
212 if ( size == 1 ) val = (int)*CHARP(cp, i);
213 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
214 else if ( size == 4 ) val = (int)*LONGP(cp, i);
215 if ( val < 0 ) val = (-val);
216 if ( val > max ) max = val;
217 }
218 return PyInt_FromLong(max);
219}
220
221static PyObject *
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000222audioop_minmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000223 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000224 PyObject *args;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000225{
226 signed char *cp;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000227 int len, size, val = 0;
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000228 int i;
229 int min = 0x7fffffff, max = -0x7fffffff;
230
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000231 if (!PyArg_Parse(args, "(s#i)", &cp, &len, &size))
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000232 return NULL;
233 if (size != 1 && size != 2 && size != 4) {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000234 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000235 return NULL;
236 }
237 for (i = 0; i < len; i += size) {
238 if (size == 1) val = (int) *CHARP(cp, i);
239 else if (size == 2) val = (int) *SHORTP(cp, i);
240 else if (size == 4) val = (int) *LONGP(cp, i);
241 if (val > max) max = val;
242 if (val < min) min = val;
243 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000244 return Py_BuildValue("(ii)", min, max);
Sjoerd Mullendera1426131994-09-06 16:19:33 +0000245}
246
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000247static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000248audioop_avg(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000249 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000250 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000251{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000252 signed char *cp;
253 int len, size, val = 0;
254 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000255 double avg = 0.0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000256
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000257 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
258 return 0;
259 if ( size != 1 && size != 2 && size != 4 ) {
260 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
261 return 0;
262 }
263 for ( i=0; i<len; i+= size) {
264 if ( size == 1 ) val = (int)*CHARP(cp, i);
265 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
266 else if ( size == 4 ) val = (int)*LONGP(cp, i);
267 avg += val;
268 }
269 if ( len == 0 )
270 val = 0;
271 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000272 val = (int)(avg / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000273 return PyInt_FromLong(val);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000274}
275
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000276static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000277audioop_rms(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000278 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000279 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000280{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000281 signed char *cp;
282 int len, size, val = 0;
283 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000284 double sum_squares = 0.0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000285
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000286 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
287 return 0;
288 if ( size != 1 && size != 2 && size != 4 ) {
289 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
290 return 0;
291 }
292 for ( i=0; i<len; i+= size) {
293 if ( size == 1 ) val = (int)*CHARP(cp, i);
294 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
295 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossum644a12b1997-04-09 19:24:53 +0000296 sum_squares += (double)val*(double)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000297 }
298 if ( len == 0 )
299 val = 0;
300 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000301 val = (int)sqrt(sum_squares / (double)(len/size));
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000302 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000303}
304
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000305static double _sum2(a, b, len)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000306 short *a;
Roger E. Massec905fff1997-01-17 18:12:04 +0000307 short *b;
308 int len;
Jack Jansena90805f1993-02-17 14:29:28 +0000309{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000310 int i;
311 double sum = 0.0;
Jack Jansena90805f1993-02-17 14:29:28 +0000312
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000313 for( i=0; i<len; i++) {
314 sum = sum + (double)a[i]*(double)b[i];
315 }
316 return sum;
Jack Jansena90805f1993-02-17 14:29:28 +0000317}
318
319/*
320** Findfit tries to locate a sample within another sample. Its main use
321** is in echo-cancellation (to find the feedback of the output signal in
322** the input signal).
323** The method used is as follows:
324**
325** let R be the reference signal (length n) and A the input signal (length N)
326** with N > n, and let all sums be over i from 0 to n-1.
327**
328** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A
329** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This
330** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2).
331**
332** Next, we compute the relative distance between the original signal and
333** the modified signal and minimize that over j:
334** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) =>
335** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 )
336**
337** In the code variables correspond as follows:
338** cp1 A
339** cp2 R
340** len1 N
341** len2 n
342** aj_m1 A[j-1]
343** aj_lm1 A[j+n-1]
344** sum_ri_2 sum(R[i]^2)
345** sum_aij_2 sum(A[i+j]^2)
346** sum_aij_ri sum(A[i+j]R[i])
347**
348** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri
349** is completely recalculated each step.
350*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000351static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000352audioop_findfit(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000353 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000354 PyObject *args;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000355{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000356 short *cp1, *cp2;
357 int len1, len2;
358 int j, best_j;
359 double aj_m1, aj_lm1;
360 double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000361
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000362 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
363 return 0;
364 if ( len1 & 1 || len2 & 1 ) {
365 PyErr_SetString(AudioopError, "Strings should be even-sized");
366 return 0;
367 }
368 len1 >>= 1;
369 len2 >>= 1;
Jack Jansena90805f1993-02-17 14:29:28 +0000370
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000371 if ( len1 < len2 ) {
372 PyErr_SetString(AudioopError, "First sample should be longer");
373 return 0;
374 }
375 sum_ri_2 = _sum2(cp2, cp2, len2);
376 sum_aij_2 = _sum2(cp1, cp1, len2);
377 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000378
379 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
380
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000381 best_result = result;
382 best_j = 0;
383 j = 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000384
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000385 for ( j=1; j<=len1-len2; j++) {
386 aj_m1 = (double)cp1[j-1];
387 aj_lm1 = (double)cp1[j+len2-1];
388
389 sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
390 sum_aij_ri = _sum2(cp1+j, cp2, len2);
391
392 result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
393 / sum_aij_2;
394
395 if ( result < best_result ) {
396 best_result = result;
397 best_j = j;
398 }
399
400 }
401
402 factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000403
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000404 return Py_BuildValue("(if)", best_j, factor);
Jack Jansena90805f1993-02-17 14:29:28 +0000405}
406
407/*
408** findfactor finds a factor f so that the energy in A-fB is minimal.
409** See the comment for findfit for details.
410*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000411static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000412audioop_findfactor(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000413 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000414 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000415{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000416 short *cp1, *cp2;
417 int len1, len2;
418 double sum_ri_2, sum_aij_ri, result;
Jack Jansena90805f1993-02-17 14:29:28 +0000419
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000420 if ( !PyArg_Parse(args, "(s#s#)", &cp1, &len1, &cp2, &len2) )
421 return 0;
422 if ( len1 & 1 || len2 & 1 ) {
423 PyErr_SetString(AudioopError, "Strings should be even-sized");
424 return 0;
425 }
426 if ( len1 != len2 ) {
427 PyErr_SetString(AudioopError, "Samples should be same size");
428 return 0;
429 }
430 len2 >>= 1;
431 sum_ri_2 = _sum2(cp2, cp2, len2);
432 sum_aij_ri = _sum2(cp1, cp2, len2);
Jack Jansena90805f1993-02-17 14:29:28 +0000433
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000434 result = sum_aij_ri / sum_ri_2;
Jack Jansena90805f1993-02-17 14:29:28 +0000435
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000436 return PyFloat_FromDouble(result);
Jack Jansena90805f1993-02-17 14:29:28 +0000437}
438
439/*
440** findmax returns the index of the n-sized segment of the input sample
441** that contains the most energy.
442*/
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000443static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000444audioop_findmax(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000445 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000446 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000447{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000448 short *cp1;
449 int len1, len2;
450 int j, best_j;
451 double aj_m1, aj_lm1;
452 double result, best_result;
Jack Jansena90805f1993-02-17 14:29:28 +0000453
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000454 if ( !PyArg_Parse(args, "(s#i)", &cp1, &len1, &len2) )
455 return 0;
456 if ( len1 & 1 ) {
457 PyErr_SetString(AudioopError, "Strings should be even-sized");
458 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000459 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000460 len1 >>= 1;
461
462 if ( len1 < len2 ) {
463 PyErr_SetString(AudioopError, "Input sample should be longer");
464 return 0;
465 }
Jack Jansena90805f1993-02-17 14:29:28 +0000466
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000467 result = _sum2(cp1, cp1, len2);
468
469 best_result = result;
470 best_j = 0;
471 j = 0;
472
473 for ( j=1; j<=len1-len2; j++) {
474 aj_m1 = (double)cp1[j-1];
475 aj_lm1 = (double)cp1[j+len2-1];
476
477 result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1;
478
479 if ( result > best_result ) {
480 best_result = result;
481 best_j = j;
482 }
483
484 }
485
486 return PyInt_FromLong(best_j);
Jack Jansendd8a6ea1993-02-17 14:21:09 +0000487}
488
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000489static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000490audioop_avgpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000491 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000492 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000493{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000494 signed char *cp;
495 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
496 prevextreme = 0;
497 int i;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000498 double avg = 0.0;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000499 int diff, prevdiff, extremediff, nextreme = 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000500
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000501 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
502 return 0;
503 if ( size != 1 && size != 2 && size != 4 ) {
504 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
505 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000506 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000507 /* Compute first delta value ahead. Also automatically makes us
508 ** skip the first extreme value
509 */
510 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
511 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
512 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
513 if ( size == 1 ) val = (int)*CHARP(cp, size);
514 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
515 else if ( size == 4 ) val = (int)*LONGP(cp, size);
516 prevdiff = val - prevval;
517
518 for ( i=size; i<len; i+= size) {
519 if ( size == 1 ) val = (int)*CHARP(cp, i);
520 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
521 else if ( size == 4 ) val = (int)*LONGP(cp, i);
522 diff = val - prevval;
523 if ( diff*prevdiff < 0 ) {
524 /* Derivative changed sign. Compute difference to last
525 ** extreme value and remember.
526 */
527 if ( prevextremevalid ) {
528 extremediff = prevval - prevextreme;
529 if ( extremediff < 0 )
530 extremediff = -extremediff;
531 avg += extremediff;
532 nextreme++;
533 }
534 prevextremevalid = 1;
535 prevextreme = prevval;
536 }
537 prevval = val;
538 if ( diff != 0 )
539 prevdiff = diff;
540 }
541 if ( nextreme == 0 )
542 val = 0;
543 else
Guido van Rossum644a12b1997-04-09 19:24:53 +0000544 val = (int)(avg / (double)nextreme);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000545 return PyInt_FromLong(val);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000546}
547
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000548static PyObject *
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000549audioop_maxpp(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000550 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000551 PyObject *args;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000552{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000553 signed char *cp;
554 int len, size, val = 0, prevval = 0, prevextremevalid = 0,
555 prevextreme = 0;
556 int i;
557 int max = 0;
558 int diff, prevdiff, extremediff;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000559
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000560 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
561 return 0;
562 if ( size != 1 && size != 2 && size != 4 ) {
563 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
564 return 0;
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000565 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000566 /* Compute first delta value ahead. Also automatically makes us
567 ** skip the first extreme value
568 */
569 if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
570 else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
571 else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
572 if ( size == 1 ) val = (int)*CHARP(cp, size);
573 else if ( size == 2 ) val = (int)*SHORTP(cp, size);
574 else if ( size == 4 ) val = (int)*LONGP(cp, size);
575 prevdiff = val - prevval;
576
577 for ( i=size; i<len; i+= size) {
578 if ( size == 1 ) val = (int)*CHARP(cp, i);
579 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
580 else if ( size == 4 ) val = (int)*LONGP(cp, i);
581 diff = val - prevval;
582 if ( diff*prevdiff < 0 ) {
583 /* Derivative changed sign. Compute difference to
584 ** last extreme value and remember.
585 */
586 if ( prevextremevalid ) {
587 extremediff = prevval - prevextreme;
588 if ( extremediff < 0 )
589 extremediff = -extremediff;
590 if ( extremediff > max )
591 max = extremediff;
592 }
593 prevextremevalid = 1;
594 prevextreme = prevval;
595 }
596 prevval = val;
597 if ( diff != 0 )
598 prevdiff = diff;
599 }
600 return PyInt_FromLong(max);
Jack Jansene1b4d7c1992-08-24 14:36:31 +0000601}
602
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000603static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000604audioop_cross(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000605 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000606 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000607{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000608 signed char *cp;
609 int len, size, val = 0;
610 int i;
611 int prevval, ncross;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000612
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000613 if ( !PyArg_Parse(args, "(s#i)", &cp, &len, &size) )
614 return 0;
615 if ( size != 1 && size != 2 && size != 4 ) {
616 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
617 return 0;
618 }
619 ncross = -1;
620 prevval = 17; /* Anything <> 0,1 */
621 for ( i=0; i<len; i+= size) {
622 if ( size == 1 ) val = ((int)*CHARP(cp, i)) >> 7;
623 else if ( size == 2 ) val = ((int)*SHORTP(cp, i)) >> 15;
624 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 31;
625 val = val & 1;
626 if ( val != prevval ) ncross++;
627 prevval = val;
628 }
629 return PyInt_FromLong(ncross);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000630}
631
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000632static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000633audioop_mul(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000634 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000635 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000636{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000637 signed char *cp, *ncp;
638 int len, size, val = 0;
639 double factor, fval, maxval;
640 PyObject *rv;
641 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000642
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000643 if ( !PyArg_Parse(args, "(s#id)", &cp, &len, &size, &factor ) )
644 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000645
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000646 if ( size == 1 ) maxval = (double) 0x7f;
647 else if ( size == 2 ) maxval = (double) 0x7fff;
648 else if ( size == 4 ) maxval = (double) 0x7fffffff;
649 else {
650 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
651 return 0;
652 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000653
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000654 rv = PyString_FromStringAndSize(NULL, len);
655 if ( rv == 0 )
656 return 0;
657 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000658
659
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000660 for ( i=0; i < len; i += size ) {
661 if ( size == 1 ) val = (int)*CHARP(cp, i);
662 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
663 else if ( size == 4 ) val = (int)*LONGP(cp, i);
664 fval = (double)val*factor;
665 if ( fval > maxval ) fval = maxval;
666 else if ( fval < -maxval ) fval = -maxval;
667 val = (int)fval;
668 if ( size == 1 ) *CHARP(ncp, i) = (signed char)val;
669 else if ( size == 2 ) *SHORTP(ncp, i) = (short)val;
Guido van Rossum69011961998-04-23 20:23:00 +0000670 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)val;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000671 }
672 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000673}
674
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000675static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000676audioop_tomono(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000677 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000678 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000679{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000680 signed char *cp, *ncp;
681 int len, size, val1 = 0, val2 = 0;
682 double fac1, fac2, fval, maxval;
683 PyObject *rv;
684 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000685
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000686 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
687 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000688
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000689 if ( size == 1 ) maxval = (double) 0x7f;
690 else if ( size == 2 ) maxval = (double) 0x7fff;
691 else if ( size == 4 ) maxval = (double) 0x7fffffff;
692 else {
693 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
694 return 0;
695 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000696
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000697 rv = PyString_FromStringAndSize(NULL, len/2);
698 if ( rv == 0 )
699 return 0;
700 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000701
702
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000703 for ( i=0; i < len; i += size*2 ) {
704 if ( size == 1 ) val1 = (int)*CHARP(cp, i);
705 else if ( size == 2 ) val1 = (int)*SHORTP(cp, i);
706 else if ( size == 4 ) val1 = (int)*LONGP(cp, i);
707 if ( size == 1 ) val2 = (int)*CHARP(cp, i+1);
708 else if ( size == 2 ) val2 = (int)*SHORTP(cp, i+2);
709 else if ( size == 4 ) val2 = (int)*LONGP(cp, i+4);
710 fval = (double)val1*fac1 + (double)val2*fac2;
711 if ( fval > maxval ) fval = maxval;
712 else if ( fval < -maxval ) fval = -maxval;
713 val1 = (int)fval;
714 if ( size == 1 ) *CHARP(ncp, i/2) = (signed char)val1;
715 else if ( size == 2 ) *SHORTP(ncp, i/2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000716 else if ( size == 4 ) *LONGP(ncp, i/2)= (Py_Int32)val1;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000717 }
718 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000719}
720
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000721static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000722audioop_tostereo(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000723 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000724 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000725{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000726 signed char *cp, *ncp;
727 int len, size, val1, val2, val = 0;
728 double fac1, fac2, fval, maxval;
729 PyObject *rv;
730 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000731
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000732 if ( !PyArg_Parse(args, "(s#idd)", &cp, &len, &size, &fac1, &fac2 ) )
733 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000734
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000735 if ( size == 1 ) maxval = (double) 0x7f;
736 else if ( size == 2 ) maxval = (double) 0x7fff;
737 else if ( size == 4 ) maxval = (double) 0x7fffffff;
738 else {
739 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
740 return 0;
741 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000742
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000743 rv = PyString_FromStringAndSize(NULL, len*2);
744 if ( rv == 0 )
745 return 0;
746 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000747
748
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000749 for ( i=0; i < len; i += size ) {
750 if ( size == 1 ) val = (int)*CHARP(cp, i);
751 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
752 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000753
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000754 fval = (double)val*fac1;
755 if ( fval > maxval ) fval = maxval;
756 else if ( fval < -maxval ) fval = -maxval;
757 val1 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000758
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000759 fval = (double)val*fac2;
760 if ( fval > maxval ) fval = maxval;
761 else if ( fval < -maxval ) fval = -maxval;
762 val2 = (int)fval;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000763
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000764 if ( size == 1 ) *CHARP(ncp, i*2) = (signed char)val1;
765 else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
Guido van Rossum69011961998-04-23 20:23:00 +0000766 else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000767
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000768 if ( size == 1 ) *CHARP(ncp, i*2+1) = (signed char)val2;
769 else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
Guido van Rossum69011961998-04-23 20:23:00 +0000770 else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000771 }
772 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000773}
774
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000775static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000776audioop_add(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000777 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000778 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000779{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000780 signed char *cp1, *cp2, *ncp;
Guido van Rossum1851a671997-02-14 16:14:03 +0000781 int len1, len2, size, val1 = 0, val2 = 0, maxval, newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000782 PyObject *rv;
783 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000784
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000785 if ( !PyArg_Parse(args, "(s#s#i)",
786 &cp1, &len1, &cp2, &len2, &size ) )
787 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000788
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000789 if ( len1 != len2 ) {
790 PyErr_SetString(AudioopError, "Lengths should be the same");
791 return 0;
792 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000793
Guido van Rossum1851a671997-02-14 16:14:03 +0000794 if ( size == 1 ) maxval = 0x7f;
795 else if ( size == 2 ) maxval = 0x7fff;
796 else if ( size == 4 ) maxval = 0x7fffffff;
797 else {
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000798 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
799 return 0;
800 }
Guido van Rossum1851a671997-02-14 16:14:03 +0000801
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000802 rv = PyString_FromStringAndSize(NULL, len1);
803 if ( rv == 0 )
804 return 0;
805 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossum1851a671997-02-14 16:14:03 +0000806
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000807 for ( i=0; i < len1; i += size ) {
808 if ( size == 1 ) val1 = (int)*CHARP(cp1, i);
809 else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
810 else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000811
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000812 if ( size == 1 ) val2 = (int)*CHARP(cp2, i);
813 else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
814 else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000815
Guido van Rossum1851a671997-02-14 16:14:03 +0000816 newval = val1 + val2;
817 /* truncate in case of overflow */
818 if (newval > maxval) newval = maxval;
819 else if (newval < -maxval) newval = -maxval;
820 else if (size == 4 && (newval^val1) < 0 && (newval^val2) < 0)
821 newval = val1 > 0 ? maxval : - maxval;
822
823 if ( size == 1 ) *CHARP(ncp, i) = (signed char)newval;
824 else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
Guido van Rossum69011961998-04-23 20:23:00 +0000825 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000826 }
827 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000828}
829
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000830static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +0000831audioop_bias(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000832 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000833 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000834{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000835 signed char *cp, *ncp;
836 int len, size, val = 0;
837 PyObject *rv;
838 int i;
839 int bias;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000840
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000841 if ( !PyArg_Parse(args, "(s#ii)",
842 &cp, &len, &size , &bias) )
843 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000844
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000845 if ( size != 1 && size != 2 && size != 4) {
846 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
847 return 0;
848 }
Guido van Rossumb66efa01992-06-01 16:01:24 +0000849
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000850 rv = PyString_FromStringAndSize(NULL, len);
851 if ( rv == 0 )
852 return 0;
853 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000854
855
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000856 for ( i=0; i < len; i += size ) {
857 if ( size == 1 ) val = (int)*CHARP(cp, i);
858 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
859 else if ( size == 4 ) val = (int)*LONGP(cp, i);
Guido van Rossumb66efa01992-06-01 16:01:24 +0000860
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000861 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val+bias);
862 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val+bias);
Guido van Rossum69011961998-04-23 20:23:00 +0000863 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val+bias);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000864 }
865 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +0000866}
867
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000868static PyObject *
Jack Jansen337b20e1993-02-23 13:39:57 +0000869audioop_reverse(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000870 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000871 PyObject *args;
Jack Jansen337b20e1993-02-23 13:39:57 +0000872{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000873 signed char *cp;
874 unsigned char *ncp;
875 int len, size, val = 0;
876 PyObject *rv;
877 int i, j;
Jack Jansen337b20e1993-02-23 13:39:57 +0000878
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000879 if ( !PyArg_Parse(args, "(s#i)",
880 &cp, &len, &size) )
881 return 0;
Jack Jansen337b20e1993-02-23 13:39:57 +0000882
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000883 if ( size != 1 && size != 2 && size != 4 ) {
884 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
885 return 0;
886 }
Jack Jansen337b20e1993-02-23 13:39:57 +0000887
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000888 rv = PyString_FromStringAndSize(NULL, len);
889 if ( rv == 0 )
890 return 0;
891 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen337b20e1993-02-23 13:39:57 +0000892
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000893 for ( i=0; i < len; i += size ) {
894 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
895 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
896 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansen337b20e1993-02-23 13:39:57 +0000897
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000898 j = len - i - size;
Jack Jansen337b20e1993-02-23 13:39:57 +0000899
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000900 if ( size == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
901 else if ( size == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000902 else if ( size == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000903 }
904 return rv;
Jack Jansen337b20e1993-02-23 13:39:57 +0000905}
906
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000907static PyObject *
Jack Jansena90805f1993-02-17 14:29:28 +0000908audioop_lin2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000909 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +0000910 PyObject *args;
Jack Jansena90805f1993-02-17 14:29:28 +0000911{
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000912 signed char *cp;
913 unsigned char *ncp;
914 int len, size, size2, val = 0;
915 PyObject *rv;
916 int i, j;
Jack Jansena90805f1993-02-17 14:29:28 +0000917
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000918 if ( !PyArg_Parse(args, "(s#ii)",
919 &cp, &len, &size, &size2) )
920 return 0;
Jack Jansena90805f1993-02-17 14:29:28 +0000921
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000922 if ( (size != 1 && size != 2 && size != 4) ||
923 (size2 != 1 && size2 != 2 && size2 != 4)) {
924 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
925 return 0;
926 }
Jack Jansena90805f1993-02-17 14:29:28 +0000927
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000928 rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
929 if ( rv == 0 )
930 return 0;
931 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansena90805f1993-02-17 14:29:28 +0000932
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000933 for ( i=0, j=0; i < len; i += size, j += size2 ) {
934 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
935 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
936 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Jack Jansena90805f1993-02-17 14:29:28 +0000937
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000938 if ( size2 == 1 ) *CHARP(ncp, j) = (signed char)(val >> 8);
939 else if ( size2 == 2 ) *SHORTP(ncp, j) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +0000940 else if ( size2 == 4 ) *LONGP(ncp, j) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000941 }
942 return rv;
Jack Jansena90805f1993-02-17 14:29:28 +0000943}
944
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000945static int
946gcd(a, b)
947 int a, b;
948{
949 while (b > 0) {
950 int tmp = a % b;
951 a = b;
952 b = tmp;
953 }
954 return a;
955}
956
Roger E. Masseeaa6e111997-01-03 19:26:27 +0000957static PyObject *
Roger E. Massec905fff1997-01-17 18:12:04 +0000958audioop_ratecv(self, args)
Guido van Rossum1851a671997-02-14 16:14:03 +0000959 PyObject *self;
960 PyObject *args;
Roger E. Massec905fff1997-01-17 18:12:04 +0000961{
Guido van Rossum1851a671997-02-14 16:14:03 +0000962 char *cp, *ncp;
963 int len, size, nchannels, inrate, outrate, weightA, weightB;
964 int chan, d, *prev_i, *cur_i, cur_o;
Guido van Rossum65bb3281999-09-07 14:24:05 +0000965 PyObject *state, *samps, *str, *rv = NULL;
Guido van Rossum1851a671997-02-14 16:14:03 +0000966
967 weightA = 1;
968 weightB = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000969 if (!PyArg_ParseTuple(args, "s#iiiiO|ii:ratecv", &cp, &len, &size, &nchannels,
Guido van Rossum1851a671997-02-14 16:14:03 +0000970 &inrate, &outrate, &state, &weightA, &weightB))
971 return NULL;
972 if (size != 1 && size != 2 && size != 4) {
973 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
974 return NULL;
975 }
976 if (nchannels < 1) {
977 PyErr_SetString(AudioopError, "# of channels should be >= 1");
978 return NULL;
979 }
980 if (weightA < 1 || weightB < 0) {
981 PyErr_SetString(AudioopError,
982 "weightA should be >= 1, weightB should be >= 0");
983 return NULL;
984 }
985 if (len % (size * nchannels) != 0) {
986 PyErr_SetString(AudioopError, "not a whole number of frames");
987 return NULL;
988 }
Guido van Rossumb24c9ea1997-05-20 15:59:35 +0000989 if (inrate <= 0 || outrate <= 0) {
990 PyErr_SetString(AudioopError, "sampling rate not > 0");
991 return NULL;
992 }
993 /* divide inrate and outrate by their greatest common divisor */
994 d = gcd(inrate, outrate);
995 inrate /= d;
996 outrate /= d;
997
Guido van Rossum6345ac61997-10-31 20:32:13 +0000998 prev_i = (int *) malloc(nchannels * sizeof(int));
999 cur_i = (int *) malloc(nchannels * sizeof(int));
Guido van Rossum1851a671997-02-14 16:14:03 +00001000 len /= size * nchannels; /* # of frames */
Guido van Rossum65bb3281999-09-07 14:24:05 +00001001 if (prev_i == NULL || cur_i == NULL) {
1002 (void) PyErr_NoMemory();
1003 goto exit;
1004 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001005
1006 if (state == Py_None) {
1007 d = -outrate;
1008 for (chan = 0; chan < nchannels; chan++)
1009 prev_i[chan] = cur_i[chan] = 0;
1010 } else {
1011 if (!PyArg_ParseTuple(state,
1012 "iO!;audioop.ratecv: illegal state argument",
1013 &d, &PyTuple_Type, &samps))
Guido van Rossum65bb3281999-09-07 14:24:05 +00001014 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001015 if (PyTuple_Size(samps) != nchannels) {
1016 PyErr_SetString(AudioopError,
Roger E. Massec905fff1997-01-17 18:12:04 +00001017 "illegal state argument");
Guido van Rossum65bb3281999-09-07 14:24:05 +00001018 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001019 }
1020 for (chan = 0; chan < nchannels; chan++) {
1021 if (!PyArg_ParseTuple(PyTuple_GetItem(samps, chan),
Guido van Rossum43713e52000-02-29 13:59:29 +00001022 "ii:ratecv",&prev_i[chan],&cur_i[chan]))
Guido van Rossum65bb3281999-09-07 14:24:05 +00001023 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001024 }
1025 }
1026 str = PyString_FromStringAndSize(
1027 NULL, size * nchannels * (len * outrate + inrate - 1) / inrate);
1028 if (str == NULL)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001029 goto exit;
Guido van Rossum1851a671997-02-14 16:14:03 +00001030 ncp = PyString_AsString(str);
1031
1032 for (;;) {
1033 while (d < 0) {
1034 if (len == 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001035 samps = PyTuple_New(nchannels);
1036 for (chan = 0; chan < nchannels; chan++)
Guido van Rossum1851a671997-02-14 16:14:03 +00001037 PyTuple_SetItem(samps, chan,
Roger E. Massec905fff1997-01-17 18:12:04 +00001038 Py_BuildValue("(ii)",
1039 prev_i[chan],
1040 cur_i[chan]));
1041 if (PyErr_Occurred())
Guido van Rossum65bb3281999-09-07 14:24:05 +00001042 goto exit;
Guido van Rossum3bbeb7a1997-09-22 16:14:27 +00001043 len = ncp - PyString_AsString(str);
1044 if (len == 0) {
1045 /*don't want to resize to zero length*/
1046 rv = PyString_FromStringAndSize("", 0);
1047 Py_DECREF(str);
1048 str = rv;
1049 } else if (_PyString_Resize(&str, len) < 0)
Guido van Rossum65bb3281999-09-07 14:24:05 +00001050 goto exit;
Roger E. Massec905fff1997-01-17 18:12:04 +00001051 rv = Py_BuildValue("(O(iO))", str, d, samps);
Guido van Rossum1851a671997-02-14 16:14:03 +00001052 Py_DECREF(samps);
Roger E. Massec905fff1997-01-17 18:12:04 +00001053 Py_DECREF(str);
Guido van Rossum65bb3281999-09-07 14:24:05 +00001054 goto exit; /* return rv */
Roger E. Massec905fff1997-01-17 18:12:04 +00001055 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001056 for (chan = 0; chan < nchannels; chan++) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001057 prev_i[chan] = cur_i[chan];
1058 if (size == 1)
Guido van Rossum1851a671997-02-14 16:14:03 +00001059 cur_i[chan] = ((int)*CHARP(cp, 0)) << 8;
Roger E. Massec905fff1997-01-17 18:12:04 +00001060 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001061 cur_i[chan] = (int)*SHORTP(cp, 0);
Roger E. Massec905fff1997-01-17 18:12:04 +00001062 else if (size == 4)
Guido van Rossum1851a671997-02-14 16:14:03 +00001063 cur_i[chan] = ((int)*LONGP(cp, 0)) >> 16;
Roger E. Massec905fff1997-01-17 18:12:04 +00001064 cp += size;
1065 /* implements a simple digital filter */
Guido van Rossum1851a671997-02-14 16:14:03 +00001066 cur_i[chan] =
1067 (weightA * cur_i[chan] +
1068 weightB * prev_i[chan]) /
1069 (weightA + weightB);
Roger E. Massec905fff1997-01-17 18:12:04 +00001070 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001071 len--;
Roger E. Massec905fff1997-01-17 18:12:04 +00001072 d += outrate;
1073 }
Guido van Rossum1851a671997-02-14 16:14:03 +00001074 while (d >= 0) {
Roger E. Massec905fff1997-01-17 18:12:04 +00001075 for (chan = 0; chan < nchannels; chan++) {
Guido van Rossum1851a671997-02-14 16:14:03 +00001076 cur_o = (prev_i[chan] * d +
1077 cur_i[chan] * (outrate - d)) /
1078 outrate;
1079 if (size == 1)
1080 *CHARP(ncp, 0) = (signed char)(cur_o >> 8);
Roger E. Massec905fff1997-01-17 18:12:04 +00001081 else if (size == 2)
Guido van Rossum1851a671997-02-14 16:14:03 +00001082 *SHORTP(ncp, 0) = (short)(cur_o);
1083 else if (size == 4)
Guido van Rossum69011961998-04-23 20:23:00 +00001084 *LONGP(ncp, 0) = (Py_Int32)(cur_o<<16);
Guido van Rossum1851a671997-02-14 16:14:03 +00001085 ncp += size;
1086 }
1087 d -= inrate;
1088 }
1089 }
Guido van Rossum65bb3281999-09-07 14:24:05 +00001090 exit:
1091 if (prev_i != NULL)
1092 free(prev_i);
1093 if (cur_i != NULL)
1094 free(cur_i);
1095 return rv;
Roger E. Massec905fff1997-01-17 18:12:04 +00001096}
Guido van Rossum1851a671997-02-14 16:14:03 +00001097
Roger E. Massec905fff1997-01-17 18:12:04 +00001098static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001099audioop_lin2ulaw(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001100 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001101 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001102{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001103 signed char *cp;
1104 unsigned char *ncp;
1105 int len, size, val = 0;
1106 PyObject *rv;
1107 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001108
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001109 if ( !PyArg_Parse(args, "(s#i)",
1110 &cp, &len, &size) )
1111 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001112
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001113 if ( size != 1 && size != 2 && size != 4) {
1114 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1115 return 0;
1116 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001117
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001118 rv = PyString_FromStringAndSize(NULL, len/size);
1119 if ( rv == 0 )
1120 return 0;
1121 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001122
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001123 for ( i=0; i < len; i += size ) {
1124 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1125 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1126 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001127
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001128 *ncp++ = st_linear_to_ulaw(val);
1129 }
1130 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001131}
1132
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001133static PyObject *
Guido van Rossumb66efa01992-06-01 16:01:24 +00001134audioop_ulaw2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001135 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001136 PyObject *args;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001137{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001138 unsigned char *cp;
1139 unsigned char cval;
1140 signed char *ncp;
1141 int len, size, val;
1142 PyObject *rv;
1143 int i;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001144
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001145 if ( !PyArg_Parse(args, "(s#i)",
1146 &cp, &len, &size) )
1147 return 0;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001148
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001149 if ( size != 1 && size != 2 && size != 4) {
1150 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1151 return 0;
1152 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001153
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001154 rv = PyString_FromStringAndSize(NULL, len*size);
1155 if ( rv == 0 )
1156 return 0;
1157 ncp = (signed char *)PyString_AsString(rv);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001158
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001159 for ( i=0; i < len*size; i += size ) {
1160 cval = *cp++;
1161 val = st_ulaw_to_linear(cval);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001162
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001163 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(val >> 8);
1164 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(val);
Guido van Rossum69011961998-04-23 20:23:00 +00001165 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(val<<16);
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001166 }
1167 return rv;
Guido van Rossumb66efa01992-06-01 16:01:24 +00001168}
1169
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001170static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001171audioop_lin2adpcm(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001172 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001173 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001174{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001175 signed char *cp;
1176 signed char *ncp;
1177 int len, size, val = 0, step, valpred, delta,
1178 index, sign, vpdiff, diff;
1179 PyObject *rv, *state, *str;
1180 int i, outputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001181
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001182 if ( !PyArg_Parse(args, "(s#iO)",
1183 &cp, &len, &size, &state) )
1184 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001185
1186
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001187 if ( size != 1 && size != 2 && size != 4) {
1188 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1189 return 0;
1190 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001191
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001192 str = PyString_FromStringAndSize(NULL, len/(size*2));
1193 if ( str == 0 )
1194 return 0;
1195 ncp = (signed char *)PyString_AsString(str);
Jack Jansendd8a6ea1993-02-17 14:21:09 +00001196
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001197 /* Decode state, should have (value, step) */
1198 if ( state == Py_None ) {
1199 /* First time, it seems. Set defaults */
1200 valpred = 0;
1201 step = 7;
1202 index = 0;
1203 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1204 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001205
Guido van Rossumb64e6351992-07-06 14:21:56 +00001206 step = stepsizeTable[index];
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001207 bufferstep = 1;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001208
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001209 for ( i=0; i < len; i += size ) {
1210 if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
1211 else if ( size == 2 ) val = (int)*SHORTP(cp, i);
1212 else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
1213
1214 /* Step 1 - compute difference with previous value */
1215 diff = val - valpred;
1216 sign = (diff < 0) ? 8 : 0;
1217 if ( sign ) diff = (-diff);
1218
1219 /* Step 2 - Divide and clamp */
1220 /* Note:
1221 ** This code *approximately* computes:
1222 ** delta = diff*4/step;
1223 ** vpdiff = (delta+0.5)*step/4;
1224 ** but in shift step bits are dropped. The net result of this
1225 ** is that even if you have fast mul/div hardware you cannot
1226 ** put it to good use since the fixup would be too expensive.
1227 */
1228 delta = 0;
1229 vpdiff = (step >> 3);
1230
1231 if ( diff >= step ) {
1232 delta = 4;
1233 diff -= step;
1234 vpdiff += step;
1235 }
1236 step >>= 1;
1237 if ( diff >= step ) {
1238 delta |= 2;
1239 diff -= step;
1240 vpdiff += step;
1241 }
1242 step >>= 1;
1243 if ( diff >= step ) {
1244 delta |= 1;
1245 vpdiff += step;
1246 }
1247
1248 /* Step 3 - Update previous value */
1249 if ( sign )
1250 valpred -= vpdiff;
1251 else
1252 valpred += vpdiff;
1253
1254 /* Step 4 - Clamp previous value to 16 bits */
1255 if ( valpred > 32767 )
1256 valpred = 32767;
1257 else if ( valpred < -32768 )
1258 valpred = -32768;
1259
1260 /* Step 5 - Assemble value, update index and step values */
1261 delta |= sign;
1262
1263 index += indexTable[delta];
1264 if ( index < 0 ) index = 0;
1265 if ( index > 88 ) index = 88;
1266 step = stepsizeTable[index];
1267
1268 /* Step 6 - Output value */
1269 if ( bufferstep ) {
1270 outputbuffer = (delta << 4) & 0xf0;
1271 } else {
1272 *ncp++ = (delta & 0x0f) | outputbuffer;
1273 }
1274 bufferstep = !bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001275 }
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001276 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1277 Py_DECREF(str);
1278 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001279}
1280
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001281static PyObject *
Guido van Rossumb64e6351992-07-06 14:21:56 +00001282audioop_adpcm2lin(self, args)
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001283 PyObject *self;
Roger E. Massec905fff1997-01-17 18:12:04 +00001284 PyObject *args;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001285{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001286 signed char *cp;
1287 signed char *ncp;
1288 int len, size, valpred, step, delta, index, sign, vpdiff;
1289 PyObject *rv, *str, *state;
1290 int i, inputbuffer = 0, bufferstep;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001291
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001292 if ( !PyArg_Parse(args, "(s#iO)",
1293 &cp, &len, &size, &state) )
1294 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001295
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001296 if ( size != 1 && size != 2 && size != 4) {
1297 PyErr_SetString(AudioopError, "Size should be 1, 2 or 4");
1298 return 0;
1299 }
Guido van Rossumb64e6351992-07-06 14:21:56 +00001300
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001301 /* Decode state, should have (value, step) */
1302 if ( state == Py_None ) {
1303 /* First time, it seems. Set defaults */
1304 valpred = 0;
1305 step = 7;
1306 index = 0;
1307 } else if ( !PyArg_Parse(state, "(ii)", &valpred, &index) )
1308 return 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001309
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001310 str = PyString_FromStringAndSize(NULL, len*size*2);
1311 if ( str == 0 )
1312 return 0;
1313 ncp = (signed char *)PyString_AsString(str);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001314
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001315 step = stepsizeTable[index];
1316 bufferstep = 0;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001317
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001318 for ( i=0; i < len*size*2; i += size ) {
1319 /* Step 1 - get the delta value and compute next index */
1320 if ( bufferstep ) {
1321 delta = inputbuffer & 0xf;
1322 } else {
1323 inputbuffer = *cp++;
1324 delta = (inputbuffer >> 4) & 0xf;
1325 }
1326
1327 bufferstep = !bufferstep;
1328
1329 /* Step 2 - Find new index value (for later) */
1330 index += indexTable[delta];
1331 if ( index < 0 ) index = 0;
1332 if ( index > 88 ) index = 88;
1333
1334 /* Step 3 - Separate sign and magnitude */
1335 sign = delta & 8;
1336 delta = delta & 7;
1337
1338 /* Step 4 - Compute difference and new predicted value */
1339 /*
1340 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
1341 ** in adpcm_coder.
1342 */
1343 vpdiff = step >> 3;
1344 if ( delta & 4 ) vpdiff += step;
1345 if ( delta & 2 ) vpdiff += step>>1;
1346 if ( delta & 1 ) vpdiff += step>>2;
1347
1348 if ( sign )
1349 valpred -= vpdiff;
1350 else
1351 valpred += vpdiff;
1352
1353 /* Step 5 - clamp output value */
1354 if ( valpred > 32767 )
1355 valpred = 32767;
1356 else if ( valpred < -32768 )
1357 valpred = -32768;
1358
1359 /* Step 6 - Update step value */
1360 step = stepsizeTable[index];
1361
1362 /* Step 6 - Output value */
1363 if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
1364 else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
Guido van Rossum69011961998-04-23 20:23:00 +00001365 else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
Guido van Rossumb64e6351992-07-06 14:21:56 +00001366 }
1367
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001368 rv = Py_BuildValue("(O(ii))", str, valpred, index);
1369 Py_DECREF(str);
1370 return rv;
Guido van Rossumb64e6351992-07-06 14:21:56 +00001371}
1372
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001373static PyMethodDef audioop_methods[] = {
1374 { "max", audioop_max },
1375 { "minmax", audioop_minmax },
1376 { "avg", audioop_avg },
1377 { "maxpp", audioop_maxpp },
1378 { "avgpp", audioop_avgpp },
1379 { "rms", audioop_rms },
1380 { "findfit", audioop_findfit },
1381 { "findmax", audioop_findmax },
1382 { "findfactor", audioop_findfactor },
1383 { "cross", audioop_cross },
1384 { "mul", audioop_mul },
1385 { "add", audioop_add },
1386 { "bias", audioop_bias },
1387 { "ulaw2lin", audioop_ulaw2lin },
1388 { "lin2ulaw", audioop_lin2ulaw },
1389 { "lin2lin", audioop_lin2lin },
1390 { "adpcm2lin", audioop_adpcm2lin },
1391 { "lin2adpcm", audioop_lin2adpcm },
1392 { "tomono", audioop_tomono },
1393 { "tostereo", audioop_tostereo },
1394 { "getsample", audioop_getsample },
1395 { "reverse", audioop_reverse },
Roger E. Massec905fff1997-01-17 18:12:04 +00001396 { "ratecv", audioop_ratecv, 1 },
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001397 { 0, 0 }
Guido van Rossumb66efa01992-06-01 16:01:24 +00001398};
1399
Guido van Rossum3886bb61998-12-04 18:50:17 +00001400DL_EXPORT(void)
Guido van Rossumb66efa01992-06-01 16:01:24 +00001401initaudioop()
1402{
Roger E. Masseeaa6e111997-01-03 19:26:27 +00001403 PyObject *m, *d;
1404 m = Py_InitModule("audioop", audioop_methods);
1405 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001406 AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1407 if (AudioopError != NULL)
1408 PyDict_SetItemString(d,"error",AudioopError);
Guido van Rossumb66efa01992-06-01 16:01:24 +00001409}