SDL_mixer: Fix bug: fluidsynth not looping if predecode is turned off

From 4182794ea45fe28568728670c6f1583855d0e85c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Markus=20F=C3=A4lt?= <[EMAIL REDACTED]>
Date: Fri, 7 Nov 2025 21:19:23 +0100
Subject: [PATCH] Fix bug: fluidsynth not looping if predecode is turned off

When playing a midi song with fluidsynth and looping is turned on it
only works when predecoding the song.
Otherwise the program hangs and in my case must be shutdown with 'kill
-9'.
This commit fixes the bug by ensuring that the fluidsynth player is in
playing mode if seek is called on a finished song.
---
 src/decoder_fluidsynth.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/decoder_fluidsynth.c b/src/decoder_fluidsynth.c
index 05d3f071..48b5fed4 100644
--- a/src/decoder_fluidsynth.c
+++ b/src/decoder_fluidsynth.c
@@ -196,12 +196,12 @@ static void *SoundFontOpen(const char *filename)
     }
     return ptr;  // (this is actually an SDL_IOStream pointer.)
 }
- 
+
 static int SoundFontRead(void *buf, fluid_long_long_t count, void *handle)
 {
     return (SDL_ReadIO((SDL_IOStream *) handle, buf, count) == count) ? FLUID_OK : FLUID_FAILED;
 }
- 
+
 static int SoundFontSeek(void *handle, fluid_long_long_t offset, int origin)
 {
     SDL_IOWhence whence;
@@ -213,13 +213,13 @@ static int SoundFontSeek(void *handle, fluid_long_long_t offset, int origin)
     }
     return (SDL_SeekIO((SDL_IOStream *) handle, offset, whence) >= 0) ? FLUID_OK : FLUID_FAILED;
 }
- 
+
 static int SoundFontClose(void *handle)
 {
     SDL_CloseIO((SDL_IOStream *) handle);
     return FLUID_OK;
 }
- 
+
 static fluid_long_long_t SoundFontTell(void *handle)
 {
     return SDL_TellIO((SDL_IOStream *) handle);
@@ -374,7 +374,14 @@ static bool SDLCALL FLUIDSYNTH_seek(void *track_userdata, Uint64 frame)
     }
 
     // !!! FIXME: docs say this will fail if a seek was requested and then a second seek happens before we play more of the midi file, since the first seek will still be in progress.
-    return (fluidsynth.fluid_player_seek(tdata->player, (int)ticks) == FLUID_OK);
+    bool result = (fluidsynth.fluid_player_seek(tdata->player, (int)ticks) == FLUID_OK);
+
+    if (result && fluidsynth.fluid_player_get_status(tdata->player) != FLUID_PLAYER_PLAYING) {
+        /* start playing if player is done */
+        result = (fluidsynth.fluid_player_play(tdata->player) == FLUID_OK);
+    }
+
+    return result;
 #endif
 }