Mercurial > hg > aim92
diff tools/loudness.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/loudness.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,147 @@ +/*************************************************************************** + loudness.c Loudness measure from spiral sector-weights contour. + ---------- + Michael Allerhand, 1992. + + Read m binary shorts (default m=SECTORS) for each specified frame. + Compute the loudness as the mean value of the sector-weights. + +****************************************************************************/ + +#include <stdio.h> +#include <math.h> +#include "options.h" +#include "units.h" +#include "strmatch.h" + +char applic[] = "Loudness measure from spiral sector-weights contour.\n (Input and output in binary shorts)." ; + +static char *helpstr, *debugstr, *fstr, *sstr, *mstr ; + +static Options option[] = { + { "help" , "off" , &helpstr , "help" , DEBUG }, + { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, + { "frames" , "1-max" , &fstr , "select frames inclusively" , VAL }, + { "scale" , "1.848" , &sstr , "scale factor" , SVAL }, + { "nsectors" , "64" , &mstr , "number of sectors" , SVAL }, + ( char * ) 0 } ; + + +main (argc, argv) +int argc; +char **argv; +{ + FILE *fp; + int m; /* Number of sectors around spiral. */ + short *sector; /* Sector-weights contour. */ + float scalar; /* Scale factor for loudness. */ + int i, a, b; + char *val1, *val2 ; + + fp = openopts( option,argc,argv ) ; + if ( !isoff( helpstr ) ) + helpopts( helpstr, argv[0], applic, option ) ; + + m = atoi( mstr ) ; + scalar = atof( sstr ) ; + + /* parse bounds on number of frames */ + + if ( getvals( fstr, &val1, &val2, "-" ) == BADVAL ) { + fprintf(stderr,"loudness: bad frame selector [%s]\n", fstr ) ; + exit( 1 ) ; + } + a = atoi( val1 ) ; + if ( isempty( val2 ) ) b = a ; + else if ( ismax( val2 ) ) b = 0 ; + else b = atoi( val2 ) ; + + if (b<a && b>0) fprintf(stderr,"loudness: warning, bad frame specifiers\n"); + + if ( ison( debugstr ) ) { + printf("a=%d b=%d m=%d scalar=%.3f\n", + a, b, m, scalar ); + exit(0); + } + + + /* Allocate space for sector-weights contour */ + + if (( sector = (short *)malloc(m*sizeof(short))) == NULL) + fprintf(stderr,"loudness: malloc out of space\n"); + + /* Seek past a-1 frames, then read the next b-a+1 frames, or all */ + /* remaining frames if b==0. */ + + if (a>0) { + + for (i=1 ; i<a && fread(sector,sizeof(short),m,fp) ; i++) + ; + if (b > 0) + for ( ; i<=b && fread(sector,sizeof(short),m,fp) ; i++) + loudness(sector,m,scalar); + else + while ( fread(sector,sizeof(short),m,fp) ) + loudness(sector,m,scalar); + } + + fclose(fp); +} + + +loudness(sector,m,scalar) +short *sector; /* Sector-weights contour. */ +int m; /* Number of sectors around spiral. */ +float scalar; /* Scale factor for loudness measure. */ +{ + short scale; /* Mean weights. */ + + scale = (short)( normalize_scale(sector,m) * scalar ); + fwrite(&scale,sizeof(short),1,stdout); + +} + + +/**************************************************************************** + Normalize Scale. +****************************************************************************/ + +/* +Normalize for unit variance and zero mean, and then scale for MEAN and STDDEV. +In general the stddev is scaled down to STDDEV, but if the stddev is already +less than the target STDDEV, than it is left alone. +*/ + +#define MEAN 100 +#define STDDEV 32 /* Resulting variance will be this squared */ + +normalize_scale(V,m) +short *V; +int m; +{ + int i; + float mean, var; + float sum, sumsq, stddev, norm; + + sum=0; sumsq=0; + for (i=0 ; i<m ; i++) { + sum += V[i]; + sumsq += V[i] * V[i]; + } + mean = sum/m; + var = sumsq/m - mean*mean; + + if ((stddev = sqrt(var)) >= STDDEV) + for (i=0 ; i<m ; i++) { + norm = ( (float)V[i] - mean ) / stddev; + V[i] = norm * STDDEV + MEAN; + } + else + for (i=0 ; i<m ; i++) { + norm = (float)V[i]-mean; + V[i] = norm + MEAN; + } + + return (int)mean; +} +