source: examples/utils.c @ 5a66677

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

examples/: use aubio_source and aubio_sink

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