How to smoothly fade audio without any pops? Source.volume is correct, but the sound itself seems to update inconsistently

I am smoothly fading a number (~15) of Audio Sources at the same time, by modifying the Audio Source’s volume property.

Source.volume is the correct value, and smoothly interpolates between 1.0f and 0.0f. The fades are generally 0.5 to 5.0 seconds.

Unfortunately, when you listen to the game the audio seems to pop. Specifically, the actual sound doesn’t seem to update in realtime, instead only updating at specific points.

Volume: 0.1, 0.15, 0.2, 0.25, 0.3, 0.35…
Playback: 0…0.3 …

The result is an ugly pop in the audio, and reduces my smooth fade to 2, possibly 3 increments. Time seems to affect it, but even if I fade over 5 to 10 seconds, it still pops noticeably. Frame Rate is quite solid (60+) so its not that we are dropping frames.

I’ve tried anything I can think of (making sure the listener position changes, changing the sound priority, changing the update velocity type, etc). I’ve also tried a few hack solutions, such as stopping and starting the audio each frame.

If I call source.Stop() and source.Play(), I can get the volume to fade / update correctly, but the framerate drops down to single digits. I can also have the fade correct (with an abysmal framerate drop) if I modify source’s time parameter, forcing an updating by changing its position by 0.000001 seconds or so.

Is this an issue with the low level audio playback, or is there any workaround? Is there any way to use multiple listeners or setup some sort of channel system where I can fade a channel instead of fading a set of sources? Is this related to the fact that they are 3d sounds?

Thanks!

Can you post your code?

We get the same behavior for both in Editor, built Standalone, built WebPlayer - on a variety of computers through the office.

This is the first time we’ve really used 3d sounds in Unity, or needed to blend more than a music track - previously most of our content was 2d sounds.

It really looks like the audio is updated in 1/4 - 1/2 second increments, instead of per frame. If we insert a Stop()/Play()[from time] to force it to update per frame, we do get the behavior we want… at 5 fps on a very high end computer. This further implies the fade logic is correct though.

Note that we get the same behavior if we just decrement a float timer in Update() and don’t use the coroutine. We also get the same behavior if we use WaitForEndOfFrame, do the timer method during FixedUpdate.

IEnumerator FadeVolume()
{
	float timer = _interpTime;
	while(timer > 0.0f)
	{
		timer -= Time.deltaTime;
		if(timer < 0.0f)
		{
			timer = 0.0f;
		}
		float alpha = timer / _interpTime;
		UpdateAudioVolume(alpha);
		yield return 0;
	}
}

void UpdateAudioVolume(float alpha)
{
	// In the current scene, there are approximately 30 audio sources, 
	// 5 in range of the listener in our general test case
	for(int i = 0; i < _audioSourceList.Length; i++)
	{
		float target = Mathf.Lerp(_targetVolume, _oldTargetVolume, alpha);
		_audioSourceList<em>.volume = _cacheVolumeList <em>* target  masterVolumeScale;</em></em>
	}
}

Hey, This happens because you are stopping the sound from being heard when it hits 0.0 on the volume scale. That little noise your hearing is the next sound of the track trying to play but the volume is so low you can’t hear it with your ears since our pitch can only understand certain DB’s of sound.

make your cut off point even 0.2f and subtract your fade more slowly to compensate for the shorter minimum. In unity it’s working correctly Unity is doing what it is supposed to do here ^^

it just trying to play sound at a weird alpha like 0.0002f for example and you can’t obviously hear that note so it plays a weird sound to you. instead cut it off at a volume that makes sense to humans ears say if timer <= 0.2f then stop and just slow down how long it takes to fade with the timer itself.

There is no problem here on anyone’s part not yours or Unity. When doing fades in Unity for audio or otherwise try to make your own end point as well as the start point to give you better control over it. Fades can be really cool and sound really magnificent the more time you spend with it ^^ hope this answered your problem have a lovely day.

A little tip, Never fade a song that is already playing, If you do an ienumorator to wait for cliplength while track is playing you can time how long the clip is and start to fade it when it nears the end of the track being played, This will line up effectively with the song ending, Creating a professional and awesome sound to the ears of fading.

i also apologise for my post, I get a little passionate about stuff and tend to go on and on sorry lol