GMS 2 Having a weird issue with audio gain

I'll try to describe this as simply as possibly because there are a lot of moving parts. I want to control music and sound at separate volumes in my game, and I use a global variable and script to do that, vol_music and vol_sound. Every time I call a sound, I run the script scr_sound(snd_example); which runs this:

GML:
sound = argument0;

var playsound = audio_play_sound(sound, 1, false);
audio_sound_gain(playsound, vol_sound, 0);
Same thing for music. Pretty simple.

Anyways I'm working on my menu where you can adjust the music/sound volume levels, and I've noticed a weird thing that's tough to describe. The sound is adjusting, but not adjusting by the amount I want. Here's the code I'm running when you hit the button to adjust it up one notch (out of ten):

GML:
vol_music += 0.1;
vol_music = clamp(vol_music, 0, 1);

if (audio_is_playing(snd_mus_title_1))
{
    audio_sound_gain(snd_mus_title_1, vol_music, 0);
}
The goal of this is to change that global variable, vol_music, by 1/10th of its max value, and then set the gain for the menu background music to that new volume level as an indicator to the player of how loud the music is. Like I said though, if I run the game at, say, 0.2 starting vol_music (so 2/10s of its max volume), and then I go into adjust it 1 notch to the right, it adjusts the volume and actually makes it quieter than it was before. Then it builds up from there. If I max it out at this point it's not as loud as it would be if I played the sound fresh at vol_music = 1. So what seems to be happening to me is audio_sound_gain is only adjusting it to a fraction of whatever it was already playing at.

I did a test using a debug message for vol_music and audio_sound_get_gain for the background music. vol_music traced correctly at 0.2 (or whatever I set it to in the init), but audio_sound_get_gain for the music file playing traced itself as 1. I know for a fact it's not playing at full volume, so what is the deal here? When I run the music with that script, and the script immediately sets the gain, shouldn't I be able to accurately trace that?

I know this is a lot and probably no one knows what I'm talking about, but I'm just scratching my head at this point. Any help is greatly appreciated.
 

rytan451

Member
For debugging purposes, perhaps add the following line of code to check your vol_music is the value you expect it.

GML:
show_debug_message("ALERT: vol_music is " + string(vol_music));
Then make sure the values are as expected. If the value of vol_music is still as expected, perhaps add a debug log for what vol_music was before being changed.
 
For debugging purposes, perhaps add the following line of code to check your vol_music is the value you expect it.

GML:
show_debug_message("ALERT: vol_music is " + string(vol_music));
Then make sure the values are as expected. If the value of vol_music is still as expected, perhaps add a debug log for what vol_music was before being changed.
Thanks for the suggestion! I have a couple debugs running, one of which is vol_music. If I init the game with this variable at 0.2, it traces 0.2 until I adjust it in the menu, in which case it clicks right over to 0.3. What's odd is that, as you can see in that first script I posted, the song should be playing at whatever vol_music is set to. However if I trace the gain it says, "1." The song is definitely playing quieter than if I init vol_music at 1, so it appears to be executing the script properly.
 

rytan451

Member
Have you checked the value of vol_sound using show_debug_message in the first script? There might be a scoping problem going on, causing vol_sound to not be your expected value.
 
Have you checked the value of vol_sound using show_debug_message in the first script? There might be a scoping problem going on, causing vol_sound to not be your expected value.
Sry for the late reply, had to deal with some other things.

I think you're right that it's a scoping issue, though I'm not sure quite why. Like I said I run a script to play all (looped) music that is just this:
GML:
music = argument0;

var playmusic = audio_play_sound(music, 1, true);
audio_sound_gain(playmusic, vol_music, 0);
I recorded a little video of what happens if I run this code, with text on the top left showing the vol_music global variable as well as the 'gain' of the music currently playing. As you can see, they don't match, and when I go to adjust the volume, it does so incorrectly.

With this in mind, I decided to forego the script and just trigger the audio to play with my menu object, and get rid of that local variable. So instead of calling scr_music_loop(snd_mus_title_1);, I write this:
Code:
audio_play_sound(snd_mus_title_1, 1, false);
audio_sound_gain(snd_mus_title_1, vol_music, 0);
This seems to work. You'll notice when I load up the menu, vol_music is 0.2, and the gain of the track playing is 0.2. And when I adjust the volume, it does so correctly.

I suppose I could consider this fixed? I don't really see an issue with calling the sound locally in this one instance. I have a pause menu with a similar volume adjust, but I plan to do it a little differently anyways. I'll post here if as I progress I come across any other issues as it's all cataloged. Thanks for the help.
 

Roldy

Member
You keep saying 'global variable' but none of your code uses global variables, only instance variables and local as far as I can see.
 

woods

Member
dont you need to declare/reference that global like this?

vol_music //instance variable?
vs
global.vol_music //global variable?
 

Roldy

Member
Last edited:
Hi. Here is the documentation on variables and scope. https://docs2.yoyogames.com/source/_build/3_scripting/3_gml_overview/6_scope.html

Make sure you are familiar with it.

Unless you are using the deprecated globalvar declaration, then the variables in your code are either local or instance variables. If you are using globalvar, stop, and instead use 'global.' syntax.
I wasn't aware it had been deprecated. I am using globalvar. I will look into updating all of them to use global.
 
Top