SDL_mixer/mikmod problems on bigendian machines

Hi,

I’ve been trying some games that I heard of either directly or
indirectly from this list, specifically:

defendguin (http://www.newbreedsoftware.com/defendguin/)
njam (http://njam.sourceforge.net/)

I’ve e-mailed both the authors privately and they weren’t sure what to
make of this issue either, so I thought I’d try my question here.

Basically, it sounds like the endianness is not being corrected for mod
music. The wav sounds in both games play fine, and audio isn’t garbled
if I disable the music in both games.

Looking at the source I see:

defendguin.c: if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0)
njam.cpp: if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 1, 1024)==-1)

And in music.c from SDL_mixer I see the following for MOD_MUSIC:

            case AUDIO_S16LSB:
            case AUDIO_S16MSB: {
                    /* See if we need to correct MikMod mixing */

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
if ( mixer->format == AUDIO_S16MSB ) {
#else
if ( mixer->format == AUDIO_S16LSB ) {
#endif
music_swap16 = 1;
}
md_mode = DMODE_16BITS;
}

defendguin uses AUDIO_S16. AUDIO_S16 defined as AUDIO_S16LSB. since the
machine is actually AUDIO_S16MSB, the mod will be bitswapped?

njam uses MIX_DEFAULT_FORMAT. MIX_DEFAULT_FORMAT is AUDIO_S16MSB on
bigendian machines. since the mixer format will be AUDIO_S16MSB and the
audio format is AUDIO_S16MSB, the mod won’t be bitswapped?

How can different mixer formats yield the same results?

My environment is:

OpenBSD turing.no.tld 3.3 GENERIC#19 sparc64
gcc version 2.95.3 20010125 (prerelease, propolice)
SDL 1.2.5 w/sun audio driver
SDL_mixer 1.2.5 w/mikmod 3.1.10

rocks`n’diamonds (http://www.artsoft.org/rocksndiamonds/) mixes wavs and
mods just fine on my sparc64, and I can’t seem to figure out why.

And of course, music sounds okay when defendguin & njam are played on
my i386 machine which has the same environment as my sparc64.

I’m pretty sure I’m misunderstanding something. Anyone care to
straighten me out?

defendguin.c: if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0)

(For the record, using AUDIO_S16 when you really mean AUDIO_S16SYS is a
common mistake, but SDL_mixer should handle it…depending on your audio
data and hardware, it might even mean less byte swapping in the long run,
but usually it’s incorrect if you’re doing any manual audio
manipulation…but this is a game-specific decision, really.)

And in music.c from SDL_mixer I see the following for MOD_MUSIC:

            case AUDIO_S16LSB:
            case AUDIO_S16MSB: {
                    /* See if we need to correct MikMod mixing */

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
if ( mixer->format == AUDIO_S16MSB ) {
#else
if ( mixer->format == AUDIO_S16LSB ) {
#endif
music_swap16 = 1;
}
md_mode = DMODE_16BITS;
}

Can you rebuild SDL_mixer with that “music_swap16 = 1;” commented out?
Perhaps MikMod is feeding SDL_mixer data in the native byte order format
and our assumption that we must manually swap its output is incorrect?

I can’t really test this here at the moment, so you’ll have to try it if
you can.

njam uses MIX_DEFAULT_FORMAT. MIX_DEFAULT_FORMAT is AUDIO_S16MSB on
bigendian machines. since the mixer format will be AUDIO_S16MSB and the
audio format is AUDIO_S16MSB, the mod won’t be bitswapped?

How can different mixer formats yield the same results?

Mix_OpenAudio()'s format is just a hint so SDL_mixer users can aim to open
the audio device in a format close to what they plan to feed it…this is
to reduce or eliminate the amount of data conversion done on-the-fly, but
it is JUST A HINT.

At the lower level, Mix_OpenAudio() calls SDL_OpenAudio() with a non-NULL
second parameter, so it will get the closest native format the audio
device support and then convert as necessary (passing a NULL there might
"fix" this problem but just moves the conversion out of SDL_mixer and into
SDL…)

In short, just because Mix_OpenAudio() asked for AUDIO_S16LSB doesn’t mean
that mixer->format isn’t AUDIO_S16MSB when you hit the test in question.
In fact, it’s entirely possible that the Sun Audio Driver target can only
do bigendian data.

rocks`n’diamonds (http://www.artsoft.org/rocksndiamonds/) mixes wavs and
mods just fine on my sparc64, and I can’t seem to figure out why.

I don’t see any .mod files in the Unix distribution of Rocks’n’Diamonds
(the music is in .wav files), and the grepping the source for "mikmod"
doesn’t yield any results. So I guess that answers that. :slight_smile:

–ryan.

Can you rebuild SDL_mixer with that “music_swap16 = 1;” commented out?
Perhaps MikMod is feeding SDL_mixer data in the native byte order format
and our assumption that we must manually swap its output is incorrect?

I tried it and there’s no discernible change. wav sounds still play
clear and mod music is still garbled.

I don’t see any .mod files in the Unix distribution of Rocks’n’Diamonds
(the music is in .wav files), and the grepping the source for "mikmod"
doesn’t yield any results. So I guess that answers that. :slight_smile:

Sorry, should have mentioned this quirk beforehand. The mods are named
mod.* rather than *.mod. I traced the binary to make sure that they’re
opened and read and they are. I started digging into the source but
there’s a lot of mixing code that I’m not sure I understand yet so I’ll
refrain from speculating.

Right now, I’m trying to figure out how to get njam compiling on MacOSX
to see if I can reproduce and I’m failing miserably:

g++ -o njam njam.o njamnet.o njamgame.o njammap.o njamfont.o njamutils.o
-F/Users/jolan/Library/Frameworks -framework SDL -framework SDL_mixer
-framework SDL_net
ld: /usr/lib/crt1.o illegal reference to symbol: __objcInit defined in
indirectly referenced dynamic library /usr/lib/libobjc.A.dylib
make: *** [njam] Error 1

Guess I’ll buckle down and learn project builder… :)On Mon, Jun 09, 2003 at 03:03:36AM -0400, Ryan C. Gordon wrote:

By the way, when I installed the OSX SDL devel package, I noticed it was
set mode 777 rather than 755 like the image/mixer/net frameworks.

Anyone else see this?On Mon, Jun 09, 2003 at 09:48:06PM -0400, Jolan Luff wrote:

Right now, I’m trying to figure out how to get njam compiling on MacOSX
to see if I can reproduce and I’m failing miserably:

The problem is present in the ‘playmus’ test progam and appears to be
outside of mikmod:

  1. Playing mod sounds horrible.
  2. Playing mp3 sounds horrible, but prints this warning before
    playing “Warning: incorrect audio format”. (Where is this from?)
  3. Playing ogg works…?!

There doesn’t seem to be a problem with playmus on MacOSX/iBook. I’m
doubtful it is an issue with my OpenBSD/sparc64 machine/soundcard, as
xmms plays mods with the mikmod plugin just fine (and other formats as
well). playwave works just fine too.

I’m completely stumped. Anyone?