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