fluidsynth_metronome.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:4k
源码类别:

midi

开发平台:

C/C++

  1. /* FluidSynth Metronome - Sequencer API example
  2.  *
  3.  * This code is in the public domain.
  4.  *
  5.  * To compile:
  6.  *   gcc -o fluidsynth_metronome -lfluidsynth fluidsynth_metronome.c
  7.  *
  8.  * To run:
  9.  *   fluidsynth_metronome soundfont [beats [tempo]]
  10.  *
  11.  * [Pedro Lopez-Cabanillas <plcl@users.sf.net>]
  12.  */
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <fluidsynth.h>
  16. fluid_synth_t *synth;
  17. fluid_audio_driver_t *audiodriver;
  18. fluid_sequencer_t *sequencer;
  19. short synth_destination, client_destination;
  20. unsigned int time_marker;
  21. /* default tempo, beats per minute */
  22. #define TEMPO 120
  23. unsigned int note_duration = 60000 / TEMPO;
  24. /* metronome click/bell */
  25. unsigned int weak_note = 33;
  26. unsigned int strong_note = 34;
  27. /* number of notes in one pattern */
  28. unsigned int pattern_size = 4;
  29. /* prototype */
  30. void
  31. sequencer_callback (unsigned int time, fluid_event_t *event,
  32.                     fluid_sequencer_t *seq, void *data);
  33. /* schedule a note on message */
  34. void
  35. schedule_noteon (int chan, short key, unsigned int ticks)
  36. {
  37.     fluid_event_t *ev = new_fluid_event ();
  38.     fluid_event_set_source (ev, -1);
  39.     fluid_event_set_dest (ev, synth_destination);
  40.     fluid_event_noteon (ev, chan, key, 127);
  41.     fluid_sequencer_send_at (sequencer, ev, ticks, 1);
  42.     delete_fluid_event (ev);
  43. }
  44. /* schedule a timer event (shall trigger the callback) */
  45. void
  46. schedule_timer_event ()
  47. {
  48.     fluid_event_t *ev = new_fluid_event ();
  49.     fluid_event_set_source (ev, -1);
  50.     fluid_event_set_dest (ev, client_destination);
  51.     fluid_event_timer (ev, NULL);
  52.     fluid_sequencer_send_at (sequencer, ev, time_marker, 1);
  53.     delete_fluid_event (ev);
  54. }
  55. /* schedule the metronome pattern */
  56. void
  57. schedule_pattern ()
  58. {
  59.     int i, note_time;
  60.     note_time = time_marker;
  61.     for (i = 0; i < pattern_size; ++i) {
  62.         schedule_noteon (9, i ? weak_note : strong_note, note_time);
  63.         note_time += note_duration;
  64.     }
  65.     time_marker = note_time;
  66. }
  67. void
  68. sequencer_callback (unsigned int time, fluid_event_t *event,
  69.                     fluid_sequencer_t *seq, void *data)
  70. {
  71.     schedule_timer_event ();
  72.     schedule_pattern ();
  73. }
  74. void
  75. usage (char* prog_name)
  76. {
  77.     printf ("Usage: %s soundfont.sf2 [beats [tempo]]n", prog_name);
  78.     printf ("t(optional) beats: number of pattern beats, default %dn",
  79.             pattern_size);
  80.     printf ("t(optional) tempo: BPM (Beats Per Minute), default %dn", TEMPO);
  81. }
  82. int
  83. main (int argc, char *argv[])
  84. {
  85.     int n;
  86.     fluid_settings_t *settings;
  87.     settings = new_fluid_settings ();
  88.     if (argc < 2) {
  89.         usage (argv[0]);
  90.     } else {
  91.         /* create the synth, driver and sequencer instances */
  92.         synth = new_fluid_synth (settings);
  93.         audiodriver = new_fluid_audio_driver (settings, synth);
  94.         sequencer = new_fluid_sequencer ();
  95.         /* register the synth with the sequencer */
  96.         synth_destination = fluid_sequencer_register_fluidsynth (sequencer,
  97.                 synth);
  98.         /* register the client name and callback */
  99.         client_destination = fluid_sequencer_register_client (sequencer,
  100.                 "fluidsynth_metronome", sequencer_callback, NULL);
  101.         /* load a SoundFont */
  102.         n = fluid_synth_sfload (synth, argv[1], 1);
  103.         if (n != -1) {
  104.             if (argc > 2) {
  105.                 n = atoi (argv[2]);
  106.                 if (n > 0) pattern_size = n;
  107.             }
  108.             if (argc > 3) {
  109.                 n = atoi (argv[3]);
  110.                 if (n > 0) note_duration = 60000 / n;
  111.             }
  112.             /* get the current time in ticks */
  113.             time_marker = fluid_sequencer_get_tick (sequencer);
  114.             /* schedule patterns */
  115.             schedule_pattern ();
  116.             schedule_timer_event ();
  117.             schedule_pattern ();
  118.             /* wait for user input */
  119.             printf ("press <Enter> to stopn");
  120.             n = getchar ();
  121.         }
  122.         /* clean and exit */
  123.         delete_fluid_sequencer (sequencer);
  124.         delete_fluid_audio_driver (audiodriver);
  125.         delete_fluid_synth (synth);
  126.     }
  127.     delete_fluid_settings (settings);
  128.     return 0;
  129. }