Per-channel ALL_SOUND_OFF when seeking/stopping player (#980)

- Only send all sound off on channels which had notes playing
- Send it as ALL_SOUND_OFF CC to a MIDI router to route it to a different synth channel afterwards
This commit is contained in:
Bill Peterson 2021-09-28 14:29:26 -05:00 committed by GitHub
parent 926581851e
commit 6c593180ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View file

@ -1604,6 +1604,10 @@ fluid_track_send_events(fluid_track_t *track,
if(player->playback_callback)
{
player->playback_callback(player->playback_userdata, event);
if(event->type == NOTE_ON && event->param2 != 0 && !player->channel_isplaying[event->channel])
{
player->channel_isplaying[event->channel] = TRUE;
}
}
}
@ -1787,6 +1791,11 @@ fluid_player_reset(fluid_player_t *player)
}
}
for(i = 0; i < MAX_NUMBER_OF_CHANNELS; i++)
{
player->channel_isplaying[i] = FALSE;
}
/* player->current_file = NULL; */
/* player->status = FLUID_PLAYER_READY; */
/* player->loop = 1; */
@ -2080,18 +2089,30 @@ fluid_player_callback(void *data, unsigned int msec)
int i;
int loadnextfile;
int status = FLUID_PLAYER_DONE;
fluid_midi_event_t mute_event;
fluid_player_t *player;
fluid_synth_t *synth;
player = (fluid_player_t *) data;
synth = player->synth;
loadnextfile = player->currentfile == NULL ? 1 : 0;
fluid_midi_event_set_type(&mute_event, CONTROL_CHANGE);
mute_event.param1 = ALL_SOUND_OFF;
mute_event.param2 = 1;
if(fluid_player_get_status(player) != FLUID_PLAYER_PLAYING)
{
if(fluid_atomic_int_get(&player->stopping))
{
fluid_synth_all_notes_off(synth, -1);
for(i = 0; i < synth->midi_channels; i++)
{
if(player->channel_isplaying[i])
{
fluid_midi_event_set_channel(&mute_event, i);
player->playback_callback(player->playback_userdata, &mute_event);
}
}
fluid_atomic_int_set(&player->stopping, 0);
}
return 1;
@ -2121,7 +2142,14 @@ fluid_player_callback(void *data, unsigned int msec)
seek_ticks = fluid_atomic_int_get(&player->seek_ticks);
if(seek_ticks >= 0)
{
fluid_synth_all_sounds_off(synth, -1); /* avoid hanging notes */
for(i = 0; i < synth->midi_channels; i++)
{
if(player->channel_isplaying[i])
{
fluid_midi_event_set_channel(&mute_event, i);
player->playback_callback(player->playback_userdata, &mute_event);
}
}
}
for(i = 0; i < player->ntracks; i++)

View file

@ -39,6 +39,7 @@ fluid_midi_event_t *fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigne
#define MAX_NUMBER_OF_TRACKS 128
#define MAX_NUMBER_OF_CHANNELS 16
enum fluid_midi_event_type
{
@ -325,6 +326,8 @@ struct _fluid_player_t
void *playback_userdata; /* pointer to user-defined data passed to playback_callback function */
handle_midi_tick_func_t tick_callback; /* function fired on each tick change */
void *tick_userdata; /* pointer to user-defined data passed to tick_callback function */
int channel_isplaying[MAX_NUMBER_OF_CHANNELS]; /* flags indicating channels on which notes have played */
};
void fluid_player_settings(fluid_settings_t *settings);