1 /*
2 MPEG Maaate: An Australian MPEG audio analysis toolkit
3 Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
4 (CSIRO), Australia.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <math.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <float.h>
25 #include <ctype.h>
26 #include <string.h>
27
28 #include "config.h"
29
30 #include "SOUNDfile.H"
31 #include "plugins.H"
32
33 #ifndef true
34 #define true 1
35 #endif
36
37 #ifndef false
38 #define false 0
39 #endif
40
41 #ifndef bool
42 #define bool int
43 #endif
44
45 #ifndef NULL
46 #define NULL 0L
47 #endif
48
49 /* parameters to control what is to be extracted */
50 static float from = 0.0; /* start at second 0.0 */
51 static float to = FLT_MAX; /* end at end of file */
52 static bool verbose = false;
53 static short fromSb = 0; /* first subband to be extracted */
54 static short toSb = 575; /* last subband to be extracted */
55 static float thresh = 0.07; /* threshold between [0;1] */
56 static float minDur = 0.1; /* minimum duration [sec] */
57 static float maxInterrupt = 0.0; /* mam tolerated disruption [sec] */
58 static float releaseTime = 0.01; /* release time for sil start [sec] */
59 static float onsetTime = 0.01; /* onset time for sil end [sec] */
60 static int bins = 10; /* number of bins for histo */
61 static float starthisto = DBL_MAX; /* start of the histogram values */
62 static float endhisto = DBL_MIN; /* end of the histogram values */
63 static float tolerance = 0.0; /* time identity tolerance for compare */
64 static bool wantSilence = false; /* want silence? */
65 static bool wantNoise = false; /* want noise? */
66 static bool wantBgLevel = false; /* want background noise level? */
67 static bool wantSumSCF = false; /* want sum of scalefactors? */
68 static bool wantSSCFhisto = false; /* want histogram of SumSCF? */
69 static char *filename = NULL; /* mpeg-audio-file */
70
71 Plugins * plugins;
72
73 /*----------------------------------*/
74 void
PrintUsage(char * prog)75 PrintUsage(char *prog) {
76 printf("\nUsage:\n");
77 printf("%s [Options] <mpeg-audio-file>\n", prog);
78 printf("Default Options: -S 0.0 -E eof\n");
79 printf(" (i.e. analyse whole file)\n");
80 printf("\n");
81 printf("Possible Options:\n");
82 printf("-h help = prints this information\n");
83 printf("-S <from> the second (float) to start analysing from\n");
84 printf(" Default: 0.0\n");
85 printf("-E <to> the second (float) to stop analysing at\n");
86 printf(" Default: end of file\n");
87 printf("-V verbose\n");
88 printf("-B <from> <to> subband range (ints) that gets extracted\n");
89 printf(" (only required with -X sscf)\n");
90 printf(" Default: 0 31 (Layers I, II)\n");
91 printf(" 0 575 (Layer III)\n");
92 printf("-T <thresh> threshold value between [0;1]\n");
93 printf(" Default: 0.07\n");
94 printf("-M <minDur> minimum duration [sec] of specified content\n");
95 printf(" Default: 0.1\n");
96 printf("-N <maxInter> mamimum tolerated disruption [sec]\n");
97 printf(" Default: 0.0\n");
98 printf("-R <releaseT> release time [sec] delaying start of segment\n");
99 printf(" Default: 0.01 (must be < minDur)\n");
100 printf("-O <onsetT> onset time [sec] earlying end of segment\n");
101 printf(" Default: 0.01 (must be < minDur)\n");
102 printf("-Z <bins> number of bins for histogram\n");
103 printf(" Default: 10\n");
104 printf("-Y <from> <to> start and end of histogram values (float)\n");
105 printf(" Default: -1 -1 (meaning: minvalue maxvalue)\n");
106 printf("-X [content] specifies content to extract from audio file\n");
107 printf(" Possible content types:\n");
108 printf(" silence -T <thresh> -M <minDur> -N <maxInter>\n");
109 printf(" Temporal Segmentation: silence segments based on sumscf\n");
110 printf(" noise -T <thresh> -M <minDur> -N <maxInter>\n");
111 printf(" Temporal Segmentation: noise segments based on sumscf\n");
112 printf(" bglevel -M <minDur> -N <maxInter>\n");
113 printf(" Single Value: background noise level based on sumscf\n");
114 printf(" sumscf -B <fromsb> <tosb> (only first channel)\n");
115 printf(" 1D Curve: sum of scalefactors as loudness approximation\n");
116 printf(" histo -Z <bins>\n");
117 printf(" Vector: loudness distribution for whole duration based on sumscf\n");
118
119 exit (1);
120 }
121
122 /*----------------------------------*/
123 void
ParseArguments(int argc,char ** argv)124 ParseArguments (int argc, char **argv) {
125 int i;
126
127 /* go through parameters and check values */
128 for (i=1; i<argc; i++) {
129 if (argv[i][0] == '-' && argv[i][1]) {
130 switch (argv[i][1]) {
131 case 'H': case 'h': /* help */
132 PrintUsage(argv[0]);
133 break;
134 case 'S': case 's': /* second to start from */
135 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
136 from = atof(argv[++i]);
137 }
138 break;
139 case 'E': case 'e': /* second to end at */
140 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
141 to = atof(argv[++i]);
142 }
143 break;
144 case 'V': case 'v': /* verbose */
145 verbose = true;
146 break;
147 case 'B': case 'b': /* subband range */
148 if ((i+2<argc) && !isalpha(argv[i+1][0])
149 && !isalpha(argv[i+2][0])) {
150 fromSb = atoi(argv[++i]);
151 toSb = atoi(argv[++i]);
152 } else {
153 printf("%s: -B option needs two integers to follow\n", argv[0]);
154 exit(1);
155 }
156 break;
157 case 'T': case 't': /* threshold */
158 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
159 thresh = atof(argv[++i]);
160 }
161 break;
162 case 'M': case 'm': /* minimum duration */
163 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
164 minDur = atof(argv[++i]);
165 }
166 break;
167 case 'N': case 'n': /* maximum interrupt */
168 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
169 maxInterrupt = atof(argv[++i]);
170 }
171 break;
172 case 'R': case 'r': /* release time */
173 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
174 releaseTime = atof (argv[++i]);
175 }
176 break;
177 case 'O': case 'o': /* onset time */
178 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
179 onsetTime = atof (argv[++i]);
180 }
181 break;
182 case 'Z': case 'z': /* no bins */
183 if ((i+1<argc) && !isalpha(argv[i+1][0])) {
184 bins = atoi(argv[++i]);
185 }
186 break;
187 case 'Y': case 'y': /* histogram range */
188 if ((i+2<argc) && !isalpha(argv[i+1][0])
189 && !isalpha(argv[i+2][0])) {
190 starthisto = atof(argv[++i]);
191 endhisto = atof(argv[++i]);
192 } else {
193 printf("%s: -Y option needs two floats to follow\n", argv[0]);
194 exit(1);
195 }
196 break;
197 case 'X': case 'x': /* extract content */
198 if ((i+1 == argc) || !isalpha(argv[i+1][0])) {
199 printf("%s: -X option needs string-argument\n", argv[0]);
200 exit(1);
201 } else {
202 if (!strncmp(argv[i+1],"silence",3)) {
203 wantSilence = true; i++;
204 } else if (!strncmp(argv[i+1],"noise",3)) {
205 wantNoise = true; i++;
206 } else if (!strncmp(argv[i+1],"bglevel",3)) {
207 wantBgLevel = true; i++;
208 } else if (!strncmp(argv[i+1],"sumscf",3)) {
209 wantSumSCF = true; i++;
210 } else if (!strncmp(argv[i+1],"histo",3)) {
211 wantSSCFhisto = true; i++;
212 } else if (argv[i+1][0] != '-') {
213 printf("%s: -X unknown string-argument %s\n", argv[0],
214 argv[i+1]);
215 exit(1);
216 }
217 }
218 break;
219 } /* switch */
220 } else {
221 filename = argv[i];
222 }
223 }
224 }
225
226 /*----------------------------------*/
227 void
CheckArguments(char * prgname)228 CheckArguments(char *prgname) {
229 if (filename == NULL) {
230 printf("%s: Mpeg audio filename missing\n", prgname);
231 exit(1);
232 }
233 if (from < 0.0) from = 0.0;
234 if (to < from) to = from;
235 if (fromSb < 0) fromSb = 0;
236 if (toSb < fromSb) toSb = fromSb;
237 if (thresh < 0.0) thresh = 0.0;
238 if (thresh > 1.0) thresh = 1.0;
239 if (releaseTime > minDur) releaseTime = 0.0;
240 if (onsetTime > minDur) onsetTime = 0.0;
241 if (bins <= 0) bins = 10;
242 if (tolerance < 0) tolerance = -tolerance;
243
244 #ifdef DEBUG
245 printf("Parameter Settings:\n");
246 printf("From=%f\n", from);
247 printf("To=%f\n", to);
248 printf("Verbose=%d\n", verbose);
249 printf("fromSb=%d\n", fromSb);
250 printf("toSb=%d\n", toSb);
251 printf("thresh=%f\n", thresh);
252 printf("minDur=%f\n", minDur);
253 printf("maxInterrupt=%f\n", maxInterrupt);
254 printf("releaseTime=%f\n", releaseTime);
255 printf("onsetTime=%f\n", onsetTime);
256 printf("bins=%d\n", bins);
257 printf("starthisto=%d\n", starthisto);
258 printf("endhisto=%d\n", endhisto);
259 printf("tolerance=%f\n", tolerance);
260 printf("wantSilence=%d\n", wantSilence);
261 printf("wantNoise=%d\n", wantNoise);
262 printf("wantBgLevel=%d\n", wantBgLevel);
263 printf("wantSumSCF=%d\n", wantSumSCF);
264 printf("wantSSCFhisto=%d\n", wantSSCFhisto);
265 printf("filename=%s\n", filename);
266 #endif
267 }
268
269
270 /*----------------------------------*/
271 int
main(int argc,char ** argv)272 main(int argc, char **argv) {
273 SegmentData *sscf = NULL;
274 SOUNDfile *sfile;
275 double bgLevel;
276 SegmentTable *silences;
277 SegmentTable *noise;
278 SegmentData *histo;
279 Module *m;
280 ModuleParamList *paramsIn, *paramsOut;
281 ModuleParam *param;
282 double binwidth;
283 int nrvalues;
284 int i;
285
286 /* check no. of args */
287 if (argc < 2) {
288 PrintUsage(argv[0]);
289 }
290
291 /* parse arguments */
292 ParseArguments (argc, argv);
293
294 /* check arguments and correct if appropriate */
295 CheckArguments (argv[0]);
296
297 /* open mpegfile */
298 sfile = maaateP_new_soundfile(filename);
299
300 if (maaateP_get_filetype(sfile) == NOFILE) {
301 printf("Sorry can`t analyse that file.");
302 exit(1);
303 }
304
305 if (verbose) {
306 printf("Sound file opened: %s\n", filename);
307 }
308
309 /* open known plugin libraries */
310 plugins = maaateA_new_plugins();
311 if (!maaateA_add_library(plugins, "libMaaateM.so")) {
312 printf("Error loading plugin library libMaaateM.so\n");
313 }
314
315 /* calculate sum of scalefactors if required */
316 if (wantSilence || wantNoise || wantSumSCF || wantBgLevel || wantSSCFhisto) {
317 /* calculate sum of scalefactors between from and to */
318 if (verbose) {
319 printf("\nCalculating sum of scalefactors ...\n");
320 }
321
322 /* calculate it using the plugin module */
323 m = maaateA_get_module(plugins, "sumscf");
324 if (m==NULL) {
325 fprintf(stderr, "module sumscf not retrieved successfully\n");
326 exit(1);
327 }
328
329 /* get default values */
330 paramsIn = maaateA_default_values(m);
331 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
332 printf("No paramsIn\n");
333 }
334
335 /* set parameters */
336 param = maaateA_ModuleParamList_nth (paramsIn, 0);
337 maaateA_ModuleParam_setSOUNDfile (param, sfile);
338 param = maaateA_ModuleParamList_nth (paramsIn, 1);
339 maaateA_ModuleParam_setReal (param, from);
340 param = maaateA_ModuleParamList_nth (paramsIn, 2);
341 maaateA_ModuleParam_setReal (param, to);
342 param = maaateA_ModuleParamList_nth (paramsIn, 3);
343 maaateA_ModuleParam_setInt (param, fromSb);
344 param = maaateA_ModuleParamList_nth (paramsIn, 4);
345 maaateA_ModuleParam_setInt (param, toSb);
346
347 /* suggest and check parameters */
348 maaateA_suggest_values (m, paramsIn);
349 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
350 printf("no paramsIn\n");
351 }
352
353 /* execute module */
354 paramsOut = maaateA_apply (m, paramsIn);
355 if (maaateA_ModuleParamList_length(paramsOut) == 0) {
356 printf("No paramsOut\n");
357 }
358
359 /* get resulting segmentData */
360 param = maaateA_ModuleParamList_nth (paramsOut, 0);
361 sscf = maaateA_ModuleParam_getSegmentData (param);
362 if (sscf == NULL) {
363 printf("NULL sscf");
364 }
365
366 }
367
368 /* if sum of scalefactors requested, print these */
369 if (wantSumSCF) {
370 maaateA_sd_print(sscf);
371 }
372
373 /* if background noise level requested, calculate */
374 if (wantBgLevel) {
375 if (verbose) {
376 printf("\nCalculating background noise level ...\n");
377 }
378 /* calculate it using the plugin module */
379 m = maaateA_get_module(plugins, "bgnoiselevel");
380 if (m==NULL) {
381 fprintf(stderr, "module bgnoiselevel not retrieved successfully\n");
382 exit(1);
383 }
384
385 /* get default values */
386 paramsIn = maaateA_default_values(m);
387 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
388 printf("No paramsIn\n");
389 }
390
391 /* set parameters */
392 param = maaateA_ModuleParamList_nth (paramsIn, 0);
393 maaateA_ModuleParam_setSegmentData (param, sscf);
394 param = maaateA_ModuleParamList_nth (paramsIn, 1);
395 maaateA_ModuleParam_setReal (param, from);
396 param = maaateA_ModuleParamList_nth (paramsIn, 2);
397 maaateA_ModuleParam_setReal (param, to);
398 param = maaateA_ModuleParamList_nth (paramsIn, 3);
399 maaateA_ModuleParam_setReal (param, minDur);
400 param = maaateA_ModuleParamList_nth (paramsIn, 4);
401 maaateA_ModuleParam_setReal (param, maxInterrupt);
402 param = maaateA_ModuleParamList_nth (paramsIn, 5);
403 maaateA_ModuleParam_setReal (param, onsetTime);
404 param = maaateA_ModuleParamList_nth (paramsIn, 6);
405 maaateA_ModuleParam_setReal (param, releaseTime);
406
407 /* suggest and check parameters */
408 maaateA_suggest_values (m, paramsIn);
409 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
410 printf("no paramsIn\n");
411 }
412
413 /* execute module */
414 paramsOut = maaateA_apply (m, paramsIn);
415 if (maaateA_ModuleParamList_length(paramsOut) == 0) {
416 printf("No paramsOut\n");
417 }
418
419 /* get resulting double */
420 param = maaateA_ModuleParamList_nth (paramsOut, 0);
421 bgLevel = maaateA_ModuleParam_getReal (param);
422
423 printf("BackgroundNoiseLevel= %g\n", bgLevel);
424 }
425
426
427 /* if silence segments requested, calculate */
428 if (wantSilence) {
429 if (verbose) {
430 printf("\nCalculating silence segments ...\n");
431 }
432
433 /* calculate it using the plugin module */
434 m = maaateA_get_module(plugins, "silence");
435 if (m==NULL) {
436 fprintf(stderr, "module silence not retrieved successfully\n");
437 exit(1);
438 }
439
440 /* get default values */
441 paramsIn = maaateA_default_values(m);
442 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
443 printf("No paramsIn\n");
444 }
445
446 /* set parameters */
447 param = maaateA_ModuleParamList_nth (paramsIn, 0);
448 maaateA_ModuleParam_setSegmentData (param, sscf);
449 param = maaateA_ModuleParamList_nth (paramsIn, 1);
450 maaateA_ModuleParam_setReal (param, from);
451 param = maaateA_ModuleParamList_nth (paramsIn, 2);
452 maaateA_ModuleParam_setReal (param, to);
453 param = maaateA_ModuleParamList_nth (paramsIn, 3);
454 maaateA_ModuleParam_setReal (param, thresh);
455 param = maaateA_ModuleParamList_nth (paramsIn, 4);
456 maaateA_ModuleParam_setReal (param, minDur);
457 param = maaateA_ModuleParamList_nth (paramsIn, 5);
458 maaateA_ModuleParam_setReal (param, maxInterrupt);
459 param = maaateA_ModuleParamList_nth (paramsIn, 6);
460 maaateA_ModuleParam_setReal (param, onsetTime);
461 param = maaateA_ModuleParamList_nth (paramsIn, 7);
462 maaateA_ModuleParam_setReal (param, releaseTime);
463
464 /* suggest and check parameters */
465 maaateA_suggest_values (m, paramsIn);
466 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
467 printf("no paramsIn\n");
468 }
469
470 /* execute module */
471 paramsOut = maaateA_apply (m, paramsIn);
472 if (maaateA_ModuleParamList_length(paramsOut) == 0) {
473 printf("No paramsOut\n");
474 }
475
476 /* get resulting segmentData */
477 param = maaateA_ModuleParamList_nth (paramsOut, 0);
478 silences = maaateA_ModuleParam_getSegmentTable (param);
479
480 if (silences == NULL) {
481 printf("%s: no silences calculated\n", argv[0]);
482 } else {
483 if (verbose) {
484 printf("\nCalculated %d silence segments\n",
485 maaateA_st_get_size(silences));
486 }
487 maaateA_st_print_plain(silences, false);
488 }
489 }
490
491 /* if noise segments requested, calculate */
492 if (wantNoise) {
493 if (verbose) {
494 printf("\nCalculating noisy segments ...\n");
495 }
496
497 /* calculate it using the plugin module */
498 m = maaateA_get_module(plugins, "segmentation");
499 if (m==NULL) {
500 fprintf(stderr, "module segmentation not retrieved successfully\n");
501 exit(1);
502 }
503
504 /* get default values */
505 paramsIn = maaateA_default_values(m);
506 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
507 printf("No paramsIn\n");
508 }
509
510 /* set parameters */
511 param = maaateA_ModuleParamList_nth (paramsIn, 0);
512 maaateA_ModuleParam_setSegmentData (param, sscf);
513 param = maaateA_ModuleParamList_nth (paramsIn, 1);
514 maaateA_ModuleParam_setReal (param, from);
515 param = maaateA_ModuleParamList_nth (paramsIn, 2);
516 maaateA_ModuleParam_setReal (param, to);
517 param = maaateA_ModuleParamList_nth (paramsIn, 3);
518 maaateA_ModuleParam_setBool (param, false);
519 param = maaateA_ModuleParamList_nth (paramsIn, 4);
520 maaateA_ModuleParam_setReal (param, thresh);
521 param = maaateA_ModuleParamList_nth (paramsIn, 5);
522 maaateA_ModuleParam_setReal (param, minDur);
523 param = maaateA_ModuleParamList_nth (paramsIn, 6);
524 maaateA_ModuleParam_setReal (param, maxInterrupt);
525 param = maaateA_ModuleParamList_nth (paramsIn, 7);
526 maaateA_ModuleParam_setReal (param, onsetTime);
527 param = maaateA_ModuleParamList_nth (paramsIn, 8);
528 maaateA_ModuleParam_setReal (param, releaseTime);
529
530 /* suggest and check parameters */
531 maaateA_suggest_values (m, paramsIn);
532 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
533 printf("no paramsIn\n");
534 }
535
536 /* execute module */
537 paramsOut = maaateA_apply (m, paramsIn);
538 if (maaateA_ModuleParamList_length(paramsOut) == 0) {
539 printf("No paramsOut\n");
540 }
541
542 /* get resulting segmentData */
543 param = maaateA_ModuleParamList_nth (paramsOut, 0);
544 noise = maaateA_ModuleParam_getSegmentTable (param);
545
546 if (noise == NULL) {
547 printf("%s: no noise segments found\n", argv[0]);
548 } else {
549 if (verbose) {
550 printf("\nCalculated %d noise segments\n",
551 maaateA_st_get_size(noise));
552 }
553 maaateA_st_print_plain(noise, false);
554 }
555 }
556
557
558 /* if want histo of SSCF, print */
559 if (wantSSCFhisto) {
560 if (verbose) {
561 printf("\nCalculating SSCF histogram ...\n");;
562 }
563
564 /* calculate it using the plugin module */
565 m = maaateA_get_module(plugins, "histogram1D");
566 if (m==NULL) {
567 fprintf(stderr, "module histogram1D not retrieved successfully\n");
568 exit(1);
569 }
570
571 /* get default values */
572 paramsIn = maaateA_default_values(m);
573 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
574 printf("No paramsIn\n");
575 }
576
577 /* set parameters */
578 param = maaateA_ModuleParamList_nth (paramsIn, 0);
579 maaateA_ModuleParam_setSegmentData (param, sscf);
580 param = maaateA_ModuleParamList_nth (paramsIn, 1);
581 maaateA_ModuleParam_setReal (param, from);
582 param = maaateA_ModuleParamList_nth (paramsIn, 2);
583 maaateA_ModuleParam_setReal (param, to);
584 param = maaateA_ModuleParamList_nth (paramsIn, 3);
585 maaateA_ModuleParam_setInt (param, bins);
586 param = maaateA_ModuleParamList_nth (paramsIn, 4);
587 maaateA_ModuleParam_setInt (param, starthisto);
588 param = maaateA_ModuleParamList_nth (paramsIn, 5);
589 maaateA_ModuleParam_setInt (param, endhisto);
590
591 /* suggest and check parameters */
592 maaateA_suggest_values (m, paramsIn);
593 if (maaateA_ModuleParamList_length(paramsIn) == 0) {
594 printf("no paramsIn\n");
595 }
596
597 /* execute module */
598 paramsOut = maaateA_apply (m, paramsIn);
599 if (maaateA_ModuleParamList_length(paramsOut) == 0) {
600 printf("No paramsOut\n");
601 }
602
603 /* get resulting segmentData */
604 param = maaateA_ModuleParamList_nth (paramsOut, 0);
605 histo = maaateA_ModuleParam_getSegmentData (param);
606 param = maaateA_ModuleParamList_nth (paramsOut, 1);
607 starthisto = maaateA_ModuleParam_getReal (param);
608 param = maaateA_ModuleParamList_nth (paramsOut, 2);
609 endhisto = maaateA_ModuleParam_getReal (param);
610 param = maaateA_ModuleParamList_nth (paramsOut, 3);
611 binwidth = maaateA_ModuleParam_getReal (param);
612 param = maaateA_ModuleParamList_nth (paramsOut, 4);
613 nrvalues = maaateA_ModuleParam_getInt (param);
614
615 if (histo == NULL) {
616 printf("%s: histogram calculation failed\n", argv[0]);
617 } else {
618 printf("Histogram values:\n");
619 maaateA_sd_print(histo);
620 printf("Values lie between %f and %f.\n", starthisto, endhisto);
621 printf("Bins are %f wide.\n", binwidth);
622 printf("There were %d values.\n", nrvalues);
623 }
624 }
625
626 exit (0);
627 }
628
629