Merge branch 'feature/debugmode'
[aubio.git] / examples / parse_args.h
1 /*
2   Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
3
4   This file is part of aubio.
5
6   aubio 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 3 of the License, or
9   (at your option) any later version.
10
11   aubio 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 aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "config.h"
22
23 #ifdef HAVE_GETOPT_H
24 #include <getopt.h>
25 #endif
26
27 extern int verbose;
28 extern int quiet;
29 // input / output
30 extern int usejack;
31 extern char_t *source_uri;
32 extern char_t *sink_uri;
33 // general stuff
34 extern uint_t samplerate;
35 extern uint_t buffer_size;
36 extern uint_t hop_size;
37 // onset stuff
38 extern char_t * onset_method;
39 extern smpl_t onset_threshold;
40 extern smpl_t onset_minioi;
41 // pitch stuff
42 extern char_t * pitch_method;
43 extern char_t * pitch_unit;
44 extern smpl_t pitch_tolerance;
45 // time stuff
46 extern uint_t time_format;
47 // tempo stuff
48 extern char_t * tempo_method;
49 // more general stuff
50 extern smpl_t silence_threshold;
51 extern smpl_t release_drop;
52 extern uint_t mix_input;
53 // midi tap
54 extern smpl_t miditap_note;
55 extern smpl_t miditap_velo;
56
57 extern uint_t force_overwrite;
58
59 // functions defined in utils.c
60 extern void examples_common_init (int argc, char **argv);
61 extern void examples_common_del (void);
62 extern void examples_common_process (aubio_process_func_t process_func,
63     aubio_print_func_t print);
64 int parse_args (int argc, char **argv);
65
66 // internal stuff
67 extern int blocks;
68
69 extern fvec_t *input_buffer;
70 extern fvec_t *output_buffer;
71
72 const char *prog_name;
73
74 void usage (FILE * stream, int exit_code);
75
76 void usage (FILE * stream, int exit_code)
77 {
78 #ifdef HAVE_GETOPT_H
79   fprintf (stream, "usage: %s [ options ] \n", prog_name);
80   fprintf (stream,
81       "       -i      --input            input file\n"
82 #ifdef PROG_HAS_OUTPUT
83       "       -o      --output           output file\n"
84 #endif
85       "       -r      --samplerate       select samplerate\n"
86       "                 use 0 to use input source samplerate, or 32000 to force 32kHz\n"
87       "       -B      --bufsize          set buffer size\n"
88       "                 number of frames to run the analysis on\n"
89       "       -H      --hopsize          set hopsize\n"
90       "                 number of frames to read from source before each analysis\n"
91 #ifdef PROG_HAS_ONSET
92       "       -O      --onset            select onset detection algorithm\n"
93       "                 <default|energy|hfc|complex|phase|specdiff|kl|mkl|specflux>;\n"
94       "                 default=hfc\n"
95       "       -t      --onset-threshold  set onset detection threshold\n"
96       "                 a value between 0.1 (more detections) and 1 (less); default=0.3\n"
97       "       -M      --minioi           set minimum inter-onset interval\n"
98       "                 a value in second; default=0.012\n"
99 #endif /* PROG_HAS_ONSET */
100 #ifdef PROG_HAS_PITCH
101       "       -p      --pitch            select pitch detection algorithm\n"
102       "                 <default|yinfft|yinfast|yin|mcomb|fcomb|schmitt>; default=yinfft\n"
103       "       -u      --pitch-unit       select pitch output unit\n"
104       "                 <default|freq|hertz|Hz|midi|cent|bin>; default=freq\n"
105       "       -l      --pitch-tolerance  select pitch tolerance\n"
106       "                 (yin, yinfft only) a value between 0.1 and 0.7; default=0.3\n"
107 #endif /* PROG_HAS_PITCH */
108 #ifdef PROG_HAS_SILENCE
109       "       -s      --silence          select silence threshold\n"
110       "                 a value in dB, for instance -70, or -100; default=-90\n"
111 #endif /* PROG_HAS_SILENCE */
112 #ifdef PROG_HAS_NOTES
113       "       -d      --release-drop     select release drop threshold\n"
114       "                 a positive value in dB; default=10\n"
115 #endif
116       "       -T      --time-format      select time values output format\n"
117       "                 (samples, ms, seconds) default=seconds\n"
118 #ifdef PROG_HAS_OUTPUT
119       "       -m      --mix-input        mix input signal with output signal\n"
120       "                 input signal will be added to output synthesis\n"
121       "       -f      --force-overwrite  overwrite output file if needed\n"
122       "                 do not fail if output file already exists\n"
123 #endif /* PROG_HAS_OUTPUT */
124 #if defined(PROG_HAS_JACK) && defined(HAVE_JACK)
125       "       -j      --jack             use Jack\n"
126 #if defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH)
127       "       -N      --miditap-note     MIDI note; default=69.\n"
128       "       -V      --miditap-velo     MIDI velocity; default=65.\n"
129 #endif /* defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH) */
130 #endif /* defined(PROG_HAS_JACK) && defined(HAVE_JACK) */
131       "       -q      --quiet            be quiet\n"
132       "       -v      --verbose          be verbose\n"
133       "       -h      --help             display this message\n"
134       );
135 #else /* HAVE_GETOPT_H */
136   fprintf (stream, "warning: compiled with getopt.h, no argument parsing\n");
137   fprintf (stream, "usage: %s <filename> \n", prog_name);
138 #endif /* HAVE_GETOPT_H */
139   exit (exit_code);
140 }
141
142 int
143 parse_args (int argc, char **argv)
144 {
145 #ifdef HAVE_GETOPT_H
146   const char *options = "hvq"
147     "i:r:B:H:"
148 #ifdef PROG_HAS_JACK
149     "j"
150 #if defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH)
151     "N:V:"
152 #endif /* defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH) */
153 #endif /* PROG_HAS_JACK */
154 #ifdef PROG_HAS_OUTPUT
155     "o:"
156 #endif /* PROG_HAS_OUTPUT */
157 #ifdef PROG_HAS_ONSET
158     "O:t:M:"
159 #endif /* PROG_HAS_ONSET */
160 #ifdef PROG_HAS_PITCH
161     "p:u:l:"
162 #endif /* PROG_HAS_PITCH */
163     "T:"
164 #ifdef PROG_HAS_SILENCE
165     "s:"
166 #endif /* PROG_HAS_SILENCE */
167 #ifdef PROG_HAS_NOTES
168     "d:"
169 #endif /* PROG_HAS_SILENCE */
170 #ifdef PROG_HAS_OUTPUT
171     "mf"
172 #endif /* PROG_HAS_OUTPUT */
173     ;
174   int next_option;
175   struct option long_options[] = {
176     {"help",                  0, NULL, 'h'},
177     {"verbose",               0, NULL, 'v'},
178     {"quiet",                 0, NULL, 'q'},
179     {"input",                 1, NULL, 'i'},
180     {"samplerate",            1, NULL, 'r'},
181     {"bufsize",               1, NULL, 'B'},
182     {"hopsize",               1, NULL, 'H'},
183 #ifdef PROG_HAS_JACK
184     {"jack",                  0, NULL, 'j'},
185 #if defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH)
186     {"miditap-note",          1, NULL, 'N'},
187     {"miditap-velo",          1, NULL, 'V'},
188 #endif /* PROG_HAS_ONSET !PROG_HAS_PITCH */
189 #endif /* PROG_HAS_JACK */
190 #ifdef PROG_HAS_OUTPUT
191     {"output",                1, NULL, 'o'},
192 #endif /* PROG_HAS_OUTPUT */
193 #ifdef PROG_HAS_ONSET
194     {"onset",                 1, NULL, 'O'},
195     {"onset-threshold",       1, NULL, 't'},
196     {"onset-minioi",          1, NULL, 'M'},
197 #endif /* PROG_HAS_ONSET */
198 #ifdef PROG_HAS_PITCH
199     {"pitch",                 1, NULL, 'p'},
200     {"pitch-unit",            1, NULL, 'u'},
201     {"pitch-tolerance",       1, NULL, 'l'},
202 #endif /* PROG_HAS_PITCH */
203 #ifdef PROG_HAS_SILENCE
204     {"silence",               1, NULL, 's'},
205 #endif /* PROG_HAS_SILENCE */
206 #ifdef PROG_HAS_NOTES
207     {"release-drop",          1, NULL, 'd'},
208 #endif /* PROG_HAS_NOTES */
209     {"time-format",           1, NULL, 'T'},
210 #ifdef PROG_HAS_OUTPUT
211     {"mix-input",             0, NULL, 'm'},
212     {"force-overwrite",       0, NULL, 'f'},
213 #endif /* PROG_HAS_OUTPUT */
214     {NULL,                    0, NULL, 0}
215   };
216 #endif /* HAVE_GETOPT_H */
217   // better safe than sorry
218   if (argc < 1) {
219     usage (stderr, 1);
220   }
221   prog_name = argv[0];
222 #ifdef HAVE_GETOPT_H
223   do {
224     next_option = getopt_long (argc, argv, options, long_options, NULL);
225     switch (next_option) {
226       case 'h':                /* help */
227         usage (stdout, 0);
228         return -1;
229       case 'v':                /* verbose */
230         verbose = 1;
231         break;
232       case 'q':                /* quiet */
233         quiet = 1;
234         break;
235       case 'j':
236         usejack = 1;
237         break;
238       case 'N':
239         miditap_note = (smpl_t) atoi (optarg);
240         break;
241       case 'V':
242         miditap_velo = (smpl_t) atoi (optarg);
243         break;
244       case 'i':
245         source_uri = optarg;
246         break;
247       case 'o':
248         sink_uri = optarg;
249         break;
250       case 'f':                /* force_overwrite flag */
251         force_overwrite = 1;
252         break;
253       case 'r':
254         samplerate = atoi (optarg);
255         break;
256       case 'B':
257         buffer_size = atoi (optarg);
258         break;
259       case 'H':
260         hop_size = atoi (optarg);
261         break;
262       case 'O':                /*onset method */
263         onset_method = optarg;
264         break;
265       case 't':                /* threshold value for onset */
266         onset_threshold = (smpl_t) atof (optarg);
267         break;
268       case 'M':                /* minimum inter-onset-interval */
269         onset_minioi = (smpl_t) atof (optarg);
270         break;
271       case 'p':
272         pitch_method = optarg;
273         break;
274       case 'u':
275         pitch_unit = optarg;
276         break;
277       case 'l':
278         pitch_tolerance = (smpl_t) atof (optarg);
279         break;
280       case 'T':
281         if (strcmp (optarg, "samples") == 0) {
282           time_format = 2;
283         } else if (strcmp (optarg, "ms") == 0) {
284           time_format = 1;
285         } else if (strcmp (optarg, "seconds") == 0) {
286           time_format = 0;
287         } else {
288           errmsg ("Warning: did not get '%s' time-format string\n", optarg);
289         }
290         break;
291       case 's':                /* silence threshold */
292         silence_threshold = (smpl_t) atof (optarg);
293         break;
294       case 'd':                /* release-drop threshold */
295         release_drop = (smpl_t) atof (optarg);
296         break;
297       case 'm':                /* mix_input flag */
298         mix_input = 1;
299         break;
300       case '?':                /* unknown options */
301         usage (stderr, 1);
302         break;
303       case -1:                 /* done with options */
304         break;
305       default:                 /*something else unexpected */
306         fprintf (stderr, "Error parsing option '%c'\n", next_option);
307         abort ();
308     }
309   }
310   while (next_option != -1);
311 #else /* HAVE_GETOPT_H */
312   int optind = 1;
313 #endif /* HAVE_GETOPT_H */
314
315   // if unique, use the non option argument as the source
316   if ( source_uri == NULL ) {
317     if (argc - optind == 1) {
318       source_uri = argv[optind];
319     } else if ( argc - optind > 1 ) {
320       errmsg ("Error: too many non-option arguments `%s'\n", argv[argc - 1]);
321       usage ( stderr, 1 );
322     }
323   } else if ( argc - optind > 0 ) {
324     errmsg ("Error: extra non-option argument %s\n", argv[optind]);
325     usage ( stderr, 1 );
326   }
327
328   // if no source, show a message
329   if (source_uri == NULL) {
330 #ifdef PROG_HAS_JACK
331 #if HAVE_JACK
332     verbmsg("No input source given, using jack\n");
333     usejack = 1;
334 #else
335     errmsg("Error: no arguments given (and no available audio input)\n");
336     errmsg("       consider recompiling with jack support (--enable-jack)\n");
337     exit ( 1 );
338 #endif /* HAVE_JACK */
339 #else
340     errmsg("Error: no arguments given\n");
341     usage ( stderr, 1 );
342 #endif /* PROG_HAS_JACK */
343   }
344
345   if ((sint_t)hop_size < 1) {
346     errmsg("Error: got hop_size %d, but can not be < 1\n", hop_size);
347     usage ( stderr, 1 );
348   } else if ((sint_t)buffer_size < 2) {
349     errmsg("Error: got buffer_size %d, but can not be < 2\n", buffer_size);
350     usage ( stderr, 1 );
351   } else if ((sint_t)buffer_size < (sint_t)hop_size) {
352     errmsg("Error: hop size (%d) is larger than win size (%d)\n",
353         hop_size, buffer_size);
354     usage ( stderr, 1 );
355   }
356
357   if ((sint_t)samplerate < 0) {
358     errmsg("Error: got samplerate %d, but can not be < 0\n", samplerate);
359     usage ( stderr, 1 );
360   }
361
362   return 0;
363 }