source: examples/utils.c @ 27fa522

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 27fa522 was 61316a6, checked in by Paul Brossier <piem@piem.org>, 14 years ago

examples plugins: update to latest pitch prototypes

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