ValveSoftware / steam-audio

Steam Audio
https://valvesoftware.github.io/steam-audio/
Apache License 2.0
2.2k stars 152 forks source link

Attenuation Incorrect for Multiple Audio Sources #336

Closed dkotd closed 2 months ago

dkotd commented 3 months ago

System Information

Issue Description I have two audio sources in simulation mode. Each audio source has one-channel. I combined these two audio sources into a mono audio buffer using iplAudioBufferMix(). I can hear both audio sources in the mixed output buffer. However, the attenuation doesn't behave correctly. When I move one of the audio sources away from the listener, it affects the attenuation of both audio sources. When I try moving the other audio source, it barely changes the attenuation at all.

The mixed buffer don't sound correct, but the distance attenuation values in the simulation outputs appear to be correct because I see their values being reflected accordingly to me moving the audio sources. Also, the attenuation sounds fine when I only have one audio source. I think mixing multiple buffers is causing an issue with the attenuation.

IPLSimulationOutputs outputs {};
iplSourceGetOutputs(sources[i], IPL_SIMULATIONFLAGS_DIRECT, &outputs);
outputs.direct.distanceAttenuation; // This value looks correct

Is there a specific flag I need to enable to have the attenuation behave correctly for multiple audio sources? Or is there a proper way of calling iplAudioBufferMix()? Not 100% sure if this is a bug in the SDK with iplAudioBufferMix(). Thank you for your help.

Xottab-DUTY commented 2 months ago

You need to apply direct effect separately to each audio source and only then mix them into one buffer. That means you need a buffer for each sound source. Is that what you are doing?

You can't fry the onion separately from the salad if it's already in the salad. The whole salad will be fried.

dkotd commented 2 months ago

Hi @Xottab-DUTY

Yes, I am applying direct effect to each audio source and I have a buffer for each audio source as well. I can hear both audio sources in the mixed buffer but the attenuation doesn't reflect the audio sources correctly.

dkotd commented 2 months ago

I have discovered that the mixing is the not problem. The call to iplDirectEffectApply is what's causing the issue.

I have 2 sources. One source has a constant amplitude of 0.1 with distance attenuation 1.0. Another source has a constant amplitude of 0 with distance attenuation 0.0577. When I apply direct effect on the two sources sequentially, the output buffer's amplitude for the first source is not 0.5, it's 0.0376. However, the output buffer for the second source seems to be correct with a constant amplitude of 0. I am not sure why calling iplDirectEffectApply for the second source is affecting the output of the first source.

achandak commented 2 months ago

@dkotd - Are you creating one direct effect per source? One direct effect per source is the correct approach.

Direct Effect internally has a state, so usually when a parameter changes between different calls to iplDirectEffectApply, it is interpolated across a few audio frames for a smooth audio output. Feel free to share code snippets or a reproable example if the above suggestion does not resolve the issue.

Here for example is GainEffect which is used when applying changes to distance attenuation.

dkotd commented 2 months ago

Hi @achandak

No, I had one direct effect used between multiple sources. I did not know about the internal state and interpolation. Thank you so much. I'll give it a try.

Does this also mean that I should have a binaural effect, panning effect, etc. per source as well? Do they also have internal states?

achandak commented 2 months ago

Yup.

For example - in our Unity integration, spatialize_effect.cpp, which is a per Audio Source effect in Unity, has one of those effects per source.

dkotd commented 2 months ago

Ah yes, one direct effect per source fixed my issue. Thank you so much! I'll make the same changes for my other effects.