source: examples/utils.c @ 4722e63

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

examples/utils.c: avoid segfault when compiling without sndfile

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