SDL_mixer: Playing a MOD file changes music volume

I’ve come across a problem where playing a MOD-based file (using the
libmikmod support of SDL_mixer) will change the volume of the music
channel. It seems that SDL_mixer somehow secretly applies changes to
the music channel.

This results in a problem I don’t know how to solve. I have mute
functionality in my application. Initially, let’s say I do this:

Mix_VolumeMusic(64);

When the mute button is pressed, the current volume is backed up and
then set to 0 in order to mute the audio:

int vol = Mix_VolumeMusic(-1);
Mix_VolumeMusic(0);

When the user unmutes, the backed up value gets restored:

Mix_VolumeMusic(vol);

This results in the wrong volume being applied. Even though initially
the volume was set to 64, setting it again to 64 later results in a much
lower volume then what was audible before muting the music channel. The
MOD file has a long fade-in effect at the beginning, but I don’t think
this should have any effect on SDL_mixer’s music channel volume. Or
should it?

Quoth Nikos Chantziaras , on 2011-06-11 21:51:05 +0300:

I’ve come across a problem where playing a MOD-based file (using the
libmikmod support of SDL_mixer) will change the volume of the music
channel. It seems that SDL_mixer somehow secretly applies changes
to the music channel.

My guess is that the MikMod library is punning user-controlled global
volume against module-controlled global volume rather than making two
separate gain controls available, and that SDL_mixer uses this rather
than applying gain on the output for module music. Glancing at the
SDL_mixer and MikMod source suggest that this is the case.

This results in the wrong volume being applied. Even though
initially the volume was set to 64, setting it again to 64 later
results in a much lower volume then what was audible before muting
the music channel. The MOD file has a long fade-in effect at the
beginning, but I don’t think this should have any effect on
SDL_mixer’s music channel volume. Or should it?

It probably shouldn’t in the sense that I wouldn’t find it the best
behavior for the library stack, but module music normally has its own
master gain control. In Ye Moderne Day it’s sort of for hysterical
raisins but there may have been good grapes at the time…

I’ll look into a patch. Which SDL_mixer are you using, out of
curiosity?

—> Drake Wilson

Yeah, okay, so here it is. This seems to work on my machine, but I’d
strongly suggest that you/whoever give it an extra look before running
it in the Reol Wyrld. See attached patch against recent Hg SDL_mixer.
Second patch is an unrelated internal cosmetic fix. No warranty.

I did not bother to do the same work for ModPlug, for now; I imagine
it may have the same problem from a cursory glance.

I tried to follow the nearby SDL_mixer coding style, but it was a
little inconsistent, and I’m not totally sure I got it right. See
comments in source. I suspect a better approach would be to refactor
the music volume control entirely, especially given things like the
memcpy/SDL_MixAudio code that’s duplicated between several music
format handling files. For this time I went for minimal delta.

I also don’t know whether this is the actual desired function for
SDL_mixer’s Mix_VolumeMusic API, in the absence of more authoritative
words on the topic. I suspect it is.

Let me know what you think!

—> Drake Wilson
-------------- next part --------------
A non-text attachment was scrubbed…
Name: mikmod-external-gain.diff
Type: text/x-diff
Size: 8557 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110612/72a50f82/attachment.diff
-------------- next part --------------
A non-text attachment was scrubbed…
Name: mikmod-header-comment.diff
Type: text/x-diff
Size: 766 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110612/72a50f82/attachment-0001.diff

Yeah, okay, so here it is. This seems to work on my machine, but I’d
strongly suggest that you/whoever give it an extra look before running
it in the Reol Wyrld. See attached patch against recent Hg SDL_mixer.
Second patch is an unrelated internal cosmetic fix. No warranty.

Thanks. I will try those at the first opportunity and report back.

I did not bother to do the same work for ModPlug, for now; I imagine
it may have the same problem from a cursory glance.

Wait, there’s ModPlug support in SDL_mixer? That’s the preferred player
for MODs, AFAIK (better support and sound quality.) I’m using the
latest SDL_mixer (1.2.11). I suppose then it’s not released yet?On 06/12/2011 11:04 AM, Drake Wilson wrote:

Wait, there’s ModPlug support in SDL_mixer?? That’s the preferred player for MODs, AFAIK (better support and sound quality.)? I’m using the latest SDL_mixer (1.2.11).? I suppose then it’s not released yet?

It’s conditional. You have to build it yourself with the right #define set.? Right now Mikmod is #defined in by default and Modplug is disabled.>----- Original Message -----

From: Nikos Chantziaras
Subject: Re: [SDL] [PATCH] SDL_mixer: externalize MikMod gain control

Wait, there’s ModPlug support in SDL_mixer? That’s the preferred player for MODs, AFAIK (better support and sound quality.) I’m using the latest SDL_mixer (1.2.11). I suppose then it’s not released yet?

It’s conditional. You have to build it yourself with the right #define set. Right now Mikmod is #defined in by default and Modplug is disabled.

OK, I just checked the 1.2.11 sources. There’s no ModPlug support in
there. It’s only in the Hg repo. I was confused a bit, since the only
ModPlug-related commit seemed to be build fix, which suggested that
support was already there prior to the 1.2.11 release. But it turns out
the commit that introduces ModPlug support was titled “Jon Atkins to
Sam” :-POn 06/13/2011 02:50 AM, Mason Wheeler wrote:

----- Original Message -----
From: Nikos Chantziaras
Subject: Re: [SDL] [PATCH] SDL_mixer: externalize MikMod gain control

I tested your patch (against 1.2.11). Unfortunately, it results in the
music failing to fade-in, so the volume is too low throughout the
duration of the music.On 06/12/2011 11:04 AM, Drake Wilson wrote:

Yeah, okay, so here it is. This seems to work on my machine, but I’d
strongly suggest that you/whoever give it an extra look before running
it in the Reol Wyrld. See attached patch against recent Hg SDL_mixer.
Second patch is an unrelated internal cosmetic fix. No warranty.

I just checked this. Downloaded from Hg and built with ModPlug. The
issue does not exist.

I guess that means I’ll be bundling an Hg snapshot along with the
application.On 06/12/2011 11:04 AM, Drake Wilson wrote:

I did not bother to do the same work for ModPlug, for now; I imagine
it may have the same problem from a cursory glance.

Quoth Nikos Chantziaras , on 2011-06-13 03:05:52 +0300:

I tested your patch (against 1.2.11). Unfortunately, it results in
the music failing to fade-in, so the volume is too low throughout
the duration of the music.

Hmm, that’s interesting. By “fade-in” do you refer to the fade in the
music file that you mentioned before, or do you mean a mixer API fade?
Do you mean that the fade does not occur, or that it occurs but the
end volume is lower?

The volume will wind up being lower than before overall if you start
at a non-maximum volume and the module contains effects that switch to
the module-internal maximum volume, since previously the quieting was
being ignored. I didn’t see any good way to stay compatible there
that wouldn’t also screw up the gain mapping.

(I realize your problem seems to have already been solved elsewhere,
but I’m curious because I may also run into this in the future.)

—> Drake Wilson

Quoth Nikos Chantziaras, on 2011-06-13 03:05:52 +0300:

I tested your patch (against 1.2.11). Unfortunately, it results in
the music failing to fade-in, so the volume is too low throughout
the duration of the music.

Hmm, that’s interesting. By “fade-in” do you refer to the fade in the
music file that you mentioned before, or do you mean a mixer API fade?

The fade done by the MOD file itself. No mixer API fades are involved.
Well, actually it’s not an actual smooth fade-in, but it seems to get
louder in steps.

Do you mean that the fade does not occur, or that it occurs but the
end volume is lower?

It occurs, but the end volume is lower.

This is the file in question:

http://foss.aegean.gr/~realnc/out.modOn 06/13/2011 05:34 AM, Drake Wilson wrote:

Quoth Nikos Chantziaras , on 2011-06-13 06:10:24 +0300:

Do you mean that the fade does not occur, or that it occurs but the
end volume is lower?

It occurs, but the end volume is lower.
[…]
http://foss.aegean.gr/~realnc/out.mod

Right. That’s probably what I mentioned before, then—if you’re
using a volume of 64, the module was previously overriding you by
specifying full/unity volume (which you didn’t expect), so now you’d
be at half volume.

Opening up the module in Schism Tracker reveals that its initial
"fade" is actually switching between note volumes rather than using
the module global volume control. It does reset the global volume to
full a few times (for no obvious reason) during the intro, then leaves
it alone later on.

A second glance at ModPlug suggests that it properly separates the
module “global” volume and the user “master” volume, and it has some
other automatic gain control the workings of which are not obvious to
me. The master volume range is also wider, with a large range above
nominal unity. So that would explain your success with it. ModPlug
seems to have a much better API in general, so switching to it may be
a better long-term solution anyway.

Anyway, that’s about the limit of my time for actively investigating
this bit. Thanks for the clarification; at least it’ll be in the
list archives for later now. :slight_smile:

—> Drake Wilson

Anyway, that’s about the limit of my time for actively investigating
this bit. Thanks for the clarification; at least it’ll be in the
list archives for later now. :slight_smile:

So is everyone in agreement that the patch should go in as-is, or is
this a frequent issue? (Alternately: is it a frequent issue that we have
even without this patch?)

–ryan.

Quoth “Ryan C. Gordon” , on 2011-06-13 17:24:15 -0400:

So is everyone in agreement that the patch should go in as-is, or is
this a frequent issue? (Alternately: is it a frequent issue that we
have even without this patch?)

Well, the available options aren’t very good. The existing behavior
with MikMod can do things like have the module jump the music volume
to maximum when the user had supposedly set it lower. This seems
pretty obviously bad to me. But disentangling the controls without
doing anything fancier breaks existing volume settings; modules may
suddenly seem quieter or louder depending on whether anyone realized
the previous unusual volume punning was occurring. I see no good way
of avoiding the latter; the two parts seem mutually inextricable.

I think the patched behavior is better than before, but an argument
can be made that it would be a smoother transition to go straight to
ModPlug or such and avoid having a double change in the interpretation
of module music volume.

I’d weakly recommend applying as-is; a stronger idea of the tradeoff
would depend on roadmap and typical-use information that I don’t have.

—> Drake Wilson

Hello !

Well, the available options aren’t very good. The existing behavior
with MikMod can do things like have the module jump the music volume
to maximum when the user had supposedly set it lower. This seems
pretty obviously bad to me. But disentangling the controls without
doing anything fancier breaks existing volume settings; modules may
suddenly seem quieter or louder depending on whether anyone realized
the previous unusual volume punning was occurring. I see no good way
of avoiding the latter; the two parts seem mutually inextricable.

I think the patched behavior is better than before, but an argument
can be made that it would be a smoother transition to go straight to
ModPlug or such and avoid having a double change in the interpretation
of module music volume.

I’d weakly recommend applying as-is; a stronger idea of the tradeoff
would depend on roadmap and typical-use information that I don’t have.

Personally i think what SDL_mixer should do is to take the output stream
from MikMod and then increase or decrease the volume of that output stream,
the same for Timidity and every other sound source.

Like VLC, you can set the Output Volume to 0-400% 0% = quiet, 1-99% = decreased volume,
100% = original volume, 101% - 400% = increase volume.

Besides that, if the MOD format has that feature, that the composer can change the volume
on the fly, you have to deal with it. If you want to release a game, tell the musician either
not to use it or use it in a fixed range. As long as SDL_mixer would have something like VLC
or PulseAudio the user could change whole the volume to what he wants and still get the music effects right.

CU

At the risk of getting pleonastic…

Quoth Torsten Giebl , on 2011-06-14 11:05:53 +0200:

Personally i think what SDL_mixer should do is to take the output stream
from MikMod and then increase or decrease the volume of that output stream,
the same for Timidity and every other sound source.

… that’s what the patch does, minus the “increase” part. This is
consistent with the rest of the stream handling; there’s just no way
to make it consistent with the previous behavior for MikMod per se.

Like VLC, you can set the Output Volume to 0-400% 0% = quiet, 1-99% = decreased volume,
100% = original volume, 101% - 400% = increase volume.

Except the underlying mixing function used in SDL_mixer seems to be
SDL_MixAudio, which isn’t documented to be capable of supraunity gain
(amplification) AFAIK. You could probably feed it values higher than
128, and it might work, but I don’t think that’s in the API contract.
You’d probably want it to take output saturation into account there.

ModPlug uses what looks like a 0–400% range underneath, which amounts
to changing the base gain for module music in a different way from the
previous wonky MikMod behavior and in a different way from the
patched MikMod case. If the software mixing for both player libraries
were identical, that would amount to a +12 dB preamplification, but
separate players are not guaranteed to be so directly comparable. I
don’t know of any established reference amplitudes for module music.

None of that does much for existing users, because depending on their
music files they might already be depending on module volume punning
without knowing it. Those people may be hosed anyway.

—> Drake Wilson