source: examples/utils.c @ 50bc5f2

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

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

  • Property mode set to 100644
File size: 15.1 KB
RevLine 
[50bc5f2]1/*
2  Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
[96fb8ad]3
[50bc5f2]4  This file is part of aubio.
[96fb8ad]5
[50bc5f2]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*/
[96fb8ad]20
21#include "utils.h"
22
[b511fa9]23#ifdef HAVE_LASH
[71482a9]24#include <lash/lash.h>
25#include <pthread.h>
[50bc5f2]26lash_client_t *aubio_lash_client;
27lash_args_t *lash_args;
28void *lash_thread_main (void *data);
[71482a9]29int lash_main (void);
30void save_data (void);
[50bc5f2]31void restore_data (lash_config_t * lash_config);
[71482a9]32pthread_t lash_thread;
[b511fa9]33#endif /* HAVE_LASH */
[96fb8ad]34
[bd2f2ab]35/* settings */
[50bc5f2]36const char *output_filename = NULL;
37const char *input_filename = NULL;
38const char *onset_filename =
39    AUBIO_PREFIX "/share/sounds/" PACKAGE "/woodblock.aiff";
[bd2f2ab]40int frames = 0;
41int verbose = 0;
42int usejack = 0;
43int usedoubled = 1;
[e24378a]44int frames_delay = 0;
[bd2f2ab]45
46
47/* energy,specdiff,hfc,complexdomain,phase */
[50bc5f2]48aubio_onsetdetection_type type_onset = aubio_onset_kl;
[5cf415f]49aubio_onsetdetection_type type_onset2 = aubio_onset_complex;
[50bc5f2]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;
[bd2f2ab]66aubio_onsetdetection_t *o;
67aubio_onsetdetection_t *o2;
68fvec_t *onset;
69fvec_t *onset2;
70int isonset = 0;
[50bc5f2]71aubio_pickpeak_t *parms;
[bd2f2ab]72
73
74/* pitch objects */
[50bc5f2]75smpl_t pitch = 0.;
76aubio_pitchdetection_t *pitchdet;
77aubio_pitchdetection_type type_pitch = aubio_pitch_yinfft;      // aubio_pitch_mcomb
[fb615eb]78aubio_pitchdetection_mode mode_pitch = aubio_pitchm_freq;
[50bc5f2]79uint_t median = 6;
[bd2f2ab]80
[50bc5f2]81fvec_t *note_buffer = NULL;
82fvec_t *note_buffer2 = NULL;
83smpl_t curlevel = 0.;
84smpl_t maxonset = 0.;
[bd2f2ab]85
86/* midi objects */
[50bc5f2]87aubio_midi_player_t *mplay;
88aubio_midi_driver_t *mdriver;
89aubio_midi_event_t *event;
[bd2f2ab]90
91smpl_t curnote = 0.;
92smpl_t newnote = 0.;
93uint_t isready = 0;
94
95
[96fb8ad]96
97/* badly redeclare some things */
98aubio_onsetdetection_type type_onset;
99smpl_t threshold;
100smpl_t averaging;
[50bc5f2]101const char *prog_name;
[96fb8ad]102
[50bc5f2]103void
104usage (FILE * stream, int exit_code)
[96fb8ad]105{
[50bc5f2]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);
[96fb8ad]121}
122
[50bc5f2]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  };
[b511fa9]143#ifdef HAVE_LASH
[50bc5f2]144  lash_args = lash_extract_args (&argc, &argv);
[b511fa9]145#endif /* HAVE_LASH */
[50bc5f2]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 ();
[96fb8ad]191        }
[50bc5f2]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 ();
[fb615eb]220        }
[50bc5f2]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);
[71482a9]242
[50bc5f2]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;
[96fb8ad]260}
261
[50bc5f2]262void
263examples_common_init (int argc, char **argv)
264{
[bd2f2ab]265
266
[50bc5f2]267  aubio_sndfile_t *onsetfile = NULL;
[bd2f2ab]268  /* parse command line arguments */
[50bc5f2]269  parse_args (argc, argv);
[bd2f2ab]270
[50bc5f2]271  woodblock = new_fvec (buffer_size, 1);
[f382ac6]272  if (output_filename || usejack) {
[50bc5f2]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    }
[b1f723d]281  }
282  if (onsetfile) {
[50bc5f2]283    /* read the output sound once */
284    aubio_sndfile_read (onsetfile, overlap_size, woodblock);
[f382ac6]285  }
286
[50bc5f2]287  if (!usejack) {
288    debug ("Opening files ...\n");
[5e9c68a]289    file = new_aubio_sndfile_ro (input_filename);
[9af07aa]290    if (file == NULL) {
[50bc5f2]291      outmsg ("Could not open input file %s.\n", input_filename);
292      exit (1);
[9af07aa]293    }
[50bc5f2]294    if (verbose)
295      aubio_sndfile_info (file);
296    channels = aubio_sndfile_channels (file);
297    samplerate = aubio_sndfile_samplerate (file);
[bd2f2ab]298    if (output_filename != NULL)
[50bc5f2]299      fileout = new_aubio_sndfile_wo (file, output_filename);
[bd2f2ab]300  }
[b511fa9]301#ifdef HAVE_LASH
[71482a9]302  else {
[50bc5f2]303    aubio_lash_client = lash_init (lash_args, argv[0],
304        LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2, 0));
[71482a9]305    if (!aubio_lash_client) {
[50bc5f2]306      fprintf (stderr, "%s: could not initialise lash\n", __FUNCTION__);
[71482a9]307    }
308    /* tell the lash server our client id */
[50bc5f2]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);
[71482a9]315    }
316  }
[b511fa9]317#endif /* HAVE_LASH */
[bd2f2ab]318
[50bc5f2]319  ibuf = new_fvec (overlap_size, channels);
320  obuf = new_fvec (overlap_size, channels);
321  fftgrain = new_cvec (buffer_size, channels);
[bd2f2ab]322
323  if (usepitch) {
[50bc5f2]324    pitchdet = new_aubio_pitchdetection (buffer_size * 4,
[4c67dc8]325        overlap_size, channels, samplerate, type_pitch, mode_pitch);
[50bc5f2]326    aubio_pitchdetection_set_yinthresh (pitchdet, 0.7);
[4c67dc8]327
328    if (median) {
[50bc5f2]329      note_buffer = new_fvec (median, 1);
330      note_buffer2 = new_fvec (median, 1);
[4c67dc8]331    }
[bd2f2ab]332  }
333  /* phase vocoder */
[50bc5f2]334  pv = new_aubio_pvoc (buffer_size, overlap_size, channels);
[bd2f2ab]335  /* onsets */
[50bc5f2]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);
[bd2f2ab]342  }
343
344}
345
346
[50bc5f2]347void
348examples_common_del (void)
349{
[bd2f2ab]350  if (usepitch) {
[50bc5f2]351    send_noteon (curnote, 0);
352    del_aubio_pitchdetection (pitchdet);
353    if (median) {
354      del_fvec (note_buffer);
355      del_fvec (note_buffer2);
356    }
[bd2f2ab]357  }
[50bc5f2]358  if (usedoubled) {
359    del_aubio_onsetdetection (o2);
360    del_fvec (onset2);
[b91fe6e]361  }
[50bc5f2]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 ();
[bd2f2ab]371}
372
[50bc5f2]373void
374examples_common_process (aubio_process_func_t process_func,
375    aubio_print_func_t print)
376{
377  if (usejack) {
[b511fa9]378#if HAVE_JACK
[50bc5f2]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);
[bd2f2ab]383    if (usepitch) {
[50bc5f2]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 ();
[bd2f2ab]389    }
[50bc5f2]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);
[bd2f2ab]395    if (usepitch) {
[50bc5f2]396      send_noteon (curnote, 0);
397      del_aubio_midi_driver (mdriver);
[bd2f2ab]398    }
399#else
[50bc5f2]400    usage (stderr, 1);
401    outmsg ("Compiled without jack output, exiting.\n");
[bd2f2ab]402#endif
403
404  } else {
405    /* phasevoc */
[50bc5f2]406    debug ("Processing ...\n");
[bd2f2ab]407
408    frames = 0;
409
[50bc5f2]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 ();
[bd2f2ab]415      if (output_filename != NULL) {
[50bc5f2]416        aubio_sndfile_write (fileout, overlap_size, obuf);
[bd2f2ab]417      }
418      frames++;
419    }
420
[50bc5f2]421    debug ("Processed %d frames of %d samples.\n", frames, buffer_size);
[e24378a]422
[50bc5f2]423    flush_process (process_func, print);
424    del_aubio_sndfile (file);
[bd2f2ab]425
426    if (output_filename != NULL)
[50bc5f2]427      del_aubio_sndfile (fileout);
[bd2f2ab]428
429  }
430}
431
[50bc5f2]432void
433flush_process (aubio_process_func_t process_func, aubio_print_func_t print)
434{
435  uint_t i, j;
[e24378a]436  for (i = 0; i < channels; i++) {
437    for (j = 0; j < obuf->length; j++) {
[50bc5f2]438      fvec_write_sample (obuf, 0., i, j);
[e24378a]439    }
440  }
[50bc5f2]441  for (i = 0; (signed) i < frames_delay; i++) {
442    process_func (ibuf->data, obuf->data, overlap_size);
443    print ();
[e24378a]444  }
445}
[bd2f2ab]446
447
[50bc5f2]448void
449send_noteon (int pitch, int velo)
[bd2f2ab]450{
[50bc5f2]451  smpl_t mpitch = floor (aubio_freqtomidi (pitch) + .5);
452  /* we should check if we use midi here, not jack */
[b511fa9]453#if HAVE_ALSA
[50bc5f2]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
[bd2f2ab]465#endif
[50bc5f2]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);
[bd2f2ab]471    }
[50bc5f2]472  }
[bd2f2ab]473}
474
475
[50bc5f2]476void
477note_append (fvec_t * note_buffer, smpl_t curnote)
478{
[bd2f2ab]479  uint_t i = 0;
[50bc5f2]480  for (i = 0; i < note_buffer->length - 1; i++) {
481    note_buffer->data[0][i] = note_buffer->data[0][i + 1];
[bd2f2ab]482  }
483  note_buffer->data[0][note_buffer->length - 1] = curnote;
484  return;
485}
486
[50bc5f2]487uint_t
488get_note (fvec_t * note_buffer, fvec_t * note_buffer2)
489{
[bd2f2ab]490  uint_t i = 0;
[50bc5f2]491  for (i = 0; i < note_buffer->length; i++) {
492    note_buffer2->data[0][i] = note_buffer->data[0][i];
[bd2f2ab]493  }
[50bc5f2]494  return vec_median (note_buffer2);
[bd2f2ab]495}
496
[b511fa9]497#if HAVE_LASH
[71482a9]498
[50bc5f2]499void *
500lash_thread_main (void *data __attribute__ ((unused)))
[71482a9]501{
[50bc5f2]502  printf ("LASH thread running\n");
[71482a9]503
[50bc5f2]504  while (!lash_main ())
505    usleep (1000);
[71482a9]506
[50bc5f2]507  printf ("LASH thread finished\n");
508  return NULL;
[71482a9]509}
510
[50bc5f2]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;
[71482a9]546}
547
[50bc5f2]548void
549save_data ()
550{
551  lash_config_t *lash_config;
[71482a9]552
[50bc5f2]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);
[71482a9]556
557}
558
[50bc5f2]559void
560restore_data (lash_config_t * lash_config)
561{
562  const char *lash_key;
[71482a9]563
[50bc5f2]564  lash_key = lash_config_get_key (lash_config);
[71482a9]565
[50bc5f2]566  if (strcmp (lash_key, "threshold") == 0) {
567    threshold = lash_config_get_value_double (lash_config);
568    return;
569  }
[71482a9]570
571}
572
[b511fa9]573#endif /* HAVE_LASH */
Note: See TracBrowser for help on using the repository browser.