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