简体   繁体   中英

SDL_Mixer MOD music looping

I'm trying to loop some mod music in an SDL(2) application using SDL_Mixer, but I'm finding that the library doesn't handle IT/XM/S3M/MOD formats very well.

The music plays and it can technically loop, but there's a horrible stutter as the track is re-loaded and it out-right refuses to obey the "position jump" commands which these formats support. My understanding this is more of an SDL_Mixer problem than the underlying MikMod library that actually handles the format.

Bearing in mind this program needs to support multiple platforms (aka Android) is there a hacky way to create a cleaner looping mechanism and/or a viable alternative to SDL_Mixer?

To accomplish this without ditching SDL_Mixer, you will need to edit some structs for MikMod and libmodplug. There are two ways you can go about editing these structs:

Without editing and recompiling SDL_Mixer

The first option is to include and link either MikMod or libmodplug into your project. SDL_Mixer usually only uses one of these.

#ifdef MIKMOD_HACK
#include <mikmod.h>
#elif defined MODPLUG_HACK
#include <libmodplug/modplug.h>
#endif

After calling Mix_OpenAudio, you can apply the libmodplug hack:

Mix_OpenAudio(11025, AUDIO_U8, 4096)
#ifdef MODPLUG_HACK
ModPlug_Settings settings;
ModPlug_GetSettings(&settings);
settings.mLoopCount = -1;
ModPlug_SetSettings(&settings)
#endif

After playing a Mix_Music, you can apply the MikMod hack:

Mix_PlayMusic(music, 0) /*we won't be using SDL's looping*/
#ifdef MIKMOD_HACK
MODULE *mod = Player_GetModule()
mod->wrap = 1; /*This option will loop without stutter*/
mod->loop = 1; /*This option will make the player obey Position Jumps*/
#endif

As for finding out which hack to use... By default, SDL_Mixer uses libmodplug 0.8.8.5. The hack does not seem to work with linking 0.8.9.0 if SDL_Mixer uses 0.8.8.5, and the hack does not seem to work with linking 0.8.8.5 if the hack uses 0.8.9.0. SDL_Mixer uses 0.8.8.5 for SDL_Mixer 2.0.1 and below, release and MikMod for SDL_mixer 1.2 releases. SDL_Mixer uses 0.8.9.0 for SDL_Mixer 2.0.2.

Editing and recompiling SDL_Mixer

Another option is to modify SDL2_Mixer's sources and recompile yourself. You can change these values in music_mod.c and music_modplug.c:

in music_mod.c: Change

module->wrap    = 0;
module->loop    = 0;

to

module->wrap    = 1; /*This option will loop without stutter*/
module->loop    = 1; /*This option will make the player obey Position Jumps*/

In music_modplug.c, change:

settings.mLoopCount=0;

to

settings.mLoopCount=-1;

I am not certain, but if you go this route, according to the zlib license, you must mark SDL2_mixer as modified somewhere where you are displaying licenses.

2 . Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM