source: examples/utils.c @ 5c4ec3c

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

src/mathutils.{c,h}: rename all vec_ to fvec_

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