source: examples/utils.c @ f3617e7

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

examples/: use wavetable to play pitch and to replace woodblock

  • Property mode set to 100644
File size: 10.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/**
22
23  This file includes some tools common to all examples. Code specific to the
24  algorithm performed by each program should go in the source file of that
25  program instead.
26
27*/
28
29#include "utils.h"
30
31#ifdef HAVE_LASH
32#include <lash/lash.h>
33#include <pthread.h>
34lash_client_t *aubio_lash_client;
35lash_args_t *lash_args;
36void *lash_thread_main (void *data);
37int lash_main (void);
38void save_data (void);
39void restore_data (lash_config_t * lash_config);
40pthread_t lash_thread;
41#endif /* HAVE_LASH */
42
43/* settings */
44const char *sink_uri = NULL;
45const char *source_uri = NULL;
46int frames = 0;
47int verbose = 0;
48int usejack = 0;
49int frames_delay = 0;
50
51
52char_t * pitch_unit = "default";
53char_t * pitch_mode = "default";
54
55/* energy,specdiff,hfc,complexdomain,phase */
56char_t * onset_mode = "default";
57smpl_t threshold = 0.0;         // leave unset, only set as asked
58smpl_t silence = -90.;
59uint_t buffer_size = 512;       //1024;
60uint_t overlap_size = 256;      //512;
61uint_t samplerate = 44100;
62
63aubio_source_t *this_source = NULL;
64aubio_sink_t *this_sink = NULL;
65
66fvec_t *ibuf;
67fvec_t *obuf;
68
69/* badly redeclare some things */
70smpl_t threshold;
71smpl_t averaging;
72const char *prog_name;
73
74void flush_process (aubio_process_func_t process_func,
75    aubio_print_func_t print);
76
77void
78usage (FILE * stream, int exit_code)
79{
80  fprintf (stream, "usage: %s [ options ] \n", prog_name);
81  fprintf (stream,
82      "       -h      --help          Display this message.\n"
83      "       -v      --verbose       Be verbose.\n"
84      "       -j      --jack          Use Jack.\n"
85      "       -o      --output        Output type.\n"
86      "       -i      --input         Input type.\n"
87      "       -O      --onset         Select onset detection algorithm.\n"
88      "       -t      --threshold     Set onset detection threshold.\n"
89      "       -s      --silence       Select silence threshold.\n"
90      "       -p      --pitch         Select pitch detection algorithm.\n"
91      "       -B      --bufsize       Set buffer size.\n"
92      "       -H      --hopsize       Set hopsize.\n"
93      "       -a      --averaging     Use averaging.\n");
94  exit (exit_code);
95}
96
97int
98parse_args (int argc, char **argv)
99{
100  const char *options = "hvjo:i:O:t:s:p:B:H:a";
101  int next_option;
102  struct option long_options[] = {
103    {"help", 0, NULL, 'h'},
104    {"verbose", 0, NULL, 'v'},
105    {"jack", 0, NULL, 'j'},
106    {"output", 1, NULL, 'o'},
107    {"input", 1, NULL, 'i'},
108    {"onset", 1, NULL, 'O'},
109    {"threshold", 1, NULL, 't'},
110    {"silence", 1, NULL, 's'},
111    {"pitch", 1, NULL, 'p'},
112    {"averaging", 0, NULL, 'a'},
113    {"bufsize", 1, NULL, 'B'},
114    {"hopsize", 1, NULL, 'H'},
115    {NULL, 0, NULL, 0}
116  };
117#ifdef HAVE_LASH
118  lash_args = lash_extract_args (&argc, &argv);
119#endif /* HAVE_LASH */
120  prog_name = argv[0];
121  if (argc < 1) {
122    usage (stderr, 1);
123    return -1;
124  }
125  do {
126    next_option = getopt_long (argc, argv, options, long_options, NULL);
127    switch (next_option) {
128      case 'o':
129        sink_uri = optarg;
130        break;
131      case 'i':
132        source_uri = optarg;
133        break;
134      case 'h':                /* help */
135        usage (stdout, 0);
136        return -1;
137      case 'v':                /* verbose */
138        verbose = 1;
139        break;
140      case 'j':
141        usejack = 1;
142        break;
143      case 'O':                /*onset type */
144        onset_mode = optarg;
145        break;
146      case 's':                /* silence value for onset */
147        silence = (smpl_t) atof (optarg);
148        break;
149      case 't':                /* threshold value for onset */
150        threshold = (smpl_t) atof (optarg);
151        break;
152      case 'p':
153        pitch_mode = optarg;
154        break;
155      case 'a':
156        averaging = 1;
157        break;
158      case 'B':
159        buffer_size = atoi (optarg);
160        break;
161      case 'H':
162        overlap_size = atoi (optarg);
163        break;
164      case '?':                /* unknown options */
165        usage (stderr, 1);
166        break;
167      case -1:                 /* done with options */
168        break;
169      default:                 /*something else unexpected */
170        fprintf (stderr, "Error parsing option '%c'\n", next_option);
171        abort ();
172    }
173  }
174  while (next_option != -1);
175
176  if ( source_uri == NULL ) {
177    if (argc - optind == 1) {
178      source_uri = argv[optind];
179    } else if ( argc - optind > 1 ) {
180      errmsg ("Error: too many non-option arguments `%s'\n", argv[argc - 1]);
181      usage ( stderr, 1 );
182    }
183  } else if ( argc - optind > 0 ) {
184    errmsg ("Error: extra non-option argument %s\n", argv[optind]);
185    usage ( stderr, 1 );
186  }
187
188  if (source_uri != NULL) {
189    debug ("Input file : %s\n", source_uri);
190  } else if (source_uri != NULL && sink_uri != NULL) {
191    debug ("Input file : %s\n", source_uri);
192    debug ("Output file : %s\n", sink_uri);
193  } else {
194#if HAVE_JACK
195    debug ("Jack input output\n");
196    usejack = 1;
197#else
198    errmsg("Error: no arguments given (and no available audio input)\n");
199    usage ( stderr, 1 );
200#endif
201  }
202
203  return 0;
204}
205
206void
207examples_common_init (int argc, char **argv)
208{
209
210  /* parse command line arguments */
211  parse_args (argc, argv);
212
213  if (!usejack) {
214    debug ("Opening files ...\n");
215    this_source = new_aubio_source ((char_t*)source_uri, 0, overlap_size);
216    if (this_source == NULL) {
217      outmsg ("Could not open input file %s.\n", source_uri);
218      exit (1);
219    }
220    samplerate = aubio_source_get_samplerate(this_source);
221    if (sink_uri != NULL) {
222      this_sink = new_aubio_sink ((char_t*)sink_uri, samplerate);
223      if (this_sink == NULL) {
224        outmsg ("Could not open output file %s.\n", sink_uri);
225        exit (1);
226      }
227    }
228  }
229#ifdef HAVE_LASH
230  else {
231    aubio_lash_client = lash_init (lash_args, argv[0],
232        LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2, 0));
233    if (!aubio_lash_client) {
234      fprintf (stderr, "%s: could not initialise lash\n", __FUNCTION__);
235    }
236    /* tell the lash server our client id */
237    if (lash_enabled (aubio_lash_client)) {
238      lash_event_t *event =
239          (lash_event_t *) lash_event_new_with_type (LASH_Client_Name);
240      lash_event_set_string (event, "aubio");
241      lash_send_event (aubio_lash_client, event);
242      pthread_create (&lash_thread, NULL, lash_thread_main, NULL);
243    }
244  }
245#endif /* HAVE_LASH */
246
247  ibuf = new_fvec (overlap_size);
248  obuf = new_fvec (overlap_size);
249
250}
251
252void
253examples_common_del (void)
254{
255  del_fvec (ibuf);
256  del_fvec (obuf);
257  aubio_cleanup ();
258}
259
260#if HAVE_JACK
261aubio_jack_t *jack_setup;
262#endif
263
264void
265examples_common_process (aubio_process_func_t process_func,
266    aubio_print_func_t print)
267{
268
269  uint_t read = 0;
270  if (usejack) {
271
272#if HAVE_JACK
273    debug ("Jack init ...\n");
274    jack_setup = new_aubio_jack (1, 1,
275        0, 1, (aubio_process_func_t) process_func);
276    debug ("Jack activation ...\n");
277    aubio_jack_activate (jack_setup);
278    debug ("Processing (Ctrl+C to quit) ...\n");
279    pause ();
280    aubio_jack_close (jack_setup);
281#else
282    usage (stderr, 1);
283    outmsg ("Compiled without jack output, exiting.\n");
284#endif
285
286  } else {
287    /* phasevoc */
288    debug ("Processing ...\n");
289
290    frames = 0;
291
292    do {
293      aubio_source_do (this_source, ibuf, &read);
294      process_func (&ibuf->data, &obuf->data, overlap_size);
295      print ();
296      if (this_sink) {
297        aubio_sink_do (this_sink, obuf, overlap_size);
298      }
299      frames++;
300    } while (read == overlap_size);
301
302    debug ("Processed %d frames of %d samples.\n", frames, buffer_size);
303
304    flush_process (process_func, print);
305    del_aubio_source (this_source);
306    del_aubio_sink   (this_sink);
307
308  }
309}
310
311void
312flush_process (aubio_process_func_t process_func, aubio_print_func_t print)
313{
314  uint_t i;
315  fvec_zeros(obuf);
316  for (i = 0; (signed) i < frames_delay; i++) {
317    process_func (&ibuf->data, &obuf->data, overlap_size);
318    print ();
319  }
320}
321
322void
323send_noteon (int pitch, int velo)
324{
325  smpl_t mpitch = floor (aubio_freqtomidi (pitch) + .5);
326#if HAVE_JACK
327  jack_midi_event_t ev;
328  ev.size = 3;
329  ev.buffer = malloc (3 * sizeof (jack_midi_data_t)); // FIXME
330  ev.time = 0;
331  if (usejack) {
332    ev.buffer[2] = velo;
333    ev.buffer[1] = mpitch;
334    if (velo == 0) {
335      ev.buffer[0] = 0x80;      /* note off */
336    } else {
337      ev.buffer[0] = 0x90;      /* note on */
338    }
339    aubio_jack_midi_event_write (jack_setup, (jack_midi_event_t *) & ev);
340  } else
341#endif
342  if (!verbose) {
343    if (velo == 0) {
344      outmsg ("%f\n", frames * overlap_size / (float) samplerate);
345    } else {
346      outmsg ("%f\t%f\t", mpitch, frames * overlap_size / (float) samplerate);
347    }
348  }
349}
350
351
352#if HAVE_LASH
353
354void *
355lash_thread_main (void *data __attribute__ ((unused)))
356{
357  printf ("LASH thread running\n");
358
359  while (!lash_main ())
360    usleep (1000);
361
362  printf ("LASH thread finished\n");
363  return NULL;
364}
365
366int
367lash_main (void)
368{
369  lash_event_t *lash_event;
370  lash_config_t *lash_config;
371
372  while ((lash_event = lash_get_event (aubio_lash_client))) {
373    switch (lash_event_get_type (lash_event)) {
374      case LASH_Quit:
375        lash_event_destroy (lash_event);
376        exit (1);
377        return 1;
378      case LASH_Restore_Data_Set:
379        lash_send_event (aubio_lash_client, lash_event);
380        break;
381      case LASH_Save_Data_Set:
382        save_data ();
383        lash_send_event (aubio_lash_client, lash_event);
384        break;
385      case LASH_Server_Lost:
386        return 1;
387      default:
388        printf ("%s: received unknown LASH event of type %d",
389            __FUNCTION__, lash_event_get_type (lash_event));
390        lash_event_destroy (lash_event);
391        break;
392    }
393  }
394
395  while ((lash_config = lash_get_config (aubio_lash_client))) {
396    restore_data (lash_config);
397    lash_config_destroy (lash_config);
398  }
399
400  return 0;
401}
402
403void
404save_data ()
405{
406  lash_config_t *lash_config;
407
408  lash_config = lash_config_new_with_key ("threshold");
409  lash_config_set_value_double (lash_config, threshold);
410  lash_send_config (aubio_lash_client, lash_config);
411
412}
413
414void
415restore_data (lash_config_t * lash_config)
416{
417  const char *lash_key;
418
419  lash_key = lash_config_get_key (lash_config);
420
421  if (strcmp (lash_key, "threshold") == 0) {
422    threshold = lash_config_get_value_double (lash_config);
423    return;
424  }
425
426}
427
428#endif /* HAVE_LASH */
Note: See TracBrowser for help on using the repository browser.