source: examples/utils.c @ 2828382

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 2828382 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
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 */
48char_t * onset_mode = "default";
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;
63fvec_t *pitch_obuf;
64cvec_t *fftgrain;
65fvec_t *woodblock;
66aubio_onsetdetection_t *o;
67fvec_t *onset;
68fvec_t *onset2;
69smpl_t isonset = 0;
70aubio_peakpicker_t *parms;
71
72
73/* pitch objects */
74smpl_t pitch = 0.;
75aubio_pitchdetection_t *pitchdet;
76char_t * pitch_unit = "default";
77char_t * pitch_mode = "default";
78uint_t median = 6;
79
80fvec_t *note_buffer = NULL;
81fvec_t *note_buffer2 = NULL;
82smpl_t curlevel = 0.;
83smpl_t maxonset = 0.;
84
85smpl_t curnote = 0.;
86smpl_t newnote = 0.;
87uint_t isready = 0;
88
89
90
91/* badly redeclare some things */
92smpl_t threshold;
93smpl_t averaging;
94const char *prog_name;
95
96void
97usage (FILE * stream, int exit_code)
98{
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);
114}
115
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  };
136#ifdef HAVE_LASH
137  lash_args = lash_extract_args (&argc, &argv);
138#endif /* HAVE_LASH */
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 */
163        onset_mode = optarg;
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':
178        pitch_mode = optarg;
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);
200
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 {
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
215  }
216
217  return 0;
218}
219
220void
221examples_common_init (int argc, char **argv)
222{
223
224
225  aubio_sndfile_t *onsetfile = NULL;
226  /* parse command line arguments */
227  parse_args (argc, argv);
228
229  woodblock = new_fvec (buffer_size, 1);
230  if (output_filename || usejack) {
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    }
239  }
240  if (onsetfile) {
241    /* read the output sound once */
242    aubio_sndfile_read (onsetfile, overlap_size, woodblock);
243  }
244
245  if (!usejack) {
246    debug ("Opening files ...\n");
247    file = new_aubio_sndfile_ro (input_filename);
248    if (file == NULL) {
249      outmsg ("Could not open input file %s.\n", input_filename);
250      exit (1);
251    }
252    if (verbose)
253      aubio_sndfile_info (file);
254    channels = aubio_sndfile_channels (file);
255    samplerate = aubio_sndfile_samplerate (file);
256    if (output_filename != NULL)
257      fileout = new_aubio_sndfile_wo (file, output_filename);
258  }
259#ifdef HAVE_LASH
260  else {
261    aubio_lash_client = lash_init (lash_args, argv[0],
262        LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2, 0));
263    if (!aubio_lash_client) {
264      fprintf (stderr, "%s: could not initialise lash\n", __FUNCTION__);
265    }
266    /* tell the lash server our client id */
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);
273    }
274  }
275#endif /* HAVE_LASH */
276
277  ibuf = new_fvec (overlap_size, channels);
278  obuf = new_fvec (overlap_size, channels);
279  fftgrain = new_cvec (buffer_size, channels);
280
281  if (usepitch) {
282    pitchdet = new_aubio_pitchdetection (pitch_mode, buffer_size * 4,
283        overlap_size, channels, samplerate);
284    aubio_pitchdetection_set_tolerance (pitchdet, 0.7);
285    pitch_obuf = new_fvec (1, channels);
286
287    if (median) {
288      note_buffer = new_fvec (median, 1);
289      note_buffer2 = new_fvec (median, 1);
290    }
291  }
292  /* phase vocoder */
293  pv = new_aubio_pvoc (buffer_size, overlap_size, channels);
294  /* onsets */
295  parms = new_aubio_peakpicker (threshold);
296  o = new_aubio_onsetdetection (onset_mode, buffer_size, channels);
297  onset = new_fvec (1, channels);
298
299}
300
301
302void
303examples_common_del (void)
304{
305  if (usepitch) {
306    send_noteon (curnote, 0);
307    del_aubio_pitchdetection (pitchdet);
308    if (median) {
309      del_fvec (note_buffer);
310      del_fvec (note_buffer2);
311    }
312    del_fvec (pitch_obuf);
313  }
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 ();
323}
324
325#if HAVE_JACK
326aubio_jack_t *jack_setup;
327#endif
328
329void
330examples_common_process (aubio_process_func_t process_func,
331    aubio_print_func_t print)
332{
333  if (usejack) {
334
335#if HAVE_JACK
336    debug ("Jack init ...\n");
337    jack_setup = new_aubio_jack (channels, channels,
338        0, 1, (aubio_process_func_t) process_func);
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);
344#else
345    usage (stderr, 1);
346    outmsg ("Compiled without jack output, exiting.\n");
347#endif
348
349  } else {
350    /* phasevoc */
351    debug ("Processing ...\n");
352
353    frames = 0;
354
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 ();
360      if (output_filename != NULL) {
361        aubio_sndfile_write (fileout, overlap_size, obuf);
362      }
363      frames++;
364    }
365
366    debug ("Processed %d frames of %d samples.\n", frames, buffer_size);
367
368    flush_process (process_func, print);
369    del_aubio_sndfile (file);
370
371    if (output_filename != NULL)
372      del_aubio_sndfile (fileout);
373
374  }
375}
376
377void
378flush_process (aubio_process_func_t process_func, aubio_print_func_t print)
379{
380  uint_t i;
381  fvec_zeros(obuf);
382  for (i = 0; (signed) i < frames_delay; i++) {
383    process_func (ibuf->data, obuf->data, overlap_size);
384    print ();
385  }
386}
387
388void
389send_noteon (int pitch, int velo)
390{
391  smpl_t mpitch = floor (aubio_freqtomidi (pitch) + .5);
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;
397  if (usejack) {
398    ev.buffer[2] = velo;
399    ev.buffer[1] = mpitch;
400    if (velo == 0) {
401      ev.buffer[0] = 0x80;      /* note off */
402    } else {
403      ev.buffer[0] = 0x90;      /* note on */
404    }
405    aubio_jack_midi_event_write (jack_setup, (jack_midi_event_t *) & ev);
406  } else
407#endif
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);
413    }
414  }
415}
416
417
418void
419note_append (fvec_t * note_buffer, smpl_t curnote)
420{
421  uint_t i = 0;
422  for (i = 0; i < note_buffer->length - 1; i++) {
423    note_buffer->data[0][i] = note_buffer->data[0][i + 1];
424  }
425  note_buffer->data[0][note_buffer->length - 1] = curnote;
426  return;
427}
428
429uint_t
430get_note (fvec_t * note_buffer, fvec_t * note_buffer2)
431{
432  uint_t i = 0;
433  for (i = 0; i < note_buffer->length; i++) {
434    note_buffer2->data[0][i] = note_buffer->data[0][i];
435  }
436  return fvec_median (note_buffer2);
437}
438
439#if HAVE_LASH
440
441void *
442lash_thread_main (void *data __attribute__ ((unused)))
443{
444  printf ("LASH thread running\n");
445
446  while (!lash_main ())
447    usleep (1000);
448
449  printf ("LASH thread finished\n");
450  return NULL;
451}
452
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;
488}
489
490void
491save_data ()
492{
493  lash_config_t *lash_config;
494
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);
498
499}
500
501void
502restore_data (lash_config_t * lash_config)
503{
504  const char *lash_key;
505
506  lash_key = lash_config_get_key (lash_config);
507
508  if (strcmp (lash_key, "threshold") == 0) {
509    threshold = lash_config_get_value_double (lash_config);
510    return;
511  }
512
513}
514
515#endif /* HAVE_LASH */
Note: See TracBrowser for help on using the repository browser.