Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable sustain/sostenuto pedals after last MIDI event #1167

Merged
merged 1 commit into from
Sep 30, 2022

Conversation

topaz
Copy link
Contributor

@topaz topaz commented Sep 27, 2022

While working with a larger set of MIDI files with the changes in #1159, I discovered that for some of the files, fluid_synth_get_active_voice_count(player->synth) never goes to zero (at least, not after as long as I was willing to wait for it, maybe 15-30 seconds). This causes the player to appear to terminate automatically on some songs bug hang indefinitely on others.

In an attempt to prevent that situation, this PR changes the post-MIDI-events player logic in #1159 from "wait until fluid_synth_get_active_voice_count(player->synth) is zero, then wait until FLUID_PLAYER_STOP_GRACE_MS have elapsed" to instead "wait until either fluid_synth_get_active_voice_count(player->synth) or FLUID_PLAYER_STOP_GRACE_MS have elapsed".

@derselbst
Copy link
Member

I discovered that for some of the files, fluid_synth_get_active_voice_count(player->synth) never goes to zero

Oh really? Sounds like a bug. Could you provide an example MIDI where you've observed that?

@topaz
Copy link
Contributor Author

topaz commented Sep 27, 2022

Sure! I'm using a recent commit on master (89a2c4b4) that includes my change in #1159.

Just for fun, add a debug line at src/midi/fluid_midi.c line 2184:

        /* 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)
        {
            printf("waiting for zero voices; voices active: %d\n", fluid_synth_get_active_voice_count(player->synth));
            status = FLUID_PLAYER_PLAYING;
        }

Then, I tried to fast-render jtbach.mid using the FluidSynth-provided SF2 file sf2/VintageDreamsWaves-v2.sf2:

path/to/fluidsynth -F tmp path/to/sf2/VintageDreamsWaves-v2.sf2 path/to/jtbach.mid

(Realtime-render does the same thing if you wait for the song to end, and other SF2 files also seem to do the same thing.)

When I do this, it eventually just repeatedly spams:

waiting for zero voices; voices active: 34

@derselbst
Copy link
Member

Ok thanks! The problem is that MIDI channel 0 activates the sustain pedal pretty much at the end of the track, but doesn't disable it, causing some notes to keep playing in sustain forever. Therefore I would suggest the following more straightforward fix:

        /* 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)
        {
            int i;
            /* disable hold pedals on all channels to release any playing voices */
            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);
            }
            status = FLUID_PLAYER_PLAYING;
        }

It worked fine with the MIDI you provided. You might want to test a few more.

@topaz
Copy link
Contributor Author

topaz commented Sep 30, 2022

I've made the change you recommended (with a twist; it only applies the pedal changes once). This change seems to work on all of the files I have to test with. The 2000ms extra for reverb still seems like overkill to me, but I'm running with default reverb settings.

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

9.1% 9.1% Coverage
0.0% 0.0% Duplication

Copy link
Member

@derselbst derselbst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks!

@derselbst derselbst changed the title Wait no longer than FLUID_PLAYER_STOP_GRACE_MS for zero active voices Disable sustain/sostenuto pedals after last MIDI event Sep 30, 2022
@derselbst derselbst merged commit 985835b into FluidSynth:master Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants