source: examples/utils.c @ 50bc5f2

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since 50bc5f2 was 50bc5f2, checked in by Paul Brossier <piem@piem.org>, 11 years ago

examples/utils.{c,h}: update copyright and license, run through indent

  • Property mode set to 100644
File size: 15.1 KB
Line 
1/*
2  Copyright (C) 2003-2009 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 "utils.h"
22
23#ifdef HAVE_LASH
24#include <lash/lash.h>
25#include <pthread.h>
26lash_client_t *aubio_lash_client;
27lash_args_t *lash_args;
28void *lash_thread_main (void *data);
29int lash_main (void);
30void save_data (void);
31void restore_data (lash_config_t * lash_config);
32pthread_t lash_thread;
33#endif /* HAVE_LASH */
34
35/* settings */
36const char *output_filename = NULL;
37const char *input_filename = NULL;
38const char *onset_filename =
39    AUBIO_PREFIX "/share/sounds/" PACKAGE "/woodblock.aiff";
40int frames = 0;
41int verbose = 0;
42int usejack = 0;
43int usedoubled = 1;
44int frames_delay = 0;
45
46
47/* energy,specdiff,hfc,complexdomain,phase */
48aubio_onsetdetection_type type_onset = aubio_onset_kl;
49aubio_onsetdetection_type type_onset2 = aubio_onset_complex;
50smpl_t threshold = 0.3;
51smpl_t silence = -90.;
52uint_t buffer_size = 512;       //1024;
53uint_t overlap_size = 256;      //512;
54uint_t channels = 1;
55uint_t samplerate = 44100;
56
57
58aubio_sndfile_t *file = NULL;
59aubio_sndfile_t *fileout = NULL;
60
61aubio_pvoc_t *pv;
62fvec_t *ibuf;
63fvec_t *obuf;
64cvec_t *fftgrain;
65fvec_t *woodblock;
66aubio_onsetdetection_t *o;
67aubio_onsetdetection_t *o2;
68fvec_t *onset;
69fvec_t *onset2;
70int isonset = 0;
71aubio_pickpeak_t *parms;
72
73
74/* pitch objects */
75smpl_t pitch = 0.;
76aubio_pitchdetection_t *pitchdet;
77aubio_pitchdetection_type type_pitch = aubio_pitch_yinfft;      // aubio_pitch_mcomb
78aubio_pitchdetection_mode mode_pitch = aubio_pitchm_freq;
79uint_t median = 6;
80
81fvec_t *note_buffer = NULL;
82fvec_t *note_buffer2 = NULL;
83smpl_t curlevel = 0.;
84smpl_t maxonset = 0.;
85
86/* midi objects */
87aubio_midi_player_t *mplay;
88aubio_midi_driver_t *mdriver;
89aubio_midi_event_t *event;
90
91smpl_t curnote = 0.;
92smpl_t newnote = 0.;
93uint_t isready = 0;
94
95
96
97/* badly redeclare some things */
98aubio_onsetdetection_type type_onset;
99smpl_t threshold;
100smpl_t averaging;
101const char *prog_name;
102
103void
104usage (FILE * stream, int exit_code)
105{
106  fprintf (stream, "usage: %s [ options ] \n", prog_name);
107  fprintf (stream,
108      "       -h      --help          Display this message.\n"
109      "       -v      --verbose       Be verbose.\n"
110      "       -j      --jack          Use Jack.\n"
111      "       -o      --output        Output type.\n"
112      "       -i      --input         Input type.\n"
113      "       -O      --onset         Select onset detection algorithm.\n"
114      "       -t      --threshold     Set onset detection threshold.\n"
115      "       -s      --silence       Select silence threshold.\n"
116      "       -p      --pitch         Select pitch detection algorithm.\n"
117      "       -B      --bufsize       Set buffer size.\n"
118      "       -H      --hopsize       Set hopsize.\n"
119      "       -a      --averaging     Use averaging.\n");
120  exit (exit_code);
121}
122
123int
124parse_args (int argc, char **argv)
125{
126  const char *options = "hvjo:i:O:t:s:p:B:H:a";
127  int next_option;
128  struct option long_options[] = {
129    {"help", 0, NULL, 'h'},
130    {"verbose", 0, NULL, 'v'},
131    {"jack", 0, NULL, 'j'},
132    {"output", 1, NULL, 'o'},
133    {"input", 1, NULL, 'i'},
134    {"onset", 1, NULL, 'O'},
135    {"threshold", 1, NULL, 't'},
136    {"silence", 1, NULL, 's'},
137    {"pitch", 1, NULL, 'p'},
138    {"averaging", 0, NULL, 'a'},
139    {"bufsize", 1, NULL, 'B'},
140    {"hopsize", 1, NULL, 'H'},
141    {NULL, 0, NULL, 0}
142  };
143#ifdef HAVE_LASH
144  lash_args = lash_extract_args (&argc, &argv);
145#endif /* HAVE_LASH */
146  prog_name = argv[0];
147  if (argc < 1) {
148    usage (stderr, 1);
149    return -1;
150  }
151  do {
152    next_option = getopt_long (argc, argv, options, long_options, NULL);
153    switch (next_option) {
154      case 'o':
155        output_filename = optarg;
156        break;
157      case 'i':
158        input_filename = optarg;
159        break;
160      case 'h':                /* help */
161        usage (stdout, 0);
162        return -1;
163      case 'v':                /* verbose */
164        verbose = 1;
165        break;
166      case 'j':
167        usejack = 1;
168        break;
169      case 'O':                /*onset type */
170        if (strcmp (optarg, "energy") == 0)
171          type_onset = aubio_onset_energy;
172        else if (strcmp (optarg, "specdiff") == 0)
173          type_onset = aubio_onset_specdiff;
174        else if (strcmp (optarg, "hfc") == 0)
175          type_onset = aubio_onset_hfc;
176        else if (strcmp (optarg, "complexdomain") == 0)
177          type_onset = aubio_onset_complex;
178        else if (strcmp (optarg, "complex") == 0)
179          type_onset = aubio_onset_complex;
180        else if (strcmp (optarg, "phase") == 0)
181          type_onset = aubio_onset_phase;
182        else if (strcmp (optarg, "mkl") == 0)
183          type_onset = aubio_onset_mkl;
184        else if (strcmp (optarg, "kl") == 0)
185          type_onset = aubio_onset_kl;
186        else if (strcmp (optarg, "specflux") == 0)
187          type_onset = aubio_onset_specflux;
188        else {
189          errmsg ("unknown onset type.\n");
190          abort ();
191        }
192        usedoubled = 0;
193        break;
194      case 's':                /* threshold value for onset */
195        silence = (smpl_t) atof (optarg);
196        break;
197      case 't':                /* threshold value for onset */
198        threshold = (smpl_t) atof (optarg);
199        /*
200           if (!isfinite(threshold)) {
201           debug("could not get threshold.\n");
202           abort();
203           }
204         */
205        break;
206      case 'p':
207        if (strcmp (optarg, "mcomb") == 0)
208          type_pitch = aubio_pitch_mcomb;
209        else if (strcmp (optarg, "yinfft") == 0)
210          type_pitch = aubio_pitch_yin;
211        else if (strcmp (optarg, "yin") == 0)
212          type_pitch = aubio_pitch_yin;
213        else if (strcmp (optarg, "schmitt") == 0)
214          type_pitch = aubio_pitch_schmitt;
215        else if (strcmp (optarg, "fcomb") == 0)
216          type_pitch = aubio_pitch_fcomb;
217        else {
218          errmsg ("unknown pitch type.\n");
219          abort ();
220        }
221        break;
222      case 'a':
223        averaging = 1;
224        break;
225      case 'B':
226        buffer_size = atoi (optarg);
227        break;
228      case 'H':
229        overlap_size = atoi (optarg);
230        break;
231      case '?':                /* unknown options */
232        usage (stderr, 1);
233        break;
234      case -1:                 /* done with options */
235        break;
236      default:                 /*something else unexpected */
237        fprintf (stderr, "Error parsing option '%c'\n", next_option);
238        abort ();
239    }
240  }
241  while (next_option != -1);
242
243  if (input_filename != NULL) {
244    debug ("Input file : %s\n", input_filename);
245  } else if (input_filename != NULL && output_filename != NULL) {
246    debug ("Input file : %s\n", input_filename);
247    debug ("Output file : %s\n", output_filename);
248  } else {
249    if (HAVE_JACK) {
250      debug ("Jack input output\n");
251      usejack = 1;
252    } else {
253      debug
254          ("Error: Could not switch to jack mode\n   aubio was compiled without jack support\n");
255      exit (1);
256    }
257  }
258
259  return 0;
260}
261
262void
263examples_common_init (int argc, char **argv)
264{
265
266
267  aubio_sndfile_t *onsetfile = NULL;
268  /* parse command line arguments */
269  parse_args (argc, argv);
270
271  woodblock = new_fvec (buffer_size, 1);
272  if (output_filename || usejack) {
273    /* dummy assignement to keep egcs happy */
274    isonset = (onsetfile = new_aubio_sndfile_ro (onset_filename)) ||
275        (onsetfile = new_aubio_sndfile_ro ("sounds/woodblock.aiff")) ||
276        (onsetfile = new_aubio_sndfile_ro ("../sounds/woodblock.aiff"));
277    if (onsetfile == NULL) {
278      outmsg ("Could not find woodblock.aiff\n");
279      exit (1);
280    }
281  }
282  if (onsetfile) {
283    /* read the output sound once */
284    aubio_sndfile_read (onsetfile, overlap_size, woodblock);
285  }
286
287  if (!usejack) {
288    debug ("Opening files ...\n");
289    file = new_aubio_sndfile_ro (input_filename);
290    if (file == NULL) {
291      outmsg ("Could not open input file %s.\n", input_filename);
292      exit (1);
293    }
294    if (verbose)
295      aubio_sndfile_info (file);
296    channels = aubio_sndfile_channels (file);
297    samplerate = aubio_sndfile_samplerate (file);
298    if (output_filename != NULL)
299      fileout = new_aubio_sndfile_wo (file, output_filename);
300  }
301#ifdef HAVE_LASH
302  else {
303    aubio_lash_client = lash_init (lash_args, argv[0],
304        LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2, 0));
305    if (!aubio_lash_client) {
306      fprintf (stderr, "%s: could not initialise lash\n", __FUNCTION__);
307    }
308    /* tell the lash server our client id */
309    if (lash_enabled (aubio_lash_client)) {
310      lash_event_t *event =
311          (lash_event_t *) lash_event_new_with_type (LASH_Client_Name);
312      lash_event_set_string (event, "aubio");
313      lash_send_event (aubio_lash_client, event);
314      pthread_create (&lash_thread, NULL, lash_thread_main, NULL);
315    }
316  }
317#endif /* HAVE_LASH */
318
319  ibuf = new_fvec (overlap_size, channels);
320  obuf = new_fvec (overlap_size, channels);
321  fftgrain = new_cvec (buffer_size, channels);
322
323  if (usepitch) {
324    pitchdet = new_aubio_pitchdetection (buffer_size * 4,
325        overlap_size, channels, samplerate, type_pitch, mode_pitch);
326    aubio_pitchdetection_set_yinthresh (pitchdet, 0.7);
327
328    if (median) {
329      note_buffer = new_fvec (median, 1);
330      note_buffer2 = new_fvec (median, 1);
331    }
332  }
333  /* phase vocoder */
334  pv = new_aubio_pvoc (buffer_size, overlap_size, channels);
335  /* onsets */
336  parms = new_aubio_peakpicker (threshold);
337  o = new_aubio_onsetdetection (type_onset, buffer_size, channels);
338  onset = new_fvec (1, channels);
339  if (usedoubled) {
340    o2 = new_aubio_onsetdetection (type_onset2, buffer_size, channels);
341    onset2 = new_fvec (1, channels);
342  }
343
344}
345
346
347void
348examples_common_del (void)
349{
350  if (usepitch) {
351    send_noteon (curnote, 0);
352    del_aubio_pitchdetection (pitchdet);
353    if (median) {
354      del_fvec (note_buffer);
355      del_fvec (note_buffer2);
356    }
357  }
358  if (usedoubled) {
359    del_aubio_onsetdetection (o2);
360    del_fvec (onset2);
361  }
362  del_aubio_onsetdetection (o);
363  del_aubio_peakpicker (parms);
364  del_aubio_pvoc (pv);
365  del_fvec (obuf);
366  del_fvec (ibuf);
367  del_cvec (fftgrain);
368  del_fvec (onset);
369  del_fvec (woodblock);
370  aubio_cleanup ();
371}
372
373void
374examples_common_process (aubio_process_func_t process_func,
375    aubio_print_func_t print)
376{
377  if (usejack) {
378#if HAVE_JACK
379    aubio_jack_t *jack_setup;
380    debug ("Jack init ...\n");
381    jack_setup = new_aubio_jack (channels, channels,
382        1, 1, (aubio_process_func_t) process_func);
383    if (usepitch) {
384      debug ("Midi init ...\n");
385      mplay = new_aubio_midi_player ();
386      mdriver = new_aubio_midi_driver ("alsa_seq",
387          (handle_midi_event_func_t) aubio_midi_send_event, mplay);
388      event = new_aubio_midi_event ();
389    }
390    debug ("Jack activation ...\n");
391    aubio_jack_activate (jack_setup);
392    debug ("Processing (Ctrl+C to quit) ...\n");
393    pause ();
394    aubio_jack_close (jack_setup);
395    if (usepitch) {
396      send_noteon (curnote, 0);
397      del_aubio_midi_driver (mdriver);
398    }
399#else
400    usage (stderr, 1);
401    outmsg ("Compiled without jack output, exiting.\n");
402#endif
403
404  } else {
405    /* phasevoc */
406    debug ("Processing ...\n");
407
408    frames = 0;
409
410    while ((signed) overlap_size == aubio_sndfile_read (file, overlap_size,
411            ibuf)) {
412      isonset = 0;
413      process_func (ibuf->data, obuf->data, overlap_size);
414      print ();
415      if (output_filename != NULL) {
416        aubio_sndfile_write (fileout, overlap_size, obuf);
417      }
418      frames++;
419    }
420
421    debug ("Processed %d frames of %d samples.\n", frames, buffer_size);
422
423    flush_process (process_func, print);
424    del_aubio_sndfile (file);
425
426    if (output_filename != NULL)
427      del_aubio_sndfile (fileout);
428
429  }
430}
431
432void
433flush_process (aubio_process_func_t process_func, aubio_print_func_t print)
434{
435  uint_t i, j;
436  for (i = 0; i < channels; i++) {
437    for (j = 0; j < obuf->length; j++) {
438      fvec_write_sample (obuf, 0., i, j);
439    }
440  }
441  for (i = 0; (signed) i < frames_delay; i++) {
442    process_func (ibuf->data, obuf->data, overlap_size);
443    print ();
444  }
445}
446
447
448void
449send_noteon (int pitch, int velo)
450{
451  smpl_t mpitch = floor (aubio_freqtomidi (pitch) + .5);
452  /* we should check if we use midi here, not jack */
453#if HAVE_ALSA
454  if (usejack) {
455    if (velo == 0) {
456      aubio_midi_event_set_type (event, NOTE_OFF);
457    } else {
458      aubio_midi_event_set_type (event, NOTE_ON);
459    }
460    aubio_midi_event_set_channel (event, 0);
461    aubio_midi_event_set_pitch (event, mpitch);
462    aubio_midi_event_set_velocity (event, velo);
463    aubio_midi_direct_output (mdriver, event);
464  } else
465#endif
466  if (!verbose) {
467    if (velo == 0) {
468      outmsg ("%f\n", frames * overlap_size / (float) samplerate);
469    } else {
470      outmsg ("%f\t%f\t", mpitch, frames * overlap_size / (float) samplerate);
471    }
472  }
473}
474
475
476void
477note_append (fvec_t * note_buffer, smpl_t curnote)
478{
479  uint_t i = 0;
480  for (i = 0; i < note_buffer->length - 1; i++) {
481    note_buffer->data[0][i] = note_buffer->data[0][i + 1];
482  }
483  note_buffer->data[0][note_buffer->length - 1] = curnote;
484  return;
485}
486
487uint_t
488get_note (fvec_t * note_buffer, fvec_t * note_buffer2)
489{
490  uint_t i = 0;
491  for (i = 0; i < note_buffer->length; i++) {
492    note_buffer2->data[0][i] = note_buffer->data[0][i];
493  }
494  return vec_median (note_buffer2);
495}
496
497#if HAVE_LASH
498
499void *
500lash_thread_main (void *data __attribute__ ((unused)))
501{
502  printf ("LASH thread running\n");
503
504  while (!lash_main ())
505    usleep (1000);
506
507  printf ("LASH thread finished\n");
508  return NULL;
509}
510
511int
512lash_main (void)
513{
514  lash_event_t *lash_event;
515  lash_config_t *lash_config;
516
517  while ((lash_event = lash_get_event (aubio_lash_client))) {
518    switch (lash_event_get_type (lash_event)) {
519      case LASH_Quit:
520        lash_event_destroy (lash_event);
521        exit (1);
522        return 1;
523      case LASH_Restore_Data_Set:
524        lash_send_event (aubio_lash_client, lash_event);
525        break;
526      case LASH_Save_Data_Set:
527        save_data ();
528        lash_send_event (aubio_lash_client, lash_event);
529        break;
530      case LASH_Server_Lost:
531        return 1;
532      default:
533        printf ("%s: received unknown LASH event of type %d",
534            __FUNCTION__, lash_event_get_type (lash_event));
535        lash_event_destroy (lash_event);
536        break;
537    }
538  }
539
540  while ((lash_config = lash_get_config (aubio_lash_client))) {
541    restore_data (lash_config);
542    lash_config_destroy (lash_config);
543  }
544
545  return 0;
546}
547
548void
549save_data ()
550{
551  lash_config_t *lash_config;
552
553  lash_config = lash_config_new_with_key ("threshold");
554  lash_config_set_value_double (lash_config, threshold);
555  lash_send_config (aubio_lash_client, lash_config);
556
557}
558
559void
560restore_data (lash_config_t * lash_config)
561{
562  const char *lash_key;
563
564  lash_key = lash_config_get_key (lash_config);
565
566  if (strcmp (lash_key, "threshold") == 0) {
567    threshold = lash_config_get_value_double (lash_config);
568    return;
569  }
570
571}
572
573#endif /* HAVE_LASH */
Note: See TracBrowser for help on using the repository browser.