-
Notifications
You must be signed in to change notification settings - Fork 142
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
Stop/Start/Pause/Resume for Fluidsynth #592
Conversation
The problem is |
Let me know if you want that rolled up in one commit. I didn't notice any other warnings for fluidsynth in the build. |
Yes please. @slouken: Can you review? |
Lemme take a look... |
Actually, I ... applied this thing to my side of the MixerX a while ago, but actually, I didn't used it, because my builds mostly used my custom FluidLite thing and my custom C++-coded MIDI sequencer with loop points, etc. Just now I built it with FluidSynth and I see this patch on my side being applied a while ago, and I confirm here is abug:
I do use the system-installed Fluidsynth of the version 2.2.5 (Ubuntu 22.04). In this demo I play the song with two synths: with FluidSynth and your patch and trying to pause/resume, and with libADLMIDI as "how it should work". 2024-02-18_06-09-58.mp4 |
Hmm, the patch calls |
It isn't clear what the semantics of stop should be when paired with resume or play with pause. If you would rather not seek on stop and make it the same as pause we can. |
As far as I can see, no other music code under codecs/ rewind to 0 in their stop procedure, so we shouldn't do that in fluidsynth either. @slouken? |
|
@Wohlstand I'm not entirely clear on what you're saying, resume after pause does not seek to 0 and does not restart the track. The fluid_player_stop does not reset, and play resumes which is why the patch was necessary to fix the current play/stop behaviour. |
@TheCycoONE: I think @Wohlstand is referring to SDL_mixer calls I think the patch is acceptable after removing the offending rewind call from the _STOP procedure, like: diff --git a/src/codecs/music_fluidsynth.c b/src/codecs/music_fluidsynth.c
index bc6a78e..55ba900 100644
--- a/src/codecs/music_fluidsynth.c
+++ b/src/codecs/music_fluidsynth.c
@@ -327,9 +327,6 @@ static void FLUIDSYNTH_Stop(void *context)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
fluidsynth.fluid_player_stop(music->player);
-#if (FLUIDSYNTH_VERSION_MAJOR >= 2)
- fluidsynth.fluid_player_seek(music->player, 0);
-#endif
}
static void FLUIDSYNTH_Pause(void *context) @Wohlstand, @slouken: This does match the rest of SDL_mixer behavior, yes? |
Okay, I debugged the thing just now, and... it actually calls the "Play" command... and... In my case, the logic is messed up:
|
I made another solution:
static SDL_bool FLUIDSYNTH_IsPlaying(void *context)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
- return fluidsynth.fluid_player_get_status(music->player) == FLUID_PLAYER_PLAYING ? SDL_TRUE : SDL_FALSE;
+ return music->is_paused || fluidsynth.fluid_player_get_status(music->player) == FLUID_PLAYER_PLAYING ? SDL_TRUE : SDL_FALSE;
} And then, the thing works correctly. |
Thanks. That makes sense. In a bout of bad luck my computer died. I'll make and test the suggested changes when my replacement arrives. I am also open to either of you patching in the mean time. |
I think all those and your changes are specific to your own fork, yes? |
Oh hell, never mind -- |
This change I shown is not: the
|
Changes I did in format of compatible patch: diff --git a/src/codecs/music_fluidsynth.c b/src/codecs/music_fluidsynth.c
@@ -137,6 +137,7 @@
void *buffer;
int buffer_size;
int volume;
+ SDL_bool is_paused;
} FLUIDSYNTH_Music;
static void FLUIDSYNTH_Delete(void *context);
@@ -283,6 +284,7 @@
fluidsynth.fluid_player_seek(music->player, 0);
#endif
fluidsynth.fluid_player_play(music->player);
+ music->is_paused = SDL_FALSE;
return 0;
}
@@ -290,12 +292,13 @@
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
fluidsynth.fluid_player_play(music->player);
+ music->is_paused = SDL_FALSE;
}
static SDL_bool FLUIDSYNTH_IsPlaying(void *context)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
- return fluidsynth.fluid_player_get_status(music->player) == FLUID_PLAYER_PLAYING ? SDL_TRUE : SDL_FALSE;
+ return music->is_paused || fluidsynth.fluid_player_get_status(music->player) == FLUID_PLAYER_PLAYING ? SDL_TRUE : SDL_FALSE;
}
static int FLUIDSYNTH_GetSome(void *context, void *data, int bytes, SDL_bool *done)
@@ -330,12 +333,14 @@
#if (FLUIDSYNTH_VERSION_MAJOR >= 2)
fluidsynth.fluid_player_seek(music->player, 0);
#endif
+ music->is_paused = SDL_FALSE;
}
static void FLUIDSYNTH_Pause(void *context)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
fluidsynth.fluid_player_stop(music->player);
+ music->is_paused = SDL_TRUE;
}
static void FLUIDSYNTH_Delete(void *context) |
About Is it not supposed to be like: return ( !music->is_paused &&
fluidsynth.fluid_player_get_status(music->player) == FLUID_PLAYER_PLAYING) ?
SDL_TRUE : SDL_FALSE; |
Also: You keep the rewinding call in FLUIDSYNTH_Stop() : If I remove it as I described above by removing seek-to-0 call, Am I missing something? |
No, it's wrong: it should always return "true" when paused. In your case, it WILL return the "false" when paused, it's wrong. If it doesn't returns "true", it starts behave differently than general Mixer behaviour:
The |
Okay, look:
|
And so, the declaration of the pause call is only required for really asynchronious players like the Native MIDI or CMD music. For music that gets pulled locally, there is no necessary to specify the Pause/Resume calls. And if specify, then, do as Mixer itself does: return |
|
Also: calling FluidSynth's "stop" has sense in only condition when its audio output gets persistently pulled even while paused (that's needed to play the note releasing decays as MIDI sequencer gets paused, but sound generator still works persistently. But, in a case of Mixer here is no sence as Mixer totally suspends the input stream even without calling the stop of FluidSynth itself. |
It is all contradictory with music_timidity and timidity. But I'm confused enough, and won't bother more. Letting you and @slouken to decide and finalize this. |
I'm available again. I don't think my say should count for a lot here but @Wohlstand 's pause patch makes sense to me. I'll merge that and squash if no one objects. |
The fluidsynth player would resume from the point when the track was stopped instead of the beginning when Play was called. This was the desired behaviour for the unsupported Pause/Resume functions, so I moved the definitions to those functions and added new Start/Stop functions that seek to the beginning of the track before playing. When paused SDL_mixer should return true for IsPlaying. Fix supplied by Wohlstand.
a401a7b
to
fe8a615
Compare
Merged, thanks! |
The fluidsynth player would resume from the point when the track was stopped instead of the beginning when Play was called. This was the desired behaviour for the unsupported Pause/Resume functions, so I moved the definitions to those functions and added new Start/Stop functions that seek to the beginning of the track before playing.
I previously submitted a larger version of this patch that included seek/tell but the ticks in fluidsynth turned out to be problematic so this version only covers stop/play, which fixes the jukebox functionality in CorsixTH.