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