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

midi

开发平台:

C/C++

  1. /* FluidSynth Arpeggio - Sequencer API example
  2.  *
  3.  * This code is in the public domain.
  4.  *
  5.  * To compile:
  6.  *   gcc -o fluidsynth_arpeggio -lfluidsynth fluidsynth_arpeggio.c
  7.  *
  8.  * To run:
  9.  *   fluidsynth_arpeggio soundfont [steps [duration]]
  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. /* duration of the pattern in ticks. */
  22. unsigned int duration = 1440;
  23. /* notes of the arpeggio */
  24. unsigned int notes[] = { 60, 64, 67, 72, 76, 79, 84, 79, 76, 72, 67, 64 };
  25. /* number of notes in one pattern */
  26. unsigned int pattern_size;
  27. /* prototype */
  28. void
  29. sequencer_callback (unsigned int time, fluid_event_t *event,
  30.                     fluid_sequencer_t *seq, void *data);
  31. /* schedule a note on message */
  32. void
  33. schedule_noteon (int chan, short key, unsigned int ticks)
  34. {
  35.     fluid_event_t *ev = new_fluid_event ();
  36.     fluid_event_set_source (ev, -1);
  37.     fluid_event_set_dest (ev, synth_destination);
  38.     fluid_event_noteon (ev, chan, key, 127);
  39.     fluid_sequencer_send_at (sequencer, ev, ticks, 1);
  40.     delete_fluid_event (ev);
  41. }
  42. /* schedule a note off message */
  43. void
  44. schedule_noteoff (int chan, short key, unsigned int ticks)
  45. {
  46.     fluid_event_t *ev = new_fluid_event ();
  47.     fluid_event_set_source (ev, -1);
  48.     fluid_event_set_dest (ev, synth_destination);
  49.     fluid_event_noteoff (ev, chan, key);
  50.     fluid_sequencer_send_at (sequencer, ev, ticks, 1);
  51.     delete_fluid_event (ev);
  52. }
  53. /* schedule a timer event (shall trigger the callback) */
  54. void
  55. schedule_timer_event ()
  56. {
  57.     fluid_event_t *ev = new_fluid_event ();
  58.     fluid_event_set_source (ev, -1);
  59.     fluid_event_set_dest (ev, client_destination);
  60.     fluid_event_timer (ev, NULL);
  61.     fluid_sequencer_send_at (sequencer, ev, time_marker, 1);
  62.     delete_fluid_event (ev);
  63. }
  64. /* schedule the arpeggio's notes */
  65. void
  66. schedule_pattern ()
  67. {
  68.     int i, note_time, note_duration;
  69.     note_time = time_marker;
  70.     note_duration = duration / pattern_size;
  71.     for (i = 0; i < pattern_size; ++i) {
  72.         schedule_noteon (0, notes[i], note_time);
  73.         note_time += note_duration;
  74.         schedule_noteoff (0, notes[i], note_time);
  75.     }
  76.     time_marker += duration;
  77. }
  78. void
  79. sequencer_callback (unsigned int time, fluid_event_t *event,
  80.                     fluid_sequencer_t *seq, void *data)
  81. {
  82.     schedule_timer_event ();
  83.     schedule_pattern ();
  84. }
  85. void
  86. usage (char* prog_name)
  87. {
  88.     printf ("Usage: %s soundfont.sf2 [steps [duration]]n", prog_name);
  89.     printf ("t(optional) steps: number of pattern notes, from 2 to %dn",
  90.             pattern_size);
  91.     printf ("t(optional) duration: of the pattern in ticks, default %dn",
  92.             duration);
  93. }
  94. int
  95. main (int argc, char* argv[])
  96. {
  97.     int n;
  98.     fluid_settings_t *settings;
  99.     settings = new_fluid_settings ();
  100.     pattern_size = sizeof(notes) / sizeof(int);
  101.     if (argc < 2) {
  102.         usage (argv[0]);
  103.     } else {
  104.         /* create the synth, driver and sequencer instances */
  105.         synth = new_fluid_synth (settings);
  106.         audiodriver = new_fluid_audio_driver (settings, synth);
  107.         sequencer = new_fluid_sequencer ();
  108.         /* register the synth with the sequencer */
  109.         synth_destination = fluid_sequencer_register_fluidsynth (sequencer,
  110.                 synth);
  111.         /* register the client name and callback */
  112.         client_destination = fluid_sequencer_register_client (sequencer,
  113.                 "arpeggio", sequencer_callback, NULL);
  114.         /* load a SoundFont */
  115.         n = fluid_synth_sfload (synth, argv[1], 1);
  116.         if (n != -1) {
  117.             if (argc > 2) {
  118.                 n = atoi (argv[2]);
  119.                 if ((n > 1) && (n <= pattern_size)) pattern_size = n;
  120.             }
  121.             if (argc > 3) {
  122.                 n = atoi (argv[3]);
  123.                 if (n > 0) duration = n;
  124.             }
  125.             /* get the current time in ticks */
  126.             time_marker = fluid_sequencer_get_tick (sequencer);
  127.             /* schedule patterns */
  128.             schedule_pattern ();
  129.             schedule_timer_event ();
  130.             schedule_pattern ();
  131.             /* wait for user input */
  132.             printf ("press <Enter> to stopn");
  133.             n = getchar ();
  134.         }
  135.         /* clean and exit */
  136.         delete_fluid_sequencer (sequencer);
  137.         delete_fluid_audio_driver (audiodriver);
  138.         delete_fluid_synth (synth);
  139.     }
  140.     delete_fluid_settings (settings);
  141.     return 0;
  142. }