Merge branch 'feature/debugmode'
[aubio.git] / examples / utils.c
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 /**
22
23   This file includes some tools common to all examples. Code specific to the
24   algorithm performed by each program should go in the source file of that
25   program instead.
26
27 */
28
29 #include "utils.h"
30 #ifdef HAVE_JACK
31 #include "jackio.h"
32 #endif /* HAVE_JACK */
33
34 int verbose = 0;
35 int quiet = 0;
36 int usejack = 0;
37 // input / output
38 char_t *sink_uri = NULL;
39 char_t *source_uri = NULL;
40 // general stuff
41 uint_t samplerate = 0;
42 uint_t buffer_size = 512;
43 uint_t hop_size = 256;
44 // onset stuff
45 char_t * onset_method = "default";
46 smpl_t onset_threshold = 0.0; // will be set if != 0.
47 smpl_t onset_minioi = 0.0; // will be set if != 0.
48 // pitch stuff
49 char_t * pitch_unit = "default";
50 char_t * pitch_method = "default";
51 smpl_t pitch_tolerance = 0.0; // will be set if != 0.
52 // time stuff
53 uint_t time_format = 0; // for "seconds", 1 for "ms", 2 for "samples"
54 // tempo stuff
55 char_t * tempo_method = "default";
56 // more general stuff
57 smpl_t silence_threshold = -90.;
58 smpl_t release_drop = 10.;
59 uint_t mix_input = 0;
60
61 uint_t force_overwrite = 0;
62
63 //
64 // internal memory stuff
65 aubio_source_t *this_source = NULL;
66 aubio_sink_t *this_sink = NULL;
67 fvec_t *input_buffer;
68 fvec_t *output_buffer;
69
70 smpl_t miditap_note = 69.;
71 smpl_t miditap_velo = 65.;
72
73 /* settings */
74 int blocks = 0;
75
76 extern void usage (FILE * stream, int exit_code);
77 extern int parse_args (int argc, char **argv);
78
79 #if HAVE_JACK
80 #define MAX_MIDI_EVENTS 128
81 #define MAX_MIDI_EVENT_SIZE 3
82 aubio_jack_t *jack_setup;
83 jack_midi_event_t ev;
84 jack_midi_data_t midi_data[MAX_MIDI_EVENTS * MAX_MIDI_EVENT_SIZE];
85 size_t midi_event_count = 0;
86 #endif /* HAVE_JACK */
87
88 void examples_common_init (int argc, char **argv);
89 void examples_common_del (void);
90 void examples_common_process (aubio_process_func_t process_func,
91     aubio_print_func_t print);
92
93 void examples_common_init (int argc, char **argv)
94 {
95
96   /* parse command line arguments */
97   parse_args (argc, argv);
98
99   if (!usejack) {
100     debug ("Opening files ...\n");
101     this_source = new_aubio_source ((char_t*)source_uri, samplerate, hop_size);
102     if (this_source == NULL) {
103       errmsg ("Error: could not open input file %s\n", source_uri);
104       exit (1);
105     }
106     if (samplerate == 0) {
107       samplerate = aubio_source_get_samplerate(this_source);
108     }
109     if (sink_uri != NULL) {
110       uint_t sink_exists = (access(sink_uri, F_OK) == 0 );
111       if (!force_overwrite && sink_exists) {
112         errmsg ("Error: output file %s already exists, use -f to overwrite.\n",
113             sink_uri);
114         exit (1);
115       }
116       this_sink = new_aubio_sink ((char_t*)sink_uri, samplerate);
117       if (this_sink == NULL) {
118         errmsg ("Error: could not create output file %s\n", sink_uri);
119         exit (1);
120       }
121     }
122 #ifdef HAVE_JACK
123   } else {
124     debug ("Jack init ...\n");
125     jack_setup = new_aubio_jack (hop_size, 1, 1, 0, 1);
126     samplerate = aubio_jack_get_samplerate (jack_setup);
127     source_uri = "jack";
128 #endif /* HAVE_JACK */
129   }
130   input_buffer = new_fvec (hop_size);
131   output_buffer = new_fvec (hop_size);
132
133 }
134
135 void examples_common_del (void)
136 {
137   del_fvec (input_buffer);
138   del_fvec (output_buffer);
139   aubio_cleanup ();
140   fflush(stderr);
141   fflush(stdout);
142 }
143
144 void examples_common_process (aubio_process_func_t process_func,
145     aubio_print_func_t print)
146 {
147
148   uint_t read = 0;
149   if (usejack) {
150
151 #ifdef HAVE_JACK
152     ev.size = MAX_MIDI_EVENT_SIZE;
153     ev.time = 0; // send it now
154     debug ("Jack activation ...\n");
155     aubio_jack_activate (jack_setup, process_func);
156     debug ("Processing (Ctrl+C to quit) ...\n");
157     pause ();
158     aubio_jack_close (jack_setup);
159 #else /* HAVE_JACK */
160     usage (stderr, 1);
161     outmsg ("Compiled without jack output, exiting.\n");
162 #endif /* HAVE_JACK */
163
164   } else {
165
166     uint_t total_read = 0;
167     blocks = 0;
168
169     do {
170       aubio_source_do (this_source, input_buffer, &read);
171       process_func (input_buffer, output_buffer);
172       // print to console if verbose or no output given
173       if ((verbose || sink_uri == NULL) && !quiet) {
174         print();
175       }
176       if (this_sink) {
177         aubio_sink_do (this_sink, output_buffer, hop_size);
178       }
179       blocks++;
180       total_read += read;
181     } while (read == hop_size);
182
183     verbmsg ("read %.2fs (%d samples in %d blocks of %d) from %s at %dHz\n",
184         total_read * 1. / samplerate,
185         total_read, blocks, hop_size, source_uri, samplerate);
186
187     del_aubio_source (this_source);
188     if (this_sink)
189       del_aubio_sink   (this_sink);
190
191   }
192 }
193
194 void
195 send_noteon (smpl_t pitch, smpl_t velo)
196 {
197 #ifdef HAVE_JACK
198   if (usejack) {
199     ev.buffer = midi_data + midi_event_count++ * MAX_MIDI_EVENT_SIZE;
200     if (midi_event_count >= MAX_MIDI_EVENTS) {
201       midi_event_count = 0;
202     }
203     ev.buffer[2] = velo;
204     ev.buffer[1] = pitch;
205     if (velo == 0) {
206       ev.buffer[0] = 0x80;      /* note off */
207     } else {
208       ev.buffer[0] = 0x90;      /* note on */
209     }
210     aubio_jack_midi_event_write (jack_setup, (jack_midi_event_t *) & ev);
211   } else
212 #endif
213   if (velo == 0) {
214     print_time (blocks * hop_size);
215     outmsg ("\n");
216   } else {
217     outmsg ("%f\t", pitch);
218     print_time (blocks * hop_size);
219     outmsg ("\t");
220   }
221 }
222
223 void print_time (uint_t time_in_samples) {
224   /* output times in selected format */
225   if (time_format == 2) {
226     outmsg ("%d", time_in_samples);
227   } else if (time_format == 1) {
228     outmsg ("%f", 1000. * time_in_samples / (float) samplerate);
229   } else {
230     outmsg ("%f", time_in_samples / (float) samplerate);
231   }
232 }