Mercurial > hg > aim92
view 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 source
/*************************************************************************** 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; }