mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-22 05:09:37 -05:00
- Auto-cleanup idle voice handles: Voice sound handles are now killed when player hasn't been talking for a while - Audio Occlusion refactor: Moved occlusion calculation to a dedicated SoundOcclusionSystem GameObjectSystem for better organization - This now performs really well, so we could look into improving our occlusion calculation: proper damping when sound is transferred via wall, path tracing for occlusion etc. (will open a separate issue) - Fix mixer early return bug: Fixed issue where mixer could return early, potentially skipping sounds - Voice Component lipsync toggle: Added option to enable/disable lipsync processing on VoiceComponent - Cheaper HRTF for voice audio: Disabled expensive bilinear interpolation for voice and certain other sounds in Steam Audio - Editor MixerDetail perf: Skip frame updates on MixerDetail widget when not visible - Reduced allocations in audio systems: Optimized away List and LINQ allocations in SoundOcclusionSystem, Listener, and SoundHandle.Source - MP3 decoder buffer optimization: Improved buffer handling in native CAudioMixerWaveMP3 to reduce overhead Depending on scenario can reduces audio frame time by up to 30%. This should also drastically improve performance for games that use VOIP.
102 lines
2.0 KiB
C#
102 lines
2.0 KiB
C#
using Sandbox.Audio;
|
|
|
|
namespace Sandbox;
|
|
|
|
partial class SoundHandle
|
|
{
|
|
private SteamAudioSource _audioSource;
|
|
private Dictionary<Listener, SteamAudioSource> _audioSources;
|
|
|
|
internal SteamAudioSource GetSource( Listener listener )
|
|
{
|
|
// Find listener source
|
|
if ( _audioSources?.TryGetValue( listener, out var source ) == true )
|
|
{
|
|
return source;
|
|
}
|
|
|
|
// Local audio source
|
|
return _audioSource;
|
|
}
|
|
|
|
private void UpdateSources()
|
|
{
|
|
// Only need a single audio source if listen local
|
|
if ( ListenLocal )
|
|
{
|
|
_audioSource ??= new SteamAudioSource();
|
|
_audioSource.UpdateFrom( this );
|
|
|
|
// Dispose listener sources if there's any
|
|
if ( _audioSources is not null )
|
|
{
|
|
foreach ( var source in _audioSources.Values )
|
|
{
|
|
source.Dispose();
|
|
}
|
|
|
|
_audioSources.Clear();
|
|
_audioSources = default;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Dispose local audio source if we're not listen local
|
|
if ( _audioSource is not null )
|
|
{
|
|
_audioSource?.Dispose();
|
|
_audioSource = null;
|
|
}
|
|
|
|
// Remove stale sources - only if we have any
|
|
if ( _audioSources is { Count: > 0 } )
|
|
{
|
|
foreach ( var removed in Listener.RemovedList )
|
|
{
|
|
if ( _audioSources.Remove( removed, out var source ) )
|
|
{
|
|
source.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Find listeners of this scene and update sources
|
|
var scene = Scene;
|
|
|
|
foreach ( var listener in Listener.ActiveList )
|
|
{
|
|
if ( listener.Scene != scene ) continue;
|
|
|
|
_audioSources ??= new();
|
|
|
|
if ( !_audioSources.TryGetValue( listener, out var source ) )
|
|
{
|
|
source = new SteamAudioSource();
|
|
_audioSources[listener] = source;
|
|
}
|
|
|
|
source.UpdateFrom( this, scene?.PhysicsWorld, listener.Position );
|
|
}
|
|
}
|
|
|
|
private void DisposeSources()
|
|
{
|
|
// Dispose local source
|
|
MainThread.QueueDispose( _audioSource );
|
|
_audioSource = default;
|
|
|
|
// Dispose listener sources if there's any
|
|
if ( _audioSources is not null )
|
|
{
|
|
foreach ( var source in _audioSources.Values )
|
|
{
|
|
MainThread.QueueDispose( source );
|
|
}
|
|
|
|
_audioSources.Clear();
|
|
_audioSources = default;
|
|
}
|
|
}
|
|
}
|