Files
wwdpublic/Content.Client/Audio/ContentAudioSystem.cs
SimpleStation14 f14800abe5 Mirror: fix: ambient music fade in (#25874) (#137)
## Mirror of PR #25969: [fix: ambient music fade in
(#25874)](https://github.com/space-wizards/space-station-14/pull/25969)
from <img src="https://avatars.githubusercontent.com/u/10567778?v=4"
alt="space-wizards" width="22"/>
[space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14)

###### `e47f84568eec53efd66fca6e79d8c594a508cf3c`

PR opened by <img
src="https://avatars.githubusercontent.com/u/82627200?v=4"
width="16"/><a href="https://github.com/Kokoc9n"> Kokoc9n</a> at
2024-03-10 16:26:28 UTC
PR merged by <img
src="https://avatars.githubusercontent.com/u/19864447?v=4"
width="16"/><a href="https://github.com/web-flow"> web-flow</a> at
2024-03-10 17:08:05 UTC

---

PR changed 1 files with 3 additions and 3 deletions.

The PR had the following labels:


---

<details open="true"><summary><h1>Original Body</h1></summary>

> <!-- Please read these guidelines before opening your PR:
https://docs.spacestation14.io/en/getting-started/pr-guideline -->
> <!-- The text between the arrows are comments - they will not be
visible on your PR. -->
> 
> ## About the PR
> <!-- What did you change in this PR? -->
> Ambient music  volume now set to ambient music volume slider.
> ## Why / Balance
> <!-- Why was it changed? Link any discussions or issues here. Please
discuss how this would affect game balance. -->
> Space ambience tracks being super loud #25874.
> ## Technical details
> <!-- If this is a code change, summarize at high level how your new
code works. This makes it easier to review. -->
> FadeIn and UpdateFades now get correct values instead of blasting
music on maximum volume.
> ## Media
> <!-- 
> PRs which make ingame changes (adding clothing, items, new features,
etc) are required to have media attached that showcase the changes.
> Small fixes/refactors are exempt.
> Any media may be used in SS14 progress reports, with clear credit
given.
> 
> If you're unsure whether your PR will require media, ask a maintainer.
> 
> Check the box below to confirm that you have in fact seen this (put an
X in the brackets, like [X]):
> -->
> 
> - [X] I have added screenshots/videos to this PR showcasing its
changes ingame, **or** this PR does not require an ingame showcase
> Before:
>
https://github.com/space-wizards/space-station-14/assets/82627200/8a2ab0c5-d3ae-4cb5-85d8-97703ecdb52a
> After:
>
https://github.com/space-wizards/space-station-14/assets/82627200/2b364261-b267-4bad-ab3e-10d389df6eb4


</details>

Co-authored-by: Gregg <82627200+Kokoc9n@users.noreply.github.com>
2024-05-04 19:43:30 -04:00

178 lines
5.2 KiB
C#

using Content.Shared.Audio;
using Content.Shared.GameTicking;
using AudioComponent = Robust.Shared.Audio.Components.AudioComponent;
namespace Content.Client.Audio;
public sealed partial class ContentAudioSystem : SharedContentAudioSystem
{
// Need how much volume to change per tick and just remove it when it drops below "0"
private readonly Dictionary<EntityUid, float> _fadingOut = new();
// Need volume change per tick + target volume.
private readonly Dictionary<EntityUid, (float VolumeChange, float TargetVolume)> _fadingIn = new();
private readonly List<EntityUid> _fadeToRemove = new();
private const float MinVolume = -32f;
private const float DefaultDuration = 2f;
/*
* Gain multipliers for specific audio sliders.
* The float value will get multiplied by this when setting
* i.e. a gain of 0.5f x 3 will equal 1.5f which is supported in OpenAL.
*/
public const float MasterVolumeMultiplier = 3f;
public const float MidiVolumeMultiplier = 0.25f;
public const float AmbienceMultiplier = 3f;
public const float AmbientMusicMultiplier = 3f;
public const float LobbyMultiplier = 3f;
public const float InterfaceMultiplier = 2f;
public override void Initialize()
{
base.Initialize();
UpdatesOutsidePrediction = true;
InitializeAmbientMusic();
InitializeLobbyMusic();
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
}
private void OnRoundCleanup(RoundRestartCleanupEvent ev)
{
_fadingOut.Clear();
// Preserve lobby music but everything else should get dumped.
var lobbyMusic = _lobbySoundtrackInfo?.MusicStreamEntityUid;
TryComp(lobbyMusic, out AudioComponent? lobbyMusicComp);
var oldMusicGain = lobbyMusicComp?.Gain;
var restartAudio = _lobbyRoundRestartAudioStream;
TryComp(restartAudio, out AudioComponent? restartComp);
var oldAudioGain = restartComp?.Gain;
SilenceAudio();
if (oldMusicGain != null)
{
Audio.SetGain(lobbyMusic, oldMusicGain.Value, lobbyMusicComp);
}
if (oldAudioGain != null)
{
Audio.SetGain(restartAudio, oldAudioGain.Value, restartComp);
}
PlayRestartSound(ev);
}
public override void Shutdown()
{
base.Shutdown();
ShutdownAmbientMusic();
ShutdownLobbyMusic();
}
public override void Update(float frameTime)
{
base.Update(frameTime);
if (!_timing.IsFirstTimePredicted)
return;
UpdateAmbientMusic();
UpdateLobbyMusic();
UpdateFades(frameTime);
}
#region Fades
public void FadeOut(EntityUid? stream, AudioComponent? component = null, float duration = DefaultDuration)
{
if (stream == null || duration <= 0f || !Resolve(stream.Value, ref component))
return;
// Just in case
// TODO: Maybe handle the removals by making it seamless?
_fadingIn.Remove(stream.Value);
var diff = component.Volume - MinVolume;
_fadingOut.Add(stream.Value, diff / duration);
}
public void FadeIn(EntityUid? stream, AudioComponent? component = null, float duration = DefaultDuration)
{
if (stream == null || duration <= 0f || !Resolve(stream.Value, ref component) || component.Volume < MinVolume)
return;
_fadingOut.Remove(stream.Value);
var curVolume = component.Volume;
var change = (MinVolume - curVolume) / duration;
_fadingIn.Add(stream.Value, (change, component.Volume));
component.Volume = MinVolume;
}
private void UpdateFades(float frameTime)
{
_fadeToRemove.Clear();
foreach (var (stream, change) in _fadingOut)
{
if (!TryComp(stream, out AudioComponent? component))
{
_fadeToRemove.Add(stream);
continue;
}
var volume = component.Volume - change * frameTime;
volume = MathF.Max(MinVolume, volume);
_audio.SetVolume(stream, volume, component);
if (component.Volume.Equals(MinVolume))
{
_audio.Stop(stream);
_fadeToRemove.Add(stream);
}
}
foreach (var stream in _fadeToRemove)
{
_fadingOut.Remove(stream);
}
_fadeToRemove.Clear();
foreach (var (stream, (change, target)) in _fadingIn)
{
// Cancelled elsewhere
if (!TryComp(stream, out AudioComponent? component))
{
_fadeToRemove.Add(stream);
continue;
}
var volume = component.Volume - change * frameTime;
volume = MathF.Min(target, volume);
_audio.SetVolume(stream, volume, component);
if (component.Volume.Equals(target))
{
_fadeToRemove.Add(stream);
}
}
foreach (var stream in _fadeToRemove)
{
_fadingIn.Remove(stream);
}
}
#endregion
}
/// <summary>
/// Raised whenever ambient music tries to play.
/// </summary>
[ByRefEvent]
public record struct PlayAmbientMusicEvent(bool Cancelled = false);