source: examples/utils.c @ fe163ad

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

src/pitch: use a string to set pitch method, add a new function to set pitch unit, keep pitch enums private, update pitch methods where they are used

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