source: examples/utils.c @ 61043ed

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

utils.c: woodblock vector is overlap_size long

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