Skip to content

Commit

Permalink
Clamp audio tickrate (#5296)
Browse files Browse the repository at this point in the history
* Clamp audio tickrate

I am reasonably sure I saw a recommended 30TPS figure somewhere but I cannot find it again. At any rate I can't notice this but imagine it provides significant benefits for people on 144hz+ monitors.

* rn

---------

Co-authored-by: Pieter-Jan Briers <[email protected]>
  • Loading branch information
metalgearsloth and PJB3005 authored Jul 13, 2024
1 parent 4920eca commit f696eda
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
2 changes: 1 addition & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ END TEMPLATE-->

### New features

*None yet*
* Audio ticks-per-second is now capped at 30 by default and controlled via `audio.tick_rate` cvar.

### Bugfixes

Expand Down
24 changes: 17 additions & 7 deletions Robust.Client/Audio/AudioSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public sealed partial class AudioSystem : SharedAudioSystem
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IParallelManager _parMan = default!;
[Dependency] private readonly IRuntimeLog _runtimeLog = default!;
[Dependency] private readonly IAudioInternal _audio = default!;
Expand All @@ -49,9 +48,10 @@ public sealed partial class AudioSystem : SharedAudioSystem
/// Per-tick cache of relevant streams.
/// </summary>
private readonly List<(EntityUid Entity, AudioComponent Component, TransformComponent Xform)> _streams = new();
private EntityUid? _listenerGrid;
private UpdateAudioJob _updateAudioJob;

private float _audioFrameTime;
private float _audioFrameTimeRemaining;

private EntityQuery<PhysicsComponent> _physicsQuery;

Expand Down Expand Up @@ -110,9 +110,16 @@ public override void Initialize()

Subs.CVar(CfgManager, CVars.AudioAttenuation, OnAudioAttenuation, true);
Subs.CVar(CfgManager, CVars.AudioRaycastLength, OnRaycastLengthChanged, true);
Subs.CVar(CfgManager, CVars.AudioTickRate, OnAudioTickRate, true);
InitializeLimit();
}

private void OnAudioTickRate(int obj)
{
_audioFrameTime = 1f / obj;
_audioFrameTimeRemaining = MathF.Min(_audioFrameTimeRemaining, _audioFrameTime);
}

private void OnAudioState(EntityUid uid, AudioComponent component, ref AfterAutoHandleStateEvent args)
{
ApplyAudioParams(component.Params, component);
Expand Down Expand Up @@ -254,6 +261,13 @@ private void OnRaycastLengthChanged(float value)

public override void FrameUpdate(float frameTime)
{
_audioFrameTimeRemaining -= frameTime;

if (_audioFrameTimeRemaining > 0f)
return;

// Clamp to 0 in case we have a really long frame.
_audioFrameTimeRemaining = MathF.Max(0f, _audioFrameTime + _audioFrameTimeRemaining);
var eye = _eyeManager.CurrentEye;
var localEntity = _playerManager.LocalEntity;
Vector2 listenerVelocity;
Expand All @@ -277,9 +291,6 @@ public override void FrameUpdate(float frameTime)
_streams.Add((uid, comp, xform));
}

_mapManager.TryFindGridAt(ourPos, out var gridUid, out _);
_listenerGrid = gridUid == EntityUid.Invalid ? null : gridUid;

try
{
_updateAudioJob.OurPosition = ourPos;
Expand Down Expand Up @@ -332,7 +343,6 @@ private void ProcessStream(EntityUid entity, AudioComponent component, Transform

Vector2 worldPos;
component.Volume = component.Params.Volume;
Vector2 delta;

// Handle grid audio differently by using grid position.
if ((component.Flags & AudioFlags.GridAudio) != 0x0)
Expand All @@ -346,7 +356,7 @@ private void ProcessStream(EntityUid entity, AudioComponent component, Transform
}

// Max distance check
delta = worldPos - listener.Position;
var delta = worldPos - listener.Position;
var distance = delta.Length();

// Out of range so just clip it for us.
Expand Down
7 changes: 7 additions & 0 deletions Robust.Shared/CVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,13 @@ protected CVars()
public static readonly CVarDef<float> AudioRaycastLength =
CVarDef.Create("audio.raycast_length", SharedAudioSystem.DefaultSoundRange, CVar.ARCHIVE | CVar.CLIENTONLY);

/// <summary>
/// Tickrate for audio calculations.
/// OpenAL recommends 30TPS. This is to avoid running raycasts every frame especially for high-refresh rate monitors.
/// </summary>
public static readonly CVarDef<int> AudioTickRate =
CVarDef.Create("audio.tick_rate", 30, CVar.CLIENTONLY);

public static readonly CVarDef<float> AudioZOffset =
CVarDef.Create("audio.z_offset", -5f, CVar.REPLICATED);

Expand Down

0 comments on commit f696eda

Please sign in to comment.