Skip to content

Commit

Permalink
Fixed FluidSynth support and added a default soundfont path on Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Oct 21, 2017
1 parent 1a207a6 commit 5f4c8ea
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 28 deletions.
22 changes: 14 additions & 8 deletions README.txt
Expand Up @@ -6,17 +6,17 @@ http://www.libsdl.org/projects/SDL_mixer/

Due to popular demand, here is a simple multi-channel audio mixer.
It supports 8 channels of 16 bit stereo audio, plus a single channel
of music, mixed by the popular MikMod MOD, Timidity MIDI and SMPEG MP3
libraries.
of music.

See the header file SDL_mixer.h and the examples playwave.c and playmus.c
for documentation on this mixer library.

The mixer can currently load Microsoft WAVE files and Creative Labs VOC
files as audio samples, and can load MIDI files via Timidity and the
following music formats via MikMod: .MOD .S3M .IT .XM. It can load
Ogg Vorbis streams as music if built with Ogg Vorbis or Tremor libraries,
and finally it can load MP3 music using the SMPEG or libmad libraries.
files as audio samples, it can load FLAC files with libFLAC, it can load
Ogg Vorbis files with Ogg Vorbis or Tremor libraries, it can load MP3 files
using mpg123, SMPEG or libmad, and it can load MIDI files with Timidity,
FluidSynth, and natively on Windows, Mac OSX, and Linux, and finally it can
load the following file formats via ModPlug or MikMod: .MOD .S3M .IT .XM.

Tremor decoding is disabled by default; you can enable it by passing
--enable-music-ogg-tremor
Expand All @@ -34,8 +34,14 @@ The process of mixing MIDI files to wave output is very CPU intensive,
so if playing regular WAVE files sound great, but playing MIDI files
sound choppy, try using 8-bit audio, mono audio, or lower frequencies.

To play MIDI files, you'll need to get a complete set of GUS patches
from:
To play MIDI files using FluidSynth, you'll need to set the SDL_SOUNDFONTS
environment variable to a Sound Font 2 (.sf2) file containing the musical
instruments you want to use for MIDI playback.
(On some Linux distributions you can install the fluid-soundfont-gm package)


To play MIDI files using Timidity, you'll need to get a complete set of
GUS patches from:
http://www.libsdl.org/projects/mixer/timidity/timidity.tar.gz
and unpack them in /usr/local/lib under UNIX, and C:\ under Win32.

Expand Down
11 changes: 0 additions & 11 deletions mixer.c
Expand Up @@ -140,12 +140,6 @@ int Mix_Init(int flags)
{
int result = 0;

#ifdef MIX_INIT_SOUNDFONT_PATHS
if (!soundfont_paths) {
soundfont_paths = SDL_strdup(MIX_INIT_SOUNDFONT_PATHS);
}
#endif

load_music();

if (flags & MIX_INIT_FLAC) {
Expand Down Expand Up @@ -189,11 +183,6 @@ int Mix_Init(int flags)
void Mix_Quit()
{
unload_music();

if (soundfont_paths) {
SDL_free(soundfont_paths);
soundfont_paths = NULL;
}
}

static int _Mix_remove_all_effects(int channel, effect_info **e);
Expand Down
51 changes: 45 additions & 6 deletions music.c
Expand Up @@ -66,7 +66,7 @@ static const char **music_decoders = NULL;
static int num_decoders = 0;

/* Semicolon-separated SoundFont paths */
char* soundfont_paths = NULL;
static char* soundfont_paths = NULL;

/* Interfaces for the various music interfaces, ordered by priority */
static Mix_MusicInterface *s_music_interfaces[] =
Expand Down Expand Up @@ -297,6 +297,13 @@ int open_music(const SDL_AudioSpec *spec)
int i;
SDL_bool use_native_midi = SDL_FALSE;

#ifdef MIX_INIT_SOUNDFONT_PATHS
if (!soundfont_paths) {
soundfont_paths = SDL_strdup(MIX_INIT_SOUNDFONT_PATHS);
}
#endif


#ifdef MUSIC_MID_NATIVE
if (SDL_GetHintBoolean("SDL_NATIVE_MUSIC", SDL_FALSE) && native_midi_detect()) {
use_native_midi = SDL_TRUE;
Expand Down Expand Up @@ -929,9 +936,16 @@ void close_music(void)
interface->opened = SDL_FALSE;
}

if (soundfont_paths) {
SDL_free(soundfont_paths);
soundfont_paths = NULL;
}

/* rcg06042009 report available decoders at runtime. */
SDL_free((void *)music_decoders);
music_decoders = NULL;
if (music_decoders) {
SDL_free((void *)music_decoders);
music_decoders = NULL;
}
num_decoders = 0;

ms_per_step = 0;
Expand Down Expand Up @@ -972,11 +986,36 @@ int Mix_SetSoundFonts(const char *paths)

const char* Mix_GetSoundFonts(void)
{
if (!soundfont_paths || SDL_GetHintBoolean("SDL_FORCE_SOUNDFONTS", SDL_FALSE)) {
return SDL_getenv("SDL_SOUNDFONTS");
} else {
const char *env_paths = SDL_getenv("SDL_SOUNDFONTS");
SDL_bool force_env_paths = SDL_GetHintBoolean("SDL_FORCE_SOUNDFONTS", SDL_FALSE);
if (force_env_paths && (!env_paths || !*env_paths)) {
force_env_paths = SDL_FALSE;
}
if (soundfont_paths && *soundfont_paths && !force_env_paths) {
return soundfont_paths;
}
if (env_paths) {
return env_paths;
}

/* We don't have any sound fonts set programmatically or in the environment
Time to start guessing where they might be...
*/
{
static char *s_soundfont_paths[] = {
"/usr/share/sounds/sf2/FluidR3_GM.sf2" /* Remember to add ',' here */
};
unsigned i;

for (i = 0; i < SDL_arraysize(s_soundfont_paths); ++i) {
SDL_RWops *rwops = SDL_RWFromFile(s_soundfont_paths[i], "rb");
if (rwops) {
SDL_RWclose(rwops);
return s_soundfont_paths[i];
}
}
}
return NULL;
}

int Mix_EachSoundFont(int (*function)(const char*, void*), void *data)
Expand Down
1 change: 0 additions & 1 deletion music.h
Expand Up @@ -117,7 +117,6 @@ extern void unload_music(void);

extern char *music_cmd;
extern SDL_AudioSpec music_spec;
extern char *soundfont_paths;

#endif /* MUSIC_H_ */

Expand Down
4 changes: 2 additions & 2 deletions music_fluidsynth.c
Expand Up @@ -242,15 +242,15 @@ static SDL_bool FLUIDSYNTH_IsPlaying(void *context)

static int FLUIDSYNTH_GetSome(void *context, void *data, int bytes, SDL_bool *done)
{
FLUIDSYNTH_Music *music = (FLUIDSYNTH_Music *)context;
int filled;

filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
}

/* FIXME: What happens at end of song? */
if (fluidsynth.fluid_synth_write_s16(music->synth, mixer_spec.samples, music->buffer, 0, 2, music->buffer, 1, 2) != FLUID_OK) {
if (fluidsynth.fluid_synth_write_s16(music->synth, music_spec.samples, music->buffer, 0, 2, music->buffer, 1, 2) != FLUID_OK) {
Mix_SetError("Error generating FluidSynth audio");
return -1;
}
Expand Down

0 comments on commit 5f4c8ea

Please sign in to comment.