Skip to content

Commit

Permalink
Disable sustain/sostenuto pedals after last MIDI event (#1167)
Browse files Browse the repository at this point in the history
Co-authored-by: Topaz <topaz@zephyr>
  • Loading branch information
topaz and Topaz authored Sep 30, 2022
1 parent 89a2c4b commit 985835b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/midi/fluid_midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,7 @@ new_fluid_player(fluid_synth_t *synth)
player->cur_msec = 0;
player->cur_ticks = 0;
player->end_msec = -1;
player->end_pedals_disabled = 0;
player->last_callback_ticks = -1;
fluid_atomic_int_set(&player->seek_ticks, -1);
fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth);
Expand Down Expand Up @@ -2181,10 +2182,22 @@ fluid_player_callback(void *data, unsigned int msec)
/* Once we've run out of MIDI events, keep playing until no voices are active */
if(status == FLUID_PLAYER_DONE && fluid_synth_get_active_voice_count(player->synth) > 0)
{
/* The first time we notice we've run out of MIDI events but there are still active voices, disable all hold pedals */
if(!player->end_pedals_disabled)
{
for(i = 0; i < synth->midi_channels; i++)
{
fluid_synth_cc(player->synth, i, SUSTAIN_SWITCH, 0);
fluid_synth_cc(player->synth, i, SOSTENUTO_SWITCH, 0);
}

player->end_pedals_disabled = 1;
}

status = FLUID_PLAYER_PLAYING;
}

/* Once no voices are active, if end_msec hasn't been scheduled, schedule it */
/* Once no voices are active, if end_msec hasn't been scheduled, schedule it so we wait for reverb, etc to finish */
if(status == FLUID_PLAYER_DONE && player->end_msec < 0)
{
player->end_msec = msec + FLUID_PLAYER_STOP_GRACE_MS;
Expand All @@ -2195,6 +2208,7 @@ fluid_player_callback(void *data, unsigned int msec)
status = FLUID_PLAYER_PLAYING;
}

/* Once there's no reason to keep playing, we're actually done */
if(status == FLUID_PLAYER_DONE)
{
FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec", __FILE__,
Expand Down Expand Up @@ -2250,6 +2264,7 @@ fluid_player_play(fluid_player_t *player)
}

player->end_msec = -1;
player->end_pedals_disabled = 0;

fluid_atomic_int_set(&player->status, FLUID_PLAYER_PLAYING);

Expand Down
1 change: 1 addition & 0 deletions src/midi/fluid_midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ struct _fluid_player_t
int start_msec; /* the start time of the last tempo change */
int cur_msec; /* the current time */
int end_msec; /* when >=0, playback is extended until this time (for, e.g., reverb) */
char end_pedals_disabled; /* 1 once the pedals have been released after the last midi event, 0 otherwise */
/* sync mode: indicates the tempo mode the player is driven by (see fluid_player_set_tempo()):
1, the player is driven by internal tempo (miditempo). This is the default.
0, the player is driven by external tempo (exttempo)
Expand Down

0 comments on commit 985835b

Please sign in to comment.