fix compilation without jack
[aubio.git] / examples / utils.c
1
2 #include "aubio.h"
3
4 #ifndef JACK_SUPPORT
5 #define JACK_SUPPORT 0
6 #endif
7
8 #include <getopt.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <math.h> /* for isfinite */
13 #include "utils.h"
14
15 /* not supported yet */
16 #ifdef LADCCA_SUPPORT
17 #include <ladcca/ladcca.h>
18 cca_client_t * aubio_cca_client;
19 #endif /* LADCCA_SUPPORT */
20
21 /* settings */
22 const char * output_filename = NULL;
23 const char * input_filename  = NULL;
24 const char * onset_filename  = "/usr/share/sounds/aubio/woodblock.aiff";
25 int frames = 0;
26 int verbose = 0;
27 int usejack = 0;
28 int usedoubled = 1;
29
30
31 /* energy,specdiff,hfc,complexdomain,phase */
32 aubio_onsetdetection_type type_onset  = hfc;
33 aubio_onsetdetection_type type_onset2 = complexdomain;
34 smpl_t threshold                      = 0.3;
35 smpl_t threshold2                     = -90.;
36 uint_t buffer_size                    = 1024;
37 uint_t overlap_size                   = 512;
38 uint_t channels                       = 1;
39 uint_t samplerate                     = 44100;
40
41
42 aubio_file_t * file = NULL;
43 aubio_file_t * fileout = NULL;
44
45 aubio_pvoc_t * pv;
46 fvec_t * ibuf;
47 fvec_t * obuf;
48 cvec_t * fftgrain;
49 fvec_t * woodblock;
50 aubio_onsetdetection_t *o;
51 aubio_onsetdetection_t *o2;
52 fvec_t *onset;
53 fvec_t *onset2;
54 int isonset = 0;
55 aubio_pickpeak_t * parms;
56
57
58 /* pitch objects */
59 smpl_t pitch               = 0.;
60 aubio_pitchdetection_t * pitchdet;
61 aubio_pitchdetection_type mode = aubio_yin; // aubio_mcomb
62 uint_t median         = 6;
63
64 fvec_t * note_buffer  = NULL;
65 fvec_t * note_buffer2 = NULL;
66 smpl_t curlevel       = 0.;
67 smpl_t maxonset       = 0.;
68
69 /* midi objects */
70 aubio_midi_player_t * mplay; 
71 aubio_midi_driver_t * mdriver; 
72 aubio_midi_event_t  * event;
73
74 smpl_t curnote = 0.;
75 smpl_t newnote = 0.;
76 uint_t isready = 0;
77
78
79
80 /* badly redeclare some things */
81 aubio_onsetdetection_type type_onset;
82 smpl_t threshold;
83 smpl_t averaging;
84 const char * prog_name;
85
86 void usage (FILE * stream, int exit_code)
87 {
88         fprintf(stream, "usage: %s [ options ] \n", prog_name);
89         fprintf(stream, 
90                         "       -j      --jack          Use Jack.\n"
91                         "       -o      --output        Output type.\n"
92                         "       -i      --input         Input type.\n"
93                         "       -h      --help          Display this message.\n"
94                         "       -v      --verbose       Print verbose message.\n"
95                );
96         exit(exit_code);
97 }
98
99 int parse_args (int argc, char **argv) {
100         const char *options = "hvjo:i:O:t:s:a";
101         int next_option;
102         struct option long_options[] =
103         {
104                 {"help"     , 0, NULL, 'h'},
105                 {"verbose"  , 0, NULL, 'v'},
106                 {"jack"     , 0, NULL, 'j'},
107                 {"output"   , 0, NULL, 'o'},
108                 {"input"    , 0, NULL, 'i'},
109                 {"onset"    , 0, NULL, 'O'},
110                 {"threshold", 0, NULL, 't'},
111                 {"silence"  , 0, NULL, 's'},
112                 {"averaging", 0, NULL, 'a'},
113                 {NULL       , 0, NULL, 0}
114         };
115         prog_name = argv[0];    
116         if( argc < 1 ) {
117                 usage (stderr, 1);
118                 return -1;
119         }
120         do {
121                 next_option = getopt_long (argc, argv, options, 
122                                 long_options, NULL);
123                 switch (next_option) {
124                         case 'o':
125                                 output_filename = optarg;
126                                 break;
127                         case 'i':
128                                 input_filename = optarg;
129                                 break;
130                         case 'h':       /* help */
131                                 usage (stdout, 0);
132                                 return -1;
133                         case 'v':               /* verbose */
134                                 verbose = 1;
135                                 break;
136                         case 'j':               /* verbose */
137                                 usejack = 1;
138                                 break;
139                         case 'O':   /*onset type*/
140                                 if (strcmp(optarg,"energy") == 0) 
141                                         type_onset = energy;
142                                 else if (strcmp(optarg,"specdiff") == 0) 
143                                         type_onset = specdiff;
144                                 else if (strcmp(optarg,"hfc") == 0) 
145                                         type_onset = hfc;
146                                 else if (strcmp(optarg,"complexdomain") == 0) 
147                                         type_onset = complexdomain;
148                                 else if (strcmp(optarg,"phase") == 0) 
149                                         type_onset = phase;
150                                 else {
151                                         debug("could not get onset type.\n");
152                                         abort();
153                                 }
154                                 usedoubled = 0;
155                                 break;
156                         case 's':   /* threshold value for onset */
157                                 threshold2 = (smpl_t)atof(optarg);
158                                 break;
159                         case 't':   /* threshold value for onset */
160                                 threshold = (smpl_t)atof(optarg);
161                                 /*
162                                    if (!isfinite(threshold)) {
163                                    debug("could not get threshold.\n");
164                                    abort();
165                                    }
166                                    */
167                                 break;
168                         case 'a':
169                                 averaging = 1;
170                                 break; 
171                         case '?':       /* unknown options */
172                                 usage(stderr, 1);
173                                 break;
174                         case -1:                /* done with options */
175                                 break;
176                         default:                /*something else unexpected */
177                                 abort ();
178                 }
179         }
180         while (next_option != -1);
181
182         if (input_filename != NULL) {
183                 debug ("Input file : %s\n", input_filename );
184         } else if (input_filename != NULL && output_filename != NULL) {
185                 debug ("Input file : %s\n", input_filename );
186                 debug ("Output file : %s\n", output_filename );
187         } else {
188                 if (JACK_SUPPORT)
189                 {
190                         debug ("Jack input output\n");
191                         usejack = 1;
192                 } else {
193                         debug ("Error: Could not switch to jack mode\n   aubio was compiled without jack support\n");
194                         exit(1);
195                 }
196         }       
197         return 0;
198 }
199
200 void examples_common_init(int argc,char ** argv) {
201
202
203   aubio_file_t * onsetfile;
204   /* parse command line arguments */
205   parse_args(argc, argv);
206
207   woodblock = new_fvec(buffer_size,1);
208   if (output_filename || usejack) {
209           (onsetfile = new_file_ro(onset_filename)) ||
210                   (onsetfile = new_file_ro("sounds/woodblock.aiff")) ||
211                   (onsetfile = new_file_ro("../sounds/woodblock.aiff"));
212           /* read the output sound once */
213           file_read(onsetfile, overlap_size, woodblock);
214   }
215
216   if(!usejack)
217   {
218     debug("Opening files ...\n");
219     file = new_file_ro (input_filename);
220     if (verbose) file_info(file);
221     channels = aubio_file_channels(file);
222     samplerate = aubio_file_samplerate(file);
223     if (output_filename != NULL)
224       fileout = new_file_wo(file, output_filename);
225   }
226
227   ibuf      = new_fvec(overlap_size, channels);
228   obuf      = new_fvec(overlap_size, channels);
229   fftgrain  = new_cvec(buffer_size, channels);
230
231   if (usepitch) {
232     pitchdet = new_aubio_pitchdetection(buffer_size*4, 
233                     overlap_size, channels, samplerate, mode, aubio_freq);
234   
235   if (median) {
236           note_buffer = new_fvec(median, 1);
237           note_buffer2= new_fvec(median, 1);
238   }
239   }
240   /* phase vocoder */
241   pv = new_aubio_pvoc(buffer_size, overlap_size, channels);
242   /* onsets */
243   parms = new_aubio_peakpicker(threshold);
244   o = new_aubio_onsetdetection(type_onset,buffer_size,channels);
245   onset = new_fvec(1, channels);
246   if (usedoubled)    {
247     o2 = new_aubio_onsetdetection(type_onset2,buffer_size,channels);
248     onset2 = new_fvec(1 , channels);
249   }
250
251 }
252
253
254 void examples_common_del(void){
255   if (usepitch) {
256           send_noteon(curnote,0);
257           del_aubio_pitchdetection(pitchdet);
258           if (median) {
259                   del_fvec(note_buffer);
260                   del_fvec(note_buffer2);
261           }
262   }
263   del_aubio_pvoc(pv);
264   del_fvec(obuf);
265   del_fvec(ibuf);
266   del_cvec(fftgrain);
267   del_fvec(onset);
268 }
269
270 void examples_common_process(aubio_process_func_t process_func, aubio_print_func_t print ){
271   if(usejack) {
272 #if JACK_SUPPORT
273     aubio_jack_t * jack_setup;
274     debug("Jack init ...\n");
275     jack_setup = new_aubio_jack(channels, channels,
276           (aubio_process_func_t)process_func);
277     if (usepitch) {
278             debug("Midi init ...\n");
279             mplay = new_aubio_midi_player();
280             mdriver = new_aubio_midi_driver("alsa_seq",
281                             (handle_midi_event_func_t)aubio_midi_send_event, mplay);
282             event = new_aubio_midi_event();
283     }
284     debug("Jack activation ...\n");
285     aubio_jack_activate(jack_setup);
286     debug("Processing (Ctrl+C to quit) ...\n");
287     pause();
288     aubio_jack_close(jack_setup);
289     if (usepitch) {
290             send_noteon(curnote,0);
291             del_aubio_midi_driver(mdriver);
292     }
293 #else
294     usage(stderr, 1);
295     outmsg("Compiled without jack output, exiting.\n");
296 #endif
297
298   } else {
299     /* phasevoc */
300     debug("Processing ...\n");
301
302     frames = 0;
303
304     while (overlap_size == file_read(file, overlap_size, ibuf))
305     {
306       isonset=0;
307       process_func(ibuf->data, obuf->data, overlap_size);
308       print(); 
309       if (output_filename != NULL) {
310         file_write(fileout,overlap_size,obuf);
311       }
312       frames++;
313     }
314
315     debug("Processed %d frames of %d samples.\n", frames, buffer_size);
316     del_file(file);
317
318     if (output_filename != NULL)
319       del_file(fileout);
320
321   }
322 }
323
324
325
326 void send_noteon(int pitch, int velo)
327 {
328     smpl_t mpitch = (FLOOR)(freqtomidi(pitch)+.5);
329     /* we should check if we use midi here, not jack */
330 #if ALSA_SUPPORT
331     if (usejack) {
332         if (velo==0) {
333             aubio_midi_event_set_type(event,NOTE_OFF);
334         } else {
335             aubio_midi_event_set_type(event,NOTE_ON);
336         }
337         aubio_midi_event_set_channel(event,0);
338         aubio_midi_event_set_pitch(event,mpitch);
339         aubio_midi_event_set_velocity(event,velo);
340         aubio_midi_direct_output(mdriver,event);
341     } else 
342 #endif
343     if (!verbose)
344     {
345         if (velo==0) {
346             outmsg("%f\n",frames*overlap_size/(float)samplerate);
347         } else {
348             outmsg("%f\t%f\t", mpitch,
349                         frames*overlap_size/(float)samplerate);
350         }
351     }
352 }
353
354
355 void note_append(fvec_t * note_buffer, smpl_t curnote) {
356   uint_t i = 0;
357   for (i = 0; i < note_buffer->length - 1; i++) { 
358       note_buffer->data[0][i] = note_buffer->data[0][i+1];
359   }
360   note_buffer->data[0][note_buffer->length - 1] = curnote;
361   return;
362 }
363
364 uint_t get_note(fvec_t *note_buffer, fvec_t *note_buffer2){
365   uint_t i = 0;
366   for (i = 0; i < note_buffer->length; i++) { 
367       note_buffer2->data[0][i] = note_buffer->data[0][i];
368   }
369   return vec_median(note_buffer2);
370 }
371