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