source: examples/utils.c @ 615ac7d

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

examples/: make use of aubio_onset in aubioonset and aubionotes, simplify, keep only general stuff in utils

  • Property mode set to 100644
File size: 11.3 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
[d4c5de7]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
[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";
[50bc5f2]59smpl_t threshold = 0.3;
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;
[96fb8ad]73
74/* badly redeclare some things */
75smpl_t threshold;
76smpl_t averaging;
[50bc5f2]77const char *prog_name;
[96fb8ad]78
[d4c5de7]79void flush_process (aubio_process_func_t process_func,
80    aubio_print_func_t print);
81
[50bc5f2]82void
83usage (FILE * stream, int exit_code)
[96fb8ad]84{
[50bc5f2]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);
[96fb8ad]100}
101
[50bc5f2]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  };
[b511fa9]122#ifdef HAVE_LASH
[50bc5f2]123  lash_args = lash_extract_args (&argc, &argv);
[b511fa9]124#endif /* HAVE_LASH */
[50bc5f2]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 */
[b4f5967]149        onset_mode = optarg;
[50bc5f2]150        break;
151      case 's':                /* threshold 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        /*
157           if (!isfinite(threshold)) {
158           debug("could not get threshold.\n");
159           abort();
160           }
161         */
162        break;
163      case 'p':
[fe163ad]164        pitch_mode = optarg;
[50bc5f2]165        break;
166      case 'a':
167        averaging = 1;
168        break;
169      case 'B':
170        buffer_size = atoi (optarg);
171        break;
172      case 'H':
173        overlap_size = atoi (optarg);
174        break;
175      case '?':                /* unknown options */
176        usage (stderr, 1);
177        break;
178      case -1:                 /* done with options */
179        break;
180      default:                 /*something else unexpected */
181        fprintf (stderr, "Error parsing option '%c'\n", next_option);
182        abort ();
183    }
184  }
185  while (next_option != -1);
[71482a9]186
[50bc5f2]187  if (input_filename != NULL) {
188    debug ("Input file : %s\n", input_filename);
189  } else if (input_filename != NULL && output_filename != NULL) {
190    debug ("Input file : %s\n", input_filename);
191    debug ("Output file : %s\n", output_filename);
192  } else {
[ebbf5a0]193#if HAVE_JACK
194    debug ("Jack input output\n");
195    usejack = 1;
196#else
197    debug
198        ("Error: Could not switch to jack mode\n   aubio was compiled without jack support\n");
199    exit (1);
200#endif
[50bc5f2]201  }
202
203  return 0;
[96fb8ad]204}
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  woodblock = new_fvec (buffer_size, 1);
[f382ac6]217  if (output_filename || usejack) {
[50bc5f2]218    /* dummy assignement to keep egcs happy */
[d4c5de7]219    found_wood = (onsetfile = new_aubio_sndfile_ro (onset_filename)) ||
[50bc5f2]220        (onsetfile = new_aubio_sndfile_ro ("sounds/woodblock.aiff")) ||
221        (onsetfile = new_aubio_sndfile_ro ("../sounds/woodblock.aiff"));
222    if (onsetfile == NULL) {
223      outmsg ("Could not find woodblock.aiff\n");
224      exit (1);
225    }
[b1f723d]226  }
227  if (onsetfile) {
[50bc5f2]228    /* read the output sound once */
229    aubio_sndfile_read (onsetfile, overlap_size, woodblock);
[f382ac6]230  }
231
[50bc5f2]232  if (!usejack) {
233    debug ("Opening files ...\n");
[5e9c68a]234    file = new_aubio_sndfile_ro (input_filename);
[9af07aa]235    if (file == NULL) {
[50bc5f2]236      outmsg ("Could not open input file %s.\n", input_filename);
237      exit (1);
[9af07aa]238    }
[50bc5f2]239    if (verbose)
240      aubio_sndfile_info (file);
241    channels = aubio_sndfile_channels (file);
242    samplerate = aubio_sndfile_samplerate (file);
[bd2f2ab]243    if (output_filename != NULL)
[50bc5f2]244      fileout = new_aubio_sndfile_wo (file, output_filename);
[bd2f2ab]245  }
[b511fa9]246#ifdef HAVE_LASH
[71482a9]247  else {
[50bc5f2]248    aubio_lash_client = lash_init (lash_args, argv[0],
249        LASH_Config_Data_Set | LASH_Terminal, LASH_PROTOCOL (2, 0));
[71482a9]250    if (!aubio_lash_client) {
[50bc5f2]251      fprintf (stderr, "%s: could not initialise lash\n", __FUNCTION__);
[71482a9]252    }
253    /* tell the lash server our client id */
[50bc5f2]254    if (lash_enabled (aubio_lash_client)) {
255      lash_event_t *event =
256          (lash_event_t *) lash_event_new_with_type (LASH_Client_Name);
257      lash_event_set_string (event, "aubio");
258      lash_send_event (aubio_lash_client, event);
259      pthread_create (&lash_thread, NULL, lash_thread_main, NULL);
[71482a9]260    }
261  }
[b511fa9]262#endif /* HAVE_LASH */
[bd2f2ab]263
[50bc5f2]264  ibuf = new_fvec (overlap_size, channels);
265  obuf = new_fvec (overlap_size, channels);
[bd2f2ab]266
267}
268
269
[50bc5f2]270void
271examples_common_del (void)
272{
273  del_fvec (ibuf);
[d4c5de7]274  del_fvec (obuf);
[50bc5f2]275  del_fvec (woodblock);
276  aubio_cleanup ();
[bd2f2ab]277}
278
[ebbf5a0]279#if HAVE_JACK
280aubio_jack_t *jack_setup;
281#endif
282
[50bc5f2]283void
284examples_common_process (aubio_process_func_t process_func,
285    aubio_print_func_t print)
286{
287  if (usejack) {
[ebbf5a0]288
[b511fa9]289#if HAVE_JACK
[50bc5f2]290    debug ("Jack init ...\n");
291    jack_setup = new_aubio_jack (channels, channels,
[ebbf5a0]292        0, 1, (aubio_process_func_t) process_func);
[50bc5f2]293    debug ("Jack activation ...\n");
294    aubio_jack_activate (jack_setup);
295    debug ("Processing (Ctrl+C to quit) ...\n");
296    pause ();
297    aubio_jack_close (jack_setup);
[bd2f2ab]298#else
[50bc5f2]299    usage (stderr, 1);
300    outmsg ("Compiled without jack output, exiting.\n");
[bd2f2ab]301#endif
302
303  } else {
304    /* phasevoc */
[50bc5f2]305    debug ("Processing ...\n");
[bd2f2ab]306
307    frames = 0;
308
[50bc5f2]309    while ((signed) overlap_size == aubio_sndfile_read (file, overlap_size,
310            ibuf)) {
311      process_func (ibuf->data, obuf->data, overlap_size);
312      print ();
[bd2f2ab]313      if (output_filename != NULL) {
[50bc5f2]314        aubio_sndfile_write (fileout, overlap_size, obuf);
[bd2f2ab]315      }
316      frames++;
317    }
318
[50bc5f2]319    debug ("Processed %d frames of %d samples.\n", frames, buffer_size);
[e24378a]320
[50bc5f2]321    flush_process (process_func, print);
322    del_aubio_sndfile (file);
[bd2f2ab]323
324    if (output_filename != NULL)
[50bc5f2]325      del_aubio_sndfile (fileout);
[bd2f2ab]326
327  }
328}
329
[50bc5f2]330void
331flush_process (aubio_process_func_t process_func, aubio_print_func_t print)
332{
[05a3479]333  uint_t i;
[847b374]334  fvec_zeros(obuf);
[50bc5f2]335  for (i = 0; (signed) i < frames_delay; i++) {
336    process_func (ibuf->data, obuf->data, overlap_size);
337    print ();
[e24378a]338  }
339}
[bd2f2ab]340
[50bc5f2]341void
342send_noteon (int pitch, int velo)
[bd2f2ab]343{
[50bc5f2]344  smpl_t mpitch = floor (aubio_freqtomidi (pitch) + .5);
[ebbf5a0]345#if HAVE_JACK
346  jack_midi_event_t ev;
347  ev.size = 3;
348  ev.buffer = malloc (3 * sizeof (jack_midi_data_t)); // FIXME
349  ev.time = 0;
[50bc5f2]350  if (usejack) {
[ebbf5a0]351    ev.buffer[2] = velo;
352    ev.buffer[1] = mpitch;
[50bc5f2]353    if (velo == 0) {
[ebbf5a0]354      ev.buffer[0] = 0x80;      /* note off */
[50bc5f2]355    } else {
[ebbf5a0]356      ev.buffer[0] = 0x90;      /* note on */
[50bc5f2]357    }
[ebbf5a0]358    aubio_jack_midi_event_write (jack_setup, (jack_midi_event_t *) & ev);
[50bc5f2]359  } else
[bd2f2ab]360#endif
[50bc5f2]361  if (!verbose) {
362    if (velo == 0) {
363      outmsg ("%f\n", frames * overlap_size / (float) samplerate);
364    } else {
365      outmsg ("%f\t%f\t", mpitch, frames * overlap_size / (float) samplerate);
[bd2f2ab]366    }
[50bc5f2]367  }
[bd2f2ab]368}
369
370
[b511fa9]371#if HAVE_LASH
[71482a9]372
[50bc5f2]373void *
374lash_thread_main (void *data __attribute__ ((unused)))
[71482a9]375{
[50bc5f2]376  printf ("LASH thread running\n");
[71482a9]377
[50bc5f2]378  while (!lash_main ())
379    usleep (1000);
[71482a9]380
[50bc5f2]381  printf ("LASH thread finished\n");
382  return NULL;
[71482a9]383}
384
[50bc5f2]385int
386lash_main (void)
387{
388  lash_event_t *lash_event;
389  lash_config_t *lash_config;
390
391  while ((lash_event = lash_get_event (aubio_lash_client))) {
392    switch (lash_event_get_type (lash_event)) {
393      case LASH_Quit:
394        lash_event_destroy (lash_event);
395        exit (1);
396        return 1;
397      case LASH_Restore_Data_Set:
398        lash_send_event (aubio_lash_client, lash_event);
399        break;
400      case LASH_Save_Data_Set:
401        save_data ();
402        lash_send_event (aubio_lash_client, lash_event);
403        break;
404      case LASH_Server_Lost:
405        return 1;
406      default:
407        printf ("%s: received unknown LASH event of type %d",
408            __FUNCTION__, lash_event_get_type (lash_event));
409        lash_event_destroy (lash_event);
410        break;
411    }
412  }
413
414  while ((lash_config = lash_get_config (aubio_lash_client))) {
415    restore_data (lash_config);
416    lash_config_destroy (lash_config);
417  }
418
419  return 0;
[71482a9]420}
421
[50bc5f2]422void
423save_data ()
424{
425  lash_config_t *lash_config;
[71482a9]426
[50bc5f2]427  lash_config = lash_config_new_with_key ("threshold");
428  lash_config_set_value_double (lash_config, threshold);
429  lash_send_config (aubio_lash_client, lash_config);
[71482a9]430
431}
432
[50bc5f2]433void
434restore_data (lash_config_t * lash_config)
435{
436  const char *lash_key;
[71482a9]437
[50bc5f2]438  lash_key = lash_config_get_key (lash_config);
[71482a9]439
[50bc5f2]440  if (strcmp (lash_key, "threshold") == 0) {
441    threshold = lash_config_get_value_double (lash_config);
442    return;
443  }
[71482a9]444
445}
446
[b511fa9]447#endif /* HAVE_LASH */
Note: See TracBrowser for help on using the repository browser.