Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Make mono and stereo sounds play at the same volume #411

Open
garethyr opened this issue Feb 14, 2022 · 0 comments
Open

Make mono and stereo sounds play at the same volume #411

garethyr opened this issue Feb 14, 2022 · 0 comments
Labels
enhancement New feature or request refactor Code needs to be refactored

Comments

@garethyr
Copy link

Right now fmod plays stereo sounds louder than mono ones. Explanation for why (thanks Bhijn):

its a side effect of how fmod handles multichannel audio sources in 3d space, yep; the 2d audio plays normally, with channels playing exclusively for their respective speakers, but the positional audio part of the mix ends up treating the channels as separate audio sources. this results in stereo audio effectively ending up with 1.5x of the original volume! this also applies to surround audio, which would effectively end up with 2.5x of the original volume (ouch)
pretty sure there's a way to fix that, buried somewhere in fmod's docs! will likely do some digging myself tomorrow if i remember to

The way to fix it is as follows (again, thanks Bhijn):

update: did some digging! to give details, the way to calculate the approximate volume of a given 3d sound is along the lines of: ([number of channels in the sample] * [3DLevel]) + (1 - [3DLevel]).
3DLevel gets set on a per-sound basis throughout audioman, which the current codebase sets to 0.5 by default! admittedly, i'm unsure of where exactly it'd be appropriate to put in checks for how many channels a given sample has (havent touched anything c++ related in quite a while, so the audio code is a bit esoteric to me), but the function to do that is a part of FMOD::Sound, getFormat()
once fetching channel info is figured out, making multichannel audio be normalized ingame would be fairly simple; as part of sound attenuation (AudioMan::UpdatePositionalEffectsForSoundChannel()), simply divide the total volume by the above approximate volume calc, and in theory, multichannel audio should have playback volume that most people would expect
fmod unfortunately doesn't have any easy function to fix this as i originally thought. but! the workaround is fairly simple on paper


This is some quick code to make the change and prove it works. Place in audioman PlaySoundContainer, right after UpdatePositionalEffectsForSoundChannel is called, and comment out the update call to UpdatePositionalEffectsForSoundChannel:

				int numChannels = 0;
				soundData->SoundObject->getFormat(nullptr, nullptr, &numChannels, nullptr);
				if (numChannels > 1) {
					float volume = 0;
					channel->getVolume(&volume);
					channel->setVolume(volume / (static_cast<float>(numChannels) * m_SoundPanningEffectStrength + (1 - m_SoundPanningEffectStrength)));
					channel->getVolume(&volume);
					bool b = true;
				}

To do this properly, this needs to work in UpdatePositionalEffectsForSoundChannel. My thinking is that the number of channels should be part of sound data, so it's only collected when the sound is added (rather than each time it's played), but it may need to be stored as userdata as well in order to be easily accessed during UpdatePositionalEffectsForSoundChannel.

@garethyr garethyr added enhancement New feature or request refactor Code needs to be refactored labels Feb 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request refactor Code needs to be refactored
Projects
None yet
Development

No branches or pull requests

1 participant