Skip to content
This repository was archived by the owner on Jun 28, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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*
* Added doppler factor as a CVar.

### Bugfixes

Expand Down
30 changes: 24 additions & 6 deletions Robust.Client/Audio/AudioManager.Public.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.IO;
using System.Numerics;
using System.Threading;
using JetBrains.Annotations;
using OpenTK.Audio.OpenAL;
using Robust.Shared;
using Robust.Client.Audio.Sources;
using Robust.Client.Graphics;
using Robust.Shared.Audio;
Expand All @@ -16,6 +18,12 @@ internal partial class AudioManager
{
private float _zOffset;

/// <inheritdoc />
public float MasterGain { get; private set; }

/// <inheritdoc />
public float DopplerFactor { get; private set; } = 1f;

public void SetZOffset(float offset)
{
_zOffset = offset;
Expand Down Expand Up @@ -229,13 +237,11 @@ public AudioStream LoadAudioRaw(ReadOnlySpan<short> samples, int channels, int s

public void SetMasterGain(float newGain)
{
if (newGain < 0f)
{
OpenALSawmill.Error("Tried to set master gain below 0, clamping to 0");
AL.Listener(ALListenerf.Gain, 0f);
return;
}
if (!float.IsFinite(newGain))
newGain = 0f;

newGain = MathF.Max(newGain, 0f);
MasterGain = newGain;

#region Platform hack for MacOS
// HACK/BUG: Apple's OpenAL implementation has a bug where values of 0f for listener gain don't actually
Expand All @@ -251,6 +257,18 @@ public void SetMasterGain(float newGain)
AL.Listener(ALListenerf.Gain, newGain);
}

private void SetDopplerFactor(float value)
{
if (!float.IsFinite(value))
value = 0f;

value = MathF.Max(value, 0f);

DopplerFactor = value;
AL.DopplerFactor(value);
_checkAlError();
}

public void SetAttenuation(Attenuation attenuation)
{
switch (attenuation)
Expand Down
1 change: 1 addition & 0 deletions Robust.Client/Audio/AudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ private void InitializeAudio()
IsEfxSupported = HasAlDeviceExtension("ALC_EXT_EFX");

_cfg.OnValueChanged(CVars.AudioMasterVolume, SetMasterGain, true);
_cfg.OnValueChanged(CVars.AudioDopplerFactor, SetDopplerFactor, true);

_reload.Register("/Audio", "*.ogg");
_reload.Register("/Audio", "*.wav");
Expand Down
47 changes: 46 additions & 1 deletion Robust.Client/Audio/HeadlessAudioManager.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.IO;
using System.Numerics;
using Robust.Shared;
using Robust.Shared.Audio;
using Robust.Shared.Audio.AudioLoading;
using Robust.Shared.Configuration;
using Robust.Shared.IoC;
using Robust.Shared.Audio.Sources;
using Robust.Shared.Maths;

Expand All @@ -11,13 +14,51 @@ namespace Robust.Client.Audio;
/// <summary>
/// Headless client audio.
/// </summary>
internal sealed class HeadlessAudioManager : IAudioInternal
internal sealed partial class HeadlessAudioManager : IAudioInternal
{
[Dependency] private IConfigurationManager _cfg = default!;

private int _audioBuffer;
private float _masterGain;
private float _dopplerFactor = 1f;

/// <inheritdoc />
public float MasterGain => _masterGain;

/// <inheritdoc />
public float DopplerFactor
{
get => _dopplerFactor;
set => SetDopplerFactor(value, true);
}

/// <inheritdoc />
public void InitializePostWindowing()
{
_cfg.OnValueChanged(CVars.AudioDopplerFactor, SetDopplerFactorFromCVar, true);
}

private void SetDopplerFactorFromCVar(float value)
{
SetDopplerFactor(value, false);
}

private void SetDopplerFactor(float value, bool updateCVar)
{
var original = _dopplerFactor;

if (!float.IsFinite(value))
value = 0f;

value = MathF.Max(value, 0f);

if (MathHelper.CloseTo(original, value))
return;

if (updateCVar)
_cfg.SetCVar(CVars.AudioDopplerFactor, value, true);

_dopplerFactor = value;
}

/// <inheritdoc />
Expand Down Expand Up @@ -60,6 +101,10 @@ public void SetRotation(Angle angle)
/// <inheritdoc />
public void SetMasterGain(float newGain)
{
if (!float.IsFinite(newGain))
newGain = 0f;

_masterGain = MathF.Max(newGain, 0f);
}

/// <inheritdoc />
Expand Down
10 changes: 10 additions & 0 deletions Robust.Client/Audio/IAudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ namespace Robust.Client.Audio;
[NotContentImplementable]
public interface IAudioManager
{
/// <summary>
/// OpenAL master gain for audio.
/// </summary>
float MasterGain { get; }

/// <summary>
/// OpenAL Doppler factor for audio.
/// </summary>
float DopplerFactor { get; }

IAudioSource? CreateAudioSource(AudioStream stream);

AudioStream LoadAudioOggVorbis(Stream stream, string? name = null);
Expand Down
6 changes: 6 additions & 0 deletions Robust.Shared/CVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,12 @@ protected CVars()
public static readonly CVarDef<float> AudioMasterVolume =
CVarDef.Create("audio.mastervolume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);

/// <summary>
/// OpenAL doppler factor for positional audio.
/// </summary>
public static readonly CVarDef<float> AudioDopplerFactor =
CVarDef.Create("audio.doppler_factor", 1f, CVar.SERVER | CVar.REPLICATED);
Comment on lines +1306 to +1307

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth making this a SERVER CVar? With master gain, RMC had to do some workarounds to make a deafness effect work since it's set in many places
Granted I don't really see an usecase in setting this in code or per-client, but still

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can make it client and add a setter.


/// <summary>
/// Maximum raycast distance for audio occlusion.
/// </summary>
Expand Down
Loading