source: examples/utils.c @ 37eb9ce

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

merge from master, print beats once in demo_beat.py

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