I’m having an issue on Switch regarding distance attenuation. On our other platforms we are having no issues with events attenuating. Our game has an overhead camera looking at a 2D world and our engine sets the attenuation distances of every 3D event so that their volume is related to how far from the center of the screen the sound is, and in terms of screen width. This way we can make sure that, at any zoom level, certain sounds will not be audible if they are offscreen, or will be audible when a little bit offscreen (depending on what we desire). This system has worked just fine in our previous games and is still working fine on PC and XBox at the moment, but on Switch we’ve notice that sounds are not attenuating. Our game has many more one-shot sounds than persistent sounds so the effect is most noticeable on persistent audio that runs at all times.
I have been testing this issue with a waterfall in the first level of our game. No matter where I am in the level, I can hear the waterfall at what seems to be full volume. Panning is working fine still (the audio sounds as if it is coming from the correct direction), but attenuation seems to be nonexistent. Our engine is pretty straight forward regarding the frame by frame audio updates. I can see that, for the sound I’m testing with (a waterfall), we update the rolloff values of the event whenever the zoom of the camera changes via FMOD::Studio::EventInstance::setProperty(…), with the properties FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE (one call each). This is because we are forcing the sounds to attenuate based on how close they are to the edge of the screen, rather than more realistic considerations. Indeed, checking on the rolloff distances reported by fmod each frame (using getProperty with the same property ids) shows the exact values I would expect, and which were set. We also update the listener every frame with:
FMOD::System::set3DListenerAttributes
and
FMOD::Studio::System::setListenerAttributes
And the position being input is always correctly showing as the world position the camera is in.
Given that panning still works, and that this works on other platforms just fine, I’m trying to figure out what could be causing this to fail on Switch specifically. I’ve shared an image of the waterfall event as it appears in FMOD studio.
That “3D” parameter only affects the “Min Extent” on the “Spatializer_3D2D” effect. It’s a way that we allow our engine to request a 3D event be played as a 2D event without needing separate events, one with and one without the spatializer. Otherwise, the Spatializer_3D2D effect is just like any other spatializer. Again, all of this works just fine on PC and Xbox.
The only other things to note are that, when an EventInstance is created, the EventInstance has its rolloff distances set via the exact same calculation used when updating that EventInstance after a zoom change in the frame by frame update (and by calling on setProperty as noted above). This is just to initialize the rolloff values. And also, after an event is created, and we get the callback FMOD_STUDIO_EVENT_CALLBACK_CREATED, we update the ChannelGroup of the EventInstance as follows (this is C++):
Note that “pos” is just the position that was set on the EventInstance when it was created, and corresponds to the location of the EventInstance in the game’s world coordinates. “vel” is always the zero vector (we don’t bother with doppler effects for our game). You can see that when “pos” is the zero vector we just set the “3D” parameter I mentioned earlier to 0.0, corresponding to it having its panning removed. That section isn’t relevant for the 3D audio at issue here.
This is probably the section I’m least comfortable with. It’s unclear to me why the ChannelGroup had to be set up with Min and Max distances and 3D attributes (I figured that the default settings would have allowed the events themselves to control their own panning). This was done simply because it works on our other platforms. It’s particularly confusing to me because I thought that the ChannelGroup was responsible for, potentially, multiple events. This makes it seem like I shouldn’t be setting properties on the ChannelGroup of an EventInstance based on that instance alone. Once again, since this all works on our other platforms, I’m not sure why this would fail on Switch.
Any insights would be much appreciated. I’m at a loss as to what might be failing here.
Cheers,
Mike