Fixed FluidSynth support and added a default soundfont path on Linux
authorSam Lantinga <slouken@libsdl.org>
Sat, 21 Oct 2017 02:10:33 -0700
changeset 80146acd70caa6a
parent 800 cc4aef7fef64
child 802 98ee7bc3833a
Fixed FluidSynth support and added a default soundfont path on Linux
README.txt
mixer.c
music.c
music.h
music_fluidsynth.c
     1.1 --- a/README.txt	Sat Oct 21 01:32:12 2017 -0700
     1.2 +++ b/README.txt	Sat Oct 21 02:10:33 2017 -0700
     1.3 @@ -6,17 +6,17 @@
     1.4  
     1.5  Due to popular demand, here is a simple multi-channel audio mixer.
     1.6  It supports 8 channels of 16 bit stereo audio, plus a single channel
     1.7 -of music, mixed by the popular MikMod MOD, Timidity MIDI and SMPEG MP3
     1.8 -libraries.
     1.9 +of music.
    1.10  
    1.11  See the header file SDL_mixer.h and the examples playwave.c and playmus.c
    1.12  for documentation on this mixer library.
    1.13  
    1.14  The mixer can currently load Microsoft WAVE files and Creative Labs VOC
    1.15 -files as audio samples, and can load MIDI files via Timidity and the
    1.16 -following music formats via MikMod:  .MOD .S3M .IT .XM. It can load
    1.17 -Ogg Vorbis streams as music if built with Ogg Vorbis or Tremor libraries,
    1.18 -and finally it can load MP3 music using the SMPEG or libmad libraries.
    1.19 +files as audio samples, it can load FLAC files with libFLAC, it can load
    1.20 +Ogg Vorbis files with Ogg Vorbis or Tremor libraries, it can load MP3 files
    1.21 +using mpg123, SMPEG or libmad, and it can load MIDI files with Timidity,
    1.22 +FluidSynth, and natively on Windows, Mac OSX, and Linux, and finally it can
    1.23 +load the following file formats via ModPlug or MikMod: .MOD .S3M .IT .XM.
    1.24  
    1.25  Tremor decoding is disabled by default; you can enable it by passing
    1.26  	--enable-music-ogg-tremor
    1.27 @@ -34,8 +34,14 @@
    1.28  so if playing regular WAVE files sound great, but playing MIDI files
    1.29  sound choppy, try using 8-bit audio, mono audio, or lower frequencies.
    1.30  
    1.31 -To play MIDI files, you'll need to get a complete set of GUS patches
    1.32 -from:
    1.33 +To play MIDI files using FluidSynth, you'll need to set the SDL_SOUNDFONTS
    1.34 +environment variable to a Sound Font 2 (.sf2) file containing the musical
    1.35 +instruments you want to use for MIDI playback.
    1.36 +(On some Linux distributions you can install the fluid-soundfont-gm package)
    1.37 +
    1.38 +
    1.39 +To play MIDI files using Timidity, you'll need to get a complete set of
    1.40 +GUS patches from:
    1.41  http://www.libsdl.org/projects/mixer/timidity/timidity.tar.gz
    1.42  and unpack them in /usr/local/lib under UNIX, and C:\ under Win32.
    1.43  
     2.1 --- a/mixer.c	Sat Oct 21 01:32:12 2017 -0700
     2.2 +++ b/mixer.c	Sat Oct 21 02:10:33 2017 -0700
     2.3 @@ -140,12 +140,6 @@
     2.4  {
     2.5      int result = 0;
     2.6  
     2.7 -#ifdef MIX_INIT_SOUNDFONT_PATHS
     2.8 -    if (!soundfont_paths) {
     2.9 -        soundfont_paths = SDL_strdup(MIX_INIT_SOUNDFONT_PATHS);
    2.10 -    }
    2.11 -#endif
    2.12 -
    2.13      load_music();
    2.14  
    2.15      if (flags & MIX_INIT_FLAC) {
    2.16 @@ -189,11 +183,6 @@
    2.17  void Mix_Quit()
    2.18  {
    2.19      unload_music();
    2.20 -
    2.21 -    if (soundfont_paths) {
    2.22 -        SDL_free(soundfont_paths);
    2.23 -        soundfont_paths = NULL;
    2.24 -    }
    2.25  }
    2.26  
    2.27  static int _Mix_remove_all_effects(int channel, effect_info **e);
     3.1 --- a/music.c	Sat Oct 21 01:32:12 2017 -0700
     3.2 +++ b/music.c	Sat Oct 21 02:10:33 2017 -0700
     3.3 @@ -66,7 +66,7 @@
     3.4  static int num_decoders = 0;
     3.5  
     3.6  /* Semicolon-separated SoundFont paths */
     3.7 -char* soundfont_paths = NULL;
     3.8 +static char* soundfont_paths = NULL;
     3.9  
    3.10  /* Interfaces for the various music interfaces, ordered by priority */
    3.11  static Mix_MusicInterface *s_music_interfaces[] =
    3.12 @@ -297,6 +297,13 @@
    3.13      int i;
    3.14      SDL_bool use_native_midi = SDL_FALSE;
    3.15  
    3.16 +#ifdef MIX_INIT_SOUNDFONT_PATHS
    3.17 +    if (!soundfont_paths) {
    3.18 +        soundfont_paths = SDL_strdup(MIX_INIT_SOUNDFONT_PATHS);
    3.19 +    }
    3.20 +#endif
    3.21 +
    3.22 +
    3.23  #ifdef MUSIC_MID_NATIVE
    3.24      if (SDL_GetHintBoolean("SDL_NATIVE_MUSIC", SDL_FALSE) && native_midi_detect()) {
    3.25          use_native_midi = SDL_TRUE;
    3.26 @@ -929,9 +936,16 @@
    3.27          interface->opened = SDL_FALSE;
    3.28      }
    3.29  
    3.30 +    if (soundfont_paths) {
    3.31 +        SDL_free(soundfont_paths);
    3.32 +        soundfont_paths = NULL;
    3.33 +    }
    3.34 +
    3.35      /* rcg06042009 report available decoders at runtime. */
    3.36 -    SDL_free((void *)music_decoders);
    3.37 -    music_decoders = NULL;
    3.38 +    if (music_decoders) {
    3.39 +        SDL_free((void *)music_decoders);
    3.40 +        music_decoders = NULL;
    3.41 +    }
    3.42      num_decoders = 0;
    3.43  
    3.44      ms_per_step = 0;
    3.45 @@ -972,11 +986,36 @@
    3.46  
    3.47  const char* Mix_GetSoundFonts(void)
    3.48  {
    3.49 -    if (!soundfont_paths || SDL_GetHintBoolean("SDL_FORCE_SOUNDFONTS", SDL_FALSE)) {
    3.50 -        return SDL_getenv("SDL_SOUNDFONTS");
    3.51 -    } else {
    3.52 +    const char *env_paths = SDL_getenv("SDL_SOUNDFONTS");
    3.53 +    SDL_bool force_env_paths = SDL_GetHintBoolean("SDL_FORCE_SOUNDFONTS", SDL_FALSE);
    3.54 +    if (force_env_paths && (!env_paths || !*env_paths)) {
    3.55 +        force_env_paths = SDL_FALSE;
    3.56 +    }
    3.57 +    if (soundfont_paths && *soundfont_paths && !force_env_paths) {
    3.58          return soundfont_paths;
    3.59      }
    3.60 +    if (env_paths) {
    3.61 +        return env_paths;
    3.62 +    }
    3.63 +
    3.64 +    /* We don't have any sound fonts set programmatically or in the environment
    3.65 +       Time to start guessing where they might be...
    3.66 +     */
    3.67 +    {
    3.68 +        static char *s_soundfont_paths[] = {
    3.69 +            "/usr/share/sounds/sf2/FluidR3_GM.sf2"  /* Remember to add ',' here */
    3.70 +        };
    3.71 +        unsigned i;
    3.72 +
    3.73 +        for (i = 0; i < SDL_arraysize(s_soundfont_paths); ++i) {
    3.74 +            SDL_RWops *rwops = SDL_RWFromFile(s_soundfont_paths[i], "rb");
    3.75 +            if (rwops) {
    3.76 +                SDL_RWclose(rwops);
    3.77 +                return s_soundfont_paths[i];
    3.78 +            }
    3.79 +        }
    3.80 +    }
    3.81 +    return NULL;
    3.82  }
    3.83  
    3.84  int Mix_EachSoundFont(int (*function)(const char*, void*), void *data)
     4.1 --- a/music.h	Sat Oct 21 01:32:12 2017 -0700
     4.2 +++ b/music.h	Sat Oct 21 02:10:33 2017 -0700
     4.3 @@ -117,7 +117,6 @@
     4.4  
     4.5  extern char *music_cmd;
     4.6  extern SDL_AudioSpec music_spec;
     4.7 -extern char *soundfont_paths;
     4.8  
     4.9  #endif /* MUSIC_H_ */
    4.10  
     5.1 --- a/music_fluidsynth.c	Sat Oct 21 01:32:12 2017 -0700
     5.2 +++ b/music_fluidsynth.c	Sat Oct 21 02:10:33 2017 -0700
     5.3 @@ -242,6 +242,7 @@
     5.4  
     5.5  static int FLUIDSYNTH_GetSome(void *context, void *data, int bytes, SDL_bool *done)
     5.6  {
     5.7 +    FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
     5.8      int filled;
     5.9  
    5.10      filled = SDL_AudioStreamGet(music->stream, data, bytes);
    5.11 @@ -249,8 +250,7 @@
    5.12          return filled;
    5.13      }
    5.14  
    5.15 -    /* FIXME: What happens at end of song? */
    5.16 -    if (fluidsynth.fluid_synth_write_s16(music->synth, mixer_spec.samples, music->buffer, 0, 2, music->buffer, 1, 2) != FLUID_OK) {
    5.17 +    if (fluidsynth.fluid_synth_write_s16(music->synth, music_spec.samples, music->buffer, 0, 2, music->buffer, 1, 2) != FLUID_OK) {
    5.18          Mix_SetError("Error generating FluidSynth audio");
    5.19          return -1;
    5.20      }