comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:5242703e91d3
1 /***************************************************************************
2 loudness.c Loudness measure from spiral sector-weights contour.
3 ----------
4 Michael Allerhand, 1992.
5
6 Read m binary shorts (default m=SECTORS) for each specified frame.
7 Compute the loudness as the mean value of the sector-weights.
8
9 ****************************************************************************/
10
11 #include <stdio.h>
12 #include <math.h>
13 #include "options.h"
14 #include "units.h"
15 #include "strmatch.h"
16
17 char applic[] = "Loudness measure from spiral sector-weights contour.\n (Input and output in binary shorts)." ;
18
19 static char *helpstr, *debugstr, *fstr, *sstr, *mstr ;
20
21 static Options option[] = {
22 { "help" , "off" , &helpstr , "help" , DEBUG },
23 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
24 { "frames" , "1-max" , &fstr , "select frames inclusively" , VAL },
25 { "scale" , "1.848" , &sstr , "scale factor" , SVAL },
26 { "nsectors" , "64" , &mstr , "number of sectors" , SVAL },
27 ( char * ) 0 } ;
28
29
30 main (argc, argv)
31 int argc;
32 char **argv;
33 {
34 FILE *fp;
35 int m; /* Number of sectors around spiral. */
36 short *sector; /* Sector-weights contour. */
37 float scalar; /* Scale factor for loudness. */
38 int i, a, b;
39 char *val1, *val2 ;
40
41 fp = openopts( option,argc,argv ) ;
42 if ( !isoff( helpstr ) )
43 helpopts( helpstr, argv[0], applic, option ) ;
44
45 m = atoi( mstr ) ;
46 scalar = atof( sstr ) ;
47
48 /* parse bounds on number of frames */
49
50 if ( getvals( fstr, &val1, &val2, "-" ) == BADVAL ) {
51 fprintf(stderr,"loudness: bad frame selector [%s]\n", fstr ) ;
52 exit( 1 ) ;
53 }
54 a = atoi( val1 ) ;
55 if ( isempty( val2 ) ) b = a ;
56 else if ( ismax( val2 ) ) b = 0 ;
57 else b = atoi( val2 ) ;
58
59 if (b<a && b>0) fprintf(stderr,"loudness: warning, bad frame specifiers\n");
60
61 if ( ison( debugstr ) ) {
62 printf("a=%d b=%d m=%d scalar=%.3f\n",
63 a, b, m, scalar );
64 exit(0);
65 }
66
67
68 /* Allocate space for sector-weights contour */
69
70 if (( sector = (short *)malloc(m*sizeof(short))) == NULL)
71 fprintf(stderr,"loudness: malloc out of space\n");
72
73 /* Seek past a-1 frames, then read the next b-a+1 frames, or all */
74 /* remaining frames if b==0. */
75
76 if (a>0) {
77
78 for (i=1 ; i<a && fread(sector,sizeof(short),m,fp) ; i++)
79 ;
80 if (b > 0)
81 for ( ; i<=b && fread(sector,sizeof(short),m,fp) ; i++)
82 loudness(sector,m,scalar);
83 else
84 while ( fread(sector,sizeof(short),m,fp) )
85 loudness(sector,m,scalar);
86 }
87
88 fclose(fp);
89 }
90
91
92 loudness(sector,m,scalar)
93 short *sector; /* Sector-weights contour. */
94 int m; /* Number of sectors around spiral. */
95 float scalar; /* Scale factor for loudness measure. */
96 {
97 short scale; /* Mean weights. */
98
99 scale = (short)( normalize_scale(sector,m) * scalar );
100 fwrite(&scale,sizeof(short),1,stdout);
101
102 }
103
104
105 /****************************************************************************
106 Normalize Scale.
107 ****************************************************************************/
108
109 /*
110 Normalize for unit variance and zero mean, and then scale for MEAN and STDDEV.
111 In general the stddev is scaled down to STDDEV, but if the stddev is already
112 less than the target STDDEV, than it is left alone.
113 */
114
115 #define MEAN 100
116 #define STDDEV 32 /* Resulting variance will be this squared */
117
118 normalize_scale(V,m)
119 short *V;
120 int m;
121 {
122 int i;
123 float mean, var;
124 float sum, sumsq, stddev, norm;
125
126 sum=0; sumsq=0;
127 for (i=0 ; i<m ; i++) {
128 sum += V[i];
129 sumsq += V[i] * V[i];
130 }
131 mean = sum/m;
132 var = sumsq/m - mean*mean;
133
134 if ((stddev = sqrt(var)) >= STDDEV)
135 for (i=0 ; i<m ; i++) {
136 norm = ( (float)V[i] - mean ) / stddev;
137 V[i] = norm * STDDEV + MEAN;
138 }
139 else
140 for (i=0 ; i<m ; i++) {
141 norm = (float)V[i]-mean;
142 V[i] = norm + MEAN;
143 }
144
145 return (int)mean;
146 }
147