@@ -28,6 +28,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28
28
#define signed
29
29
#endif
30
30
31
+ #include <math.h>
32
+
31
33
#include "allobjects.h"
32
34
#include "modsupport.h"
33
35
@@ -239,6 +241,147 @@ audioop_avg(self, args)
239
241
return newintobject (val );
240
242
}
241
243
244
+ static object *
245
+ audioop_rms (self , args )
246
+ object * self ;
247
+ object * args ;
248
+ {
249
+ signed char * cp ;
250
+ int len , size , val ;
251
+ int i ;
252
+ float sum_squares = 0.0 ;
253
+
254
+ if ( !getargs (args , "(s#i)" , & cp , & len , & size ) )
255
+ return 0 ;
256
+ if ( size != 1 && size != 2 && size != 4 ) {
257
+ err_setstr (AudioopError , "Size should be 1, 2 or 4" );
258
+ return 0 ;
259
+ }
260
+ for ( i = 0 ; i < len ; i += size ) {
261
+ if ( size == 1 ) val = (int )* CHARP (cp , i );
262
+ else if ( size == 2 ) val = (int )* SHORTP (cp , i );
263
+ else if ( size == 4 ) val = (int )* LONGP (cp , i );
264
+ sum_squares += (float )val * (float )val ;
265
+ }
266
+ if ( len == 0 )
267
+ val = 0 ;
268
+ else
269
+ val = (int )sqrt (sum_squares / (float )(len /size ));
270
+ return newintobject (val );
271
+ }
272
+
273
+ static object *
274
+ audioop_avgpp (self , args )
275
+ object * self ;
276
+ object * args ;
277
+ {
278
+ signed char * cp ;
279
+ int len , size , val , prevval , prevextremevalid = 0 , prevextreme ;
280
+ int i ;
281
+ float avg = 0.0 ;
282
+ int diff , prevdiff , extremediff , nextreme = 0 ;
283
+
284
+ if ( !getargs (args , "(s#i)" , & cp , & len , & size ) )
285
+ return 0 ;
286
+ if ( size != 1 && size != 2 && size != 4 ) {
287
+ err_setstr (AudioopError , "Size should be 1, 2 or 4" );
288
+ return 0 ;
289
+ }
290
+ /* Compute first delta value ahead. Also automatically makes us
291
+ ** skip the first extreme value
292
+ */
293
+ if ( size == 1 ) prevval = (int )* CHARP (cp , 0 );
294
+ else if ( size == 2 ) prevval = (int )* SHORTP (cp , 0 );
295
+ else if ( size == 4 ) prevval = (int )* LONGP (cp , 0 );
296
+ if ( size == 1 ) val = (int )* CHARP (cp , size );
297
+ else if ( size == 2 ) val = (int )* SHORTP (cp , size );
298
+ else if ( size == 4 ) val = (int )* LONGP (cp , size );
299
+ prevdiff = val - prevval ;
300
+
301
+ for ( i = size ; i < len ; i += size ) {
302
+ if ( size == 1 ) val = (int )* CHARP (cp , i );
303
+ else if ( size == 2 ) val = (int )* SHORTP (cp , i );
304
+ else if ( size == 4 ) val = (int )* LONGP (cp , i );
305
+ diff = val - prevval ;
306
+ if ( diff * prevdiff < 0 ) {
307
+ /* Derivative changed sign. Compute difference to last extreme
308
+ ** value and remember.
309
+ */
310
+ if ( prevextremevalid ) {
311
+ extremediff = prevval - prevextreme ;
312
+ if ( extremediff < 0 )
313
+ extremediff = - extremediff ;
314
+ avg += extremediff ;
315
+ nextreme ++ ;
316
+ }
317
+ prevextremevalid = 1 ;
318
+ prevextreme = prevval ;
319
+ }
320
+ prevval = val ;
321
+ if ( diff != 0 )
322
+ prevdiff = diff ;
323
+ }
324
+ if ( nextreme == 0 )
325
+ val = 0 ;
326
+ else
327
+ val = (int )(avg / (float )nextreme );
328
+ return newintobject (val );
329
+ }
330
+
331
+ static object *
332
+ audioop_maxpp (self , args )
333
+ object * self ;
334
+ object * args ;
335
+ {
336
+ signed char * cp ;
337
+ int len , size , val , prevval , prevextremevalid = 0 , prevextreme ;
338
+ int i ;
339
+ int max = 0 ;
340
+ int diff , prevdiff , extremediff ;
341
+
342
+ if ( !getargs (args , "(s#i)" , & cp , & len , & size ) )
343
+ return 0 ;
344
+ if ( size != 1 && size != 2 && size != 4 ) {
345
+ err_setstr (AudioopError , "Size should be 1, 2 or 4" );
346
+ return 0 ;
347
+ }
348
+ /* Compute first delta value ahead. Also automatically makes us
349
+ ** skip the first extreme value
350
+ */
351
+ if ( size == 1 ) prevval = (int )* CHARP (cp , 0 );
352
+ else if ( size == 2 ) prevval = (int )* SHORTP (cp , 0 );
353
+ else if ( size == 4 ) prevval = (int )* LONGP (cp , 0 );
354
+ if ( size == 1 ) val = (int )* CHARP (cp , size );
355
+ else if ( size == 2 ) val = (int )* SHORTP (cp , size );
356
+ else if ( size == 4 ) val = (int )* LONGP (cp , size );
357
+ prevdiff = val - prevval ;
358
+
359
+ for ( i = size ; i < len ; i += size ) {
360
+ if ( size == 1 ) val = (int )* CHARP (cp , i );
361
+ else if ( size == 2 ) val = (int )* SHORTP (cp , i );
362
+ else if ( size == 4 ) val = (int )* LONGP (cp , i );
363
+ diff = val - prevval ;
364
+ if ( diff * prevdiff < 0 ) {
365
+ /* Derivative changed sign. Compute difference to last extreme
366
+ ** value and remember.
367
+ */
368
+ if ( prevextremevalid ) {
369
+ extremediff = prevval - prevextreme ;
370
+ if ( extremediff < 0 )
371
+ extremediff = - extremediff ;
372
+ if ( extremediff > max )
373
+ max = extremediff ;
374
+ }
375
+ prevextremevalid = 1 ;
376
+ prevextreme = prevval ;
377
+ }
378
+ prevval = val ;
379
+ if ( diff != 0 )
380
+ prevdiff = diff ;
381
+ }
382
+ return newintobject (max );
383
+ }
384
+
242
385
static object *
243
386
audioop_cross (self , args )
244
387
object * self ;
@@ -869,6 +1012,9 @@ audioop_adpcm2lin(self, args)
869
1012
static struct methodlist audioop_methods [] = {
870
1013
{ "max" , audioop_max },
871
1014
{ "avg" , audioop_avg },
1015
+ { "maxpp" , audioop_maxpp },
1016
+ { "avgpp" , audioop_avgpp },
1017
+ { "rms" , audioop_rms },
872
1018
{ "cross" , audioop_cross },
873
1019
{ "mul" , audioop_mul },
874
1020
{ "add" , audioop_add },
0 commit comments