GMS 2.3+ Play Sound At help

Yizzard

Member
So I'm trying to make buzz saw objects that just play a constant buzz saw sound effect that get louder the closer you are to them and quieter the farther away. Basically like the ones in Hollow Knight. I first tried to do
GML:
snd = audio_play_sound_at(buzzSound, x, y, depth, 16, 46, 1, true, .1);
audio_sound_gain(snd, global.sfxVolume, 0);
in the create event for each buzzsaw, but for some reason the sound would never update and would just constantly be loud. So I then tried
GML:
if(!audio_is_playing(snd))
{
    snd = audio_play_sound_at(sou_Explosion, x, y, depth, 16, 46, 1, false, .1);
    audio_sound_gain(snd, global.sfxVolume, 0);
}
in the step event (with snd being initialized in create) and then it worked much better but it seemed like the sound was only updating volume and such once the full 6 second buzz saw sound effect was over. It was really confusing and didn't really make sense to me, is there a way to have it constantly update?
I tried to use audio emitters as well but couldn't even get them to play any sound and I don't even know if that would help anyway.
 

kburkhart84

Firehammer Games
I'm not sure what all you have going on...but looking at the code there, it seems that you want the sound to only be heard if your listener is less than 46 units away from the sound. It may be an approximation and depends on the falloff method/formula, but that seems like a really small number to me. The units are generally pixels, since you are setting the position based on pixels. Maybe adjust that and see what happens.
 

curato

Member
I don't think you need to play with the gain the sound is at position and will be louder when you are closer. You just need to make sure you are updating the listener position with audio_listener_position
 

kburkhart84

Firehammer Games
I don't think you need to play with the gain the sound is at position and will be louder when you are closer. You just need to make sure you are updating the listener position with audio_listener_position
This is also true, I probably should have mentioned it. And the play_sound_at() function doesn't have the sound moving so if the object moves you may want to figure out the emitters as well so it can actually change position. If it doesn't move that fast before the sound is done playing it may not matter.
 

Yizzard

Member
This is also true, I probably should have mentioned it. And the play_sound_at() function doesn't have the sound moving so if the object moves you may want to figure out the emitters as well so it can actually change position. If it doesn't move that fast before the sound is done playing it may not matter.
Yeah, it doesn't move at all. And I had the units higher at first but I could hear it really far away, I can try getting rid of the gain stuff and increase it a little bit and see if that works. Thanks!
 

Yizzard

Member
Ok yeah, it seems that removing the audio gain function fixed the problem. I guess that was overriding the volume every time instead of changing the original volumes position. The problem now would be, how would I have it scale the volume with the global.sfxVolume variable? I'm trying to do a thing like
GML:
var gain = audio_sound_get_gain(snd)
audio_sound_gain(snd, global.sfxVolume * gain, 0);
but I don't know how to get it to only do this after the gain is updated from play_sound_at, because otherwise it will always converge to 0 unless sfxVolume = 1
 

curato

Member
unless the sound itself should be louder if it were in the real world I would say comment on that line and update the listener position. It will be louder where you are closer and less when you are further away.
 

kburkhart84

Firehammer Games
I'm looking back at your original code in the first post. You had it right, assuming that the saw object isn't moving. The play_sound_at() function doesn't support moving sounds. But the way you were doing it is the correct way. And if you move the listener away, it should indeed fade lower. Note that you shouldn't be modifying the gain of the sound at all(except to set the initial max volume), as the final volume should be controlled by the sound system as it calculates distance, etc...

If you want the listener to stand still and have the sound actually move, you are going to need to mess with learning to use emitters. A nice part about using emitters and doing things correctly here is that if you set the velocity values as well on the sound and/or listener, you can get doppler effects added automatically, so it sounds different moving away compared to when it is moving closer.
 

Yizzard

Member
Ok, so never mind on that last problem, I assumed it was converging to 0 instantly but really I just didn't do audio_resume_all when unpausing the game lol so the saws just never resumed from when I paused to change the sfxVolume. I have no idea what the original problem was though, I tried checking the gain variable that I showed above and it was always 1 (because it was always done right after the play_sound_at function) So I literally just went back to what I had originally and everything works now... I'm very confused.
Now the only problem is that if I change the sfxVolume in the pause menu it doesn't update the volume until the next loop of the audio. I tried to fix it by doing the audio_group_set_gain for all sound effects and for all music upon exiting the menu, but it does a really weird thing where it seems to only partially update the volume then on the next loop update it all of the way. What I mean is that if volume is set to 1 and then I open up the menu and change it to .3 let's say, it will immediately get significantly quieter but not all the way but then once the audio loops back to the beginning it will be correctly at .3. I am very confused as to why this is happening, my only idea about why this could be would be that since there are a bunch of saws, the audio_group_set_gain is only setting some of them to the correct gain, but then they all reset once they loop. No idea if that's the case or not, but it's just my guess because it sounds super weird, and it's nearly impossible to debug since I only have 7 seconds to debug each time before the audio file loops. The documentation on audio_group_set_gain doesn't say anything about a maximum number of entities, do you all happen to know if there is one and how to get around it if so? or any other ideas on what could be causing this?
Thanks so much for the help so far!
And also yeah the audio listener moves and the emitters are all stationary so that's not a problem.
 

Yizzard

Member
Ohhhhhh shoot I think I may know what's happening. I think that the audio_group_set_gain is a separate gain than the audio_set_gain, so it's actually doubling whatever change I make, so it's setting it correctly the first time then is doubling down on the difference the second time. I managed to use audio_sound_get_gain and time it to where I could go into settings right when the loop started then change the sfxVolume then exit out and check the gain. So changing from 1 to .3, even though I could audibly hear the noise quiet down, the gain was set to 1 still until it looped and then was changed to .3 and I could hear another noise drop. So I think if I just delete the audio_sound_gain and have it once upon entering a room on the asynchronous event just set the audio group and then that should theoretically work as long as everything is always going to have the same audio as the whole group, which since I'm just setting it always to the global.sfxVolume variable, that should be the case.

EDIT: Yup lol that worked. Sweet! Thank you all so much for the help!
Second EDIT: So also I figured out my original problem, it was that the audio falloff model was exponential clamped, apparently I changed it to regular exponential and it worked a lot better. Idk why the clamped was basically not updating at all, but that is what was causing it as I tried switching it back and it stopped working again. Weird
 
Last edited:
Top