SHA256
1
0
forked from pool/SDL2_mixer
SDL2_mixer/SDL2_mixer-only-load-required-interfaces.patch

469 lines
14 KiB
Diff
Raw Normal View History

# HG changeset patch
# User Sam Lantinga <slouken@libsdl.org>
# Date 1508906510 25200
# Node ID 7fa15b556953502e11c911d104450ae02c807c84
# Parent 7d6df0a13bd02a3eb7fbdf64eca628913d46c291
Only load music interfaces that are explicitly initialized or needed for audio content
diff -r 7d6df0a13bd0 -r 7fa15b556953 mixer.c
--- a/mixer.c Mon Oct 23 12:40:10 2017 -0700
+++ b/mixer.c Tue Oct 24 21:41:50 2017 -0700
@@ -118,9 +118,19 @@
return SDL_FALSE;
}
-static void add_chunk_decoder(const char *decoder)
+void add_chunk_decoder(const char *decoder)
{
- void *ptr = SDL_realloc((void *)chunk_decoders, (num_decoders + 1) * sizeof (const char *));
+ int i;
+ void *ptr;
+
+ /* Check to see if we already have this decoder */
+ for (i = 0; i < num_decoders; ++i) {
+ if (SDL_strcmp(chunk_decoders[i], decoder) == 0) {
+ return;
+ }
+ }
+
+ ptr = SDL_realloc((void *)chunk_decoders, (num_decoders + 1) * sizeof (const char *));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
@@ -140,44 +150,47 @@
{
int result = 0;
- load_music();
-
if (flags & MIX_INIT_FLAC) {
- if (has_music(MUS_FLAC)) {
+ if (load_music_type(MUS_FLAC)) {
+ open_music_type(MUS_FLAC);
result |= MIX_INIT_FLAC;
} else {
Mix_SetError("FLAC support not available");
}
}
if (flags & MIX_INIT_MOD) {
- if (has_music(MUS_MOD)) {
+ if (load_music_type(MUS_MOD)) {
+ open_music_type(MUS_MOD);
result |= MIX_INIT_MOD;
} else {
Mix_SetError("MOD support not available");
}
}
if (flags & MIX_INIT_MP3) {
- if (has_music(MUS_MP3)) {
+ if (load_music_type(MUS_MP3)) {
+ open_music_type(MUS_MP3);
result |= MIX_INIT_MP3;
} else {
Mix_SetError("MP3 support not available");
}
}
if (flags & MIX_INIT_OGG) {
- if (has_music(MUS_OGG)) {
+ if (load_music_type(MUS_OGG)) {
+ open_music_type(MUS_OGG);
result |= MIX_INIT_OGG;
} else {
Mix_SetError("OGG support not available");
}
}
if (flags & MIX_INIT_MID) {
- if (has_music(MUS_MID)) {
+ if (load_music_type(MUS_MID)) {
+ open_music_type(MUS_MID);
result |= MIX_INIT_MID;
} else {
Mix_SetError("MIDI support not available");
}
}
- return (result);
+ return result;
}
void Mix_Quit()
@@ -400,13 +413,6 @@
PrintFormat("Audio device", &mixer);
#endif
- /* Initialize the music players */
- load_music();
- if (open_music(&mixer) < 0) {
- SDL_CloseAudioDevice(audio_device);
- return(-1);
- }
-
num_channels = MIX_CHANNELS;
mix_channel = (struct _Mix_Channel *) SDL_malloc(num_channels * sizeof(struct _Mix_Channel));
@@ -431,21 +437,9 @@
add_chunk_decoder("WAVE");
add_chunk_decoder("AIFF");
add_chunk_decoder("VOC");
- if (has_music(MUS_MOD)) {
- add_chunk_decoder("MOD");
- }
- if (has_music(MUS_MID)) {
- add_chunk_decoder("MID");
- }
- if (has_music(MUS_OGG)) {
- add_chunk_decoder("OGG");
- }
- if (has_music(MUS_MP3)) {
- add_chunk_decoder("MP3");
- }
- if (has_music(MUS_FLAC)) {
- add_chunk_decoder("FLAC");
- }
+
+ /* Initialize the music players */
+ open_music(&mixer);
audio_opened = 1;
SDL_PauseAudioDevice(audio_device, 0);
@@ -536,6 +530,10 @@
int count = 0;
int fragment_size;
+ if (!load_music_type(music_type) || !open_music_type(music_type)) {
+ return NULL;
+ }
+
*spec = mixer;
/* Use fragments sized on full audio frame boundaries - this'll do */
@@ -544,6 +542,9 @@
start = SDL_RWtell(src);
for (i = 0; i < get_num_music_interfaces(); ++i) {
interface = get_music_interface(i);
+ if (!interface->opened) {
+ continue;
+ }
if (interface->type != music_type) {
continue;
}
diff -r 7d6df0a13bd0 -r 7fa15b556953 mixer.h
--- a/mixer.h Mon Oct 23 12:40:10 2017 -0700
+++ b/mixer.h Tue Oct 24 21:41:50 2017 -0700
@@ -23,4 +23,6 @@
extern void Mix_LockAudio(void);
extern void Mix_UnlockAudio(void);
+extern void add_chunk_decoder(const char *decoder);
+
/* vi: set ts=4 sw=4 expandtab: */
diff -r 7d6df0a13bd0 -r 7fa15b556953 music.c
--- a/music.c Mon Oct 23 12:40:10 2017 -0700
+++ b/music.c Tue Oct 24 21:41:50 2017 -0700
@@ -42,6 +42,9 @@
#include "music_flac.h"
#include "native_midi/native_midi.h"
+/* Set this hint to true if you want verbose logging of music interfaces */
+#define SDL_MIXER_HINT_DEBUG_MUSIC_INTERFACES \
+ "SDL_MIXER_DEBUG_MUSIC_INTERFACES"
char *music_cmd = NULL;
static SDL_bool music_active = SDL_TRUE;
@@ -135,7 +138,17 @@
static void add_music_decoder(const char *decoder)
{
- void *ptr = SDL_realloc((void *)music_decoders, (num_decoders + 1) * sizeof (const char *));
+ void *ptr;
+ int i;
+
+ /* Check to see if we already have this decoder */
+ for (i = 0; i < num_decoders; ++i) {
+ if (SDL_strcmp(music_decoders[i], decoder) == 0) {
+ return;
+ }
+ }
+
+ ptr = SDL_realloc((void *)music_decoders, (num_decoders + 1) * sizeof (const char *));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
@@ -252,28 +265,123 @@
}
}
-/* Load the music interface libraries */
-int load_music(void)
+/* Load the music interface libraries for a given music type */
+SDL_bool load_music_type(Mix_MusicType type)
{
- char hint[128];
-
- int i;
+ int i, loaded = 0;
for (i = 0; i < SDL_arraysize(s_music_interfaces); ++i) {
Mix_MusicInterface *interface = s_music_interfaces[i];
- if (interface->loaded) {
+ if (interface->type != type) {
+ continue;
+ }
+ if (!interface->loaded) {
+ char hint[64];
+ SDL_snprintf(hint, sizeof(hint), "SDL_MIXER_DISABLE_%s", interface->tag);
+ if (SDL_GetHintBoolean(hint, SDL_FALSE)) {
+ continue;
+ }
+
+ if (interface->Load && interface->Load() < 0) {
+ if (SDL_GetHintBoolean(SDL_MIXER_HINT_DEBUG_MUSIC_INTERFACES, SDL_FALSE)) {
+ SDL_Log("Couldn't load %s: %s\n", interface->tag, Mix_GetError());
+ }
+ continue;
+ }
+ interface->loaded = SDL_TRUE;
+ }
+ ++loaded;
+ }
+ return (loaded > 0) ? SDL_TRUE : SDL_FALSE;
+}
+
+/* Open the music interfaces for a given music type */
+SDL_bool open_music_type(Mix_MusicType type)
+{
+ int i, opened = 0;
+ SDL_bool use_native_midi = SDL_FALSE;
+
+ if (!music_spec.format) {
+ /* Music isn't opened yet */
+ return SDL_FALSE;
+ }
+
+#ifdef MUSIC_MID_NATIVE
+ if (type == MUS_MID && SDL_GetHintBoolean("SDL_NATIVE_MUSIC", SDL_FALSE) && native_midi_detect()) {
+ use_native_midi = SDL_TRUE;
+ }
+#endif
+
+ for (i = 0; i < SDL_arraysize(s_music_interfaces); ++i) {
+ Mix_MusicInterface *interface = s_music_interfaces[i];
+ if (!interface->loaded) {
+ continue;
+ }
+ if (type != MUS_NONE && interface->type != type) {
continue;
}
- SDL_snprintf(hint, sizeof(hint), "SDL_MIXER_DISABLE_%s", interface->tag);
- if (SDL_GetHintBoolean(hint, SDL_FALSE)) {
+ if (interface->type == MUS_MID && use_native_midi && interface->api != MIX_MUSIC_NATIVEMIDI) {
continue;
}
- if (!interface->Load || interface->Load() == 0) {
- interface->loaded = SDL_TRUE;
+ if (!interface->opened) {
+ if (interface->Open && interface->Open(&music_spec) < 0) {
+ if (SDL_GetHintBoolean(SDL_MIXER_HINT_DEBUG_MUSIC_INTERFACES, SDL_FALSE)) {
+ SDL_Log("Couldn't open %s: %s\n", interface->tag, Mix_GetError());
+ }
+ continue;
+ }
+ interface->opened = SDL_TRUE;
+ add_music_decoder(interface->tag);
}
+ ++opened;
}
- return 0;
+
+ if (has_music(MUS_MOD)) {
+ add_music_decoder("MOD");
+ add_chunk_decoder("MOD");
+ }
+ if (has_music(MUS_MID)) {
+ add_music_decoder("MIDI");
+ add_chunk_decoder("MID");
+ }
+ if (has_music(MUS_OGG)) {
+ add_music_decoder("OGG");
+ add_chunk_decoder("OGG");
+ }
+ if (has_music(MUS_MP3)) {
+ add_music_decoder("MP3");
+ add_chunk_decoder("MP3");
+ }
+ if (has_music(MUS_FLAC)) {
+ add_music_decoder("FLAC");
+ add_chunk_decoder("FLAC");
+ }
+
+ return (opened > 0) ? SDL_TRUE : SDL_FALSE;
+}
+
+/* Initialize the music interfaces with a certain desired audio format */
+void open_music(const SDL_AudioSpec *spec)
+{
+#ifdef MIX_INIT_SOUNDFONT_PATHS
+ if (!soundfont_paths) {
+ soundfont_paths = SDL_strdup(MIX_INIT_SOUNDFONT_PATHS);
+ }
+#endif
+
+ /* Load the music interfaces that don't have explicit initialization */
+ load_music_type(MUS_CMD);
+ load_music_type(MUS_WAV);
+
+ /* Open all the interfaces that are loaded */
+ music_spec = *spec;
+ open_music_type(MUS_NONE);
+
+ Mix_VolumeMusic(MIX_MAX_VOLUME);
+
+ /* Calculate the number of ms for each callback */
+ ms_per_step = (int) (((float)spec->samples * 1000.0) / spec->freq);
}
/* Return SDL_TRUE if the music type is available */
@@ -292,60 +400,6 @@
return SDL_FALSE;
}
-/* Initialize the music interfaces with a certain desired audio format */
-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;
- }
-#endif
-
- music_spec = *spec;
- for (i = 0; i < SDL_arraysize(s_music_interfaces); ++i) {
- Mix_MusicInterface *interface = s_music_interfaces[i];
- if (!interface->loaded) {
- continue;
- }
-
- if (interface->type == MUS_MID && use_native_midi && interface->api != MIX_MUSIC_NATIVEMIDI) {
- continue;
- }
-
- if (!interface->Open || interface->Open(spec) == 0) {
- interface->opened = SDL_TRUE;
- add_music_decoder(interface->tag);
- }
- }
-
- if (has_music(MUS_MOD)) {
- add_music_decoder("MOD");
- }
- if (has_music(MUS_MID)) {
- add_music_decoder("MIDI");
- }
- if (has_music(MUS_MP3)) {
- add_music_decoder("MP3");
- }
-
- Mix_VolumeMusic(MIX_MAX_VOLUME);
-
- /* Calculate the number of ms for each callback */
- ms_per_step = (int) (((float)spec->samples * 1000.0) / spec->freq);
-
- return 0;
-}
-
Mix_MusicType detect_music_type_from_magic(const Uint8 *magic)
{
/* Ogg Vorbis files have the magic four bytes "OggS" */
@@ -509,32 +563,34 @@
Mix_ClearError();
- for (i = 0; i < SDL_arraysize(s_music_interfaces); ++i) {
- Mix_MusicInterface *interface = s_music_interfaces[i];
- if (!interface->opened || type != interface->type || !interface->CreateFromRW) {
- continue;
+ if (load_music_type(type) && open_music_type(type)) {
+ for (i = 0; i < SDL_arraysize(s_music_interfaces); ++i) {
+ Mix_MusicInterface *interface = s_music_interfaces[i];
+ if (!interface->opened || type != interface->type || !interface->CreateFromRW) {
+ continue;
+ }
+
+ context = interface->CreateFromRW(src, freesrc);
+ if (context) {
+ /* Allocate memory for the music structure */
+ Mix_Music *music = (Mix_Music *)SDL_calloc(1, sizeof(Mix_Music));
+ if (music == NULL) {
+ interface->Delete(context);
+ Mix_SetError("Out of memory");
+ return NULL;
+ }
+ music->interface = interface;
+ music->context = context;
+
+ if (SDL_GetHintBoolean(SDL_MIXER_HINT_DEBUG_MUSIC_INTERFACES, SDL_FALSE)) {
+ SDL_Log("Loaded music with %s\n", interface->tag);
+ }
+ return music;
+ }
+
+ /* Reset the stream for the next decoder */
+ SDL_RWseek(src, start, RW_SEEK_SET);
}
-
- context = interface->CreateFromRW(src, freesrc);
- if (context) {
- /* Allocate memory for the music structure */
- Mix_Music *music = (Mix_Music *)SDL_calloc(1, sizeof(Mix_Music));
- if (music == NULL) {
- interface->Delete(context);
- Mix_SetError("Out of memory");
- return NULL;
- }
- music->interface = interface;
- music->context = context;
-#ifdef DEBUG_MUSIC
- /* This would be useful to expose via an API */
- SDL_Log("Music playing with %s\n", interface->tag);
-#endif
- return music;
- }
-
- /* Reset the stream for the next decoder */
- SDL_RWseek(src, start, RW_SEEK_SET);
}
if (!*Mix_GetError()) {
diff -r 7d6df0a13bd0 -r 7fa15b556953 music.h
--- a/music.h Mon Oct 23 12:40:10 2017 -0700
+++ b/music.h Tue Oct 24 21:41:50 2017 -0700
@@ -103,12 +103,13 @@
} Mix_MusicInterface;
-extern int load_music(void);
-extern Mix_MusicType detect_music_type_from_magic(const Uint8 *magic);
extern int get_num_music_interfaces(void);
extern Mix_MusicInterface *get_music_interface(int index);
+extern Mix_MusicType detect_music_type_from_magic(const Uint8 *magic);
+extern SDL_bool load_music_type(Mix_MusicType type);
+extern SDL_bool open_music_type(Mix_MusicType type);
extern SDL_bool has_music(Mix_MusicType type);
-extern int open_music(const SDL_AudioSpec *spec);
+extern void open_music(const SDL_AudioSpec *spec);
extern int music_pcm_getaudio(void *context, void *data, int bytes, int volume,
int (*GetSome)(void *context, void *data, int bytes, SDL_bool *done));
extern void SDLCALL music_mixer(void *udata, Uint8 *stream, int len);