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