diff --git a/fluidsynth/include/fluidsynth/midi.h b/fluidsynth/include/fluidsynth/midi.h index 7ce559fe..bd34c06f 100644 --- a/fluidsynth/include/fluidsynth/midi.h +++ b/fluidsynth/include/fluidsynth/midi.h @@ -132,6 +132,7 @@ FLUIDSYNTH_API int fluid_player_set_loop(fluid_player_t* player, int loop); FLUIDSYNTH_API int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo); FLUIDSYNTH_API int fluid_player_set_bpm(fluid_player_t* player, int bpm); FLUIDSYNTH_API int fluid_player_get_status(fluid_player_t* player); +FLUIDSYNTH_API int fluid_player_set_playback_callback(fluid_player_t* player, handle_midi_event_func_t handler, void* handler_data); #ifdef __cplusplus } diff --git a/fluidsynth/src/midi/fluid_midi.c b/fluidsynth/src/midi/fluid_midi.c index 8989e8aa..549530dd 100644 --- a/fluidsynth/src/midi/fluid_midi.c +++ b/fluidsynth/src/midi/fluid_midi.c @@ -1204,8 +1204,10 @@ fluid_track_send_events(fluid_track_t *track, track->ticks += event->dtime; - if (event->type != MIDI_SET_TEMPO) - fluid_synth_handle_midi_event(synth, event); + if (event->type != MIDI_SET_TEMPO) { + if (player->playback_callback) + player->playback_callback(player->playback_userdata, event); + } else if (player) fluid_player_set_midi_tempo(player, event->param1); @@ -1252,6 +1254,7 @@ new_fluid_player(fluid_synth_t *synth) player->deltatime = 4.0; player->cur_msec = 0; player->cur_ticks = 0; + fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth); player->use_system_timer = fluid_settings_str_equal(synth->settings, "player.timing-source", "system"); @@ -1370,6 +1373,28 @@ fluid_player_get_track(fluid_player_t *player, int i) } } +/** + * Change the MIDI callback function. This is usually set to + * fluid_synth_handle_midi_event, but can optionally be changed + * to a user-defined function instead, for intercepting all MIDI + * messages sent to the synth. You can also use a midi router as + * the callback function to modify the MIDI messages before sending + * them to the synth. + * @param player MIDI player instance + * @param handler Pointer to callback function + * @param handler_data Parameter sent to the callback function + * @returns FLUID_OK + * @since 1.1.4 + */ +int +fluid_player_set_playback_callback(fluid_player_t* player, + handle_midi_event_func_t handler, void* handler_data) +{ + player->playback_callback = handler; + player->playback_userdata = handler_data; + return FLUID_OK; +} + /** * Add a MIDI file to a player queue. * @param player MIDI player instance diff --git a/fluidsynth/src/midi/fluid_midi.h b/fluidsynth/src/midi/fluid_midi.h index b3738a0b..b6a828bf 100644 --- a/fluidsynth/src/midi/fluid_midi.h +++ b/fluidsynth/src/midi/fluid_midi.h @@ -304,6 +304,9 @@ struct _fluid_player_t { int miditempo; /* as indicated by MIDI SetTempo: n 24th of a usec per midi-clock. bravo! */ double deltatime; /* milliseconds per midi tick. depends on set-tempo */ unsigned int division; + + handle_midi_event_func_t playback_callback; /* function fired on each midi event as it is played */ + void* playback_userdata; /* pointer to user-defined data passed to playback_callback function */ }; int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track);