blupi-games / planetblupi

Planet Blupi source code
https://www.blupi.org
Other
86 stars 22 forks source link

Midi playback could set the Mix_SetSoundFonts order of preference #114

Open OdyX opened 8 months ago

OdyX commented 8 months ago

Following your suggestion in https://github.com/blupi-games/blupimania/issues/10#issuecomment-1865245777, I've tried generating the ogg files for planetblupi with the following line:

resources/music/music%.ogg: resources/music/music%.mid
        # Encode to ogg with "Quality=0" ~ 64 kB
        timidity --config-string="soundfont /usr/share/sounds/sf2/sf_GMbank.sf2" -Ow $< -o - | oggenc -Q -q0 --serial 1 -o $@ -

This works fine and produces fine .ogg's indeed, but…

It made me observe that when planetblupi --restore-midi (or when only MIDI files are available), fluidsynth / SDL_mixer rely on the default SF3 soundfont as provided by the system (which makes sense!).

It looks like Mix_SetSoundFonts() could be used to set the program's preferences, with something like

Mix_SetSoundFonts("/usr/share/sounds/sf2/sf_GMbank.sf2;/usr/share/sounds/sf2/FluidR3_GM.sf2");
Skywalker13 commented 8 months ago

OK, the doc on SDL2_mixer is a bit incomplete. I must check what happens when all paths are not returning something existing, if in this case it fallbacks on the default system soundfont.

Skywalker13 commented 8 months ago

I'm discovering that Mix_SetSoundFonts is only useful with fluidsynth that I don't use with my own static build.

Now, I can't test easily with my setup. But I think that something like that should do the job:

diff --git a/src/sound.cxx b/src/sound.cxx
index 2b581aa..7392a1b 100644
--- a/src/sound.cxx
+++ b/src/sound.cxx
@@ -121,6 +121,19 @@ CSound::~CSound ()
 bool
 CSound::Create ()
 {
+#ifdef __linux__
+  static const std::string soundfont = "/usr/share/sounds/sf2/sf_GMbank.sf2";
+
+  std::string soundfonts = Mix_GetSoundFonts ();
+  if (soundfonts != soundfont)
+  {
+    if (soundfonts.empty ())
+      Mix_SetSoundFonts (soundfont.c_str ());
+    else
+      Mix_SetSoundFonts ((soundfont + ";" + soundfonts).c_str ());
+  }
+#endif /* __linux__ */
+
   if (
     Mix_OpenAudio (44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024) == -1)
     return false;