summaryrefslogtreecommitdiffstats
path: root/Modules/audioop.c
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1992-08-24 14:36:31 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1992-08-24 14:36:31 (GMT)
commite1b4d7ce14c3463c14a188cb86eb1e267e66c254 (patch)
tree9cb0cdbc3abc342a15177636a984302018fbc552 /Modules/audioop.c
parent8eace20f686ca6a0540478b5a3fed23df12b68c7 (diff)
downloadcpython-e1b4d7ce14c3463c14a188cb86eb1e267e66c254.zip
cpython-e1b4d7ce14c3463c14a188cb86eb1e267e66c254.tar.gz
cpython-e1b4d7ce14c3463c14a188cb86eb1e267e66c254.tar.bz2
Added rms, maxpp and avgpp methods.
Diffstat (limited to 'Modules/audioop.c')
-rw-r--r--Modules/audioop.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/Modules/audioop.c b/Modules/audioop.c
index d37ce8f..0c75a46 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -28,6 +28,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define signed
#endif
+#include <math.h>
+
#include "allobjects.h"
#include "modsupport.h"
@@ -240,6 +242,147 @@ audioop_avg(self, args)
}
static object *
+audioop_rms(self, args)
+ object *self;
+ object *args;
+{
+ signed char *cp;
+ int len, size, val;
+ int i;
+ float sum_squares = 0.0;
+
+ if ( !getargs(args, "(s#i)", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ err_setstr(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ for ( i=0; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ sum_squares += (float)val*(float)val;
+ }
+ if ( len == 0 )
+ val = 0;
+ else
+ val = (int)sqrt(sum_squares / (float)(len/size));
+ return newintobject(val);
+}
+
+static object *
+audioop_avgpp(self, args)
+ object *self;
+ object *args;
+{
+ signed char *cp;
+ int len, size, val, prevval, prevextremevalid = 0, prevextreme;
+ int i;
+ float avg = 0.0;
+ int diff, prevdiff, extremediff, nextreme = 0;
+
+ if ( !getargs(args, "(s#i)", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ err_setstr(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ /* Compute first delta value ahead. Also automatically makes us
+ ** skip the first extreme value
+ */
+ if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
+ else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
+ else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
+ if ( size == 1 ) val = (int)*CHARP(cp, size);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, size);
+ else if ( size == 4 ) val = (int)*LONGP(cp, size);
+ prevdiff = val - prevval;
+
+ for ( i=size; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ diff = val - prevval;
+ if ( diff*prevdiff < 0 ) {
+ /* Derivative changed sign. Compute difference to last extreme
+ ** value and remember.
+ */
+ if ( prevextremevalid ) {
+ extremediff = prevval - prevextreme;
+ if ( extremediff < 0 )
+ extremediff = -extremediff;
+ avg += extremediff;
+ nextreme++;
+ }
+ prevextremevalid = 1;
+ prevextreme = prevval;
+ }
+ prevval = val;
+ if ( diff != 0 )
+ prevdiff = diff;
+ }
+ if ( nextreme == 0 )
+ val = 0;
+ else
+ val = (int)(avg / (float)nextreme);
+ return newintobject(val);
+}
+
+static object *
+audioop_maxpp(self, args)
+ object *self;
+ object *args;
+{
+ signed char *cp;
+ int len, size, val, prevval, prevextremevalid = 0, prevextreme;
+ int i;
+ int max = 0;
+ int diff, prevdiff, extremediff;
+
+ if ( !getargs(args, "(s#i)", &cp, &len, &size) )
+ return 0;
+ if ( size != 1 && size != 2 && size != 4 ) {
+ err_setstr(AudioopError, "Size should be 1, 2 or 4");
+ return 0;
+ }
+ /* Compute first delta value ahead. Also automatically makes us
+ ** skip the first extreme value
+ */
+ if ( size == 1 ) prevval = (int)*CHARP(cp, 0);
+ else if ( size == 2 ) prevval = (int)*SHORTP(cp, 0);
+ else if ( size == 4 ) prevval = (int)*LONGP(cp, 0);
+ if ( size == 1 ) val = (int)*CHARP(cp, size);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, size);
+ else if ( size == 4 ) val = (int)*LONGP(cp, size);
+ prevdiff = val - prevval;
+
+ for ( i=size; i<len; i+= size) {
+ if ( size == 1 ) val = (int)*CHARP(cp, i);
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = (int)*LONGP(cp, i);
+ diff = val - prevval;
+ if ( diff*prevdiff < 0 ) {
+ /* Derivative changed sign. Compute difference to last extreme
+ ** value and remember.
+ */
+ if ( prevextremevalid ) {
+ extremediff = prevval - prevextreme;
+ if ( extremediff < 0 )
+ extremediff = -extremediff;
+ if ( extremediff > max )
+ max = extremediff;
+ }
+ prevextremevalid = 1;
+ prevextreme = prevval;
+ }
+ prevval = val;
+ if ( diff != 0 )
+ prevdiff = diff;
+ }
+ return newintobject(max);
+}
+
+static object *
audioop_cross(self, args)
object *self;
object *args;
@@ -869,6 +1012,9 @@ audioop_adpcm2lin(self, args)
static struct methodlist audioop_methods[] = {
{ "max", audioop_max },
{ "avg", audioop_avg },
+ { "maxpp", audioop_maxpp },
+ { "avgpp", audioop_avgpp },
+ { "rms", audioop_rms },
{ "cross", audioop_cross },
{ "mul", audioop_mul },
{ "add", audioop_add },